/* * Copyright (c) 2002 Sergey Chaban */ using System; using System.IO; using System.Text; using System.Collections; using System.Runtime.InteropServices; namespace Mono.PEToolkit.Metadata { /// /// Metadata stream. /// public class MDStream { /// /// MetaData stream header as described /// in ECMA CLI specs, Partition II Metadata, 23.1.2 /// protected class Header { internal uint offs; internal uint size; internal string name; public void Read(BinaryReader reader, MDStream stream) { offs = reader.ReadUInt32 (); size = reader.ReadUInt32 (); StringBuilder name_builder = new StringBuilder (); while (true) { sbyte c = reader.ReadSByte(); if (c == 0) break; name_builder.Append ((char) c); } name = name_builder.ToString (); if (name.Length == 0) throw new BadImageException("Invalid stream name."); // Round up to dword boundary. long pos = reader.BaseStream.Position; if (stream != null) pos -= stream.Root.filePos; pos += 3; pos &= ~3; if (stream != null) pos += stream.Root.filePos; // Advance file pointer. reader.BaseStream.Position = pos; } public void Write (BinaryWriter writer, MDStream stream) { writer.Write (offs); writer.Write (size); for (int i=0; i /// Name of the stream. /// /// /// Stored on-disk as a null-terminated ASCII string, /// rounded up to 4-byte boundary. /// public string Name { get { return hdr.name; } set { hdr.name = value; } } public byte [] RawData { get { return data; } } public MetaDataRoot Root { get { return root; } } public MDHeap Heap { get { lock (this) { if (heap == null) InitHeap(); return heap; } } } /// /// Reads stream header and body from supplied BinaryReader. /// /// /// Reader must be positioned at the first byte of metadata stream. /// /// unsafe public void Read(BinaryReader reader) { hdr.Read(reader, this); long oldPos = reader.BaseStream.Position; // Offset field in the stream header is relataive to // the start of metadata. reader.BaseStream.Position = root.filePos + hdr.offs; data = reader.ReadBytes((int) hdr.size); // set reader's position to the first byte after // stream header. reader.BaseStream.Position = oldPos; } public void Write (BinaryWriter writer) { hdr.Write (writer, this); long old_pos = writer.BaseStream.Position; writer.BaseStream.Position = root.filePos + hdr.offs; writer.Write (data); writer.BaseStream.Position = old_pos; } /// /// Initializes heap for this stream. /// protected void InitHeap() { heap = MDHeap.Create(this); } /// /// public void Dump(TextWriter writer) { string dump = String.Format( "Name : {0}" + Environment.NewLine + "Offset : 0x{1:x8}" + Environment.NewLine + "Size : 0x{2:x8}" + Environment.NewLine, hdr.name, hdr.offs, hdr.size ); writer.WriteLine(dump); } /// /// public override string ToString() { StringWriter sw = new StringWriter (); Dump(sw); return sw.ToString(); } } }