/// <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); }
/// <inheritdoc/> public void Write( TinyBinaryWriter writer) { foreach (var item in _dataByteArrays) { writer.WriteBytes(item); } }
/// <inheritdoc/> public void Write( TinyBinaryWriter writer) { foreach (var method in _methods) { writer.WriteBytes(CreateByteCode(method, writer)); } }
/// <inheritdoc/> protected override void WriteSingleItem( TinyBinaryWriter writer, AssemblyNameReference item) { WriteStringReference(writer, item.Name); writer.WriteUInt16(0); // padding writer.WriteVersion(item.Version); }
/// <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 }
/// <inheritdoc/> public void Write( TinyBinaryWriter writer) { foreach (var item in _idsByStrings .OrderBy(item => item.Value) .Select(item => item.Key)) { writer.WriteString(item); } }
/// <inheritdoc/> public void Write( TinyBinaryWriter writer) { foreach (var item in _idsByItemsDictionary .OrderBy(item => item.Value) .Select(item => item.Key)) { WriteSingleItem(writer, item); } }
/// <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 }
/// <inheritdoc/> public void Write( TinyBinaryWriter writer) { foreach (var signature in _idsBySignatures .OrderBy(item => item.Value) .Select(item => item.Key)) { writer.WriteBytes(signature); } }
/// <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 } }
/// <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); } }
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()); } }
/// <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); }
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()); } }
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)); } }
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); }
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()); } }
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); }
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()); } }
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()); } }
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()); } }
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); } }
/// <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 } }
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()); } }
/// <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); }
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); } } } }
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); } }
/// <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); } }
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(); } }
/// <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()); } } }