diff options
author | Jb Evain <jbevain@gmail.com> | 2011-10-27 17:54:43 +0400 |
---|---|---|
committer | Jb Evain <jbevain@gmail.com> | 2011-10-27 17:54:43 +0400 |
commit | 0dcfa1739d948a2b1221da397561ceb6b3c517d1 (patch) | |
tree | 15edaf10905dca2fcfbc0a197e41645051e5271c /Mono.Cecil.Metadata | |
parent | 8771de6415d3fa5e34b12fd90519a5405c02e8b2 (diff) |
Only keep the table heap in memory; read the other heaps from the underlying stream
Diffstat (limited to 'Mono.Cecil.Metadata')
-rw-r--r-- | Mono.Cecil.Metadata/BlobHeap.cs | 17 | ||||
-rw-r--r-- | Mono.Cecil.Metadata/GuidHeap.cs | 11 | ||||
-rw-r--r-- | Mono.Cecil.Metadata/Heap.cs | 18 | ||||
-rw-r--r-- | Mono.Cecil.Metadata/StringHeap.cs | 28 | ||||
-rw-r--r-- | Mono.Cecil.Metadata/TableHeap.cs | 7 | ||||
-rw-r--r-- | Mono.Cecil.Metadata/UserStringHeap.cs | 24 | ||||
-rw-r--r-- | Mono.Cecil.Metadata/Utilities.cs | 20 |
7 files changed, 59 insertions, 66 deletions
diff --git a/Mono.Cecil.Metadata/BlobHeap.cs b/Mono.Cecil.Metadata/BlobHeap.cs index 2488569..ecbe9c2 100644 --- a/Mono.Cecil.Metadata/BlobHeap.cs +++ b/Mono.Cecil.Metadata/BlobHeap.cs @@ -26,30 +26,23 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -using System; +using Mono.Cecil.PE; namespace Mono.Cecil.Metadata { sealed class BlobHeap : Heap { - public BlobHeap (byte [] data) - : base (data) + public BlobHeap (Image image, uint offset, uint size) + : base (image, offset, size) { } public byte [] Read (uint index) { - if (index == 0 || index > this.data.Length - 1) + if (index == 0 || index > Size - 1) return Empty<byte>.Array; - int position = (int) index; - int length = (int) data.ReadCompressedUInt32 (ref position); - - var buffer = new byte [length]; - - Buffer.BlockCopy (data, position, buffer, 0, length); - - return buffer; + return ReadAt (index, reader => reader.ReadBytes ((int) reader.ReadCompressedUInt32 ())); } } } diff --git a/Mono.Cecil.Metadata/GuidHeap.cs b/Mono.Cecil.Metadata/GuidHeap.cs index 4199af1..996606f 100644 --- a/Mono.Cecil.Metadata/GuidHeap.cs +++ b/Mono.Cecil.Metadata/GuidHeap.cs @@ -27,13 +27,14 @@ // using System; +using Mono.Cecil.PE; namespace Mono.Cecil.Metadata { sealed class GuidHeap : Heap { - public GuidHeap (byte [] data) - : base (data) + public GuidHeap (Image image, uint offset, uint size) + : base (image, offset, size) { } @@ -44,13 +45,9 @@ namespace Mono.Cecil.Metadata { const int guid_size = 16; - var buffer = new byte [guid_size]; - index--; - Buffer.BlockCopy (this.data, (int) index, buffer, 0, guid_size); - - return new Guid (buffer); + return ReadAt (index, reader => new Guid (reader.ReadBytes (guid_size))); } } } diff --git a/Mono.Cecil.Metadata/Heap.cs b/Mono.Cecil.Metadata/Heap.cs index 715e59b..afa6d7d 100644 --- a/Mono.Cecil.Metadata/Heap.cs +++ b/Mono.Cecil.Metadata/Heap.cs @@ -26,17 +26,29 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using System; +using Mono.Cecil.PE; + namespace Mono.Cecil.Metadata { abstract class Heap { public int IndexSize; - internal byte [] data; + public readonly Image Image; + public readonly uint Offset; + public readonly uint Size; + + protected Heap (Image image, uint offset, uint size) + { + this.Image = image; + this.Offset = offset; + this.Size = size; + } - protected Heap (byte [] data) + public TRet ReadAt<TRet> (uint index, Func<BinaryStreamReader, TRet> read) { - this.data = data; + return Image.ReadAt(Image.MetadataSection.VirtualAddress, reader => { reader.Advance ((int)(Offset + index)); return read(reader); }); } } } diff --git a/Mono.Cecil.Metadata/StringHeap.cs b/Mono.Cecil.Metadata/StringHeap.cs index f195535..c37b4fa 100644 --- a/Mono.Cecil.Metadata/StringHeap.cs +++ b/Mono.Cecil.Metadata/StringHeap.cs @@ -26,18 +26,19 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -using System; using System.Collections.Generic; using System.Text; +using Mono.Cecil.PE; + namespace Mono.Cecil.Metadata { class StringHeap : Heap { readonly Dictionary<uint, string> strings = new Dictionary<uint, string> (); - public StringHeap (byte [] data) - : base (data) + public StringHeap (Image image, uint offset, uint size) + : base (image, offset, size) { } @@ -50,7 +51,7 @@ namespace Mono.Cecil.Metadata { if (strings.TryGetValue (index, out @string)) return @string; - if (index > data.Length - 1) + if (index > Size - 1) return string.Empty; @string = ReadStringAt (index); @@ -62,17 +63,20 @@ namespace Mono.Cecil.Metadata { protected virtual string ReadStringAt (uint index) { - int length = 0; - int start = (int) index; + return ReadAt (index, reader => { + int length = 0; + var start = reader.Position; - for (int i = start; ; i++) { - if (data [i] == 0) - break; + for (int i = 0; ; i++) { + if (reader.ReadByte () == 0) + break; - length++; - } + length++; + } - return Encoding.UTF8.GetString (data, start, length); + reader.Position = start; + return Encoding.UTF8.GetString (reader.ReadBytes (length), 0, length); + }); } } } diff --git a/Mono.Cecil.Metadata/TableHeap.cs b/Mono.Cecil.Metadata/TableHeap.cs index 25a2ccc..af6b772 100644 --- a/Mono.Cecil.Metadata/TableHeap.cs +++ b/Mono.Cecil.Metadata/TableHeap.cs @@ -98,9 +98,12 @@ namespace Mono.Cecil.Metadata { get { return Tables [(int) table]; } } - public TableHeap (byte [] data) - : base (data) + internal byte [] data; + + public TableHeap (Image image, uint offset, uint size, byte [] data) + : base (image, offset, size) { + this.data = data; } public bool HasTable (Table table) diff --git a/Mono.Cecil.Metadata/UserStringHeap.cs b/Mono.Cecil.Metadata/UserStringHeap.cs index 7046eff..b33eea8 100644 --- a/Mono.Cecil.Metadata/UserStringHeap.cs +++ b/Mono.Cecil.Metadata/UserStringHeap.cs @@ -26,29 +26,33 @@ // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // +using Mono.Cecil.PE; + namespace Mono.Cecil.Metadata { sealed class UserStringHeap : StringHeap { - public UserStringHeap (byte [] data) - : base (data) + public UserStringHeap (Image image, uint offset, uint size) + : base (image, offset, size) { } protected override string ReadStringAt (uint index) { - int start = (int) index; + return ReadAt (index, reader => { + uint length = (uint) (reader.ReadCompressedUInt32 () & ~1); + var data = reader.ReadBytes ((int) length); - uint length = (uint) (data.ReadCompressedUInt32 (ref start) & ~1); - if (length < 1) - return string.Empty; + if (length < 1) + return string.Empty; - var chars = new char [length / 2]; + var chars = new char [length / 2]; - for (int i = start, j = 0; i < start + length; i += 2) - chars [j++] = (char) (data [i] | (data [i + 1] << 8)); + for (int i = 0, j = 0; i < length; i += 2) + chars [j++] = (char) (data [i] | (data [i + 1] << 8)); - return new string (chars); + return new string (chars); + }); } } } diff --git a/Mono.Cecil.Metadata/Utilities.cs b/Mono.Cecil.Metadata/Utilities.cs index d752b24..4c5a6bf 100644 --- a/Mono.Cecil.Metadata/Utilities.cs +++ b/Mono.Cecil.Metadata/Utilities.cs @@ -34,26 +34,6 @@ namespace Mono.Cecil { static partial class Mixin { - public static uint ReadCompressedUInt32 (this byte [] data, ref int position) - { - uint integer; - if ((data [position] & 0x80) == 0) { - integer = data [position]; - position++; - } else if ((data [position] & 0x40) == 0) { - integer = (uint) (data [position] & ~0x80) << 8; - integer |= data [position + 1]; - position += 2; - } else { - integer = (uint) (data [position] & ~0xc0) << 24; - integer |= (uint) data [position + 1] << 16; - integer |= (uint) data [position + 2] << 8; - integer |= (uint) data [position + 3]; - position += 4; - } - return integer; - } - public static MetadataToken GetMetadataToken (this CodedIndex self, uint data) { uint rid; |