/// <summary> /// Read the header /// </summary> internal void ReadHeader(ClassFile cf) { var magic = stream.ReadU4(); if (magic != ClassFile.Magic) throw new Dot42Exception("Invalid magic"); cf.MinorVersion = stream.ReadU2(); cf.MajorVersion = stream.ReadU2(); var cpCount = stream.ReadU2(); var cp = new ConstantPool(cpCount, cf.Loader); for (var i = 1; i < cpCount; i++) { var tag = (ConstantPoolTags) stream.ReadU1(); ConstantPoolEntry entry; int tmp; switch (tag) { case ConstantPoolTags.Class: entry = new ConstantPoolClass(cp, stream.ReadU2()); break; case ConstantPoolTags.Fieldref: tmp = stream.ReadU2(); entry = new ConstantPoolFieldRef(cp, tmp, stream.ReadU2()); break; case ConstantPoolTags.Methodref: tmp = stream.ReadU2(); entry = new ConstantPoolMethodRef(cp, tmp, stream.ReadU2()); break; case ConstantPoolTags.InterfaceMethodref: tmp = stream.ReadU2(); entry = new ConstantPoolInterfaceMethodRef(cp, tmp, stream.ReadU2()); break; case ConstantPoolTags.String: entry = new ConstantPoolString(cp, stream.ReadU2()); break; case ConstantPoolTags.Integer: entry = new ConstantPoolInteger(cp, stream.ReadS4()); break; case ConstantPoolTags.Float: entry = new ConstantPoolFloat(cp, stream.ReadF4()); break; case ConstantPoolTags.Long: entry = new ConstantPoolLong(cp, stream.ReadS8()); break; case ConstantPoolTags.Double: entry = new ConstantPoolDouble(cp, stream.ReadF8()); break; case ConstantPoolTags.NameAndType: tmp = stream.ReadU2(); entry = new ConstantPoolNameAndType(cp, tmp, stream.ReadU2()); break; case ConstantPoolTags.Utf8: tmp = stream.ReadU2(); entry = new ConstantPoolUtf8(cp, stream.ReadUTF8(tmp)); break; default: throw new Dot42Exception("Unknown constant pool tag: " + (int)tag); } cp[i] = entry; if ((tag == ConstantPoolTags.Double) || (tag == ConstantPoolTags.Long)) i++; } cf.ClassAccessFlags = (ClassAccessFlags) stream.ReadU2(); var index = stream.ReadU2(); cf.ClassName = cp.GetEntry<ConstantPoolClass>(index).Name; index = stream.ReadU2(); cf.SuperClass = (index == 0) ? null : new ObjectTypeReference(cp.GetEntry<ConstantPoolClass>(index).Name, null); // Interfaces var icount = stream.ReadU2(); var interfaces = new string[icount]; for (var i = 0; i < icount; i++) { index = stream.ReadU2(); interfaces[i] = cp.GetEntry<ConstantPoolClass>(index).Name; } cf.Interfaces = interfaces.Select(x => new ObjectTypeReference(x, null)).ToArray(); // Fields var fcount = stream.ReadU2(); for (var i = 0; i < fcount; i++) { var accessFlags = (FieldAccessFlags) stream.ReadU2(); var nameIndex = stream.ReadU2(); var descriptorIndex = stream.ReadU2(); var name = cp.GetEntry<ConstantPoolUtf8>(nameIndex).Value; var descriptor = cp.GetEntry<ConstantPoolUtf8>(descriptorIndex).Value; var field = new FieldDefinition(cf, accessFlags, name, descriptor, null); ReadAttributes(cp, field); cf.Fields.Add(field); } // Methods var mcount = stream.ReadU2(); for (var i = 0; i < mcount; i++) { var accessFlags = (MethodAccessFlags)stream.ReadU2(); var nameIndex = stream.ReadU2(); var descriptorIndex = stream.ReadU2(); var name = cp.GetEntry<ConstantPoolUtf8>(nameIndex).Value; var descriptor = cp.GetEntry<ConstantPoolUtf8>(descriptorIndex).Value; var method = new MethodDefinition(cf, accessFlags, name, descriptor, null); ReadAttributes(cp, method); cf.Methods.Add(method); } // Attributes ReadAttributes(cp, cf); }
/// <summary> /// Make a .NET field reference from a java constant pool method reference. /// </summary> private XFieldReference AsFieldReference(ConstantPoolFieldRef cpField) { return XBuilder.AsFieldReference(module, cpField); }
/// <summary> /// Convert an Java field reference to an XFieldReference. /// </summary> public static XFieldReference AsFieldReference(XModule module, ConstantPoolFieldRef field) { return AsFieldReference(module, field.Name, field.Descriptor, field.DeclaringType, field.ClassName); }