/// <inheritdoc/>
        protected override void WriteSingleItem(
            TinyBinaryWriter writer,
            MethodDefinition item)
        {
            WriteStringReference(writer, item.Name);
            writer.WriteUInt16(_context.ByteCodeTable.GetMethodRva(item));

            writer.WriteUInt32(GetFlags(item));

            var parametersCount = (Byte)item.Parameters.Count;

            if (!item.IsStatic)
            {
                ++parametersCount; // add implicit 'this' pointer into non-static methods
            }

            _context.SignaturesTable.WriteDataType(item.ReturnType, writer, false, false);
            if (item.ReturnType is TypeSpecification)
            {
                _context.TypeSpecificationsTable
                .GetOrCreateTypeSpecificationId(item.ReturnType);
            }

            writer.WriteByte(parametersCount);
            writer.WriteByte((Byte)(item.HasBody ? item.Body.Variables.Count : 0));
            writer.WriteByte(CodeWriter.CalculateStackSize(item.Body));

            var methodSignature = _context.SignaturesTable.GetOrCreateSignatureId(item);

            writer.WriteUInt16(item.HasBody ?
                               _context.SignaturesTable.GetOrCreateSignatureId(item.Body.Variables) :
                               (item.IsAbstract || item.IsRuntime ? (UInt16)0x0000 : (UInt16)0xFFFF));
            writer.WriteUInt16(methodSignature);
        }
 /// <inheritdoc/>
 public void Write(
     TinyBinaryWriter writer)
 {
     WriteAttributes(writer, 0x0004, _typesAttributes);
     WriteAttributes(writer, 0x0005, _fieldsAttributes);
     WriteAttributes(writer, 0x0006, _methodsAttributes);
 }
Пример #3
0
 /// <inheritdoc/>
 public void Write(
     TinyBinaryWriter writer)
 {
     WriteAttributes(writer, 0x0004, _typesAttributes);
     WriteAttributes(writer, 0x0005, _fieldsAttributes);
     WriteAttributes(writer, 0x0006, _methodsAttributes);
 }
 /// <inheritdoc/>
 public void Write(
     TinyBinaryWriter writer)
 {
     foreach (var item in _dataByteArrays)
     {
         writer.WriteBytes(item);
     }
 }
Пример #5
0
 /// <inheritdoc/>
 public void Write(
     TinyBinaryWriter writer)
 {
     foreach (var method in _methods)
     {
         writer.WriteBytes(CreateByteCode(method, writer));
     }
 }
 /// <inheritdoc/>
 public void Write(
     TinyBinaryWriter writer)
 {
     foreach (var item in _dataByteArrays)
     {
         writer.WriteBytes(item);
     }
 }
Пример #7
0
        /// <inheritdoc/>
        protected override void WriteSingleItem(
            TinyBinaryWriter writer,
            AssemblyNameReference item)
        {
            WriteStringReference(writer, item.Name);
            writer.WriteUInt16(0); // padding

            writer.WriteVersion(item.Version);
        }
Пример #8
0
        /// <inheritdoc/>
        protected override void WriteSingleItem(
            TinyBinaryWriter writer,
            TypeDefinition item)
        {
            _context.StringTable.GetOrCreateStringId(item.Namespace);

            WriteStringReference(writer, item.Name);
            WriteStringReference(writer, item.Namespace);

            writer.WriteUInt16(GetTypeReferenceOrDefinitionId(item.BaseType));
            writer.WriteUInt16(GetTypeReferenceOrDefinitionId(item.DeclaringType));

            var fieldsList = item.Fields
                             .Where(field => !field.HasConstant)
                             .OrderByDescending(field => field.IsStatic)
                             .ToList();

            foreach (var field in fieldsList)
            {
                _context.SignaturesTable.GetOrCreateSignatureId(field);
                _context.SignaturesTable.GetOrCreateSignatureId(field.InitialValue);
            }

            using (var stream = new MemoryStream(6))
            {
                WriteClassFields(fieldsList, writer.GetMemoryBasedClone(stream));

                if (item.DeclaringType == null)
                {
                    foreach (var method in item.Methods)
                    {
                        var offsets = CodeWriter
                                      .PreProcessMethod(method, _context.ByteCodeTable.FakeStringTable)
                                      .ToList();
                        _byteCodeOffsets.Add(method.MetadataToken.ToUInt32(), offsets);
                    }
                }
                foreach (var nestedType in item.NestedTypes)
                {
                    foreach (var method in nestedType.Methods)
                    {
                        var offsets = CodeWriter
                                      .PreProcessMethod(method, _context.ByteCodeTable.FakeStringTable)
                                      .ToList();
                        _byteCodeOffsets.Add(method.MetadataToken.ToUInt32(), offsets);
                    }
                }

                WriteMethodBodies(item.Methods, item.Interfaces, writer);

                _context.SignaturesTable.WriteDataType(item, writer, false, true);

                writer.WriteBytes(stream.ToArray());
            }

            writer.WriteUInt16(GetFlags(item)); // flags
        }
