Merge remote branch 'upstream/master'
[mono.git] / mcs / class / IKVM.Reflection / Reader / MetadataReader.cs
1 /*
2   Copyright (C) 2009 Jeroen Frijters
3
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.
7
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:
11
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.
19
20   Jeroen Frijters
21   jeroen@frijters.net
22   
23 */
24 using System;
25 using System.Collections.Generic;
26 using System.Text;
27 using System.IO;
28 using IKVM.Reflection.Metadata;
29
30 namespace IKVM.Reflection.Reader
31 {
32         sealed class MetadataReader : MetadataRW
33         {
34                 private readonly BinaryReader br;
35
36                 internal MetadataReader(ModuleReader module, BinaryReader br, byte heapSizes)
37                         : base(module, (heapSizes & 0x01) != 0, (heapSizes & 0x02) != 0, (heapSizes & 0x04) != 0)
38                 {
39                         this.br = br;
40                 }
41
42                 internal short ReadInt16()
43                 {
44                         return br.ReadInt16();
45                 }
46
47                 internal ushort ReadUInt16()
48                 {
49                         return br.ReadUInt16();
50                 }
51
52                 internal int ReadInt32()
53                 {
54                         return br.ReadInt32();
55                 }
56
57                 internal int ReadStringIndex()
58                 {
59                         if (bigStrings)
60                         {
61                                 return br.ReadInt32();
62                         }
63                         else
64                         {
65                                 return br.ReadUInt16();
66                         }
67                 }
68
69                 internal int ReadGuidIndex()
70                 {
71                         if (bigGuids)
72                         {
73                                 return br.ReadInt32();
74                         }
75                         else
76                         {
77                                 return br.ReadUInt16();
78                         }
79                 }
80
81                 internal int ReadBlobIndex()
82                 {
83                         if (bigBlobs)
84                         {
85                                 return br.ReadInt32();
86                         }
87                         else
88                         {
89                                 return br.ReadUInt16();
90                         }
91                 }
92
93                 internal int ReadResolutionScope()
94                 {
95                         int codedIndex;
96                         if (bigResolutionScope)
97                         {
98                                 codedIndex = br.ReadInt32();
99                         }
100                         else
101                         {
102                                 codedIndex = br.ReadUInt16();
103                         }
104                         switch (codedIndex & 3)
105                         {
106                                 case 0:
107                                         return (ModuleTable.Index << 24) + (codedIndex >> 2);
108                                 case 1:
109                                         return (ModuleRefTable.Index << 24) + (codedIndex >> 2);
110                                 case 2:
111                                         return (AssemblyRefTable.Index << 24) + (codedIndex >> 2);
112                                 case 3:
113                                         return (TypeRefTable.Index << 24) + (codedIndex >> 2);
114                                 default:
115                                         throw new BadImageFormatException();
116                         }
117                 }
118
119                 internal int ReadTypeDefOrRef()
120                 {
121                         int codedIndex;
122                         if (bigTypeDefOrRef)
123                         {
124                                 codedIndex = br.ReadInt32();
125                         }
126                         else
127                         {
128                                 codedIndex = br.ReadUInt16();
129                         }
130                         switch (codedIndex & 3)
131                         {
132                                 case 0:
133                                         return (TypeDefTable.Index << 24) + (codedIndex >> 2);
134                                 case 1:
135                                         return (TypeRefTable.Index << 24) + (codedIndex >> 2);
136                                 case 2:
137                                         return (TypeSpecTable.Index << 24) + (codedIndex >> 2);
138                                 default:
139                                         throw new BadImageFormatException();
140                         }
141                 }
142
143                 internal int ReadMemberRefParent()
144                 {
145                         int codedIndex;
146                         if (bigMemberRefParent)
147                         {
148                                 codedIndex = br.ReadInt32();
149                         }
150                         else
151                         {
152                                 codedIndex = br.ReadUInt16();
153                         }
154                         switch (codedIndex & 7)
155                         {
156                                 case 0:
157                                         return (TypeDefTable.Index << 24) + (codedIndex >> 3);
158                                 case 1:
159                                         return (TypeRefTable.Index << 24) + (codedIndex >> 3);
160                                 case 2:
161                                         return (ModuleRefTable.Index << 24) + (codedIndex >> 3);
162                                 case 3:
163                                         return (MethodDefTable.Index << 24) + (codedIndex >> 3);
164                                 case 4:
165                                         return (TypeSpecTable.Index << 24) + (codedIndex >> 3);
166                                 default:
167                                         throw new BadImageFormatException();
168                         }
169                 }
170
171                 internal int ReadHasCustomAttribute()
172                 {
173                         int codedIndex;
174                         if (bigHasCustomAttribute)
175                         {
176                                 codedIndex = br.ReadInt32();
177                         }
178                         else
179                         {
180                                 codedIndex = br.ReadUInt16();
181                         }
182                         switch (codedIndex & 31)
183                         {
184                                 case 0:
185                                         return (MethodDefTable.Index << 24) + (codedIndex >> 5);
186                                 case 1:
187                                         return (FieldTable.Index << 24) + (codedIndex >> 5);
188                                 case 2:
189                                         return (TypeRefTable.Index << 24) + (codedIndex >> 5);
190                                 case 3:
191                                         return (TypeDefTable.Index << 24) + (codedIndex >> 5);
192                                 case 4:
193                                         return (ParamTable.Index << 24) + (codedIndex >> 5);
194                                 case 5:
195                                         return (InterfaceImplTable.Index << 24) + (codedIndex >> 5);
196                                 case 6:
197                                         return (MemberRefTable.Index << 24) + (codedIndex >> 5);
198                                 case 7:
199                                         return (ModuleTable.Index << 24) + (codedIndex >> 5);
200                                 case 8:
201                                         throw new BadImageFormatException();
202                                 case 9:
203                                         return (PropertyTable.Index << 24) + (codedIndex >> 5);
204                                 case 10:
205                                         return (EventTable.Index << 24) + (codedIndex >> 5);
206                                 case 11:
207                                         return (StandAloneSigTable.Index << 24) + (codedIndex >> 5);
208                                 case 12:
209                                         return (ModuleRefTable.Index << 24) + (codedIndex >> 5);
210                                 case 13:
211                                         return (TypeSpecTable.Index << 24) + (codedIndex >> 5);
212                                 case 14:
213                                         return (AssemblyTable.Index << 24) + (codedIndex >> 5);
214                                 case 15:
215                                         return (AssemblyRefTable.Index << 24) + (codedIndex >> 5);
216                                 case 16:
217                                         return (FileTable.Index << 24) + (codedIndex >> 5);
218                                 case 17:
219                                         return (ExportedTypeTable.Index << 24) + (codedIndex >> 5);
220                                 case 18:
221                                         return (ManifestResourceTable.Index << 24) + (codedIndex >> 5);
222                                 case 19:
223                                         return (GenericParamTable.Index << 24) + (codedIndex >> 5);
224                                 default:
225                                         throw new BadImageFormatException();
226                         }
227                 }
228
229                 internal int ReadCustomAttributeType()
230                 {
231                         int codedIndex;
232                         if (bigCustomAttributeType)
233                         {
234                                 codedIndex = br.ReadInt32();
235                         }
236                         else
237                         {
238                                 codedIndex = br.ReadUInt16();
239                         }
240                         switch (codedIndex & 7)
241                         {
242                                 case 2:
243                                         return (MethodDefTable.Index << 24) + (codedIndex >> 3);
244                                 case 3:
245                                         return (MemberRefTable.Index << 24) + (codedIndex >> 3);
246                                 default:
247                                         throw new BadImageFormatException();
248                         }
249                 }
250
251                 internal int ReadMethodDefOrRef()
252                 {
253                         int codedIndex;
254                         if (bigMethodDefOrRef)
255                         {
256                                 codedIndex = br.ReadInt32();
257                         }
258                         else
259                         {
260                                 codedIndex = br.ReadUInt16();
261                         }
262                         switch (codedIndex & 1)
263                         {
264                                 case 0:
265                                         return (MethodDefTable.Index << 24) + (codedIndex >> 1);
266                                 case 1:
267                                         return (MemberRefTable.Index << 24) + (codedIndex >> 1);
268                                 default:
269                                         throw new BadImageFormatException();
270                         }
271                 }
272
273                 internal int ReadHasConstant()
274                 {
275                         int codedIndex;
276                         if (bigHasConstant)
277                         {
278                                 codedIndex = br.ReadInt32();
279                         }
280                         else
281                         {
282                                 codedIndex = br.ReadUInt16();
283                         }
284                         switch (codedIndex & 3)
285                         {
286                                 case 0:
287                                         return (FieldTable.Index << 24) + (codedIndex >> 2);
288                                 case 1:
289                                         return (ParamTable.Index << 24) + (codedIndex >> 2);
290                                 case 2:
291                                         return (PropertyTable.Index << 24) + (codedIndex >> 2);
292                                 default:
293                                         throw new BadImageFormatException();
294                         }
295                 }
296
297                 internal int ReadHasSemantics()
298                 {
299                         int codedIndex;
300                         if (bigHasSemantics)
301                         {
302                                 codedIndex = br.ReadInt32();
303                         }
304                         else
305                         {
306                                 codedIndex = br.ReadUInt16();
307                         }
308                         switch (codedIndex & 1)
309                         {
310                                 case 0:
311                                         return (EventTable.Index << 24) + (codedIndex >> 1);
312                                 case 1:
313                                         return (PropertyTable.Index << 24) + (codedIndex >> 1);
314                                 default:
315                                         throw new BadImageFormatException();
316                         }
317                 }
318
319                 internal int ReadHasFieldMarshal()
320                 {
321                         int codedIndex;
322                         if (bigHasFieldMarshal)
323                         {
324                                 codedIndex = br.ReadInt32();
325                         }
326                         else
327                         {
328                                 codedIndex = br.ReadUInt16();
329                         }
330                         switch (codedIndex & 1)
331                         {
332                                 case 0:
333                                         return (FieldTable.Index << 24) + (codedIndex >> 1);
334                                 case 1:
335                                         return (ParamTable.Index << 24) + (codedIndex >> 1);
336                                 default:
337                                         throw new BadImageFormatException();
338                         }
339                 }
340
341                 internal int ReadHasDeclSecurity()
342                 {
343                         int codedIndex;
344                         if (bigHasDeclSecurity)
345                         {
346                                 codedIndex = br.ReadInt32();
347                         }
348                         else
349                         {
350                                 codedIndex = br.ReadUInt16();
351                         }
352                         switch (codedIndex & 3)
353                         {
354                                 case 0:
355                                         return (TypeDefTable.Index << 24) + (codedIndex >> 2);
356                                 case 1:
357                                         return (MethodDefTable.Index << 24) + (codedIndex >> 2);
358                                 case 2:
359                                         return (AssemblyTable.Index << 24) + (codedIndex >> 2);
360                                 default:
361                                         throw new BadImageFormatException();
362                         }
363                 }
364
365                 internal int ReadTypeOrMethodDef()
366                 {
367                         int codedIndex;
368                         if (bigTypeOrMethodDef)
369                         {
370                                 codedIndex = br.ReadInt32();
371                         }
372                         else
373                         {
374                                 codedIndex = br.ReadUInt16();
375                         }
376                         switch (codedIndex & 1)
377                         {
378                                 case 0:
379                                         return (TypeDefTable.Index << 24) + (codedIndex >> 1);
380                                 case 1:
381                                         return (MethodDefTable.Index << 24) + (codedIndex >> 1);
382                                 default:
383                                         throw new BadImageFormatException();
384                         }
385                 }
386
387                 internal int ReadMemberForwarded()
388                 {
389                         int codedIndex;
390                         if (bigMemberForwarded)
391                         {
392                                 codedIndex = br.ReadInt32();
393                         }
394                         else
395                         {
396                                 codedIndex = br.ReadUInt16();
397                         }
398                         switch (codedIndex & 1)
399                         {
400                                 case 0:
401                                         return (FieldTable.Index << 24) + (codedIndex >> 1);
402                                 case 1:
403                                         return (MethodDefTable.Index << 24) + (codedIndex >> 1);
404                                 default:
405                                         throw new BadImageFormatException();
406                         }
407                 }
408
409                 internal int ReadImplementation()
410                 {
411                         int codedIndex;
412                         if (bigImplementation)
413                         {
414                                 codedIndex = br.ReadInt32();
415                         }
416                         else
417                         {
418                                 codedIndex = br.ReadUInt16();
419                         }
420                         switch (codedIndex & 3)
421                         {
422                                 case 0:
423                                         return (FileTable.Index << 24) + (codedIndex >> 2);
424                                 case 1:
425                                         return (AssemblyRefTable.Index << 24) + (codedIndex >> 2);
426                                 case 2:
427                                         return (ExportedTypeTable.Index << 24) + (codedIndex >> 2);
428                                 default:
429                                         throw new BadImageFormatException();
430                         }
431                 }
432
433                 private int ReadToken(int table, bool big)
434                 {
435                         int rid;
436                         if (big)
437                         {
438                                 rid = br.ReadInt32();
439                         }
440                         else
441                         {
442                                 rid = br.ReadUInt16();
443                         }
444                         return rid | (table << 24);
445                 }
446
447                 internal int ReadField()
448                 {
449                         if (bigField)
450                         {
451                                 return br.ReadInt32();
452                         }
453                         else
454                         {
455                                 return br.ReadUInt16();
456                         }
457                 }
458
459                 internal int ReadMethodDef()
460                 {
461                         if (bigMethodDef)
462                         {
463                                 return br.ReadInt32();
464                         }
465                         else
466                         {
467                                 return br.ReadUInt16();
468                         }
469                 }
470
471                 internal int ReadParam()
472                 {
473                         if (bigParam)
474                         {
475                                 return br.ReadInt32();
476                         }
477                         else
478                         {
479                                 return br.ReadUInt16();
480                         }
481                 }
482
483                 internal int ReadProperty()
484                 {
485                         if (bigProperty)
486                         {
487                                 return br.ReadInt32();
488                         }
489                         else
490                         {
491                                 return br.ReadUInt16();
492                         }
493                 }
494
495                 internal int ReadEvent()
496                 {
497                         if (bigEvent)
498                         {
499                                 return br.ReadInt32();
500                         }
501                         else
502                         {
503                                 return br.ReadUInt16();
504                         }
505                 }
506
507                 internal int ReadTypeDef()
508                 {
509                         return ReadToken(TypeDefTable.Index, bigTypeDef);
510                 }
511
512                 internal int ReadGenericParam()
513                 {
514                         return ReadToken(GenericParamTable.Index, bigGenericParam);
515                 }
516
517                 internal int ReadModuleRef()
518                 {
519                         return ReadToken(ModuleRefTable.Index, bigModuleRef);
520                 }
521         }
522 }