public VariableDefinition[] ReadVariableSignature(uint signature, MethodDefinition parentMethod) { VariableDefinition[] variables = null; BlobSignatureReader reader; if (TryGetBlobReader(signature, parentMethod, out reader)) { using (reader) { reader.GenericContext = parentMethod; byte local_sig = reader.ReadByte(); if (local_sig != 0x7) { throw new ArgumentException("Signature doesn't refer to a valid local variable signature"); } uint count = NETGlobals.ReadCompressedUInt32(reader); if (count == 0) { return(null); } variables = new VariableDefinition[count]; for (int i = 0; i < count; i++) { variables[i] = new VariableDefinition(i, reader.ReadTypeReference()); } } } return(variables); }
public PropertySignature ReadPropertySignature(uint signature, PropertyDefinition parentProperty) { PropertySignature propertySig = null; BlobSignatureReader reader; if (TryGetBlobReader(signature, out reader)) { using (reader) { reader.GenericContext = parentProperty.DeclaringType; byte flag = reader.ReadByte(); if ((flag & 8) == 0) { throw new ArgumentException("Signature doesn't refer to a valid property signature."); } propertySig = new PropertySignature(); propertySig.HasThis = (flag & 0x20) != 0; NETGlobals.ReadCompressedUInt32(reader); propertySig.ReturnType = reader.ReadTypeReference(); } } return(propertySig); }
/// <summary> /// Gets a string by its offset. /// </summary> /// <param name="offset">The offset of the string.</param> /// <returns></returns> public string GetStringByOffset(uint offset) { string stringValue; if (_readStrings.TryGetValue(offset, out stringValue)) { return(stringValue); } _mainStream.Seek(offset, SeekOrigin.Begin); uint length = (uint)(NETGlobals.ReadCompressedUInt32(_binReader) & -2); if (length == 0) { _readStrings.Add(offset, string.Empty); return(string.Empty); } char[] chars = new char[length / 2]; for (int i = 0; i < length; i += 2) { chars[i / 2] = (char)_binReader.ReadInt16(); } stringValue = new string(chars); _readStrings.Add(offset, stringValue); return(stringValue); }
public IMemberSignature ReadMemberRefSignature(uint sig, IGenericContext context) { IMemberSignature signature = null; BlobSignatureReader reader; if (TryGetBlobReader(sig, context, out reader)) { using (reader) { byte flag = reader.ReadByte(); if (flag == 0x6) { FieldSignature fieldsignature = new FieldSignature(); fieldsignature.ReturnType = reader.ReadTypeReference((ElementType)reader.ReadByte()); signature = fieldsignature; } else { MethodSignature methodsignature = new MethodSignature(); if ((flag & 0x20) != 0) { methodsignature.HasThis = true; flag = (byte)(flag & -33); } if ((flag & 0x40) != 0) { methodsignature.ExplicitThis = true; flag = (byte)(flag & -65); } if ((flag & 0x10) != 0) { int genericsig = NETGlobals.ReadCompressedInt32(reader); if (!context.IsDefinition) { AddMissingGenericParameters(context.Method, genericsig - 1); } } methodsignature.CallingConvention = (MethodCallingConvention)flag; uint paramCount = NETGlobals.ReadCompressedUInt32(reader); methodsignature.ReturnType = reader.ReadTypeReference(); ParameterReference[] parameters = new ParameterReference[paramCount]; for (int i = 0; i < paramCount; i++) { parameters[i] = new ParameterReference() { ParameterType = reader.ReadTypeReference((ElementType)reader.ReadByte()) }; } methodsignature.Parameters = parameters; signature = methodsignature; } } } return(signature); }
//internal override void Reconstruct() //{ // MemoryStream newStream = new MemoryStream(); // BinaryWriter writer = new BinaryWriter(newStream); // writer.Write((byte)0); // ReadAllStrings(); // foreach (var readString in readStrings) // { // byte[] bytes = Encoding.Unicode.GetBytes(readString.Value); // NETGlobals.WriteCompressedUInt32(writer, (uint)bytes.Length + 1); // length + terminator length // writer.Write(bytes); // data // writer.Write((byte)0); // terminator // } // binaryreader.Dispose(); // stream.Dispose(); // stream = newStream; // binaryreader = new BinaryReader(newStream); // this.streamHeader.Size = (uint)newStream.Length; // this.contents = newStream.ToArray(); //} internal void ReadAllStrings() { _mainStream.Seek(0, SeekOrigin.Begin); uint lastPosition = (uint)_mainStream.Position; while (_mainStream.Position + 1 < _mainStream.Length) { // TODO: write string.empty strings.. bool alreadyExisted = _readStrings.ContainsKey((uint)_mainStream.Position + 1); string value = GetStringByOffset((uint)_mainStream.Position + 1); int length = value.Length * 2; if (length == 0 && lastPosition == (uint)_mainStream.Position) { _mainStream.Seek(1, SeekOrigin.Current); } if (alreadyExisted) { _mainStream.Seek(length + NETGlobals.GetCompressedUInt32Size((uint)length) + 1, SeekOrigin.Current); } lastPosition = (uint)_mainStream.Position; } _hasReadAllStrings = true; _newEntryOffset = (uint)_mainStream.Length; }
public string ReadUtf8String() { if (ReadByte() == 0xFF) { return(string.Empty); } BaseStream.Seek(-1, SeekOrigin.Current); uint size = NETGlobals.ReadCompressedUInt32(this); byte[] rawdata = this.ReadBytes((int)size); return(Encoding.UTF8.GetString(rawdata)); }
public TypeReference[] ReadGenericArguments() { uint number = NETGlobals.ReadCompressedUInt32(this); var genericArguments = new TypeReference[number]; for (int i = 0; i < number; i++) { genericArguments[i] = ReadTypeReference(); } return(genericArguments); }
public TypeReference ReadTypeToken() { TypeReference typeRef; if (_netHeader.TablesHeap.TypeDefOrRef.TryGetMember((int)NETGlobals.ReadCompressedUInt32(this), out typeRef)) { if (typeRef is ISpecification) { typeRef = (typeRef as TypeSpecification).TransformWith(GenericContext) as TypeReference; } } return(typeRef); }
/// <summary> /// Gets the blob value by it's signature/index. /// </summary> /// <param name="index">The index or signature to get the blob value from.</param> /// <returns></returns> public byte[] GetBlob(uint index) { byte[] bytes = null; if (_readBlobs.TryGetValue(index, out bytes)) { return(bytes); } _mainStream.Seek(index, SeekOrigin.Begin); int length = (int)NETGlobals.ReadCompressedUInt32(_binReader); bytes = _binReader.ReadBytes(length); _readBlobs.Add(index, bytes); return(bytes); }
public uint GetBlobIndex(byte[] blobValue) { ReadAllBlobs(); if (_readBlobs.ContainsValue(blobValue)) { return(_readBlobs.FirstOrDefault(b => b.Value == blobValue).Key); } _mainStream.Seek(0, SeekOrigin.End); uint index = (uint)_mainStream.Position; NETGlobals.WriteCompressedUInt32(_binWriter, (uint)blobValue.Length); _binWriter.Write(blobValue); _readBlobs.Add(index, blobValue); return(index); }
public ArrayType ReadArrayType() { TypeReference arrayType = ReadTypeReference((ElementType)this.ReadByte()); uint rank = NETGlobals.ReadCompressedUInt32(this); uint[] upperbounds = new uint[NETGlobals.ReadCompressedUInt32(this)]; for (int i = 0; i < upperbounds.Length; i++) { upperbounds[i] = NETGlobals.ReadCompressedUInt32(this); } int[] lowerbounds = new int[NETGlobals.ReadCompressedUInt32(this)]; for (int i = 0; i < lowerbounds.Length; i++) { lowerbounds[i] = NETGlobals.ReadCompressedInt32(this); } ArrayDimension[] dimensions = new ArrayDimension[rank]; for (int i = 0; i < rank; i++) { int?lower = null; int?upper = null; if (i < lowerbounds.Length) { lower = new int?(lowerbounds[i]); } if (i < upperbounds.Length) { int x = (int)upperbounds[i]; upper = (lower.HasValue ? new int?(lower.GetValueOrDefault() + x) : 0) - 1; } ArrayDimension dimension = new ArrayDimension(lower, upper); dimensions[i] = dimension; } return(new ArrayType(arrayType, (int)rank, dimensions)); }
internal void ReadAllBlobs() { _mainStream.Seek(1, SeekOrigin.Begin); while (_mainStream.Position < _mainStream.Length) { bool alreadyExisted = _readBlobs.ContainsKey((uint)_mainStream.Position); byte[] value = GetBlob((uint)_mainStream.Position); int length = value.Length; if (length == 0) { break; } if (alreadyExisted) { _mainStream.Seek(length + NETGlobals.GetCompressedUInt32Size((uint)length), SeekOrigin.Current); } } }
public TypeReference[] ReadGenericArgumentsSignature(uint signature, IGenericContext context) { BlobSignatureReader reader; if (TryGetBlobReader(signature, context, out reader)) { using (reader) { if (reader.ReadByte() == 0xa) { uint count = NETGlobals.ReadCompressedUInt32(reader); TypeReference[] types = new TypeReference[count]; for (int i = 0; i < count; i++) { types[i] = reader.ReadTypeReference(); } return(types); } } } throw new ArgumentException("Signature doesn't point to a valid generic arguments signature"); }
internal void Reconstruct() { // will be removed once blobs are being serialized. MemoryStream newStream = new MemoryStream(); BinaryWriter writer = new BinaryWriter(newStream); writer.Write((byte)0); ReadAllBlobs(); foreach (var blob in _readBlobs) { NETGlobals.WriteCompressedUInt32(writer, (uint)blob.Value.Length); writer.Write(blob.Value); } _mainStream.Dispose(); _binReader.Dispose(); _binWriter.Dispose(); _mainStream = newStream; _binReader = new BinaryReader(newStream); _binWriter = new BinaryWriter(newStream); this._streamHeader.Size = (uint)newStream.Length; }
public TypeReference ReadTypeReference(ElementType type) { switch (type) { case ElementType.Void: return(_netHeader.TypeSystem.Void); case ElementType.I: return(_netHeader.TypeSystem.IntPtr); case ElementType.I1: return(_netHeader.TypeSystem.Int8); case ElementType.I2: return(_netHeader.TypeSystem.Int16); case ElementType.I4: return(_netHeader.TypeSystem.Int32); case ElementType.I8: return(_netHeader.TypeSystem.Int64); case ElementType.U: return(_netHeader.TypeSystem.UIntPtr); case ElementType.U1: return(_netHeader.TypeSystem.UInt8); case ElementType.U2: return(_netHeader.TypeSystem.UInt16); case ElementType.U4: return(_netHeader.TypeSystem.UInt32); case ElementType.U8: return(_netHeader.TypeSystem.UInt64); case ElementType.Object: return(_netHeader.TypeSystem.Object); case ElementType.R4: return(_netHeader.TypeSystem.Single); case ElementType.R8: return(_netHeader.TypeSystem.Double); case ElementType.String: return(_netHeader.TypeSystem.String); case ElementType.Char: return(_netHeader.TypeSystem.Char); case ElementType.Type: return(_netHeader.TypeSystem.Type); case ElementType.Boolean: return(_netHeader.TypeSystem.Boolean); case ElementType.Ptr: return(new PointerType(ReadTypeReference((ElementType)this.ReadByte()))); case ElementType.MVar: return(GetGenericParameter(GenericParamType.Method, (int)NETGlobals.ReadCompressedUInt32(this))); case ElementType.Var: return(GetGenericParameter(GenericParamType.Type, (int)NETGlobals.ReadCompressedUInt32(this))); case ElementType.Array: return(ReadArrayType()); case ElementType.SzArray: return(new ArrayType(ReadTypeReference((ElementType)this.ReadByte()))); case ElementType.Class: TypeReference typeRef; if (_netHeader.TablesHeap.TypeDefOrRef.TryGetMember((int)NETGlobals.ReadCompressedUInt32(this), out typeRef)) { return(typeRef); } break; case ElementType.ValueType: if (_netHeader.TablesHeap.TypeDefOrRef.TryGetMember((int)NETGlobals.ReadCompressedUInt32(this), out typeRef)) { typeRef.IsValueType = true; return(typeRef); } break; case ElementType.ByRef: return(new ByReferenceType(ReadTypeReference((ElementType)this.ReadByte()))); case ElementType.Pinned: return(new PinnedType(ReadTypeReference((ElementType)this.ReadByte()))); case ElementType.GenericInst: bool isValueType = this.ReadByte() == 0x11; TypeReference reference2 = ReadTypeToken(); GenericInstanceType instance = new GenericInstanceType(reference2); instance._genericArguments = ReadGenericArguments(); instance.IsValueType = isValueType; return(instance); case ElementType.CModOpt: return(new CustomModifierType(ReadTypeToken(), ReadTypeReference(), false)); case ElementType.CModReqD: return(new CustomModifierType(ReadTypeToken(), ReadTypeReference(), true)); } return(new TypeReference(string.Empty, type.ToString(), null) { _netheader = this._netHeader }); }