Free cookie consent management tool by TermsFeed Policy Generator

source: branches/2965_CancelablePersistence/HeuristicLab.ExtLibs/HeuristicLab.Cecil/0.9.5/Mono.Cecil-0.9.5/Mono.Cecil/Mono.Cecil.Metadata/Utilities.cs @ 16321

Last change on this file since 16321 was 11700, checked in by jkarder, 10 years ago

#2077: created branch and added first version

File size: 13.4 KB
Line 
1//
2// Utilities.cs
3//
4// Author:
5//   Jb Evain (jbevain@gmail.com)
6//
7// Copyright (c) 2008 - 2011 Jb Evain
8//
9// Permission is hereby granted, free of charge, to any person obtaining
10// a copy of this software and associated documentation files (the
11// "Software"), to deal in the Software without restriction, including
12// without limitation the rights to use, copy, modify, merge, publish,
13// distribute, sublicense, and/or sell copies of the Software, and to
14// permit persons to whom the Software is furnished to do so, subject to
15// the following conditions:
16//
17// The above copyright notice and this permission notice shall be
18// included in all copies or substantial portions of the Software.
19//
20// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27//
28
29using System;
30
31using Mono.Cecil.Metadata;
32
33namespace Mono.Cecil {
34
35  static partial class Mixin {
36
37    public static uint ReadCompressedUInt32 (this byte [] data, ref int position)
38    {
39      uint integer;
40      if ((data [position] & 0x80) == 0) {
41        integer = data [position];
42        position++;
43      } else if ((data [position] & 0x40) == 0) {
44        integer = (uint) (data [position] & ~0x80) << 8;
45        integer |= data [position + 1];
46        position += 2;
47      } else {
48        integer = (uint) (data [position] & ~0xc0) << 24;
49        integer |= (uint) data [position + 1] << 16;
50        integer |= (uint) data [position + 2] << 8;
51        integer |= (uint) data [position + 3];
52        position += 4;
53      }
54      return integer;
55    }
56
57    public static MetadataToken GetMetadataToken (this CodedIndex self, uint data)
58    {
59      uint rid;
60      TokenType token_type;
61      switch (self) {
62      case CodedIndex.TypeDefOrRef:
63        rid = data >> 2;
64        switch (data & 3) {
65        case 0:
66          token_type = TokenType.TypeDef; goto ret;
67        case 1:
68          token_type = TokenType.TypeRef; goto ret;
69        case 2:
70          token_type = TokenType.TypeSpec; goto ret;
71        default:
72          goto exit;
73        }
74      case CodedIndex.HasConstant:
75        rid = data >> 2;
76        switch (data & 3) {
77        case 0:
78          token_type = TokenType.Field; goto ret;
79        case 1:
80          token_type = TokenType.Param; goto ret;
81        case 2:
82          token_type = TokenType.Property; goto ret;
83        default:
84          goto exit;
85        }
86      case CodedIndex.HasCustomAttribute:
87        rid = data >> 5;
88        switch (data & 31) {
89        case 0:
90          token_type = TokenType.Method; goto ret;
91        case 1:
92          token_type = TokenType.Field; goto ret;
93        case 2:
94          token_type = TokenType.TypeRef; goto ret;
95        case 3:
96          token_type = TokenType.TypeDef; goto ret;
97        case 4:
98          token_type = TokenType.Param; goto ret;
99        case 5:
100          token_type = TokenType.InterfaceImpl; goto ret;
101        case 6:
102          token_type = TokenType.MemberRef; goto ret;
103        case 7:
104          token_type = TokenType.Module; goto ret;
105        case 8:
106          token_type = TokenType.Permission; goto ret;
107        case 9:
108          token_type = TokenType.Property; goto ret;
109        case 10:
110          token_type = TokenType.Event; goto ret;
111        case 11:
112          token_type = TokenType.Signature; goto ret;
113        case 12:
114          token_type = TokenType.ModuleRef; goto ret;
115        case 13:
116          token_type = TokenType.TypeSpec; goto ret;
117        case 14:
118          token_type = TokenType.Assembly; goto ret;
119        case 15:
120          token_type = TokenType.AssemblyRef; goto ret;
121        case 16:
122          token_type = TokenType.File; goto ret;
123        case 17:
124          token_type = TokenType.ExportedType; goto ret;
125        case 18:
126          token_type = TokenType.ManifestResource; goto ret;
127        case 19:
128          token_type = TokenType.GenericParam; goto ret;
129        default:
130          goto exit;
131        }
132      case CodedIndex.HasFieldMarshal:
133        rid = data >> 1;
134        switch (data & 1) {
135        case 0:
136          token_type = TokenType.Field; goto ret;
137        case 1:
138          token_type = TokenType.Param; goto ret;
139        default:
140          goto exit;
141        }
142      case CodedIndex.HasDeclSecurity:
143        rid = data >> 2;
144        switch (data & 3) {
145        case 0:
146          token_type = TokenType.TypeDef; goto ret;
147        case 1:
148          token_type = TokenType.Method; goto ret;
149        case 2:
150          token_type = TokenType.Assembly; goto ret;
151        default:
152          goto exit;
153        }
154      case CodedIndex.MemberRefParent:
155        rid = data >> 3;
156        switch (data & 7) {
157        case 0:
158          token_type = TokenType.TypeDef; goto ret;
159        case 1:
160          token_type = TokenType.TypeRef; goto ret;
161        case 2:
162          token_type = TokenType.ModuleRef; goto ret;
163        case 3:
164          token_type = TokenType.Method; goto ret;
165        case 4:
166          token_type = TokenType.TypeSpec; goto ret;
167        default:
168          goto exit;
169        }
170      case CodedIndex.HasSemantics:
171        rid = data >> 1;
172        switch (data & 1) {
173        case 0:
174          token_type = TokenType.Event; goto ret;
175        case 1:
176          token_type = TokenType.Property; goto ret;
177        default:
178          goto exit;
179        }
180      case CodedIndex.MethodDefOrRef:
181        rid = data >> 1;
182        switch (data & 1) {
183        case 0:
184          token_type = TokenType.Method; goto ret;
185        case 1:
186          token_type = TokenType.MemberRef; goto ret;
187        default:
188          goto exit;
189        }
190      case CodedIndex.MemberForwarded:
191        rid = data >> 1;
192        switch (data & 1) {
193        case 0:
194          token_type = TokenType.Field; goto ret;
195        case 1:
196          token_type = TokenType.Method; goto ret;
197        default:
198          goto exit;
199        }
200      case CodedIndex.Implementation:
201        rid = data >> 2;
202        switch (data & 3) {
203        case 0:
204          token_type = TokenType.File; goto ret;
205        case 1:
206          token_type = TokenType.AssemblyRef; goto ret;
207        case 2:
208          token_type = TokenType.ExportedType; goto ret;
209        default:
210          goto exit;
211        }
212      case CodedIndex.CustomAttributeType:
213        rid = data >> 3;
214        switch (data & 7) {
215        case 2:
216          token_type = TokenType.Method; goto ret;
217        case 3:
218          token_type = TokenType.MemberRef; goto ret;
219        default:
220          goto exit;
221        }
222      case CodedIndex.ResolutionScope:
223        rid = data >> 2;
224        switch (data & 3) {
225        case 0:
226          token_type = TokenType.Module; goto ret;
227        case 1:
228          token_type = TokenType.ModuleRef; goto ret;
229        case 2:
230          token_type = TokenType.AssemblyRef; goto ret;
231        case 3:
232          token_type = TokenType.TypeRef; goto ret;
233        default:
234          goto exit;
235        }
236      case CodedIndex.TypeOrMethodDef:
237        rid = data >> 1;
238        switch (data & 1) {
239        case 0:
240          token_type = TokenType.TypeDef; goto ret;
241        case 1:
242          token_type = TokenType.Method; goto ret;
243        default: goto exit;
244        }
245      default:
246        goto exit;
247      }
248    ret:
249      return new MetadataToken (token_type, rid);
250    exit:
251      return MetadataToken.Zero;
252    }
253
254#if !READ_ONLY
255    public static uint CompressMetadataToken (this CodedIndex self, MetadataToken token)
256    {
257      uint ret = 0;
258      if (token.RID == 0)
259        return ret;
260      switch (self) {
261      case CodedIndex.TypeDefOrRef:
262        ret = token.RID << 2;
263        switch (token.TokenType) {
264        case TokenType.TypeDef:
265          return ret | 0;
266        case TokenType.TypeRef:
267          return ret | 1;
268        case TokenType.TypeSpec:
269          return ret | 2;
270        default:
271          goto exit;
272        }
273      case CodedIndex.HasConstant:
274        ret = token.RID << 2;
275        switch (token.TokenType) {
276        case TokenType.Field:
277          return ret | 0;
278        case TokenType.Param:
279          return ret | 1;
280        case TokenType.Property:
281          return ret | 2;
282        default:
283          goto exit;
284        }
285      case CodedIndex.HasCustomAttribute:
286        ret = token.RID << 5;
287        switch (token.TokenType) {
288        case TokenType.Method:
289          return ret | 0;
290        case TokenType.Field:
291          return ret | 1;
292        case TokenType.TypeRef:
293          return ret | 2;
294        case TokenType.TypeDef:
295          return ret | 3;
296        case TokenType.Param:
297          return ret | 4;
298        case TokenType.InterfaceImpl:
299          return ret | 5;
300        case TokenType.MemberRef:
301          return ret | 6;
302        case TokenType.Module:
303          return ret | 7;
304        case TokenType.Permission:
305          return ret | 8;
306        case TokenType.Property:
307          return ret | 9;
308        case TokenType.Event:
309          return ret | 10;
310        case TokenType.Signature:
311          return ret | 11;
312        case TokenType.ModuleRef:
313          return ret | 12;
314        case TokenType.TypeSpec:
315          return ret | 13;
316        case TokenType.Assembly:
317          return ret | 14;
318        case TokenType.AssemblyRef:
319          return ret | 15;
320        case TokenType.File:
321          return ret | 16;
322        case TokenType.ExportedType:
323          return ret | 17;
324        case TokenType.ManifestResource:
325          return ret | 18;
326        case TokenType.GenericParam:
327          return ret | 19;
328        default:
329          goto exit;
330        }
331      case CodedIndex.HasFieldMarshal:
332        ret = token.RID << 1;
333        switch (token.TokenType) {
334        case TokenType.Field:
335          return ret | 0;
336        case TokenType.Param:
337          return ret | 1;
338        default:
339          goto exit;
340        }
341      case CodedIndex.HasDeclSecurity:
342        ret = token.RID << 2;
343        switch (token.TokenType) {
344        case TokenType.TypeDef:
345          return ret | 0;
346        case TokenType.Method:
347          return ret | 1;
348        case TokenType.Assembly:
349          return ret | 2;
350        default:
351          goto exit;
352        }
353      case CodedIndex.MemberRefParent:
354        ret = token.RID << 3;
355        switch (token.TokenType) {
356        case TokenType.TypeDef:
357          return ret | 0;
358        case TokenType.TypeRef:
359          return ret | 1;
360        case TokenType.ModuleRef:
361          return ret | 2;
362        case TokenType.Method:
363          return ret | 3;
364        case TokenType.TypeSpec:
365          return ret | 4;
366        default:
367          goto exit;
368        }
369      case CodedIndex.HasSemantics:
370        ret = token.RID << 1;
371        switch (token.TokenType) {
372        case TokenType.Event:
373          return ret | 0;
374        case TokenType.Property:
375          return ret | 1;
376        default:
377          goto exit;
378        }
379      case CodedIndex.MethodDefOrRef:
380        ret = token.RID << 1;
381        switch (token.TokenType) {
382        case TokenType.Method:
383          return ret | 0;
384        case TokenType.MemberRef:
385          return ret | 1;
386        default:
387          goto exit;
388        }
389      case CodedIndex.MemberForwarded:
390        ret = token.RID << 1;
391        switch (token.TokenType) {
392        case TokenType.Field:
393          return ret | 0;
394        case TokenType.Method:
395          return ret | 1;
396        default:
397          goto exit;
398        }
399      case CodedIndex.Implementation:
400        ret = token.RID << 2;
401        switch (token.TokenType) {
402        case TokenType.File:
403          return ret | 0;
404        case TokenType.AssemblyRef:
405          return ret | 1;
406        case TokenType.ExportedType:
407          return ret | 2;
408        default:
409          goto exit;
410        }
411      case CodedIndex.CustomAttributeType:
412        ret = token.RID << 3;
413        switch (token.TokenType) {
414        case TokenType.Method:
415          return ret | 2;
416        case TokenType.MemberRef:
417          return ret | 3;
418        default:
419          goto exit;
420        }
421      case CodedIndex.ResolutionScope:
422        ret = token.RID << 2;
423        switch (token.TokenType) {
424        case TokenType.Module:
425          return ret | 0;
426        case TokenType.ModuleRef:
427          return ret | 1;
428        case TokenType.AssemblyRef:
429          return ret | 2;
430        case TokenType.TypeRef:
431          return ret | 3;
432        default:
433          goto exit;
434        }
435      case CodedIndex.TypeOrMethodDef:
436        ret = token.RID << 1;
437        switch (token.TokenType) {
438        case TokenType.TypeDef:
439          return ret | 0;
440        case TokenType.Method:
441          return ret | 1;
442        default:
443          goto exit;
444        }
445      default:
446        goto exit;
447      }
448    exit:
449      throw new ArgumentException ();
450    }
451#endif
452
453    public static int GetSize (this CodedIndex self, Func<Table, int> counter)
454    {
455      int bits;
456      Table [] tables;
457
458      switch (self) {
459      case CodedIndex.TypeDefOrRef:
460        bits = 2;
461        tables = new [] { Table.TypeDef, Table.TypeRef, Table.TypeSpec };
462        break;
463      case CodedIndex.HasConstant:
464        bits = 2;
465        tables = new [] { Table.Field, Table.Param, Table.Property };
466        break;
467      case CodedIndex.HasCustomAttribute:
468        bits = 5;
469        tables = new [] {
470          Table.Method, Table.Field, Table.TypeRef, Table.TypeDef, Table.Param, Table.InterfaceImpl, Table.MemberRef,
471          Table.Module, Table.DeclSecurity, Table.Property, Table.Event, Table.StandAloneSig, Table.ModuleRef,
472          Table.TypeSpec, Table.Assembly, Table.AssemblyRef, Table.File, Table.ExportedType,
473          Table.ManifestResource, Table.GenericParam
474        };
475        break;
476      case CodedIndex.HasFieldMarshal:
477        bits = 1;
478        tables = new [] { Table.Field, Table.Param };
479        break;
480      case CodedIndex.HasDeclSecurity:
481        bits = 2;
482        tables = new [] { Table.TypeDef, Table.Method, Table.Assembly };
483        break;
484      case CodedIndex.MemberRefParent:
485        bits = 3;
486        tables = new [] { Table.TypeDef, Table.TypeRef, Table.ModuleRef, Table.Method, Table.TypeSpec };
487        break;
488      case CodedIndex.HasSemantics:
489        bits = 1;
490        tables = new [] { Table.Event, Table.Property };
491        break;
492      case CodedIndex.MethodDefOrRef:
493        bits = 1;
494        tables = new [] { Table.Method, Table.MemberRef };
495        break;
496      case CodedIndex.MemberForwarded:
497        bits = 1;
498        tables = new [] { Table.Field, Table.Method };
499        break;
500      case CodedIndex.Implementation:
501        bits = 2;
502        tables = new [] { Table.File, Table.AssemblyRef, Table.ExportedType };
503        break;
504      case CodedIndex.CustomAttributeType:
505        bits = 3;
506        tables = new [] { Table.Method, Table.MemberRef };
507        break;
508      case CodedIndex.ResolutionScope:
509        bits = 2;
510        tables = new [] { Table.Module, Table.ModuleRef, Table.AssemblyRef, Table.TypeRef };
511        break;
512      case CodedIndex.TypeOrMethodDef:
513        bits = 1;
514        tables = new [] { Table.TypeDef, Table.Method };
515        break;
516      default:
517        throw new ArgumentException ();
518      }
519
520      int max = 0;
521
522      for (int i = 0; i < tables.Length; i++) {
523        max = System.Math.Max (counter (tables [i]), max);
524      }
525
526      return max < (1 << (16 - bits)) ? 2 : 4;
527    }
528  }
529}
Note: See TracBrowser for help on using the repository browser.