5 // Jb Evain (jbevain@gmail.com)
7 // Copyright (c) 2008 - 2010 Jb Evain
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:
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
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.
31 using Mono.Cecil.Metadata;
33 namespace Mono.Cecil {
35 static partial class Mixin {
37 public static uint ReadCompressedUInt32 (this byte [] data, ref int position)
40 if ((data [position] & 0x80) == 0) {
41 integer = data [position];
43 } else if ((data [position] & 0x40) == 0) {
44 integer = (uint) (data [position] & ~0x80) << 8;
45 integer |= data [position + 1];
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];
57 public static MetadataToken GetMetadataToken (this CodedIndex self, uint data)
62 case CodedIndex.TypeDefOrRef:
66 token_type = TokenType.TypeDef; goto ret;
68 token_type = TokenType.TypeRef; goto ret;
70 token_type = TokenType.TypeSpec; goto ret;
74 case CodedIndex.HasConstant:
78 token_type = TokenType.Field; goto ret;
80 token_type = TokenType.Param; goto ret;
82 token_type = TokenType.Property; goto ret;
86 case CodedIndex.HasCustomAttribute:
90 token_type = TokenType.Method; goto ret;
92 token_type = TokenType.Field; goto ret;
94 token_type = TokenType.TypeRef; goto ret;
96 token_type = TokenType.TypeDef; goto ret;
98 token_type = TokenType.Param; goto ret;
100 token_type = TokenType.InterfaceImpl; goto ret;
102 token_type = TokenType.MemberRef; goto ret;
104 token_type = TokenType.Module; goto ret;
106 token_type = TokenType.Permission; goto ret;
108 token_type = TokenType.Property; goto ret;
110 token_type = TokenType.Event; goto ret;
112 token_type = TokenType.Signature; goto ret;
114 token_type = TokenType.ModuleRef; goto ret;
116 token_type = TokenType.TypeSpec; goto ret;
118 token_type = TokenType.Assembly; goto ret;
120 token_type = TokenType.AssemblyRef; goto ret;
122 token_type = TokenType.File; goto ret;
124 token_type = TokenType.ExportedType; goto ret;
126 token_type = TokenType.ManifestResource; goto ret;
128 token_type = TokenType.GenericParam; goto ret;
132 case CodedIndex.HasFieldMarshal:
136 token_type = TokenType.Field; goto ret;
138 token_type = TokenType.Param; goto ret;
142 case CodedIndex.HasDeclSecurity:
146 token_type = TokenType.TypeDef; goto ret;
148 token_type = TokenType.Method; goto ret;
150 token_type = TokenType.Assembly; goto ret;
154 case CodedIndex.MemberRefParent:
158 token_type = TokenType.TypeDef; goto ret;
160 token_type = TokenType.TypeRef; goto ret;
162 token_type = TokenType.ModuleRef; goto ret;
164 token_type = TokenType.Method; goto ret;
166 token_type = TokenType.TypeSpec; goto ret;
170 case CodedIndex.HasSemantics:
174 token_type = TokenType.Event; goto ret;
176 token_type = TokenType.Property; goto ret;
180 case CodedIndex.MethodDefOrRef:
184 token_type = TokenType.Method; goto ret;
186 token_type = TokenType.MemberRef; goto ret;
190 case CodedIndex.MemberForwarded:
194 token_type = TokenType.Field; goto ret;
196 token_type = TokenType.Method; goto ret;
200 case CodedIndex.Implementation:
204 token_type = TokenType.File; goto ret;
206 token_type = TokenType.AssemblyRef; goto ret;
208 token_type = TokenType.ExportedType; goto ret;
212 case CodedIndex.CustomAttributeType:
216 token_type = TokenType.Method; goto ret;
218 token_type = TokenType.MemberRef; goto ret;
222 case CodedIndex.ResolutionScope:
226 token_type = TokenType.Module; goto ret;
228 token_type = TokenType.ModuleRef; goto ret;
230 token_type = TokenType.AssemblyRef; goto ret;
232 token_type = TokenType.TypeRef; goto ret;
236 case CodedIndex.TypeOrMethodDef:
240 token_type = TokenType.TypeDef; goto ret;
242 token_type = TokenType.Method; goto ret;
249 return new MetadataToken (token_type, rid);
251 return MetadataToken.Zero;
255 public static uint CompressMetadataToken (this CodedIndex self, MetadataToken token)
261 case CodedIndex.TypeDefOrRef:
262 ret = token.RID << 2;
263 switch (token.TokenType) {
264 case TokenType.TypeDef:
266 case TokenType.TypeRef:
268 case TokenType.TypeSpec:
273 case CodedIndex.HasConstant:
274 ret = token.RID << 2;
275 switch (token.TokenType) {
276 case TokenType.Field:
278 case TokenType.Param:
280 case TokenType.Property:
285 case CodedIndex.HasCustomAttribute:
286 ret = token.RID << 5;
287 switch (token.TokenType) {
288 case TokenType.Method:
290 case TokenType.Field:
292 case TokenType.TypeRef:
294 case TokenType.TypeDef:
296 case TokenType.Param:
298 case TokenType.InterfaceImpl:
300 case TokenType.MemberRef:
302 case TokenType.Module:
304 case TokenType.Permission:
306 case TokenType.Property:
308 case TokenType.Event:
310 case TokenType.Signature:
312 case TokenType.ModuleRef:
314 case TokenType.TypeSpec:
316 case TokenType.Assembly:
318 case TokenType.AssemblyRef:
322 case TokenType.ExportedType:
324 case TokenType.ManifestResource:
326 case TokenType.GenericParam:
331 case CodedIndex.HasFieldMarshal:
332 ret = token.RID << 1;
333 switch (token.TokenType) {
334 case TokenType.Field:
336 case TokenType.Param:
341 case CodedIndex.HasDeclSecurity:
342 ret = token.RID << 2;
343 switch (token.TokenType) {
344 case TokenType.TypeDef:
346 case TokenType.Method:
348 case TokenType.Assembly:
353 case CodedIndex.MemberRefParent:
354 ret = token.RID << 3;
355 switch (token.TokenType) {
356 case TokenType.TypeDef:
358 case TokenType.TypeRef:
360 case TokenType.ModuleRef:
362 case TokenType.Method:
364 case TokenType.TypeSpec:
369 case CodedIndex.HasSemantics:
370 ret = token.RID << 1;
371 switch (token.TokenType) {
372 case TokenType.Event:
374 case TokenType.Property:
379 case CodedIndex.MethodDefOrRef:
380 ret = token.RID << 1;
381 switch (token.TokenType) {
382 case TokenType.Method:
384 case TokenType.MemberRef:
389 case CodedIndex.MemberForwarded:
390 ret = token.RID << 1;
391 switch (token.TokenType) {
392 case TokenType.Field:
394 case TokenType.Method:
399 case CodedIndex.Implementation:
400 ret = token.RID << 2;
401 switch (token.TokenType) {
404 case TokenType.AssemblyRef:
406 case TokenType.ExportedType:
411 case CodedIndex.CustomAttributeType:
412 ret = token.RID << 3;
413 switch (token.TokenType) {
414 case TokenType.Method:
416 case TokenType.MemberRef:
421 case CodedIndex.ResolutionScope:
422 ret = token.RID << 2;
423 switch (token.TokenType) {
424 case TokenType.Module:
426 case TokenType.ModuleRef:
428 case TokenType.AssemblyRef:
430 case TokenType.TypeRef:
435 case CodedIndex.TypeOrMethodDef:
436 ret = token.RID << 1;
437 switch (token.TokenType) {
438 case TokenType.TypeDef:
440 case TokenType.Method:
449 throw new ArgumentException ();
453 public static int GetSize (this CodedIndex self, Func<Table, int> counter)
459 case CodedIndex.TypeDefOrRef:
461 tables = new [] { Table.TypeDef, Table.TypeRef, Table.TypeSpec };
463 case CodedIndex.HasConstant:
465 tables = new [] { Table.Field, Table.Param, Table.Property };
467 case CodedIndex.HasCustomAttribute:
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
476 case CodedIndex.HasFieldMarshal:
478 tables = new [] { Table.Field, Table.Param };
480 case CodedIndex.HasDeclSecurity:
482 tables = new [] { Table.TypeDef, Table.Method, Table.Assembly };
484 case CodedIndex.MemberRefParent:
486 tables = new [] { Table.TypeDef, Table.TypeRef, Table.ModuleRef, Table.Method, Table.TypeSpec };
488 case CodedIndex.HasSemantics:
490 tables = new [] { Table.Event, Table.Property };
492 case CodedIndex.MethodDefOrRef:
494 tables = new [] { Table.Method, Table.MemberRef };
496 case CodedIndex.MemberForwarded:
498 tables = new [] { Table.Field, Table.Method };
500 case CodedIndex.Implementation:
502 tables = new [] { Table.File, Table.AssemblyRef, Table.ExportedType };
504 case CodedIndex.CustomAttributeType:
506 tables = new [] { Table.Method, Table.MemberRef };
508 case CodedIndex.ResolutionScope:
510 tables = new [] { Table.Module, Table.ModuleRef, Table.AssemblyRef, Table.TypeRef };
512 case CodedIndex.TypeOrMethodDef:
514 tables = new [] { Table.TypeDef, Table.Method };
517 throw new ArgumentException ();
522 for (int i = 0; i < tables.Length; i++) {
523 max = System.Math.Max (counter (tables [i]), max);
526 return max < (1 << (16 - bits)) ? 2 : 4;