Update mcs/class/Commons.Xml.Relaxng/Commons.Xml.Relaxng/RelaxngPattern.cs
[mono.git] / mcs / class / IKVM.Reflection / Reader / MetadataReader.cs
1 /*
2   Copyright (C) 2009-2011 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 Stream stream;
35                 private const int bufferLength = 2048;
36                 private readonly byte[] buffer = new byte[bufferLength];
37                 private int pos = bufferLength;
38
39                 internal MetadataReader(ModuleReader module, Stream stream, byte heapSizes)
40                         : base(module, (heapSizes & 0x01) != 0, (heapSizes & 0x02) != 0, (heapSizes & 0x04) != 0)
41                 {
42                         this.stream = stream;
43                 }
44
45                 private void FillBuffer(int needed)
46                 {
47                         int count = bufferLength - pos;
48                         if (count != 0)
49                         {
50                                 // move remaining bytes to the front of the buffer
51                                 Buffer.BlockCopy(buffer, pos, buffer, 0, count);
52                         }
53                         pos = 0;
54
55                         while (count < needed)
56                         {
57                                 int len = stream.Read(buffer, count, bufferLength - count);
58                                 if (len == 0)
59                                 {
60                                         throw new BadImageFormatException();
61                                 }
62                                 count += len;
63                         }
64
65                         if (count != bufferLength)
66                         {
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;
71                         }
72                 }
73
74                 internal ushort ReadUInt16()
75                 {
76                         return (ushort)ReadInt16();
77                 }
78
79                 internal short ReadInt16()
80                 {
81                         if (pos > bufferLength - 2)
82                         {
83                                 FillBuffer(2);
84                         }
85                         byte b1 = buffer[pos++];
86                         byte b2 = buffer[pos++];
87                         return (short)(b1 | (b2 << 8));
88                 }
89
90                 internal int ReadInt32()
91                 {
92                         if (pos > bufferLength - 4)
93                         {
94                                 FillBuffer(4);
95                         }
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);
101                 }
102
103                 private int ReadIndex(bool big)
104                 {
105                         if (big)
106                         {
107                                 return ReadInt32();
108                         }
109                         else
110                         {
111                                 return ReadUInt16();
112                         }
113                 }
114
115                 internal int ReadStringIndex()
116                 {
117                         return ReadIndex(bigStrings);
118                 }
119
120                 internal int ReadGuidIndex()
121                 {
122                         return ReadIndex(bigGuids);
123                 }
124
125                 internal int ReadBlobIndex()
126                 {
127                         return ReadIndex(bigBlobs);
128                 }
129
130                 internal int ReadResolutionScope()
131                 {
132                         int codedIndex = ReadIndex(bigResolutionScope);
133                         switch (codedIndex & 3)
134                         {
135                                 case 0:
136                                         return (ModuleTable.Index << 24) + (codedIndex >> 2);
137                                 case 1:
138                                         return (ModuleRefTable.Index << 24) + (codedIndex >> 2);
139                                 case 2:
140                                         return (AssemblyRefTable.Index << 24) + (codedIndex >> 2);
141                                 case 3:
142                                         return (TypeRefTable.Index << 24) + (codedIndex >> 2);
143                                 default:
144                                         throw new BadImageFormatException();
145                         }
146                 }
147
148                 internal int ReadTypeDefOrRef()
149                 {
150                         int codedIndex = ReadIndex(bigTypeDefOrRef);
151                         switch (codedIndex & 3)
152                         {
153                                 case 0:
154                                         return (TypeDefTable.Index << 24) + (codedIndex >> 2);
155                                 case 1:
156                                         return (TypeRefTable.Index << 24) + (codedIndex >> 2);
157                                 case 2:
158                                         return (TypeSpecTable.Index << 24) + (codedIndex >> 2);
159                                 default:
160                                         throw new BadImageFormatException();
161                         }
162                 }
163
164                 internal int ReadMemberRefParent()
165                 {
166                         int codedIndex = ReadIndex(bigMemberRefParent);
167                         switch (codedIndex & 7)
168                         {
169                                 case 0:
170                                         return (TypeDefTable.Index << 24) + (codedIndex >> 3);
171                                 case 1:
172                                         return (TypeRefTable.Index << 24) + (codedIndex >> 3);
173                                 case 2:
174                                         return (ModuleRefTable.Index << 24) + (codedIndex >> 3);
175                                 case 3:
176                                         return (MethodDefTable.Index << 24) + (codedIndex >> 3);
177                                 case 4:
178                                         return (TypeSpecTable.Index << 24) + (codedIndex >> 3);
179                                 default:
180                                         throw new BadImageFormatException();
181                         }
182                 }
183
184                 internal int ReadHasCustomAttribute()
185                 {
186                         int codedIndex = ReadIndex(bigHasCustomAttribute);
187                         switch (codedIndex & 31)
188                         {
189                                 case 0:
190                                         return (MethodDefTable.Index << 24) + (codedIndex >> 5);
191                                 case 1:
192                                         return (FieldTable.Index << 24) + (codedIndex >> 5);
193                                 case 2:
194                                         return (TypeRefTable.Index << 24) + (codedIndex >> 5);
195                                 case 3:
196                                         return (TypeDefTable.Index << 24) + (codedIndex >> 5);
197                                 case 4:
198                                         return (ParamTable.Index << 24) + (codedIndex >> 5);
199                                 case 5:
200                                         return (InterfaceImplTable.Index << 24) + (codedIndex >> 5);
201                                 case 6:
202                                         return (MemberRefTable.Index << 24) + (codedIndex >> 5);
203                                 case 7:
204                                         return (ModuleTable.Index << 24) + (codedIndex >> 5);
205                                 case 8:
206                                         throw new BadImageFormatException();
207                                 case 9:
208                                         return (PropertyTable.Index << 24) + (codedIndex >> 5);
209                                 case 10:
210                                         return (EventTable.Index << 24) + (codedIndex >> 5);
211                                 case 11:
212                                         return (StandAloneSigTable.Index << 24) + (codedIndex >> 5);
213                                 case 12:
214                                         return (ModuleRefTable.Index << 24) + (codedIndex >> 5);
215                                 case 13:
216                                         return (TypeSpecTable.Index << 24) + (codedIndex >> 5);
217                                 case 14:
218                                         return (AssemblyTable.Index << 24) + (codedIndex >> 5);
219                                 case 15:
220                                         return (AssemblyRefTable.Index << 24) + (codedIndex >> 5);
221                                 case 16:
222                                         return (FileTable.Index << 24) + (codedIndex >> 5);
223                                 case 17:
224                                         return (ExportedTypeTable.Index << 24) + (codedIndex >> 5);
225                                 case 18:
226                                         return (ManifestResourceTable.Index << 24) + (codedIndex >> 5);
227                                 case 19:
228                                         return (GenericParamTable.Index << 24) + (codedIndex >> 5);
229                                 default:
230                                         throw new BadImageFormatException();
231                         }
232                 }
233
234                 internal int ReadCustomAttributeType()
235                 {
236                         int codedIndex = ReadIndex(bigCustomAttributeType);
237                         switch (codedIndex & 7)
238                         {
239                                 case 2:
240                                         return (MethodDefTable.Index << 24) + (codedIndex >> 3);
241                                 case 3:
242                                         return (MemberRefTable.Index << 24) + (codedIndex >> 3);
243                                 default:
244                                         throw new BadImageFormatException();
245                         }
246                 }
247
248                 internal int ReadMethodDefOrRef()
249                 {
250                         int codedIndex = ReadIndex(bigMethodDefOrRef);
251                         switch (codedIndex & 1)
252                         {
253                                 case 0:
254                                         return (MethodDefTable.Index << 24) + (codedIndex >> 1);
255                                 case 1:
256                                         return (MemberRefTable.Index << 24) + (codedIndex >> 1);
257                                 default:
258                                         throw new BadImageFormatException();
259                         }
260                 }
261
262                 internal int ReadHasConstant()
263                 {
264                         int codedIndex = ReadIndex(bigHasConstant);
265                         switch (codedIndex & 3)
266                         {
267                                 case 0:
268                                         return (FieldTable.Index << 24) + (codedIndex >> 2);
269                                 case 1:
270                                         return (ParamTable.Index << 24) + (codedIndex >> 2);
271                                 case 2:
272                                         return (PropertyTable.Index << 24) + (codedIndex >> 2);
273                                 default:
274                                         throw new BadImageFormatException();
275                         }
276                 }
277
278                 internal int ReadHasSemantics()
279                 {
280                         int codedIndex = ReadIndex(bigHasSemantics);
281                         switch (codedIndex & 1)
282                         {
283                                 case 0:
284                                         return (EventTable.Index << 24) + (codedIndex >> 1);
285                                 case 1:
286                                         return (PropertyTable.Index << 24) + (codedIndex >> 1);
287                                 default:
288                                         throw new BadImageFormatException();
289                         }
290                 }
291
292                 internal int ReadHasFieldMarshal()
293                 {
294                         int codedIndex = ReadIndex(bigHasFieldMarshal);
295                         switch (codedIndex & 1)
296                         {
297                                 case 0:
298                                         return (FieldTable.Index << 24) + (codedIndex >> 1);
299                                 case 1:
300                                         return (ParamTable.Index << 24) + (codedIndex >> 1);
301                                 default:
302                                         throw new BadImageFormatException();
303                         }
304                 }
305
306                 internal int ReadHasDeclSecurity()
307                 {
308                         int codedIndex = ReadIndex(bigHasDeclSecurity);
309                         switch (codedIndex & 3)
310                         {
311                                 case 0:
312                                         return (TypeDefTable.Index << 24) + (codedIndex >> 2);
313                                 case 1:
314                                         return (MethodDefTable.Index << 24) + (codedIndex >> 2);
315                                 case 2:
316                                         return (AssemblyTable.Index << 24) + (codedIndex >> 2);
317                                 default:
318                                         throw new BadImageFormatException();
319                         }
320                 }
321
322                 internal int ReadTypeOrMethodDef()
323                 {
324                         int codedIndex = ReadIndex(bigTypeOrMethodDef);
325                         switch (codedIndex & 1)
326                         {
327                                 case 0:
328                                         return (TypeDefTable.Index << 24) + (codedIndex >> 1);
329                                 case 1:
330                                         return (MethodDefTable.Index << 24) + (codedIndex >> 1);
331                                 default:
332                                         throw new BadImageFormatException();
333                         }
334                 }
335
336                 internal int ReadMemberForwarded()
337                 {
338                         int codedIndex = ReadIndex(bigMemberForwarded);
339                         switch (codedIndex & 1)
340                         {
341                                 case 0:
342                                         return (FieldTable.Index << 24) + (codedIndex >> 1);
343                                 case 1:
344                                         return (MethodDefTable.Index << 24) + (codedIndex >> 1);
345                                 default:
346                                         throw new BadImageFormatException();
347                         }
348                 }
349
350                 internal int ReadImplementation()
351                 {
352                         int codedIndex = ReadIndex(bigImplementation);
353                         switch (codedIndex & 3)
354                         {
355                                 case 0:
356                                         return (FileTable.Index << 24) + (codedIndex >> 2);
357                                 case 1:
358                                         return (AssemblyRefTable.Index << 24) + (codedIndex >> 2);
359                                 case 2:
360                                         return (ExportedTypeTable.Index << 24) + (codedIndex >> 2);
361                                 default:
362                                         throw new BadImageFormatException();
363                         }
364                 }
365
366                 internal int ReadField()
367                 {
368                         return ReadIndex(bigField);
369                 }
370
371                 internal int ReadMethodDef()
372                 {
373                         return ReadIndex(bigMethodDef);
374                 }
375
376                 internal int ReadParam()
377                 {
378                         return ReadIndex(bigParam);
379                 }
380
381                 internal int ReadProperty()
382                 {
383                         return ReadIndex(bigProperty);
384                 }
385
386                 internal int ReadEvent()
387                 {
388                         return ReadIndex(bigEvent);
389                 }
390
391                 internal int ReadTypeDef()
392                 {
393                         return ReadIndex(bigTypeDef) | (TypeDefTable.Index << 24);
394                 }
395
396                 internal int ReadGenericParam()
397                 {
398                         return ReadIndex(bigGenericParam) | (GenericParamTable.Index << 24);
399                 }
400
401                 internal int ReadModuleRef()
402                 {
403                         return ReadIndex(bigModuleRef) | (ModuleRefTable.Index << 24);
404                 }
405         }
406 }