2 Copyright (C) 2009 Jeroen Frijters
4 This software is provided 'as-is', without any express or implied
5 warranty. In no event will the authors be held liable for any damages
6 arising from the use of this software.
8 Permission is granted to anyone to use this software for any purpose,
9 including commercial applications, and to alter it and redistribute it
10 freely, subject to the following restrictions:
12 1. The origin of this software must not be misrepresented; you must not
13 claim that you wrote the original software. If you use this software
14 in a product, an acknowledgment in the product documentation would be
15 appreciated but is not required.
16 2. Altered source versions must be plainly marked as such, and must not be
17 misrepresented as being the original software.
18 3. This notice may not be removed or altered from any source distribution.
25 using System.Collections.Generic;
28 namespace IKVM.Reflection.Reader
30 sealed class ByteReader
32 private byte[] buffer;
36 internal ByteReader(byte[] buffer, int offset, int length)
40 this.end = pos + length;
43 internal static ByteReader FromBlob(byte[] blobHeap, int blob)
45 ByteReader br = new ByteReader(blobHeap, blob, 4);
46 int length = br.ReadCompressedInt();
47 br.end = br.pos + length;
53 get { return end - pos; }
56 internal byte PeekByte()
59 throw new BadImageFormatException();
63 internal byte ReadByte()
66 throw new BadImageFormatException();
70 internal byte[] ReadBytes(int count)
73 throw new BadImageFormatException();
74 if (end - pos < count)
75 throw new BadImageFormatException();
76 byte[] buf = new byte[count];
77 Buffer.BlockCopy(buffer, pos, buf, 0, count);
82 internal int ReadCompressedInt()
89 else if ((b1 & 0xC0) == 0x80)
92 return ((b1 & 0x3F) << 8) | b2;
99 return ((b1 & 0x3F) << 24) + (b2 << 16) + (b3 << 8) + b4;
103 internal string ReadString()
105 if (PeekByte() == 0xFF)
110 int length = ReadCompressedInt();
111 string str = Encoding.UTF8.GetString(buffer, pos, length);
116 internal char ReadChar()
118 return (char)ReadInt16();
121 internal sbyte ReadSByte()
123 return (sbyte)ReadByte();
126 internal short ReadInt16()
129 throw new BadImageFormatException();
130 byte b1 = buffer[pos++];
131 byte b2 = buffer[pos++];
132 return (short)(b1 | (b2 << 8));
135 internal ushort ReadUInt16()
137 return (ushort)ReadInt16();
140 internal int ReadInt32()
143 throw new BadImageFormatException();
144 byte b1 = buffer[pos++];
145 byte b2 = buffer[pos++];
146 byte b3 = buffer[pos++];
147 byte b4 = buffer[pos++];
148 return (int)(b1 | (b2 << 8) | (b3 << 16) | (b4 << 24));
151 internal uint ReadUInt32()
153 return (uint)ReadInt32();
156 internal long ReadInt64()
158 ulong lo = ReadUInt32();
159 ulong hi = ReadUInt32();
160 return (long)(lo | (hi << 32));
163 internal ulong ReadUInt64()
165 return (ulong)ReadInt64();
168 internal float ReadSingle()
170 return SingleConverter.Int32BitsToSingle(ReadInt32());
173 internal double ReadDouble()
175 return BitConverter.Int64BitsToDouble(ReadInt64());
178 internal ByteReader Slice(int length)
180 if (end - pos < length)
181 throw new BadImageFormatException();
182 ByteReader br = new ByteReader(buffer, pos, length);
187 // NOTE this method only works if the original offset was aligned and for alignments that are a power of 2
188 internal void Align(int alignment)
191 pos = (pos + alignment) & ~alignment;