2 Copyright (C) 2009-2011 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 using IKVM.Reflection.Metadata;
30 namespace IKVM.Reflection.Reader
32 sealed class MetadataReader : MetadataRW
34 private readonly Stream stream;
35 private const int bufferLength = 2048;
36 private readonly byte[] buffer = new byte[bufferLength];
37 private int pos = bufferLength;
39 internal MetadataReader(ModuleReader module, Stream stream, byte heapSizes)
40 : base(module, (heapSizes & 0x01) != 0, (heapSizes & 0x02) != 0, (heapSizes & 0x04) != 0)
45 private void FillBuffer(int needed)
47 int count = bufferLength - pos;
50 // move remaining bytes to the front of the buffer
51 Buffer.BlockCopy(buffer, pos, buffer, 0, count);
55 while (count < needed)
57 int len = stream.Read(buffer, count, bufferLength - count);
60 throw new BadImageFormatException();
65 if (count != bufferLength)
67 // we didn't fill the buffer completely, so have to restore the invariant
68 // that all data from pos up until the end of the buffer is valid
69 Buffer.BlockCopy(buffer, 0, buffer, bufferLength - count, count);
70 pos = bufferLength - count;
74 internal ushort ReadUInt16()
76 return (ushort)ReadInt16();
79 internal short ReadInt16()
81 if (pos > bufferLength - 2)
85 byte b1 = buffer[pos++];
86 byte b2 = buffer[pos++];
87 return (short)(b1 | (b2 << 8));
90 internal int ReadInt32()
92 if (pos > bufferLength - 4)
96 byte b1 = buffer[pos++];
97 byte b2 = buffer[pos++];
98 byte b3 = buffer[pos++];
99 byte b4 = buffer[pos++];
100 return b1 | (b2 << 8) | (b3 << 16) | (b4 << 24);
103 private int ReadIndex(bool big)
115 internal int ReadStringIndex()
117 return ReadIndex(bigStrings);
120 internal int ReadGuidIndex()
122 return ReadIndex(bigGuids);
125 internal int ReadBlobIndex()
127 return ReadIndex(bigBlobs);
130 internal int ReadResolutionScope()
132 int codedIndex = ReadIndex(bigResolutionScope);
133 switch (codedIndex & 3)
136 return (ModuleTable.Index << 24) + (codedIndex >> 2);
138 return (ModuleRefTable.Index << 24) + (codedIndex >> 2);
140 return (AssemblyRefTable.Index << 24) + (codedIndex >> 2);
142 return (TypeRefTable.Index << 24) + (codedIndex >> 2);
144 throw new BadImageFormatException();
148 internal int ReadTypeDefOrRef()
150 int codedIndex = ReadIndex(bigTypeDefOrRef);
151 switch (codedIndex & 3)
154 return (TypeDefTable.Index << 24) + (codedIndex >> 2);
156 return (TypeRefTable.Index << 24) + (codedIndex >> 2);
158 return (TypeSpecTable.Index << 24) + (codedIndex >> 2);
160 throw new BadImageFormatException();
164 internal int ReadMemberRefParent()
166 int codedIndex = ReadIndex(bigMemberRefParent);
167 switch (codedIndex & 7)
170 return (TypeDefTable.Index << 24) + (codedIndex >> 3);
172 return (TypeRefTable.Index << 24) + (codedIndex >> 3);
174 return (ModuleRefTable.Index << 24) + (codedIndex >> 3);
176 return (MethodDefTable.Index << 24) + (codedIndex >> 3);
178 return (TypeSpecTable.Index << 24) + (codedIndex >> 3);
180 throw new BadImageFormatException();
184 internal int ReadHasCustomAttribute()
186 int codedIndex = ReadIndex(bigHasCustomAttribute);
187 switch (codedIndex & 31)
190 return (MethodDefTable.Index << 24) + (codedIndex >> 5);
192 return (FieldTable.Index << 24) + (codedIndex >> 5);
194 return (TypeRefTable.Index << 24) + (codedIndex >> 5);
196 return (TypeDefTable.Index << 24) + (codedIndex >> 5);
198 return (ParamTable.Index << 24) + (codedIndex >> 5);
200 return (InterfaceImplTable.Index << 24) + (codedIndex >> 5);
202 return (MemberRefTable.Index << 24) + (codedIndex >> 5);
204 return (ModuleTable.Index << 24) + (codedIndex >> 5);
206 throw new BadImageFormatException();
208 return (PropertyTable.Index << 24) + (codedIndex >> 5);
210 return (EventTable.Index << 24) + (codedIndex >> 5);
212 return (StandAloneSigTable.Index << 24) + (codedIndex >> 5);
214 return (ModuleRefTable.Index << 24) + (codedIndex >> 5);
216 return (TypeSpecTable.Index << 24) + (codedIndex >> 5);
218 return (AssemblyTable.Index << 24) + (codedIndex >> 5);
220 return (AssemblyRefTable.Index << 24) + (codedIndex >> 5);
222 return (FileTable.Index << 24) + (codedIndex >> 5);
224 return (ExportedTypeTable.Index << 24) + (codedIndex >> 5);
226 return (ManifestResourceTable.Index << 24) + (codedIndex >> 5);
228 return (GenericParamTable.Index << 24) + (codedIndex >> 5);
230 throw new BadImageFormatException();
234 internal int ReadCustomAttributeType()
236 int codedIndex = ReadIndex(bigCustomAttributeType);
237 switch (codedIndex & 7)
240 return (MethodDefTable.Index << 24) + (codedIndex >> 3);
242 return (MemberRefTable.Index << 24) + (codedIndex >> 3);
244 throw new BadImageFormatException();
248 internal int ReadMethodDefOrRef()
250 int codedIndex = ReadIndex(bigMethodDefOrRef);
251 switch (codedIndex & 1)
254 return (MethodDefTable.Index << 24) + (codedIndex >> 1);
256 return (MemberRefTable.Index << 24) + (codedIndex >> 1);
258 throw new BadImageFormatException();
262 internal int ReadHasConstant()
264 int codedIndex = ReadIndex(bigHasConstant);
265 switch (codedIndex & 3)
268 return (FieldTable.Index << 24) + (codedIndex >> 2);
270 return (ParamTable.Index << 24) + (codedIndex >> 2);
272 return (PropertyTable.Index << 24) + (codedIndex >> 2);
274 throw new BadImageFormatException();
278 internal int ReadHasSemantics()
280 int codedIndex = ReadIndex(bigHasSemantics);
281 switch (codedIndex & 1)
284 return (EventTable.Index << 24) + (codedIndex >> 1);
286 return (PropertyTable.Index << 24) + (codedIndex >> 1);
288 throw new BadImageFormatException();
292 internal int ReadHasFieldMarshal()
294 int codedIndex = ReadIndex(bigHasFieldMarshal);
295 switch (codedIndex & 1)
298 return (FieldTable.Index << 24) + (codedIndex >> 1);
300 return (ParamTable.Index << 24) + (codedIndex >> 1);
302 throw new BadImageFormatException();
306 internal int ReadHasDeclSecurity()
308 int codedIndex = ReadIndex(bigHasDeclSecurity);
309 switch (codedIndex & 3)
312 return (TypeDefTable.Index << 24) + (codedIndex >> 2);
314 return (MethodDefTable.Index << 24) + (codedIndex >> 2);
316 return (AssemblyTable.Index << 24) + (codedIndex >> 2);
318 throw new BadImageFormatException();
322 internal int ReadTypeOrMethodDef()
324 int codedIndex = ReadIndex(bigTypeOrMethodDef);
325 switch (codedIndex & 1)
328 return (TypeDefTable.Index << 24) + (codedIndex >> 1);
330 return (MethodDefTable.Index << 24) + (codedIndex >> 1);
332 throw new BadImageFormatException();
336 internal int ReadMemberForwarded()
338 int codedIndex = ReadIndex(bigMemberForwarded);
339 switch (codedIndex & 1)
342 return (FieldTable.Index << 24) + (codedIndex >> 1);
344 return (MethodDefTable.Index << 24) + (codedIndex >> 1);
346 throw new BadImageFormatException();
350 internal int ReadImplementation()
352 int codedIndex = ReadIndex(bigImplementation);
353 switch (codedIndex & 3)
356 return (FileTable.Index << 24) + (codedIndex >> 2);
358 return (AssemblyRefTable.Index << 24) + (codedIndex >> 2);
360 return (ExportedTypeTable.Index << 24) + (codedIndex >> 2);
362 throw new BadImageFormatException();
366 internal int ReadField()
368 return ReadIndex(bigField);
371 internal int ReadMethodDef()
373 return ReadIndex(bigMethodDef);
376 internal int ReadParam()
378 return ReadIndex(bigParam);
381 internal int ReadProperty()
383 return ReadIndex(bigProperty);
386 internal int ReadEvent()
388 return ReadIndex(bigEvent);
391 internal int ReadTypeDef()
393 return ReadIndex(bigTypeDef) | (TypeDefTable.Index << 24);
396 internal int ReadGenericParam()
398 return ReadIndex(bigGenericParam) | (GenericParamTable.Index << 24);
401 internal int ReadModuleRef()
403 return ReadIndex(bigModuleRef) | (ModuleRefTable.Index << 24);