Пример #9
0
 /// <inheritdoc/>
 public void Write(
     TinyBinaryWriter writer)
 {
     foreach (var item in _idsByStrings
              .OrderBy(item => item.Value)
              .Select(item => item.Key))
     {
         writer.WriteString(item);
     }
 }
Пример #10
0
 /// <inheritdoc/>
 public void Write(
     TinyBinaryWriter writer)
 {
     foreach (var item in _idsByItemsDictionary
              .OrderBy(item => item.Value)
              .Select(item => item.Key))
     {
         WriteSingleItem(writer, item);
     }
 }
Пример #11
0
        /// <inheritdoc/>
        protected override void WriteSingleItem(
            TinyBinaryWriter writer,
            FieldDefinition item)
        {
            WriteStringReference(writer, item.Name);
            writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item));

            writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item.InitialValue));
            writer.WriteUInt16(GetFlags(item));
        }
        /// <inheritdoc/>
        protected override void WriteSingleItem(
            TinyBinaryWriter writer,
            TypeReference item)
        {
            WriteStringReference(writer, item.Name);
            WriteStringReference(writer, item.Namespace);

            writer.WriteUInt16(GetScope(item)); // scope - TBL_AssemblyRef | TBL_TypeRef // 0x8000
            writer.WriteUInt16(0);              // padding
        }
Пример #13
0
 /// <inheritdoc/>
 public void Write(
     TinyBinaryWriter writer)
 {
     foreach (var signature in _idsBySignatures
              .OrderBy(item => item.Value)
              .Select(item => item.Key))
     {
         writer.WriteBytes(signature);
     }
 }
Пример #14
0
 /// <inheritdoc/>
 public void Write(
     TinyBinaryWriter writer)
 {
     foreach (var item in _idByTypeSpecifications
              .OrderBy(item => item.Value)
              .Select(item => item.Key))
     {
         writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item));
         writer.WriteUInt16(0x0000); // padding
     }
 }
Пример #15
0
        /// <summary>
        /// Creates new instance of <see cref="Mono.Cecil.Cil.CodeWriter"/> object.
        /// </summary>
        /// <param name="method">Original method body in Mono.Cecil format.</param>
        /// <param name="writer">Binary writer for writing byte code in correct endianess.</param>
        /// <param name="stringTable">String references table (for obtaining string ID).</param>
        /// <param name="context">
        /// Assembly tables context - contains all tables used for building target assembly.
        /// </param>
        public CodeWriter(
	        MethodDefinition method,
            TinyBinaryWriter writer,
            TinyStringTable stringTable,
            TinyTablesContext context)
	    {
            _stringTable = stringTable;

            _body = method.Body;
            _context = context;
            _writer = writer;
        }
