Example #1
0
 internal static void WriteAttribute(Stream stream, AttributeNode attribute, ClassWriterState state, AttributeScope scope)
 {
     Binary.BigEndian.Write(stream, state.ConstantPool.Find(new Utf8Entry(attribute.Name)));
     attribute.Data = attribute.ParsedAttribute?.Save(state, scope) ?? attribute.Data;
     if (attribute.Data.LongLength > uint.MaxValue)
     {
         throw new ArgumentOutOfRangeException(nameof(attribute.Data.LongLength), $"Attribute data length too big: {attribute.Data.LongLength} > {uint.MaxValue}");
     }
     Binary.BigEndian.Write(stream, (uint)attribute.Data.LongLength);
     stream.Write(attribute.Data);
 }
Example #2
0
 private static void WriteMethod(Stream stream, MethodNode methodNode, ClassWriterState state)
 {
     Binary.BigEndian.Write(stream, (ushort)methodNode.Access);
     Binary.BigEndian.Write(stream, state.ConstantPool.Find(new Utf8Entry(methodNode.Name)));
     Binary.BigEndian.Write(stream, state.ConstantPool.Find(new Utf8Entry(methodNode.Descriptor.ToString())));
     if (methodNode.Attributes.Count > ushort.MaxValue)
     {
         throw new ArgumentOutOfRangeException(nameof(methodNode.Attributes.Count), $"Too many attributes: {methodNode.Attributes.Count} > {ushort.MaxValue}");
     }
     Binary.BigEndian.Write(stream, (ushort)methodNode.Attributes.Count);
     foreach (var attriute in methodNode.Attributes)
     {
         WriteAttribute(stream, attriute, state, AttributeScope.Method);
     }
 }
Example #3
0
        public static void WriteClass(Stream stream, ClassNode classNode)
        {
            Binary.BigEndian.Write(stream, Magic);
            Binary.BigEndian.Write(stream, classNode.MinorVersion);
            Binary.BigEndian.Write(stream, (ushort)classNode.MajorVersion);
            var afterConstantPoolDataStream = new MemoryStream();
            var constantPool = new ConstantPool();
            var state        = new ClassWriterState
            {
                ClassNode    = classNode,
                ConstantPool = constantPool
            };

            classNode.Save(state);

            Binary.BigEndian.Write(afterConstantPoolDataStream, (ushort)classNode.Access);
            Binary.BigEndian.Write(afterConstantPoolDataStream,
                                   constantPool.Find(new ClassEntry(new Utf8Entry(classNode.Name.Name))));
            Binary.BigEndian.Write(afterConstantPoolDataStream,
                                   constantPool.Find(new ClassEntry(new Utf8Entry(classNode.SuperName.Name))));

            if (classNode.Interfaces.Count > ushort.MaxValue)
            {
                throw new ArgumentOutOfRangeException(nameof(classNode.Interfaces.Count), $"Too many interfaces: {classNode.Interfaces.Count} > {ushort.MaxValue}");
            }
            Binary.BigEndian.Write(afterConstantPoolDataStream, (ushort)classNode.Interfaces.Count);
            foreach (var interfaceClassName in classNode.Interfaces)
            {
                Binary.BigEndian.Write(afterConstantPoolDataStream,
                                       constantPool.Find(new ClassEntry(new Utf8Entry(interfaceClassName.Name))));
            }

            if (classNode.Fields.Count > ushort.MaxValue)
            {
                throw new ArgumentOutOfRangeException(nameof(classNode.Fields.Count), $"Too many fields: {classNode.Fields.Count} > {ushort.MaxValue}");
            }
            Binary.BigEndian.Write(afterConstantPoolDataStream, (ushort)classNode.Fields.Count);
            foreach (var field in classNode.Fields)
            {
                WriteField(afterConstantPoolDataStream, field, state);
            }

            if (classNode.Methods.Count > ushort.MaxValue)
            {
                throw new ArgumentOutOfRangeException(nameof(classNode.Methods.Count), $"Too many methods: {classNode.Methods.Count} > {ushort.MaxValue}");
            }
            Binary.BigEndian.Write(afterConstantPoolDataStream, (ushort)classNode.Methods.Count);
            foreach (var method in classNode.Methods)
            {
                WriteMethod(afterConstantPoolDataStream, method, state);
            }

            if (classNode.Attributes.Count > ushort.MaxValue)
            {
                throw new ArgumentOutOfRangeException(nameof(classNode.Attributes.Count), $"Too many attributes: {classNode.Attributes.Count} > {ushort.MaxValue}");
            }
            Binary.BigEndian.Write(afterConstantPoolDataStream, (ushort)classNode.Attributes.Count);
            foreach (var attriute in classNode.Attributes)
            {
                WriteAttribute(afterConstantPoolDataStream, attriute, state, AttributeScope.Class);
            }

            constantPool.Write(stream);
            stream.Write(afterConstantPoolDataStream.ToArray());
        }