private void WriteOperand( Instruction instruction) { var opcode = instruction.OpCode; var operandType = opcode.OperandType; if (operandType == OperandType.InlineNone) { return; } var operand = instruction.Operand; if (operand == null) { throw new ArgumentException(); } switch (operandType) { case OperandType.InlineSwitch: { var targets = (Instruction[])operand; _writer.WriteByte((Byte)targets.Length); var diff = instruction.Offset + opcode.Size + 2 * targets.Length + 1; foreach (var item in targets) { _writer.WriteInt16((Int16)(GetTargetOffset(item) - diff)); } break; } case OperandType.ShortInlineBrTarget: { var target = (Instruction)operand; _writer.WriteSByte((SByte) (GetTargetOffset(target) - (instruction.Offset + opcode.Size + 1))); break; } case OperandType.InlineBrTarget: { var target = (Instruction)operand; _writer.WriteInt16((Int16) (GetTargetOffset(target) - (instruction.Offset + opcode.Size + 2))); break; } case OperandType.ShortInlineVar: _writer.WriteByte((byte)GetVariableIndex((VariableDefinition)operand)); break; case OperandType.ShortInlineArg: _writer.WriteByte((byte)GetParameterIndex((ParameterDefinition)operand)); break; case OperandType.InlineVar: _writer.WriteInt16((short)GetVariableIndex((VariableDefinition)operand)); break; case OperandType.InlineArg: _writer.WriteInt16((short)GetParameterIndex((ParameterDefinition)operand)); break; case OperandType.InlineSig: // TODO: implement this properly after finding when such code is generated //WriteMetadataToken (GetStandAloneSignature ((CallSite) operand)); break; case OperandType.ShortInlineI: if (opcode == OpCodes.Ldc_I4_S) { _writer.WriteSByte((SByte)operand); } else { _writer.WriteByte((Byte)operand); } break; case OperandType.InlineI: _writer.WriteInt32((Int32)operand); break; case OperandType.InlineI8: _writer.WriteInt64((Int64)operand); break; case OperandType.ShortInlineR: _writer.WriteSingle((Single)operand); break; case OperandType.InlineR: _writer.WriteDouble((Double)operand); break; case OperandType.InlineString: var stringReferenceId = _stringTable.GetOrCreateStringId((String)operand, false); _writer.WriteUInt16(stringReferenceId); break; case OperandType.InlineMethod: _writer.WriteUInt16(_context.GetMethodReferenceId((MethodReference)operand)); break; case OperandType.InlineType: _writer.WriteUInt16(GetTypeReferenceId((TypeReference)operand)); break; case OperandType.InlineField: _writer.WriteUInt16(GetFieldReferenceId((FieldReference)operand)); break; case OperandType.InlineTok: _writer.WriteUInt32(GetMetadataToken((IMetadataTokenProvider)operand)); break; default: throw new ArgumentException(); } }
/// <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); } }
/// <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); } }