← 返回首页
using Java_Bytecode_Toolkit.ExtensionsNS;
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Security.RightsManagement;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Documents;
using System.Xml;
using System.Xml.Serialization;
namespace Java_Bytecode_Toolkit
{
public class JavaClassFile : FileSystemItem
{
// Note: Everything in Java binary files is stored in big-endian order.
public const bool IS_JAVA_BINARY_FILE_LITTLE_ENDIAN = false;
public UInt32 magic = 0;
public UInt16 minorVersion = 0;
public UInt16 majorVersion = 0;
public UInt16 constantPoolCount = 0;
// Array size = constantPoolCount - 1
public ConstantPoolInfo[] constantPool = null;
// Original type: UInt16
public AccessFlags accessFlags = 0;
public UInt16 thisClass = 0;
public UInt16 superClass = 0;
public UInt16 interfacesCount = 0;
// Array size = interfacesCount
public UInt16[] interfaces = null;
public UInt16 fieldsCount = 0;
// Array size = fieldsCount
public FieldInfo[] fields = null;
public UInt16 methodsCount = 0;
// Array size = methodsCount
public MethodInfo[] methods = null;
public UInt16 attributesCount = 0;
// Array size = attributesCount
public AttributeInfo[] attributes = null;
public JavaClassFile() : base()
{
}
public JavaClassFile(string javaClassFilePath) : base(javaClassFilePath)
{
bool readSuccessful = this.Read();
}
public bool Read()
{
try
{
using (FileStream javaClassFileStream = File.OpenRead(this.filePath))
{
this.magic = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.minorVersion = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.majorVersion = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.constantPoolCount = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.constantPool = new ConstantPoolInfo[this.constantPoolCount - 1];
this.ReadConstantPool(javaClassFileStream);
this.accessFlags = (AccessFlags)javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.thisClass = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.superClass = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.interfacesCount = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.interfaces = new ushort[this.interfacesCount];
this.ReadInterfaces(javaClassFileStream);
this.fieldsCount = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.fields = new FieldInfo[this.fieldsCount];
this.ReadFields(javaClassFileStream);
this.methodsCount = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.methods = new MethodInfo[this.methodsCount];
this.ReadMethods(javaClassFileStream);
this.attributesCount = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.attributes = new AttributeInfo[this.attributesCount];
this.ReadAttributes(javaClassFileStream);
}
}
catch (Exception e)
{
App.Current.logger.WriteLine(e.ToString());
return false;
}
return true;
}
// TODO: Handle different types of attributes.
public void ReadAttributes(FileStream javaClassFileStream)
{
for (int currentIndex = 0; currentIndex < this.attributesCount; currentIndex++)
{
AttributeInfo currentAttributeInfo = new AttributeInfo();
currentAttributeInfo.attributeNameIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
currentAttributeInfo.attributeLength = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
currentAttributeInfo.info = new byte[currentAttributeInfo.attributeLength];
for (int currentInfoByteIndex = 0; currentInfoByteIndex < currentAttributeInfo.attributeLength; currentInfoByteIndex++)
{
currentAttributeInfo.info[currentInfoByteIndex] = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
}
this.attributes[currentIndex] = currentAttributeInfo;
}
}
// TODO: Handle different types of attributes.
public void ReadAttributesOfMethod(FileStream javaClassFileStream, MethodInfo methodInfo)
{
for (int currentIndex = 0; currentIndex < methodInfo.attributesCount; currentIndex++)
{
AttributeInfo currentAttributeInfo = new AttributeInfo();
currentAttributeInfo.attributeNameIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
currentAttributeInfo.attributeLength = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
currentAttributeInfo.info = new byte[currentAttributeInfo.attributeLength];
for (int currentInfoByteIndex = 0; currentInfoByteIndex < currentAttributeInfo.attributeLength; currentInfoByteIndex++)
{
currentAttributeInfo.info[currentInfoByteIndex] = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
}
methodInfo.attributes[currentIndex] = currentAttributeInfo;
}
}
public void ReadMethods(FileStream javaClassFileStream)
{
for (int currentMethodIndex = 0; currentMethodIndex < this.methodsCount; currentMethodIndex++)
{
MethodInfo currentMethodInfo = new MethodInfo();
currentMethodInfo.accessFlags = (MethodAccessFlags)javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
currentMethodInfo.nameIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
currentMethodInfo.descriptorIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
currentMethodInfo.attributesCount = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
currentMethodInfo.attributes = new AttributeInfo[currentMethodInfo.attributesCount];
this.ReadAttributesOfMethod(
javaClassFileStream,
currentMethodInfo
);
this.methods[currentMethodIndex] = currentMethodInfo;
}
}
// TODO: Handle different types of attributes.
public void ReadAttributesOfField(FileStream javaClassFileStream, FieldInfo fieldInfo)
{
for (int currentIndex = 0; currentIndex < fieldInfo.AttributesCount; currentIndex++)
{
fieldInfo.attributes[currentIndex] = new AttributeInfo()
{
attributeNameIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
),
attributeLength = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
),
info = new byte[fieldInfo.attributes[currentIndex].attributeLength]
};
for (int currentInfoByteIndex = 0; currentInfoByteIndex < fieldInfo.attributes[currentIndex].attributeLength; currentInfoByteIndex++)
{
fieldInfo.attributes[currentIndex].info[currentInfoByteIndex] = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
}
}
}
public void ReadFields(FileStream javaClassFileStream)
{
for (int currentIndex = 0; currentIndex < this.fieldsCount; currentIndex++)
{
this.fields[currentIndex] = new FieldInfo()
{
fieldAccessFlags = (FieldAccessFlags)javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
),
nameIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
),
descriptorIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
),
AttributesCount = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
)
};
this.ReadAttributesOfField(
javaClassFileStream,
this.fields[currentIndex]
);
}
}
public void ReadInterfaces(FileStream javaClassFileStream)
{
for (int currentIndex = 0; currentIndex < this.interfacesCount; currentIndex++)
{
this.interfaces[currentIndex] = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
}
}
public void ReadConstantPool(FileStream javaClassFileStream)
{
for (int currentEntryIndex = 0; currentEntryIndex < this.constantPool.Length; currentEntryIndex++)
{
ConstantPoolTags currentConstantPoolEntryTag = (ConstantPoolTags)javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
switch (currentConstantPoolEntryTag)
{
case ConstantPoolTags.CONSTANT_Class:
ConstantClassInfo constantClassInfo = new ConstantClassInfo();
constantClassInfo.nameIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.constantPool[currentEntryIndex] = constantClassInfo;
break;
case ConstantPoolTags.CONSTANT_Fieldref:
ConstantFieldRefInfo constantFieldRefInfo = new ConstantFieldRefInfo();
constantFieldRefInfo.classIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
constantFieldRefInfo.nameAndTypeIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.constantPool[currentEntryIndex] = constantFieldRefInfo;
break;
case ConstantPoolTags.CONSTANT_Methodref:
ConstantMethodRefInfo constantMethodRefInfo = new ConstantMethodRefInfo();
constantMethodRefInfo.classIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
constantMethodRefInfo.nameAndTypeIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.constantPool[currentEntryIndex] = constantMethodRefInfo;
break;
case ConstantPoolTags.CONSTANT_InterfaceMethodref:
ConstantInterfaceMethodRefInfo constantInterfaceMethodRefInfo = new ConstantInterfaceMethodRefInfo();
constantInterfaceMethodRefInfo.classIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
constantInterfaceMethodRefInfo.nameAndTypeIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.constantPool[currentEntryIndex] = constantInterfaceMethodRefInfo;
break;
case ConstantPoolTags.CONSTANT_String:
ConstantStringInfo constantStringInfo = new ConstantStringInfo();
constantStringInfo.stringIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.constantPool[currentEntryIndex] = constantStringInfo;
break;
case ConstantPoolTags.CONSTANT_Integer:
ConstantIntegerInfo constantIntegerInfo = new ConstantIntegerInfo();
constantIntegerInfo.bytes = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.constantPool[currentEntryIndex] = constantIntegerInfo;
break;
case ConstantPoolTags.CONSTANT_Float:
ConstantFloatInfo constantFloatInfo = new ConstantFloatInfo();
constantFloatInfo.bytes = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.constantPool[currentEntryIndex] = constantFloatInfo;
break;
case ConstantPoolTags.CONSTANT_Long:
ConstantLongInfo constantLongInfo = new ConstantLongInfo();
constantLongInfo.highBytes = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
constantLongInfo.lowBytes = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.constantPool[currentEntryIndex] = constantLongInfo;
break;
case ConstantPoolTags.CONSTANT_Double:
ConstantDoubleInfo constantDoubleInfo = new ConstantDoubleInfo();
constantDoubleInfo.highBytes = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
constantDoubleInfo.lowBytes = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.constantPool[currentEntryIndex] = constantDoubleInfo;
break;
case ConstantPoolTags.CONSTANT_NameAndType:
ConstantNameAndTypeInfo constantNameAndTypeInfo = new ConstantNameAndTypeInfo();
constantNameAndTypeInfo.nameIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
constantNameAndTypeInfo.descriptorIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.constantPool[currentEntryIndex] = constantNameAndTypeInfo;
break;
case ConstantPoolTags.CONSTANT_UTF8:
ConstantUTF8Info constantUTF8Info = new ConstantUTF8Info();
constantUTF8Info.Length = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
for (int currentByteIndex = 0; currentByteIndex < constantUTF8Info.Length; currentByteIndex++)
{
constantUTF8Info.bytes[currentByteIndex] = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
}
this.constantPool[currentEntryIndex] = constantUTF8Info;
break;
case ConstantPoolTags.CONSTANT_MethodHandle:
ConstantMethodHandleInfo constantMethodHandleInfo = new ConstantMethodHandleInfo();
constantMethodHandleInfo.referenceKind = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
constantMethodHandleInfo.referenceIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.constantPool[currentEntryIndex] = constantMethodHandleInfo;
break;
case ConstantPoolTags.CONSTANT_MethodType:
ConstantMethodTypeInfo constantMethodTypeInfo = new ConstantMethodTypeInfo();
constantMethodTypeInfo.descriptorIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.constantPool[currentEntryIndex] = constantMethodTypeInfo;
break;
case ConstantPoolTags.CONSTANT_InvokeDynamic:
ConstantInvokeDynamicInfo constantInvokeDynamicInfo = new ConstantInvokeDynamicInfo();
constantInvokeDynamicInfo.bootstrapMethodAttrIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
constantInvokeDynamicInfo.nameAndTypeIndex = javaClassFileStream.ReadBytesFromStreamAs(
IS_JAVA_BINARY_FILE_LITTLE_ENDIAN
);
this.constantPool[currentEntryIndex] = constantInvokeDynamicInfo;
break;
default:
break;
}
}
}
public void Save()
{
}
public override void ExportAsXMLFile(string exportedXMLFilePath)
{
using (XmlWriter xmlWriter = XmlWriter.Create(exportedXMLFilePath, DEFAULT_XML_WRITER_SETTINGS))
{
this.WriteToXMLWriter(xmlWriter, this);
xmlWriter.Flush();
}
}
public class ConstantPoolInfo
{
public ConstantPoolTags tag = ConstantPoolTags.Unknown;
public ConstantPoolInfo()
{
}
}
public class ConstantClassInfo : ConstantPoolInfo
{
public UInt16 nameIndex = 0;
public ConstantClassInfo()
{
this.tag = ConstantPoolTags.CONSTANT_Class;
}
public string GetName(JavaClassFile javaClassFile)
{
string name = "";
try
{
name = (javaClassFile.constantPool[this.nameIndex] as ConstantUTF8Info).BytesAsASCIIString;
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return name;
}
}
public class ConstantFieldRefInfo : ConstantPoolInfo
{
public UInt16 classIndex = 0;
public UInt16 nameAndTypeIndex = 0;
public ConstantFieldRefInfo()
{
this.tag = ConstantPoolTags.CONSTANT_Fieldref;
}
public string GetClassName(JavaClassFile javaClassFile)
{
string className = "";
try
{
className = (javaClassFile.constantPool[this.classIndex] as ConstantClassInfo).GetName(
javaClassFile
);
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return className;
}
public string GetName(JavaClassFile javaClassFile)
{
string name = "";
try
{
name = (javaClassFile.constantPool[this.nameAndTypeIndex] as ConstantNameAndTypeInfo).GetName(
javaClassFile
);
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return name;
}
public string GetType(JavaClassFile javaClassFile)
{
string type = "";
try
{
type = (javaClassFile.constantPool[this.nameAndTypeIndex] as ConstantNameAndTypeInfo).GetDescriptor(
javaClassFile
);
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return type;
}
}
public class ConstantMethodRefInfo : ConstantPoolInfo
{
public UInt16 classIndex = 0;
public UInt16 nameAndTypeIndex = 0;
public ConstantMethodRefInfo()
{
this.tag = ConstantPoolTags.CONSTANT_Methodref;
}
public string GetClassName(JavaClassFile javaClassFile)
{
string className = "";
try
{
className = (javaClassFile.constantPool[this.classIndex] as ConstantClassInfo).GetName(
javaClassFile
);
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return className;
}
public string GetName(JavaClassFile javaClassFile)
{
string name = "";
try
{
name = (javaClassFile.constantPool[this.nameAndTypeIndex] as ConstantNameAndTypeInfo).GetName(
javaClassFile
);
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return name;
}
public string GetType(JavaClassFile javaClassFile)
{
string type = "";
try
{
type = (javaClassFile.constantPool[this.nameAndTypeIndex] as ConstantNameAndTypeInfo).GetDescriptor(
javaClassFile
);
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return type;
}
}
public class ConstantInterfaceMethodRefInfo : ConstantPoolInfo
{
public UInt16 classIndex = 0;
public UInt16 nameAndTypeIndex = 0;
public ConstantInterfaceMethodRefInfo()
{
this.tag = ConstantPoolTags.CONSTANT_InterfaceMethodref;
}
public string GetClassName(JavaClassFile javaClassFile)
{
string className = "";
try
{
className = (javaClassFile.constantPool[this.classIndex] as ConstantClassInfo).GetName(
javaClassFile
);
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return className;
}
public string GetName(JavaClassFile javaClassFile)
{
string name = "";
try
{
name = (javaClassFile.constantPool[this.nameAndTypeIndex] as ConstantNameAndTypeInfo).GetName(
javaClassFile
);
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return name;
}
public string GetType(JavaClassFile javaClassFile)
{
string type = "";
try
{
type = (javaClassFile.constantPool[this.nameAndTypeIndex] as ConstantNameAndTypeInfo).GetDescriptor(
javaClassFile
);
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return type;
}
}
public class ConstantStringInfo : ConstantPoolInfo
{
public UInt16 stringIndex = 0;
public ConstantStringInfo()
{
this.tag = ConstantPoolTags.CONSTANT_String;
}
public string GetStringValue(JavaClassFile javaClassFile)
{
string stringValue = "";
try
{
stringValue = (javaClassFile.constantPool[this.stringIndex] as ConstantUTF8Info).BytesAsASCIIString;
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return stringValue;
}
}
public class ConstantIntegerInfo : ConstantPoolInfo
{
public UInt32 bytes = 0;
public ConstantIntegerInfo()
{
this.tag = ConstantPoolTags.CONSTANT_Integer;
}
}
public class ConstantFloatInfo : ConstantPoolInfo
{
public UInt32 bytes = 0;
public ConstantFloatInfo()
{
this.tag = ConstantPoolTags.CONSTANT_Float;
}
}
public class ConstantLongInfo : ConstantPoolInfo
{
public UInt32 highBytes = 0;
public UInt32 lowBytes = 0;
public ConstantLongInfo()
{
this.tag = ConstantPoolTags.CONSTANT_Long;
}
}
public class ConstantDoubleInfo : ConstantPoolInfo
{
public UInt32 highBytes = 0;
public UInt32 lowBytes = 0;
public ConstantDoubleInfo()
{
this.tag = ConstantPoolTags.CONSTANT_Double;
}
}
public class ConstantNameAndTypeInfo : ConstantPoolInfo
{
public UInt16 nameIndex = 0;
public UInt16 descriptorIndex = 0;
public ConstantNameAndTypeInfo()
{
this.tag = ConstantPoolTags.CONSTANT_NameAndType;
}
public string GetName(JavaClassFile javaClassFile)
{
string name = "";
try
{
name = (javaClassFile.constantPool[this.nameIndex] as ConstantUTF8Info).BytesAsASCIIString;
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return name;
}
public string GetDescriptor(JavaClassFile javaClassFile)
{
string descriptor = "";
try
{
descriptor = (javaClassFile.constantPool[this.descriptorIndex] as ConstantUTF8Info).BytesAsASCIIString;
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return descriptor;
}
}
public class ConstantUTF8Info : ConstantPoolInfo
{
public byte[] bytes = new byte[0];
public UInt16 Length
{
get
{
return (UInt16)bytes.Length;
}
set
{
bytes = new byte[value];
}
}
public string BytesAsASCIIString
{
get
{
return Encoding.ASCII.GetString(this.bytes);
}
}
public ConstantUTF8Info()
{
this.tag = ConstantPoolTags.CONSTANT_UTF8;
}
}
public class ConstantMethodHandleInfo : ConstantPoolInfo
{
public byte referenceKind = 0;
public UInt16 referenceIndex = 0;
public ConstantMethodHandleInfo()
{
this.tag = ConstantPoolTags.CONSTANT_MethodHandle;
}
}
public class ConstantMethodTypeInfo : ConstantPoolInfo
{
public UInt16 descriptorIndex = 0;
public ConstantMethodTypeInfo()
{
this.tag = ConstantPoolTags.CONSTANT_MethodType;
}
public string GetDescriptor(JavaClassFile javaClassFile)
{
string descriptor = "";
try
{
descriptor = (javaClassFile.constantPool[this.descriptorIndex] as ConstantUTF8Info).BytesAsASCIIString;
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return descriptor;
}
}
public class ConstantInvokeDynamicInfo : ConstantPoolInfo
{
public UInt16 bootstrapMethodAttrIndex = 0;
public UInt16 nameAndTypeIndex = 0;
public ConstantInvokeDynamicInfo()
{
this.tag = ConstantPoolTags.CONSTANT_InvokeDynamic;
}
public string GetName(JavaClassFile javaClassFile)
{
ConstantNameAndTypeInfo constantNameAndTypeInfo = javaClassFile.constantPool[this.nameAndTypeIndex] as ConstantNameAndTypeInfo;
return constantNameAndTypeInfo.GetName(javaClassFile);
}
public string GetType(JavaClassFile javaClassFile)
{
ConstantNameAndTypeInfo constantNameAndTypeInfo = javaClassFile.constantPool[this.nameAndTypeIndex] as ConstantNameAndTypeInfo;
return constantNameAndTypeInfo.GetDescriptor(javaClassFile);
}
}
public class FieldInfo
{
///
/// Original type: UInt16
///
public FieldAccessFlags fieldAccessFlags = 0;
public UInt16 nameIndex = 0;
public UInt16 descriptorIndex = 0;
///
/// Array size = attributesCount
///
public AttributeInfo[] attributes = new AttributeInfo[0];
public UInt16 AttributesCount
{
get
{
return (UInt16)this.attributes.Length;
}
set
{
this.attributes = new AttributeInfo[value];
}
}
public FieldInfo()
{
}
public string GetName(JavaClassFile javaClassFile)
{
string name = "";
try
{
name = (javaClassFile.constantPool[this.nameIndex] as ConstantUTF8Info).BytesAsASCIIString;
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return name;
}
public string GetDescriptor(JavaClassFile javaClassFile)
{
string descriptor = "";
try
{
descriptor = (javaClassFile.constantPool[this.descriptorIndex] as ConstantUTF8Info).BytesAsASCIIString;
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return descriptor;
}
}
public class MethodInfo
{
///
/// Original type: UInt16
///
public MethodAccessFlags accessFlags = 0;
public UInt16 nameIndex = 0;
public UInt16 descriptorIndex = 0;
public UInt16 attributesCount = 0;
public AttributeInfo[] attributes = new AttributeInfo[0];
public MethodInfo()
{
}
public string GetName(JavaClassFile javaClassFile)
{
string name = "";
try
{
name = (javaClassFile.constantPool[this.nameIndex] as ConstantUTF8Info).BytesAsASCIIString;
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return name;
}
public string GetDescriptor(JavaClassFile javaClassFile)
{
string descriptor = "";
try
{
descriptor = (javaClassFile.constantPool[this.descriptorIndex] as ConstantUTF8Info).BytesAsASCIIString;
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return descriptor;
}
}
public class AttributeInfo
{
public UInt16 attributeNameIndex = 0;
public UInt32 attributeLength = 0;
///
/// Array size = attributeLength
///
public byte[] info = new byte[0];
public AttributeInfo()
{
}
public string GetAttributeName(JavaClassFile javaClassFile)
{
string attribName = "";
try
{
attribName = (javaClassFile.constantPool[attributeNameIndex] as ConstantUTF8Info).BytesAsASCIIString;
}
catch (Exception e)
{
App.Current.logger.WriteLine(
e.ToString()
);
}
return attribName;
}
public void WriteToXMLWriter(XmlWriter xmlWriter, JavaClassFile javaClassFile)
{
}
}
[Flags]
public enum AccessFlags
{
///
/// Declared as public. May be accessed from outside its package.
///
ACC_PUBLIC = 0x0001,
///
/// Declared as final. No subclasses allowed.
///
ACC_FINAL = 0x0010,
///
/// Treat superclass methods specially when invoked by the
/// invokespecial instruction.
///
ACC_SUPER = 0x0020,
///
/// Is an interface, not a class.
///
ACC_INTERFACE = 0x0200,
///
/// Declared as abstract. Must not be instantiated.
///
ACC_ABSTRACT = 0x0400,
///
/// Declared as synthetic. Not present in the source code, generated
/// by a compiler.
///
ACC_SYNTHETIC = 0x1000,
///
/// Declared as an annotation type.
///
ACC_ANNOTATION = 0x2000,
///
/// Declared as an enum type.
///
ACC_ENUM = 0x4000
}
public enum ConstantPoolTags
{
CONSTANT_Class = 7,
CONSTANT_Fieldref = 9,
CONSTANT_Methodref = 10,
CONSTANT_InterfaceMethodref = 11,
CONSTANT_String = 8,
CONSTANT_Integer = 3,
CONSTANT_Float = 4,
CONSTANT_Long = 5,
CONSTANT_Double = 6,
CONSTANT_NameAndType = 12,
CONSTANT_UTF8 = 1,
CONSTANT_MethodHandle = 15,
CONSTANT_MethodType = 16,
CONSTANT_InvokeDynamic = 18,
Unknown = 0
}
[Flags]
public enum FieldAccessFlags
{
///
/// Declared public. May be accessed from outside its package.
///
ACC_PUBLIC = 0x0001,
///
/// Declared private. Usable only within the defining class.
///
ACC_PRIVATE = 0x0002,
///
/// Declared protected. May be accessed within subclasses.
///
ACC_PROTECTED = 0x0004,
///
/// Declared static.
///
ACC_STATIC = 0x0008,
///
/// Declared final. Never directly assigned to after object
/// construction.
///
ACC_FINAL = 0x0010,
///
/// Declared volatile. Cannot be cached.
///
ACC_VOLATILE = 0x0040,
///
/// Declared transient. Not written or read by a persistent object
/// manager.
///
ACC_TRANSIENT = 0x0080,
///
/// Declared synthetic. Not present in the source code.
///
ACC_SYNTHETIC = 0x1000,
///
/// Declared as an element of an enum.
///
ACC_ENUM = 0x4000
}
[Flags]
public enum MethodAccessFlags
{
///
/// Declared public; may be accessed from outside its package.
///
ACC_PUBLIC = 0x0001,
///
/// Declared private; accessible only within the defining class.
///
ACC_PRIVATE = 0x0002,
///
/// Declared protected; may be accessed within subclasses.
///
ACC_PROTECTED = 0x0004,
///
/// Declared static.
///
ACC_STATIC = 0x0008,
///
/// Declared final; must not be overridden.
///
ACC_FINAL = 0x0010,
///
/// Declared synchronized; invocation is wrapped by a monitor use.
///
ACC_SYNCHRONIZED = 0x0020,
///
/// A bridge method, generated by the compiler.
///
ACC_BRIDGE = 0x0040,
///
/// Declared with variable number of arguments.
///
ACC_VARARGS = 0x0080,
///
/// Declared native; implemented in a language other than Java.
///
ACC_NATIVE = 0x0100,
///
/// Declared abstract; no implementation is provided.
///
ACC_ABSTRACT = 0x0400,
///
/// Declared strictfp; floating-point mode is FP-strict.
///
ACC_STRICT = 0x0800,
///
/// Declared synthetic; not present in the source code.
///
ACC_SYNTHETIC = 0x1000
}
}
}