Пример #16
0
        /// <summary>
        /// Creates new instance of <see cref="Mono.Cecil.Cil.CodeWriter"/> object.
        /// </summary>
        /// <param name="method">Original method body in Mono.Cecil format.</param>
        /// <param name="writer">Binary writer for writing byte code in correct endianess.</param>
        /// <param name="stringTable">String references table (for obtaining string ID).</param>
        /// <param name="context">
        /// Assembly tables context - contains all tables used for building target assembly.
        /// </param>
        public CodeWriter(
            MethodDefinition method,
            TinyBinaryWriter writer,
            TinyStringTable stringTable,
            TinyTablesContext context)
        {
            _stringTable = stringTable;

            _body    = method.Body;
            _context = context;
            _writer  = writer;
        }
        /// <summary>
        /// Writes header information into output stream (w/o CRC and table offsets/paddings).
        /// </summary>
        /// <param name="writer">Binary writer with correct endianness.</param>
        /// <param name="isPreAllocationCall">If true no assembly name will be written.</param>
        public void Write(
            TinyBinaryWriter writer,
            Boolean isPreAllocationCall)
        {
            writer.WriteString("MSSpot1");

            writer.WriteUInt32(0); // header CRC
            writer.WriteUInt32(0); // assembly CRC

            writer.WriteUInt32(writer.IsBigEndian ? FLAGS_BIG_ENDIAN : FLAGS_LITTLE_ENDIAN);

            // This CRC calculated only for BE assemblies!!!
            writer.WriteUInt32(writer.IsBigEndian ? _context.NativeMethodsCrc.Current : 0x00);
            writer.WriteUInt32(0xFFFFFFFF); // Native methods offset

            writer.WriteVersion(_context.AssemblyDefinition.Name.Version);

            writer.WriteUInt16(isPreAllocationCall
                ? (UInt16) 0x0000
                : _context.StringTable.GetOrCreateStringId(_context.AssemblyDefinition.Name.Name));
            writer.WriteUInt16(1); // String table version

            if (isPreAllocationCall)
            {
                _tablesOffset = writer.BaseStream.Position;
                for (var i = 0; i < 16; ++i)
                {
                    writer.WriteUInt32(0);
                }

                writer.WriteUInt32(0); // Number of patched methods

                _paddingsOffset = writer.BaseStream.Position;
                for (var i = 0; i < 16; ++i)
                {
                    writer.WriteByte(0);
                }
            }
            else
            {
                writer.BaseStream.Seek(12, SeekOrigin.Begin);

                var assemblyCrc32 = ComputeCrc32(writer.BaseStream,
                    _paddingsOffset, writer.BaseStream.Length - _paddingsOffset);
                writer.WriteUInt32(assemblyCrc32);

                writer.BaseStream.Seek(8, SeekOrigin.Begin);

                var headerCrc32 = ComputeCrc32(writer.BaseStream, 0, _paddingsOffset);
                writer.WriteUInt32(headerCrc32);
            }
        }
        /// <summary>
        /// Writes header information into output stream (w/o CRC and table offsets/paddings).
        /// </summary>
        /// <param name="writer">Binary writer with correct endianness.</param>
        /// <param name="isPreAllocationCall">If true no assembly name will be written.</param>
        public void Write(
            TinyBinaryWriter writer,
            Boolean isPreAllocationCall)
        {
            writer.WriteString("MSSpot1");

            writer.WriteUInt32(0); // header CRC
            writer.WriteUInt32(0); // assembly CRC

            writer.WriteUInt32(writer.IsBigEndian ? FLAGS_BIG_ENDIAN : FLAGS_LITTLE_ENDIAN);

            // This CRC calculated only for BE assemblies!!!
            writer.WriteUInt32(writer.IsBigEndian ? _context.NativeMethodsCrc.Current : 0x00);
            writer.WriteUInt32(0xFFFFFFFF); // Native methods offset

            writer.WriteVersion(_context.AssemblyDefinition.Name.Version);

            writer.WriteUInt16(isPreAllocationCall
                ? (UInt16)0x0000
                : _context.StringTable.GetOrCreateStringId(_context.AssemblyDefinition.Name.Name));
            writer.WriteUInt16(1); // String table version

            if (isPreAllocationCall)
            {
                _tablesOffset = writer.BaseStream.Position;
                for (var i = 0; i < 16; ++i)
                {
                    writer.WriteUInt32(0);
                }

                writer.WriteUInt32(0); // Number of patched methods

                _paddingsOffset = writer.BaseStream.Position;
                for (var i = 0; i < 16; ++i)
                {
                    writer.WriteByte(0);
                }
            }
            else
            {
                writer.BaseStream.Seek(12, SeekOrigin.Begin);

                var assemblyCrc32 = ComputeCrc32(writer.BaseStream,
                                                 _paddingsOffset, writer.BaseStream.Length - _paddingsOffset);
                writer.WriteUInt32(assemblyCrc32);

                writer.BaseStream.Seek(8, SeekOrigin.Begin);

                var headerCrc32 = ComputeCrc32(writer.BaseStream, 0, _paddingsOffset);
                writer.WriteUInt32(headerCrc32);
            }
        }
Пример #19
0
        private Byte[] GetSignature(
            FieldReference fieldReference)
        {
            using (var buffer = new MemoryStream())
                using (var writer = new BinaryWriter(buffer)) // Only Write(Byte) will be used
                {
                    var binaryWriter = TinyBinaryWriter.CreateBigEndianBinaryWriter(writer);

                    binaryWriter.WriteByte(0x06); // Field reference calling convention
                    WriteTypeInfo(fieldReference.FieldType, binaryWriter);

                    return(buffer.ToArray());
                }
        }
Пример #20
0
        /// <inheritdoc/>
        protected override void WriteSingleItem(
            TinyBinaryWriter writer,
            MethodReference item)
        {
            UInt16 referenceId;

            _context.TypeReferencesTable.TryGetTypeReferenceId(item.DeclaringType, out referenceId);

            WriteStringReference(writer, item.Name);
            writer.WriteUInt16(referenceId);

            writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(item));
            writer.WriteUInt16(0); // padding
        }
        /// <summary>
        /// Updates tables offest value and padding value for current table and
        /// advance writing position for next method call (filling tables info).
        /// </summary>
        /// <param name="writer">Binary writer with correct endianness.</param>
        /// <param name="tableBegin">Table beginning address (offset).</param>
        /// <param name="padding">Table padding value.</param>
        public void UpdateTableOffset(
            TinyBinaryWriter writer,
            Int64 tableBegin,
            Int64 padding)
        {
            writer.BaseStream.Seek(_tablesOffset, SeekOrigin.Begin);
            writer.WriteUInt32((UInt32)tableBegin);
            _tablesOffset += sizeof(Int32);

            writer.BaseStream.Seek(_paddingsOffset, SeekOrigin.Begin);
            writer.WriteByte((Byte)padding);
            _paddingsOffset += sizeof(Byte);

            writer.BaseStream.Seek(0, SeekOrigin.End);
        }
