public override MetadataStream CreateStream() { using (var stream = new MemoryStream()) { var writer = new BinaryStreamWriter(stream); writer.WriteByte(0); var processedSignatures = new HashSet <BlobSignature>(); var agenda = new Queue <BlobSignature>(_signatureOffsetMapping.Keys); while (agenda.Count > 0) { var signature = agenda.Dequeue(); if (processedSignatures.Add(signature)) { writer.WriteCompressedUInt32(signature.GetPhysicalLength()); int count = _signatureOffsetMapping.Count; signature.Write(_parentBuffer, writer); // TODO: find more efficient way of adding newly created signatures to the queue. if (count != _signatureOffsetMapping.Count) { foreach (var sig in _signatureOffsetMapping.Keys) { agenda.Enqueue(sig); } } } } writer.WriteZeroes((int)(FileSegment.Align(_length, 4) - _length)); return(new BlobStream(new MemoryStreamReader(stream.ToArray()))); } }
public override MetadataStream CreateStream() { using (var stream = new MemoryStream()) { var writer = new BinaryStreamWriter(stream); writer.WriteByte(0); foreach (var signature in _signatureOffsetMapping.Keys) { writer.WriteCompressedUInt32(signature.GetPhysicalLength(_parentBuffer)); signature.Write(_parentBuffer, writer); } writer.WriteZeroes((int)(FileSegment.Align(_length, 4) - _length)); return(new BlobStream(new MemoryStreamReader(stream.ToArray()))); } }
public override MetadataStream CreateStream() { using (var stream = new MemoryStream()) { var writer = new BinaryStreamWriter(stream); writer.WriteByte(0); foreach (string value in _stringOffsetMapping.Keys) { writer.WriteBytes(Encoding.UTF8.GetBytes(value)); writer.WriteByte(0); } writer.WriteZeroes((int)(FileSegment.Align(_length, 4) - _length)); return(new StringStream(new MemoryStreamReader(stream.ToArray()))); } }
private int GetOperandSize() { switch (OpCode.OperandType) { case ByteCodeOperandType.None: return(0); case ByteCodeOperandType.Byte: case ByteCodeOperandType.LocalIndex: case ByteCodeOperandType.PrimitiveType: case ByteCodeOperandType.ConstantIndex: return(1); case ByteCodeOperandType.Short: case ByteCodeOperandType.LocalConst: case ByteCodeOperandType.BranchOffset: case ByteCodeOperandType.FieldIndex: case ByteCodeOperandType.MethodIndex: case ByteCodeOperandType.ClassIndex: return(2); case ByteCodeOperandType.WideConstantIndex: case ByteCodeOperandType.WideBranchOffset: case ByteCodeOperandType.WideIndexCountZero: case ByteCodeOperandType.WideIndexByte: case ByteCodeOperandType.DynamicIndex: return(4); case ByteCodeOperandType.TableSwitch: { int padding = (int)(FileSegment.Align((uint)Offset, 4) - Offset) - 1; return(padding + (3 + ((TableSwitch)Operand).Offsets.Count) * 4); } case ByteCodeOperandType.LookupSwitch: { int padding = (int)(FileSegment.Align((uint)Offset, 4) - Offset) - 1; return(padding + (2 + ((LookupSwitch)Operand).Table.Count * 2) * 4); } default: throw new ArgumentOutOfRangeException(); } }
private object ReadRawOperand(ByteOpCode opcode) { switch (opcode.OperandType) { case ByteCodeOperandType.None: return(null); case ByteCodeOperandType.Byte: case ByteCodeOperandType.ConstantIndex: case ByteCodeOperandType.LocalIndex: case ByteCodeOperandType.PrimitiveType: return(_reader.ReadByte()); case ByteCodeOperandType.Short: case ByteCodeOperandType.WideConstantIndex: case ByteCodeOperandType.BranchOffset: case ByteCodeOperandType.LocalConst: case ByteCodeOperandType.FieldIndex: case ByteCodeOperandType.MethodIndex: case ByteCodeOperandType.ClassIndex: return(_reader.ReadInt16()); case ByteCodeOperandType.TableSwitch: _reader.Position = FileSegment.Align((uint)_reader.Position, 4); return(TableSwitch.FromReader(_reader)); case ByteCodeOperandType.LookupSwitch: _reader.Position = FileSegment.Align((uint)_reader.Position, 4); return(LookupSwitch.FromReader(_reader)); case ByteCodeOperandType.WideIndexCountZero: case ByteCodeOperandType.WideIndexByte: case ByteCodeOperandType.WideBranchOffset: case ByteCodeOperandType.DynamicIndex: return(_reader.ReadInt32()); default: throw new ArgumentOutOfRangeException(); } }
private void WriteOperand(ByteCodeInstruction instruction) { switch (instruction.OpCode.OperandType) { case ByteCodeOperandType.None: break; case ByteCodeOperandType.Byte: case ByteCodeOperandType.LocalIndex: case ByteCodeOperandType.PrimitiveType: _writer.Write(Convert.ToByte(instruction.Operand)); break; case ByteCodeOperandType.Short: case ByteCodeOperandType.LocalConst: _writer.Write(Convert.ToInt16(instruction.Operand)); break; case ByteCodeOperandType.FieldIndex: _writer.Write(instruction.Operand is FieldReference fieldRef ? (ushort)OperandBuilder.GetFieldIndex(fieldRef) : Convert.ToUInt16(instruction.Operand)); break; case ByteCodeOperandType.MethodIndex: _writer.Write(instruction.Operand is MethodReference methodRef ? (ushort)OperandBuilder.GetMethodIndex(methodRef) : Convert.ToUInt16(instruction.Operand)); break; case ByteCodeOperandType.ClassIndex: _writer.Write(instruction.Operand is ClassReference classRef ? (ushort)OperandBuilder.GetClassIndex(classRef) : Convert.ToUInt16(instruction.Operand)); break; case ByteCodeOperandType.ConstantIndex: _writer.Write((byte)OperandBuilder.GetLiteralIndex(instruction.Operand)); break; case ByteCodeOperandType.WideConstantIndex: _writer.Write((ushort)OperandBuilder.GetLiteralIndex(instruction.Operand)); break; case ByteCodeOperandType.BranchOffset: { short relativeOffset; if (instruction.Operand is ByteCodeInstruction target) { relativeOffset = (short)(target.Offset - instruction.Offset); } else { relativeOffset = Convert.ToInt16(instruction.Operand); } _writer.Write(relativeOffset); break; } case ByteCodeOperandType.WideBranchOffset: { int relativeOffset; if (instruction.Operand is ByteCodeInstruction target) { relativeOffset = (target.Offset - instruction.Offset); } else { relativeOffset = Convert.ToInt32(instruction.Operand); } _writer.Write(relativeOffset); break; } case ByteCodeOperandType.TableSwitch: case ByteCodeOperandType.LookupSwitch: _writer.Position = FileSegment.Align((uint)_writer.Position, 4); ((ISwitchOperand)instruction.Operand).Write(_writer, instruction.Offset); break; case ByteCodeOperandType.WideIndexCountZero: case ByteCodeOperandType.WideIndexByte: _writer.Write(Convert.ToInt32(instruction.Operand)); break; case ByteCodeOperandType.DynamicIndex: _writer.Write(instruction.Operand is DynamicInvocation invocation ? OperandBuilder.GetDynamicIndex(invocation) << 16 : Convert.ToInt32(instruction.Operand)); break; default: throw new ArgumentOutOfRangeException(); } }