2010-04-06 Jb Evain <jbevain@novell.com>
[mcs.git] / class / Mono.Cecil / Mono.Cecil.Metadata / Utilities.cs
blob7f762529c625c56443dbaa74d784e0d01c524c2b
1 //
2 // Utilities.cs
3 //
4 // Author:
5 // Jb Evain (jbevain@gmail.com)
6 //
7 // Generated by /CodeGen/cecil-gen.rb do not edit
8 // Sat Feb 16 23:23:29 +0100 2008
9 //
10 // (C) 2005 Jb Evain
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 namespace Mono.Cecil.Metadata {
34 using System;
35 using System.Collections;
36 using System.IO;
38 sealed class Utilities {
40 Utilities ()
44 public static int ReadCompressedInteger (byte [] data, int pos, out int start)
46 int integer;
47 start = pos;
48 if ((data [pos] & 0x80) == 0) {
49 integer = data [pos];
50 start++;
51 } else if ((data [pos] & 0x40) == 0) {
52 integer = (data [start] & ~0x80) << 8;
53 integer |= data [pos + 1];
54 start += 2;
55 } else {
56 integer = (data [start] & ~0xc0) << 24;
57 integer |= data [pos + 1] << 16;
58 integer |= data [pos + 2] << 8;
59 integer |= data [pos + 3];
60 start += 4;
62 return integer;
65 public static int ReadCompressedSignedInteger (byte [] data, int pos, out int start)
67 int integer = ReadCompressedInteger (data, pos, out start) >> 1;
68 if ((integer & 1) == 0)
69 return integer;
71 if (integer < 0x40)
72 return integer - 0x40;
74 if (integer < 0x2000)
75 return integer - 0x2000;
77 if (integer < 0x10000000)
78 return integer - 0x10000000;
80 return integer - 0x20000000;
83 public static int WriteCompressedInteger (BinaryWriter writer, int value)
85 if (value < 0x80)
86 writer.Write ((byte) value);
87 else if (value < 0x4000) {
88 writer.Write ((byte) (0x80 | (value >> 8)));
89 writer.Write ((byte) (value & 0xff));
90 } else {
91 writer.Write ((byte) ((value >> 24) | 0xc0));
92 writer.Write ((byte) ((value >> 16) & 0xff));
93 writer.Write ((byte) ((value >> 8) & 0xff));
94 writer.Write ((byte) (value & 0xff));
96 return (int) writer.BaseStream.Position;
99 public static MetadataToken GetMetadataToken (CodedIndex cidx, uint data)
101 uint rid = 0;
102 switch (cidx) {
103 case CodedIndex.TypeDefOrRef :
104 rid = data >> 2;
105 switch (data & 3) {
106 case 0 :
107 return new MetadataToken (TokenType.TypeDef, rid);
108 case 1 :
109 return new MetadataToken (TokenType.TypeRef, rid);
110 case 2 :
111 return new MetadataToken (TokenType.TypeSpec, rid);
112 default :
113 return MetadataToken.Zero;
115 case CodedIndex.HasConstant :
116 rid = data >> 2;
117 switch (data & 3) {
118 case 0 :
119 return new MetadataToken (TokenType.Field, rid);
120 case 1 :
121 return new MetadataToken (TokenType.Param, rid);
122 case 2 :
123 return new MetadataToken (TokenType.Property, rid);
124 default :
125 return MetadataToken.Zero;
127 case CodedIndex.HasCustomAttribute :
128 rid = data >> 5;
129 switch (data & 31) {
130 case 0 :
131 return new MetadataToken (TokenType.Method, rid);
132 case 1 :
133 return new MetadataToken (TokenType.Field, rid);
134 case 2 :
135 return new MetadataToken (TokenType.TypeRef, rid);
136 case 3 :
137 return new MetadataToken (TokenType.TypeDef, rid);
138 case 4 :
139 return new MetadataToken (TokenType.Param, rid);
140 case 5 :
141 return new MetadataToken (TokenType.InterfaceImpl, rid);
142 case 6 :
143 return new MetadataToken (TokenType.MemberRef, rid);
144 case 7 :
145 return new MetadataToken (TokenType.Module, rid);
146 case 8 :
147 return new MetadataToken (TokenType.Permission, rid);
148 case 9 :
149 return new MetadataToken (TokenType.Property, rid);
150 case 10 :
151 return new MetadataToken (TokenType.Event, rid);
152 case 11 :
153 return new MetadataToken (TokenType.Signature, rid);
154 case 12 :
155 return new MetadataToken (TokenType.ModuleRef, rid);
156 case 13 :
157 return new MetadataToken (TokenType.TypeSpec, rid);
158 case 14 :
159 return new MetadataToken (TokenType.Assembly, rid);
160 case 15 :
161 return new MetadataToken (TokenType.AssemblyRef, rid);
162 case 16 :
163 return new MetadataToken (TokenType.File, rid);
164 case 17 :
165 return new MetadataToken (TokenType.ExportedType, rid);
166 case 18 :
167 return new MetadataToken (TokenType.ManifestResource, rid);
168 case 19 :
169 return new MetadataToken (TokenType.GenericParam, rid);
170 default :
171 return MetadataToken.Zero;
173 case CodedIndex.HasFieldMarshal :
174 rid = data >> 1;
175 switch (data & 1) {
176 case 0 :
177 return new MetadataToken (TokenType.Field, rid);
178 case 1 :
179 return new MetadataToken (TokenType.Param, rid);
180 default :
181 return MetadataToken.Zero;
183 case CodedIndex.HasDeclSecurity :
184 rid = data >> 2;
185 switch (data & 3) {
186 case 0 :
187 return new MetadataToken (TokenType.TypeDef, rid);
188 case 1 :
189 return new MetadataToken (TokenType.Method, rid);
190 case 2 :
191 return new MetadataToken (TokenType.Assembly, rid);
192 default :
193 return MetadataToken.Zero;
195 case CodedIndex.MemberRefParent :
196 rid = data >> 3;
197 switch (data & 7) {
198 case 0 :
199 return new MetadataToken (TokenType.TypeDef, rid);
200 case 1 :
201 return new MetadataToken (TokenType.TypeRef, rid);
202 case 2 :
203 return new MetadataToken (TokenType.ModuleRef, rid);
204 case 3 :
205 return new MetadataToken (TokenType.Method, rid);
206 case 4 :
207 return new MetadataToken (TokenType.TypeSpec, rid);
208 default :
209 return MetadataToken.Zero;
211 case CodedIndex.HasSemantics :
212 rid = data >> 1;
213 switch (data & 1) {
214 case 0 :
215 return new MetadataToken (TokenType.Event, rid);
216 case 1 :
217 return new MetadataToken (TokenType.Property, rid);
218 default :
219 return MetadataToken.Zero;
221 case CodedIndex.MethodDefOrRef :
222 rid = data >> 1;
223 switch (data & 1) {
224 case 0 :
225 return new MetadataToken (TokenType.Method, rid);
226 case 1 :
227 return new MetadataToken (TokenType.MemberRef, rid);
228 default :
229 return MetadataToken.Zero;
231 case CodedIndex.MemberForwarded :
232 rid = data >> 1;
233 switch (data & 1) {
234 case 0 :
235 return new MetadataToken (TokenType.Field, rid);
236 case 1 :
237 return new MetadataToken (TokenType.Method, rid);
238 default :
239 return MetadataToken.Zero;
241 case CodedIndex.Implementation :
242 rid = data >> 2;
243 switch (data & 3) {
244 case 0 :
245 return new MetadataToken (TokenType.File, rid);
246 case 1 :
247 return new MetadataToken (TokenType.AssemblyRef, rid);
248 case 2 :
249 return new MetadataToken (TokenType.ExportedType, rid);
250 default :
251 return MetadataToken.Zero;
253 case CodedIndex.CustomAttributeType :
254 rid = data >> 3;
255 switch (data & 7) {
256 case 2 :
257 return new MetadataToken (TokenType.Method, rid);
258 case 3 :
259 return new MetadataToken (TokenType.MemberRef, rid);
260 default :
261 return MetadataToken.Zero;
263 case CodedIndex.ResolutionScope :
264 rid = data >> 2;
265 switch (data & 3) {
266 case 0 :
267 return new MetadataToken (TokenType.Module, rid);
268 case 1 :
269 return new MetadataToken (TokenType.ModuleRef, rid);
270 case 2 :
271 return new MetadataToken (TokenType.AssemblyRef, rid);
272 case 3 :
273 return new MetadataToken (TokenType.TypeRef, rid);
274 default :
275 return MetadataToken.Zero;
277 case CodedIndex.TypeOrMethodDef :
278 rid = data >> 1;
279 switch (data & 1) {
280 case 0 :
281 return new MetadataToken (TokenType.TypeDef, rid);
282 case 1 :
283 return new MetadataToken (TokenType.Method, rid);
284 default :
285 return MetadataToken.Zero;
287 default :
288 return MetadataToken.Zero;
292 public static uint CompressMetadataToken (CodedIndex cidx, MetadataToken token)
294 uint ret = 0;
295 if (token.RID == 0)
296 return ret;
297 switch (cidx) {
298 case CodedIndex.TypeDefOrRef :
299 ret = token.RID << 2;
300 switch (token.TokenType) {
301 case TokenType.TypeDef :
302 return ret | 0;
303 case TokenType.TypeRef :
304 return ret | 1;
305 case TokenType.TypeSpec :
306 return ret | 2;
307 default :
308 throw new MetadataFormatException("Non valid Token for TypeDefOrRef");
310 case CodedIndex.HasConstant :
311 ret = token.RID << 2;
312 switch (token.TokenType) {
313 case TokenType.Field :
314 return ret | 0;
315 case TokenType.Param :
316 return ret | 1;
317 case TokenType.Property :
318 return ret | 2;
319 default :
320 throw new MetadataFormatException("Non valid Token for HasConstant");
322 case CodedIndex.HasCustomAttribute :
323 ret = token.RID << 5;
324 switch (token.TokenType) {
325 case TokenType.Method :
326 return ret | 0;
327 case TokenType.Field :
328 return ret | 1;
329 case TokenType.TypeRef :
330 return ret | 2;
331 case TokenType.TypeDef :
332 return ret | 3;
333 case TokenType.Param :
334 return ret | 4;
335 case TokenType.InterfaceImpl :
336 return ret | 5;
337 case TokenType.MemberRef :
338 return ret | 6;
339 case TokenType.Module :
340 return ret | 7;
341 case TokenType.Permission :
342 return ret | 8;
343 case TokenType.Property :
344 return ret | 9;
345 case TokenType.Event :
346 return ret | 10;
347 case TokenType.Signature :
348 return ret | 11;
349 case TokenType.ModuleRef :
350 return ret | 12;
351 case TokenType.TypeSpec :
352 return ret | 13;
353 case TokenType.Assembly :
354 return ret | 14;
355 case TokenType.AssemblyRef :
356 return ret | 15;
357 case TokenType.File :
358 return ret | 16;
359 case TokenType.ExportedType :
360 return ret | 17;
361 case TokenType.ManifestResource :
362 return ret | 18;
363 case TokenType.GenericParam :
364 return ret | 19;
365 default :
366 throw new MetadataFormatException("Non valid Token for HasCustomAttribute");
368 case CodedIndex.HasFieldMarshal :
369 ret = token.RID << 1;
370 switch (token.TokenType) {
371 case TokenType.Field :
372 return ret | 0;
373 case TokenType.Param :
374 return ret | 1;
375 default :
376 throw new MetadataFormatException("Non valid Token for HasFieldMarshal");
378 case CodedIndex.HasDeclSecurity :
379 ret = token.RID << 2;
380 switch (token.TokenType) {
381 case TokenType.TypeDef :
382 return ret | 0;
383 case TokenType.Method :
384 return ret | 1;
385 case TokenType.Assembly :
386 return ret | 2;
387 default :
388 throw new MetadataFormatException("Non valid Token for HasDeclSecurity");
390 case CodedIndex.MemberRefParent :
391 ret = token.RID << 3;
392 switch (token.TokenType) {
393 case TokenType.TypeDef :
394 return ret | 0;
395 case TokenType.TypeRef :
396 return ret | 1;
397 case TokenType.ModuleRef :
398 return ret | 2;
399 case TokenType.Method :
400 return ret | 3;
401 case TokenType.TypeSpec :
402 return ret | 4;
403 default :
404 throw new MetadataFormatException("Non valid Token for MemberRefParent");
406 case CodedIndex.HasSemantics :
407 ret = token.RID << 1;
408 switch (token.TokenType) {
409 case TokenType.Event :
410 return ret | 0;
411 case TokenType.Property :
412 return ret | 1;
413 default :
414 throw new MetadataFormatException("Non valid Token for HasSemantics");
416 case CodedIndex.MethodDefOrRef :
417 ret = token.RID << 1;
418 switch (token.TokenType) {
419 case TokenType.Method :
420 return ret | 0;
421 case TokenType.MemberRef :
422 return ret | 1;
423 default :
424 throw new MetadataFormatException("Non valid Token for MethodDefOrRef");
426 case CodedIndex.MemberForwarded :
427 ret = token.RID << 1;
428 switch (token.TokenType) {
429 case TokenType.Field :
430 return ret | 0;
431 case TokenType.Method :
432 return ret | 1;
433 default :
434 throw new MetadataFormatException("Non valid Token for MemberForwarded");
436 case CodedIndex.Implementation :
437 ret = token.RID << 2;
438 switch (token.TokenType) {
439 case TokenType.File :
440 return ret | 0;
441 case TokenType.AssemblyRef :
442 return ret | 1;
443 case TokenType.ExportedType :
444 return ret | 2;
445 default :
446 throw new MetadataFormatException("Non valid Token for Implementation");
448 case CodedIndex.CustomAttributeType :
449 ret = token.RID << 3;
450 switch (token.TokenType) {
451 case TokenType.Method :
452 return ret | 2;
453 case TokenType.MemberRef :
454 return ret | 3;
455 default :
456 throw new MetadataFormatException("Non valid Token for CustomAttributeType");
458 case CodedIndex.ResolutionScope :
459 ret = token.RID << 2;
460 switch (token.TokenType) {
461 case TokenType.Module :
462 return ret | 0;
463 case TokenType.ModuleRef :
464 return ret | 1;
465 case TokenType.AssemblyRef :
466 return ret | 2;
467 case TokenType.TypeRef :
468 return ret | 3;
469 default :
470 throw new MetadataFormatException("Non valid Token for ResolutionScope");
472 case CodedIndex.TypeOrMethodDef :
473 ret = token.RID << 1;
474 switch (token.TokenType) {
475 case TokenType.TypeDef :
476 return ret | 0;
477 case TokenType.Method :
478 return ret | 1;
479 default :
480 throw new MetadataFormatException("Non valid Token for TypeOrMethodDef");
482 default :
483 throw new MetadataFormatException ("Non valid CodedIndex");
487 internal static Type GetCorrespondingTable (TokenType t)
489 switch (t) {
490 case TokenType.Assembly :
491 return typeof (AssemblyTable);
492 case TokenType.AssemblyRef :
493 return typeof (AssemblyRefTable);
494 case TokenType.CustomAttribute :
495 return typeof (CustomAttributeTable);
496 case TokenType.Event :
497 return typeof (EventTable);
498 case TokenType.ExportedType :
499 return typeof (ExportedTypeTable);
500 case TokenType.Field :
501 return typeof (FieldTable);
502 case TokenType.File :
503 return typeof (FileTable);
504 case TokenType.InterfaceImpl :
505 return typeof (InterfaceImplTable);
506 case TokenType.MemberRef :
507 return typeof (MemberRefTable);
508 case TokenType.Method :
509 return typeof (MethodTable);
510 case TokenType.Module :
511 return typeof (ModuleTable);
512 case TokenType.ModuleRef :
513 return typeof (ModuleRefTable);
514 case TokenType.Param :
515 return typeof (ParamTable);
516 case TokenType.Permission :
517 return typeof (DeclSecurityTable);
518 case TokenType.Property :
519 return typeof (PropertyTable);
520 case TokenType.Signature :
521 return typeof (StandAloneSigTable);
522 case TokenType.TypeDef :
523 return typeof (TypeDefTable);
524 case TokenType.TypeRef :
525 return typeof (TypeRefTable);
526 case TokenType.TypeSpec :
527 return typeof (TypeSpecTable);
528 default :
529 return null;
533 internal delegate int TableRowCounter (int rid);
535 internal static int GetCodedIndexSize (CodedIndex ci, TableRowCounter rowCounter, int [] codedIndexCache)
537 int bits = 0, max = 0, index = (int) ci;
538 if (codedIndexCache [index] != 0)
539 return codedIndexCache [index];
541 int res = 0;
542 int [] rids;
543 switch (ci) {
544 case CodedIndex.TypeDefOrRef :
545 bits = 2;
546 rids = new int [3];
547 rids [0] = TypeDefTable.RId;
548 rids [1] = TypeRefTable.RId;
549 rids [2] = TypeSpecTable.RId;
550 break;
551 case CodedIndex.HasConstant :
552 bits = 2;
553 rids = new int [3];
554 rids [0] = FieldTable.RId;
555 rids [1] = ParamTable.RId;
556 rids [2] = PropertyTable.RId;
557 break;
558 case CodedIndex.HasCustomAttribute :
559 bits = 5;
560 rids = new int [20];
561 rids [0] = MethodTable.RId;
562 rids [1] = FieldTable.RId;
563 rids [2] = TypeRefTable.RId;
564 rids [3] = TypeDefTable.RId;
565 rids [4] = ParamTable.RId;
566 rids [5] = InterfaceImplTable.RId;
567 rids [6] = MemberRefTable.RId;
568 rids [7] = ModuleTable.RId;
569 rids [8] = DeclSecurityTable.RId;
570 rids [9] = PropertyTable.RId;
571 rids [10] = EventTable.RId;
572 rids [11] = StandAloneSigTable.RId;
573 rids [12] = ModuleRefTable.RId;
574 rids [13] = TypeSpecTable.RId;
575 rids [14] = AssemblyTable.RId;
576 rids [15] = AssemblyRefTable.RId;
577 rids [16] = FileTable.RId;
578 rids [17] = ExportedTypeTable.RId;
579 rids [18] = ManifestResourceTable.RId;
580 rids [19] = GenericParamTable.RId;
581 break;
582 case CodedIndex.HasFieldMarshal :
583 bits = 1;
584 rids = new int [2];
585 rids [0] = FieldTable.RId;
586 rids [1] = ParamTable.RId;
587 break;
588 case CodedIndex.HasDeclSecurity :
589 bits = 2;
590 rids = new int [3];
591 rids [0] = TypeDefTable.RId;
592 rids [1] = MethodTable.RId;
593 rids [2] = AssemblyTable.RId;
594 break;
595 case CodedIndex.MemberRefParent :
596 bits = 3;
597 rids = new int [5];
598 rids [0] = TypeDefTable.RId;
599 rids [1] = TypeRefTable.RId;
600 rids [2] = ModuleRefTable.RId;
601 rids [3] = MethodTable.RId;
602 rids [4] = TypeSpecTable.RId;
603 break;
604 case CodedIndex.HasSemantics :
605 bits = 1;
606 rids = new int [2];
607 rids [0] = EventTable.RId;
608 rids [1] = PropertyTable.RId;
609 break;
610 case CodedIndex.MethodDefOrRef :
611 bits = 1;
612 rids = new int [2];
613 rids [0] = MethodTable.RId;
614 rids [1] = MemberRefTable.RId;
615 break;
616 case CodedIndex.MemberForwarded :
617 bits = 1;
618 rids = new int [2];
619 rids [0] = FieldTable.RId;
620 rids [1] = MethodTable.RId;
621 break;
622 case CodedIndex.Implementation :
623 bits = 2;
624 rids = new int [3];
625 rids [0] = FileTable.RId;
626 rids [1] = AssemblyRefTable.RId;
627 rids [2] = ExportedTypeTable.RId;
628 break;
629 case CodedIndex.CustomAttributeType :
630 bits = 3;
631 rids = new int [2];
632 rids [0] = MethodTable.RId;
633 rids [1] = MemberRefTable.RId;
634 break;
635 case CodedIndex.ResolutionScope :
636 bits = 2;
637 rids = new int [4];
638 rids [0] = ModuleTable.RId;
639 rids [1] = ModuleRefTable.RId;
640 rids [2] = AssemblyRefTable.RId;
641 rids [3] = TypeRefTable.RId;
642 break;
643 case CodedIndex.TypeOrMethodDef :
644 bits = 1;
645 rids = new int [2];
646 rids [0] = TypeDefTable.RId;
647 rids [1] = MethodTable.RId;
648 break;
649 default :
650 throw new MetadataFormatException ("Non valid CodedIndex");
653 for (int i = 0; i < rids.Length; i++) {
654 int rows = rowCounter (rids [i]);
655 if (rows > max) max = rows;
658 res = max < (1 << (16 - bits)) ? 2 : 4;
659 codedIndexCache [index] = res;
660 return res;