Пример #22
0
        private byte[] GetSignature(
            IEnumerable <VariableDefinition> variables)
        {
            using (var buffer = new MemoryStream())
                using (var writer = new BinaryWriter(buffer)) // Only Write(Byte) will be used
                {
                    var binaryWriter = TinyBinaryWriter.CreateBigEndianBinaryWriter(writer);
                    foreach (var variable in variables)
                    {
                        WriteTypeInfo(variable.VariableType, binaryWriter);
                    }

                    return(buffer.ToArray());
                }
        }
Пример #23
0
        private void WriteAttributes(
            TinyBinaryWriter writer,
            UInt16 tableNumber,
            IEnumerable <Tuple <CustomAttribute, UInt16> > attributes)
        {
            foreach (var item in attributes)
            {
                var attribute        = item.Item1;
                var targetIdentifier = item.Item2;

                writer.WriteUInt16(tableNumber);
                writer.WriteUInt16(targetIdentifier);

                writer.WriteUInt16(_context.GetMethodReferenceId(attribute.Constructor));
                writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(attribute));
            }
        }
        private void WriteAttributes(
            TinyBinaryWriter writer,
            UInt16 tableNumber,
            IEnumerable<Tuple<CustomAttribute, UInt16>> attributes)
        {
            foreach (var item in attributes)
            {
                var attribute = item.Item1;
                var targetIdentifier = item.Item2;

                writer.WriteUInt16(tableNumber);
                writer.WriteUInt16(targetIdentifier);

                writer.WriteUInt16(_context.GetMethodReferenceId(attribute.Constructor));
                writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(attribute));
            }
        }
Пример #25
0
        private void WriteMethodBodies(
            Collection <MethodDefinition> methods,
            Collection <TypeReference> iInterfaces,
            TinyBinaryWriter writer)
        {
            UInt16 firstMethodId        = 0xFFFF;
            var    virtualMethodsNumber = 0;

            foreach (var method in methods.Where(item => item.IsVirtual))
            {
                firstMethodId = Math.Min(firstMethodId, _context.ByteCodeTable.GetMethodId(method));
                CreateMethodSignatures(method);
                ++virtualMethodsNumber;
            }

            var instanceMethodsNumber = 0;

            foreach (var method in methods.Where(item => !(item.IsVirtual || item.IsStatic)))
            {
                firstMethodId = Math.Min(firstMethodId, _context.ByteCodeTable.GetMethodId(method));
                CreateMethodSignatures(method);
                ++instanceMethodsNumber;
            }

            var staticMethodsNumber = 0;

            foreach (var method in methods.Where(item => item.IsStatic))
            {
                firstMethodId = Math.Min(firstMethodId, _context.ByteCodeTable.GetMethodId(method));
                CreateMethodSignatures(method);
                ++staticMethodsNumber;
            }

            if (virtualMethodsNumber + instanceMethodsNumber + staticMethodsNumber == 0)
            {
                firstMethodId = _context.ByteCodeTable.NextMethodId;
            }

            writer.WriteUInt16(_context.SignaturesTable.GetOrCreateSignatureId(iInterfaces));

            writer.WriteUInt16(firstMethodId);

            writer.WriteByte((Byte)virtualMethodsNumber);
            writer.WriteByte((Byte)instanceMethodsNumber);
            writer.WriteByte((Byte)staticMethodsNumber);
        }
Пример #26
0
        private Byte[] GetSignature(
            Collection <TypeReference> interfaces)
        {
            using (var buffer = new MemoryStream())
                using (var writer = new BinaryWriter(buffer)) // Only Write(Byte) will be used
                {
                    var binaryWriter = TinyBinaryWriter.CreateBigEndianBinaryWriter(writer);

                    binaryWriter.WriteByte((Byte)interfaces.Count);
                    foreach (var item in interfaces)
                    {
                        WriteSubTypeInfo(item, binaryWriter);
                    }

                    return(buffer.ToArray());
                }
        }
