/// <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 }
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()); } }
/// <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(); } }
/// <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); } }