unsafe override public void FromRawData(byte[] rawData) { strings = new SortedList(); strings.Add(0, String.Empty); if (rawData == null) { return; } int len = rawData.Length; dataLen = len; // the first entry in the string heap is always EmptyString if (len < 1 || rawData [0] != 0) { throw new BadMetaDataException("Invalid #Strings heap."); } int idx = 1; for (int i = 1; i < len; i++) { if (rawData [i] == 0) { fixed(void *p = &rawData[idx]) { string s = PEUtils.GetString((sbyte *)p, 0, i - idx, Encoding.UTF8); strings.Add(idx, s); } idx = i + 1; } } }
unsafe public void Read(BinaryReader reader) { filePos = reader.BaseStream.Position; sig = reader.ReadUInt32(); if (sig != Sig) { throw new BadImageException("Invalid MetaData Signature."); } majVer = reader.ReadInt16(); minVer = reader.ReadInt16(); reserved = reader.ReadUInt32(); // Length of version string. len = reader.ReadInt32(); // Read version string. if (len != 0) { sbyte *pVer = stackalloc sbyte [len]; sbyte *p = pVer; long pos = reader.BaseStream.Position; int i; for (i = len; --i >= 0;) { sbyte c = reader.ReadSByte(); if (c == 0) { break; } *p++ = c; } verStr = PEUtils.GetString(pVer, 0, len - i - 1, Encoding.UTF8); // Round up to dword boundary, relative to header start. pos += len; pos -= filePos; pos += 3; pos &= ~3; pos += filePos; // Advance file pointer. reader.BaseStream.Position = pos; } else { VersionString = String.Empty; } flags = reader.ReadInt16(); nStreams = reader.ReadInt16(); streams = new Hashtable(nStreams); // load all streams into memory for (int i = nStreams; --i >= 0;) { MDStream s = new MDStream(this); s.Read(reader); // TODO: check for duplicated streams, // use Add instead of indexer. streams[s.Name] = s; } MDStream tabs = Streams["#~"] as MDStream; // Try uncompressed stream. if (tabs == null) { tabs = Streams["#-"] as MDStream; } if (tabs == null) { throw new BadMetaDataException("Missing #~ stream."); } TablesHeap tabsHeap = tabs.Heap as TablesHeap; // cache index sizes strIdx = tabsHeap.StringsIndexSize; guidIdx = tabsHeap.GUIDIndexSize; blobIdx = tabsHeap.BlobIndexSize; }