Пример #27
0
        private void WriteClassFields(
            IList <FieldDefinition> fieldsList,
            TinyBinaryWriter writer)
        {
            var firstStaticFieldId = _context.FieldsTable.MaxFieldId;
            var staticFieldsNumber = 0;

            foreach (var field in fieldsList.Where(item => item.IsStatic))
            {
                UInt16 fieldReferenceId;
                _context.FieldsTable.TryGetFieldReferenceId(field, true, out fieldReferenceId);
                firstStaticFieldId = Math.Min(firstStaticFieldId, fieldReferenceId);

                _context.SignaturesTable.GetOrCreateSignatureId(field);
                _context.StringTable.GetOrCreateStringId(field.Name);

                ++staticFieldsNumber;
            }

            var firstInstanseFieldId = _context.FieldsTable.MaxFieldId;
            var instanceFieldsNumber = 0;

            foreach (var field in fieldsList.Where(item => !item.IsStatic))
            {
                UInt16 fieldReferenceId;
                _context.FieldsTable.TryGetFieldReferenceId(field, true, out fieldReferenceId);
                firstInstanseFieldId = Math.Min(firstInstanseFieldId, fieldReferenceId);

                _context.SignaturesTable.GetOrCreateSignatureId(field);
                _context.StringTable.GetOrCreateStringId(field.Name);

                ++instanceFieldsNumber;
            }

            if (firstStaticFieldId > firstInstanseFieldId)
            {
                firstStaticFieldId = firstInstanseFieldId;
            }

            writer.WriteUInt16(firstStaticFieldId);
            writer.WriteUInt16(firstInstanseFieldId);

            writer.WriteByte((Byte)staticFieldsNumber);
            writer.WriteByte((Byte)instanceFieldsNumber);
        }
Пример #28
0
        private Byte[] CreateByteCode(
            MethodDefinition method)
        {
            if (!method.HasBody)
            {
                return(new Byte[0]);
            }

            using (var stream = new MemoryStream())
                using (var writer = new BinaryWriter(stream))
                {
                    var codeWriter = new CodeWriter(
                        method, TinyBinaryWriter.CreateBigEndianBinaryWriter(writer),
                        _fakeStringTable, _context);
                    codeWriter.WriteMethodBody();
                    return(stream.ToArray());
                }
        }
Пример #29
0
        private Byte[] CreateByteCode(
            MethodDefinition method,
            TinyBinaryWriter writer)
        {
            if (!method.HasBody)
            {
                return(new Byte[0]);
            }

            using (var stream = new MemoryStream())
            {
                var codeWriter = new  CodeWriter(
                    method, writer.GetMemoryBasedClone(stream),
                    _context.StringTable, _context);
                codeWriter.WriteMethodBody();
                return(stream.ToArray());
            }
        }
Пример #30
0
        private Byte[] GetSignature(
            TypeReference typeReference,
            Boolean isFieldSignature)
        {
            using (var buffer = new MemoryStream())
                using (var writer = new BinaryWriter(buffer)) // Only Write(Byte) will be used
                {
                    var binaryWriter = TinyBinaryWriter.CreateBigEndianBinaryWriter(writer);

                    if (isFieldSignature)
                    {
                        writer.Write((Byte)0x06); // Field signature prefix
                    }
                    WriteTypeInfo(typeReference, binaryWriter);

                    return(buffer.ToArray());
                }
        }
Пример #31
0
        private void WriteSubTypeInfo(TypeReference typeDefinition, TinyBinaryWriter writer)
        {
            UInt16 referenceId;

            if (typeDefinition is TypeSpecification &&
                _context.TypeSpecificationsTable.TryGetTypeReferenceId(typeDefinition, out referenceId))
            {
                writer.WriteMetadataToken(((UInt32)referenceId << 2) | 0x04);
            }
            else if (_context.TypeReferencesTable.TryGetTypeReferenceId(typeDefinition, out referenceId))
            {
                writer.WriteMetadataToken(((UInt32)referenceId << 2) | 0x01);
            }
            else if (_context.TypeDefinitionTable.TryGetTypeReferenceId(
                         typeDefinition.Resolve(), out referenceId))
            {
                writer.WriteMetadataToken((UInt32)referenceId << 2);
            }
        }
Пример #32
0
        /// <inheritdoc/>
        public void Write(
            TinyBinaryWriter writer)
        {
            var offset = 0U;

            foreach (var item in _resouces)
            {
                writer.WriteUInt32(0x02); // Version
                writer.WriteUInt32(0x04); // Size of header
                writer.WriteUInt32(0x08); // Size of resouce header

                writer.WriteUInt32(item.Item2);

                writer.WriteUInt16(item.Item1);
                writer.WriteUInt16(0x0); // paddding

                writer.WriteUInt32(offset);
                offset += 8; // Size of resource table record
            }
        }
Пример #33
0
        private Byte[] GetSignature(
            IMethodSignature methodReference)
        {
            using (var buffer = new MemoryStream())
                using (var writer = new BinaryWriter(buffer)) // Only Write(Byte) will be used
                {
                    var binaryWriter = TinyBinaryWriter.CreateBigEndianBinaryWriter(writer);
                    writer.Write((Byte)(methodReference.HasThis ? 0x20 : 0x00));

                    writer.Write((Byte)(methodReference.Parameters.Count));

                    WriteTypeInfo(methodReference.ReturnType, binaryWriter);
                    foreach (var parameter in methodReference.Parameters)
                    {
                        WriteTypeInfo(parameter.ParameterType, binaryWriter);
                    }

                    return(buffer.ToArray());
                }
        }
        /// <inheritdoc/>
        public void Write(
            TinyBinaryWriter writer)
        {
            var offset = 0U;
            foreach (var item in _resouces)
            {
                writer.WriteUInt32(0x02); // Version
                writer.WriteUInt32(0x04); // Size of header
                writer.WriteUInt32(0x08); // Size of resouce header

                writer.WriteUInt32(item.Item2);
                
                writer.WriteUInt16(item.Item1);
                writer.WriteUInt16(0x0); // paddding

                writer.WriteUInt32(offset);
                offset += 8; // Size of resource table record
            }

        }
        /// <summary>
        /// Writes all .NET Micro Framework metadata into output stream.
        /// </summary>
        /// <param name="binaryWriter">Binary writer with correct endianness.</param>
        public void Write(
            TinyBinaryWriter binaryWriter)
        {
            var header = new TinyAssemblyDefinition(_tablesContext);
            header.Write(binaryWriter, true);

            foreach (var table in GetTables(_tablesContext))
            {
                var tableBegin = (binaryWriter.BaseStream.Position + 3) & 0xFFFFFFFC;
                table.Write(binaryWriter);

                var padding = (4 - ((binaryWriter.BaseStream.Position - tableBegin) % 4)) % 4;
                binaryWriter.WriteBytes(new Byte[padding]);

                header.UpdateTableOffset(binaryWriter, tableBegin, padding);
            }

            binaryWriter.BaseStream.Seek(0, SeekOrigin.Begin);
            header.Write(binaryWriter, false);
        }
Пример #36
0
        public void Process(
            TinyBinaryWriter writer)
        {
            writer.WriteUInt32((UInt32)_bitmap.Width);
            writer.WriteUInt32((UInt32)_bitmap.Height);

            writer.WriteUInt16(0x00);   // flags

            var tinyImageFormat = GetTinytImageFormat(_bitmap.RawFormat);

            if (tinyImageFormat != 0)
            {
                writer.WriteByte(0x01);     // bpp
                writer.WriteByte(tinyImageFormat);
                _bitmap.Save(writer.BaseStream, _bitmap.RawFormat);
            }
            else
            {
                writer.WriteByte(0x10);     // bpp
                writer.WriteByte(tinyImageFormat);

                var rect = new Rectangle(Point.Empty, _bitmap.Size);
                using (var convertedBitmap =
                           _bitmap.Clone(new Rectangle(Point.Empty, _bitmap.Size),
                                         PixelFormat.Format16bppRgb565))
                {
                    var bitmapData = convertedBitmap.LockBits(
                        rect, ImageLockMode.ReadOnly, convertedBitmap.PixelFormat);

                    var buffer = new Int16[bitmapData.Stride * convertedBitmap.Height / sizeof(Int16)];
                    System.Runtime.InteropServices.Marshal.Copy(
                        bitmapData.Scan0, buffer, 0, buffer.Length);

                    convertedBitmap.UnlockBits(bitmapData);
                    foreach (var item in buffer)
                    {
                        writer.WriteInt16(item);
                    }
                }
            }
        }
        public void Process(
            TinyBinaryWriter writer)
        {
            writer.WriteUInt32((UInt32)_bitmap.Width);
            writer.WriteUInt32((UInt32)_bitmap.Height);

            writer.WriteUInt16(0x00);   // flags

            var tinyImageFormat = GetTinytImageFormat(_bitmap.RawFormat);

            if (tinyImageFormat != 0)
            {
                writer.WriteByte(0x01);     // bpp
                writer.WriteByte(tinyImageFormat);
                _bitmap.Save(writer.BaseStream, _bitmap.RawFormat);
            }
            else
            {
                writer.WriteByte(0x10);     // bpp
                writer.WriteByte(tinyImageFormat);

                var rect = new Rectangle(Point.Empty, _bitmap.Size);
                using (var convertedBitmap =
                    _bitmap.Clone(new Rectangle(Point.Empty, _bitmap.Size),
                        PixelFormat.Format16bppRgb565))
                {
                    var bitmapData = convertedBitmap.LockBits(
                        rect, ImageLockMode.ReadOnly, convertedBitmap.PixelFormat);

                    var buffer = new Int16[bitmapData.Stride * convertedBitmap.Height / sizeof(Int16)];
                    System.Runtime.InteropServices.Marshal.Copy(
                        bitmapData.Scan0, buffer, 0, buffer.Length);

                    convertedBitmap.UnlockBits(bitmapData);
                    foreach (var item in buffer)
                    {
                        writer.WriteInt16(item);
                    }
                }
            }
        }
Пример #38
0
        private void WriteTypeInfo(
            TypeReference typeReference,
            TinyBinaryWriter writer)
        {
            if (typeReference.IsOptionalModifier)
            {
                writer.WriteByte(0); // OpTypeModifier ???
            }

            var byReference = typeReference as ByReferenceType;

            if (byReference != null)
            {
                writer.WriteByte((Byte)TinyDataType.DATATYPE_BYREF);
                WriteDataType(byReference.ElementType, writer, true, false);
            }
            else
            {
                WriteDataType(typeReference, writer, true, false);
            }
        }
Пример #39
0
        /// <inheritdoc/>
        public void Write(
            TinyBinaryWriter writer)
        {
            var orderedResources = new SortedDictionary<Int16, Tuple<ResourceKind, Byte[]>>();
            foreach (var item in _resources.OfType<EmbeddedResource>())
            {
                var count = 0U;
                using (var reader = new ResourceReader(item.GetResourceStream()))
                {
                    foreach (DictionaryEntry resource in reader)
                    {
                        String resourceType;
                        Byte[] resourceData;
                        var resourceName = resource.Key.ToString();

                        reader.GetResourceData(resourceName, out resourceType, out resourceData);

                        var kind = GetResourceKind(resourceType, resourceData);

                        if (kind == ResourceKind.Bitmap)
                        {
                            using (var stream = new MemoryStream(resourceData.Length))
                            {
                                var bitmapProcessor = new TinyBitmapProcessor((Bitmap)resource.Value);
                                bitmapProcessor.Process(writer.GetMemoryBasedClone(stream));
                                resourceData = stream.ToArray();
                            }
                        }

                        orderedResources.Add(GenerateIdFromResourceName(resourceName),
                            new Tuple<ResourceKind, Byte[]>(kind, resourceData));

                        ++count;
                    }
                }

                _context.ResourceFileTable.AddResourceFile(item, count);
            }

            foreach (var item in orderedResources)
            {
                var kind = item.Value.Item1;
                var bytes = item.Value.Item2;

                var padding = 0;
                switch (kind)
                {
                    case ResourceKind.String:
                        var stringLength = (Int32)bytes[0];
                        if (stringLength < 0x7F)
                        {
                            bytes = bytes.Skip(1).Concat(Enumerable.Repeat((Byte)0, 1)).ToArray();
                        }
                        else
                        {
                            bytes = bytes.Skip(2).Concat(Enumerable.Repeat((Byte)0, 1)).ToArray();
                        }
                        break;
                    case ResourceKind.Bitmap:
                        padding = _context.ResourceDataTable.AlignToWord();
                        break;
                    case ResourceKind.Binary:
                        bytes = bytes.Skip(4).ToArray();
                        break;
                    case ResourceKind.Font:
                        padding = _context.ResourceDataTable.AlignToWord();
                        bytes = bytes.Skip(32).ToArray(); // File size + resource header size
                        break;
                }

                // Pre-process font data (swap endiannes if needed).
                if (kind == ResourceKind.Font)
                {
                    using (var stream = new MemoryStream(bytes.Length))
                    {
                        var fontProcessor = new TinyFontProcessor(bytes);
                        fontProcessor.Process(writer.GetMemoryBasedClone(stream));
                        bytes = stream.ToArray();
                    }
                }

                writer.WriteInt16(item.Key);
                writer.WriteByte((Byte)kind);
                writer.WriteByte((Byte)padding);
                writer.WriteInt32(_context.ResourceDataTable.CurrentOffset);

                _context.ResourceDataTable.AddResourceData(bytes);
            }

            if (orderedResources.Count != 0)
            {
                writer.WriteInt16(0x7FFF);
                writer.WriteByte((Byte)ResourceKind.None);
                writer.WriteByte(0x00);
                writer.WriteInt32(_context.ResourceDataTable.CurrentOffset);
            }
        }
Пример #40
0
 /// <inheritdoc/>
 public void Write(
     TinyBinaryWriter writer)
 {
     foreach (var item in _idsByStrings
         .OrderBy(item => item.Value)
         .Select(item => item.Key))
     {
         writer.WriteString(item);
     }
 }
Пример #41
0
        private Byte[] CreateByteCode(
            MethodDefinition method,
            TinyBinaryWriter writer)
        {
            if (!method.HasBody)
            {
                return new Byte[0];
            }

            using(var stream = new MemoryStream())
            {
                var codeWriter = new  CodeWriter(
                    method, writer.GetMemoryBasedClone(stream),
                    _context.StringTable, _context);
                codeWriter.WriteMethodBody();
                return stream.ToArray();
            }
        }
Пример #42
0
 /// <inheritdoc/>
 public void Write(
     TinyBinaryWriter writer)
 {
     foreach (var method in _methods)
     {
         writer.WriteBytes(CreateByteCode(method, writer));
     }
 }
        /// <summary>
        /// Updates tables offest value and padding value for current table and
        /// advance writing position for next method call (filling tables info).
        /// </summary>
        /// <param name="writer">Binary writer with correct endianness.</param>
        /// <param name="tableBegin">Table beginning address (offset).</param>
        /// <param name="padding">Table padding value.</param>
        public void UpdateTableOffset(
            TinyBinaryWriter writer,
            Int64 tableBegin,
            Int64 padding)
        {
            writer.BaseStream.Seek(_tablesOffset, SeekOrigin.Begin);
            writer.WriteUInt32((UInt32)tableBegin);
            _tablesOffset += sizeof(Int32);

            writer.BaseStream.Seek(_paddingsOffset, SeekOrigin.Begin);
            writer.WriteByte((Byte)padding);
            _paddingsOffset += sizeof(Byte);

            writer.BaseStream.Seek(0, SeekOrigin.End);
        }
Пример #44
0
        /// <summary>
        /// Processes original data and writes processed data into output writer.
        /// </summary>
        /// <param name="writer">Endianness-aware binary writer.</param>
        public void Process(
            TinyBinaryWriter writer)
        {
            using (var stream = new MemoryStream(_fontResouce, false))
            using (var reader = new BinaryReader(stream))
            {
                // CLR_GFX_FontDescription

                {
                    // CLR_GFX_FontMetrics

                    writer.WriteUInt16(reader.ReadUInt16()); // CLR_GFX_FontMetrics.m_height
                    writer.WriteInt16(reader.ReadInt16()); // CLR_GFX_FontMetrics.m_offset

                    writer.WriteInt16(reader.ReadInt16()); // CLR_GFX_FontMetrics.m_ascent
                    writer.WriteInt16(reader.ReadInt16()); // CLR_GFX_FontMetrics.m_descent

                    writer.WriteInt16(reader.ReadInt16()); // CLR_GFX_FontMetrics.m_internalLeading
                    writer.WriteInt16(reader.ReadInt16()); // CLR_GFX_FontMetrics.m_externalLeading

                    writer.WriteInt16(reader.ReadInt16()); // CLR_GFX_FontMetrics.m_aveCharWidth
                    writer.WriteInt16(reader.ReadInt16()); // CLR_GFX_FontMetrics.m_aveCharWidth
                }

                var rangesCount = reader.ReadInt16();
                writer.WriteInt16(rangesCount); // CLR_GFX_FontDescription.m_ranges
                var charactersCount = reader.ReadInt16();
                writer.WriteInt16(charactersCount); // CLR_GFX_FontDescription.m_characters

                var flags = reader.ReadInt16();
                writer.WriteInt16(flags); // CLR_GFX_FontDescription.m_flags
                writer.WriteInt16(reader.ReadInt16()); // CLR_GFX_FontDescription.m_pad

                // CLR_GFX_BitmapDescription

                var width = reader.ReadUInt32();
                writer.WriteUInt32(width); // CLR_GFX_BitmapDescription.m_width
                var height = reader.ReadUInt32();
                writer.WriteUInt32(height); // CLR_GFX_BitmapDescription.m_height

                writer.WriteUInt16(reader.ReadUInt16()); // CLR_GFX_BitmapDescription.m_flags

                var bitsPerPixel = reader.ReadByte();
                writer.WriteByte(bitsPerPixel); // CLR_GFX_BitmapDescription.m_bitsPerPixel
                writer.WriteByte(reader.ReadByte()); // CLR_GFX_BitmapDescription.m_type

                for (var i = 0; i <= rangesCount; ++i) // Including sentinel range
                {
                    // CLR_GFX_FontCharacterRange

                    writer.WriteUInt32(reader.ReadUInt32()); // CLR_GFX_FontCharacterRange.m_indexOfFirstFontCharacter

                    writer.WriteUInt16(reader.ReadUInt16()); // CLR_GFX_FontCharacterRange.m_firstChar
                    writer.WriteUInt16(reader.ReadUInt16()); // CLR_GFX_FontCharacterRange.m_lastChar

                    writer.WriteUInt32(reader.ReadUInt32()); // CLR_GFX_FontCharacterRange.m_rangeOffset
                }

                for (var i = 0; i <= charactersCount; ++i) // Including sentinel character
                {
                    // CLR_GFX_FontCharacter

                    writer.WriteUInt16(reader.ReadUInt16()); // CLR_GFX_FontCharacter.m_offset

                    writer.WriteByte(reader.ReadByte()); // CLR_GFX_FontCharacter.m_marginLeft
                    writer.WriteByte(reader.ReadByte()); // CLR_GFX_FontCharacter.m_marginRight
                }

                if (bitsPerPixel == 0)
                {
                    bitsPerPixel = 16; // Native value, rest calculations are same
                }
                var totalSizeInWords = ((width * bitsPerPixel + 31) / 32) * height;
                for (var i = 0; i < totalSizeInWords; ++i)
                {
                    writer.WriteUInt32(reader.ReadUInt32());
                }

                if ((flags & FLAG_FONT_EX) == FLAG_FONT_EX)
                {
                    // TODO: implement it according original idea if needed
                }

                while (stream.Position < stream.Length)
                {
                    writer.WriteByte(reader.ReadByte());
                }
            }
        }