5
// Jb Evain (jbevain@gmail.com)
7
// (C) 2005 - 2007 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.
29
namespace Mono.Cecil.Signatures {
32
using System.Collections;
37
using Mono.Cecil.Metadata;
39
internal sealed class SignatureReader : BaseSignatureVisitor {
42
ReflectionReader m_reflectReader;
45
IDictionary m_signatures;
47
IAssemblyResolver AssemblyResolver {
48
get { return m_reflectReader.Module.Assembly.Resolver; }
51
public SignatureReader (MetadataRoot root, ReflectionReader reflectReader)
54
m_reflectReader = reflectReader;
56
m_blobData = m_root.Streams.BlobHeap != null ? m_root.Streams.BlobHeap.Data : new byte [0];
58
m_signatures = new Hashtable ();
61
public FieldSig GetFieldSig (uint index)
63
FieldSig f = m_signatures [index] as FieldSig;
65
f = new FieldSig (index);
67
m_signatures [index] = f;
72
public PropertySig GetPropSig (uint index)
74
PropertySig p = m_signatures [index] as PropertySig;
76
p = new PropertySig (index);
78
m_signatures [index] = p;
83
public MethodDefSig GetMethodDefSig (uint index)
85
MethodDefSig m = m_signatures [index] as MethodDefSig;
87
m = new MethodDefSig (index);
89
m_signatures [index] = m;
94
public MethodRefSig GetMethodRefSig (uint index)
96
MethodRefSig m = m_signatures [index] as MethodRefSig;
98
m = new MethodRefSig (index);
100
m_signatures [index] = m;
105
public TypeSpec GetTypeSpec (uint index)
107
TypeSpec ts = m_signatures [index] as TypeSpec;
110
ts = ReadTypeSpec (m_blobData, (int) index);
111
m_signatures [index] = ts;
117
public MethodSpec GetMethodSpec (uint index)
119
MethodSpec ms = m_signatures [index] as MethodSpec;
122
ms = ReadMethodSpec (m_blobData, (int) index);
123
m_signatures [index] = ms;
129
public LocalVarSig GetLocalVarSig (uint index)
131
LocalVarSig lv = m_signatures [index] as LocalVarSig;
133
lv = new LocalVarSig (index);
135
m_signatures [index] = lv;
140
public CustomAttrib GetCustomAttrib (uint index, MethodReference ctor)
142
return GetCustomAttrib (index, ctor, false);
145
public CustomAttrib GetCustomAttrib (uint index, MethodReference ctor, bool resolve)
147
return ReadCustomAttrib ((int) index, ctor, resolve);
150
public CustomAttrib GetCustomAttrib (byte [] data, MethodReference ctor)
152
return GetCustomAttrib (data, ctor, false);
155
public CustomAttrib GetCustomAttrib (byte [] data, MethodReference ctor, bool resolve)
157
BinaryReader br = new BinaryReader (new MemoryStream (data));
158
return ReadCustomAttrib (br, data, ctor, resolve);
161
public Signature GetMemberRefSig (TokenType tt, uint index)
164
Utilities.ReadCompressedInteger (m_blobData, (int) index, out start);
165
callconv = m_blobData [start];
166
if ((callconv & 0x5) == 0x5 || (callconv & 0x10) == 0x10) // vararg || generic?
167
return GetMethodDefSig (index);
168
if ((callconv & 0x6) != 0) // field ?
169
return GetFieldSig (index);
172
case TokenType.TypeDef :
173
case TokenType.TypeRef :
174
case TokenType.TypeSpec :
175
return GetMethodRefSig (index);
176
case TokenType.ModuleRef :
177
case TokenType.Method :
178
return GetMethodDefSig (index);
183
public MarshalSig GetMarshalSig (uint index)
185
MarshalSig ms = m_signatures [index] as MarshalSig;
187
byte [] data = m_root.Streams.BlobHeap.Read (index);
188
ms = ReadMarshalSig (data);
189
m_signatures [index] = ms;
194
public MethodSig GetStandAloneMethodSig (uint index)
196
byte [] data = m_root.Streams.BlobHeap.Read (index);
198
if ((data [0] & 0x5) > 0) {
199
MethodRefSig mrs = new MethodRefSig (index);
200
ReadMethodRefSig (mrs, data, 0, out start);
203
MethodDefSig mds = new MethodDefSig (index);
204
ReadMethodDefSig (mds, data, 0, out start);
209
public override void VisitMethodDefSig (MethodDefSig methodDef)
212
ReadMethodDefSig (methodDef, m_root.Streams.BlobHeap.Read (methodDef.BlobIndex), 0, out start);
215
public override void VisitMethodRefSig (MethodRefSig methodRef)
218
ReadMethodRefSig (methodRef, m_root.Streams.BlobHeap.Read (methodRef.BlobIndex), 0, out start);
221
public override void VisitFieldSig (FieldSig field)
224
Utilities.ReadCompressedInteger (m_blobData, (int) field.BlobIndex, out start);
225
field.CallingConvention = m_blobData [start];
226
field.Field = (field.CallingConvention & 0x6) != 0;
227
field.CustomMods = ReadCustomMods (m_blobData, start + 1, out start);
228
field.Type = ReadType (m_blobData, start, out start);
231
public override void VisitPropertySig (PropertySig property)
234
Utilities.ReadCompressedInteger (m_blobData, (int) property.BlobIndex, out start);
235
property.CallingConvention = m_blobData [start];
236
property.Property = (property.CallingConvention & 0x8) != 0;
237
property.ParamCount = Utilities.ReadCompressedInteger (m_blobData, start + 1, out start);
238
property.CustomMods = ReadCustomMods (m_blobData, start, out start);
239
property.Type = ReadType (m_blobData, start, out start);
240
property.Parameters = ReadParameters (property.ParamCount, m_blobData, start);
243
public override void VisitLocalVarSig (LocalVarSig localvar)
246
Utilities.ReadCompressedInteger (m_blobData, (int) localvar.BlobIndex, out start);
247
localvar.CallingConvention = m_blobData [start];
248
localvar.Local = (localvar.CallingConvention & 0x7) != 0;
249
localvar.Count = Utilities.ReadCompressedInteger (m_blobData, start + 1, out start);
250
localvar.LocalVariables = ReadLocalVariables (localvar.Count, m_blobData, start);
253
void ReadMethodDefSig (MethodDefSig methodDef, byte [] data, int pos, out int start)
255
methodDef.CallingConvention = data [pos];
257
methodDef.HasThis = (methodDef.CallingConvention & 0x20) != 0;
258
methodDef.ExplicitThis = (methodDef.CallingConvention & 0x40) != 0;
259
if ((methodDef.CallingConvention & 0x5) != 0)
260
methodDef.MethCallConv |= MethodCallingConvention.VarArg;
261
else if ((methodDef.CallingConvention & 0x10) != 0) {
262
methodDef.MethCallConv |= MethodCallingConvention.Generic;
263
methodDef.GenericParameterCount = Utilities.ReadCompressedInteger (data, start, out start);
265
methodDef.MethCallConv |= MethodCallingConvention.Default;
267
methodDef.ParamCount = Utilities.ReadCompressedInteger (data, start, out start);
268
methodDef.RetType = ReadRetType (data, start, out start);
270
methodDef.Parameters = ReadParameters (methodDef.ParamCount, data, start, out sentpos);
271
methodDef.Sentinel = sentpos;
274
void ReadMethodRefSig (MethodRefSig methodRef, byte [] data, int pos, out int start)
276
methodRef.CallingConvention = data [pos];
278
methodRef.HasThis = (methodRef.CallingConvention & 0x20) != 0;
279
methodRef.ExplicitThis = (methodRef.CallingConvention & 0x40) != 0;
280
if ((methodRef.CallingConvention & 0x1) != 0)
281
methodRef.MethCallConv |= MethodCallingConvention.C;
282
else if ((methodRef.CallingConvention & 0x2) != 0)
283
methodRef.MethCallConv |= MethodCallingConvention.StdCall;
284
else if ((methodRef.CallingConvention & 0x3) != 0)
285
methodRef.MethCallConv |= MethodCallingConvention.ThisCall;
286
else if ((methodRef.CallingConvention & 0x4) != 0)
287
methodRef.MethCallConv |= MethodCallingConvention.FastCall;
288
else if ((methodRef.CallingConvention & 0x5) != 0)
289
methodRef.MethCallConv |= MethodCallingConvention.VarArg;
291
methodRef.MethCallConv |= MethodCallingConvention.Default;
292
methodRef.ParamCount = Utilities.ReadCompressedInteger (data, start, out start);
293
methodRef.RetType = ReadRetType (data, start, out start);
295
methodRef.Parameters = ReadParameters (methodRef.ParamCount, data, start, out sentpos);
296
methodRef.Sentinel = sentpos;
299
LocalVarSig.LocalVariable [] ReadLocalVariables (int length, byte [] data, int pos)
302
LocalVarSig.LocalVariable [] types = new LocalVarSig.LocalVariable [length];
303
for (int i = 0; i < length; i++)
304
types [i] = ReadLocalVariable (data, start, out start);
308
LocalVarSig.LocalVariable ReadLocalVariable (byte [] data, int pos, out int start)
311
LocalVarSig.LocalVariable lv = new LocalVarSig.LocalVariable ();
315
lv.CustomMods = ReadCustomMods (data, start, out start);
317
int current = Utilities.ReadCompressedInteger (data, start, out start);
318
if (current == (int) ElementType.Pinned) // the only possible constraint
319
lv.Constraint |= Constraint.Pinned;
320
else if (current == (int) ElementType.ByRef) {
323
if (lv.CustomMods == null || lv.CustomMods.Length == 0)
324
lv.CustomMods = ReadCustomMods (data, start, out start);
326
lv.Type = ReadType (data, cursor, out start);
333
TypeSpec ReadTypeSpec (byte [] data, int pos)
336
Utilities.ReadCompressedInteger (data, start, out start);
337
TypeSpec ts = new TypeSpec ();
338
ts.CustomMods = ReadCustomMods (data, start, out start);
339
ts.Type = ReadType (data, start, out start);
343
MethodSpec ReadMethodSpec (byte [] data, int pos)
347
Utilities.ReadCompressedInteger (data, start, out start);
348
if (Utilities.ReadCompressedInteger (data, start, out start) != 0x0a)
349
throw new ReflectionException ("Invalid MethodSpec signature");
351
return new MethodSpec (ReadGenericInstSignature (data, start, out start));
354
RetType ReadRetType (byte [] data, int pos, out int start)
356
RetType rt = new RetType ();
358
rt.CustomMods = ReadCustomMods (data, start, out start);
360
ElementType flag = (ElementType) Utilities.ReadCompressedInteger (data, start, out start);
362
case ElementType.Void :
363
rt.ByRef = rt.TypedByRef = false;
366
case ElementType.TypedByRef :
367
rt.ByRef = rt.Void = false;
368
rt.TypedByRef = true;
370
case ElementType.ByRef :
371
rt.TypedByRef = rt.Void = false;
374
if (rt.CustomMods == null || rt.CustomMods.Length == 0)
375
rt.CustomMods = ReadCustomMods (data, start, out start);
377
rt.Type = ReadType (data, start, out start);
380
rt.TypedByRef = rt.Void = rt.ByRef = false;
381
rt.Type = ReadType (data, curs, out start);
387
Param [] ReadParameters (int length, byte [] data, int pos)
389
Param [] ret = new Param [length];
391
for (int i = 0; i < length; i++)
392
ret [i] = ReadParameter (data, start, out start);
396
Param [] ReadParameters (int length, byte [] data, int pos, out int sentinelpos)
398
Param [] ret = new Param [length];
402
for (int i = 0; i < length; i++) {
404
int flag = Utilities.ReadCompressedInteger (data, start, out start);
406
if (flag == (int) ElementType.Sentinel) {
411
ret [i] = ReadParameter (data, curs, out start);
417
Param ReadParameter (byte [] data, int pos, out int start)
419
Param p = new Param ();
422
p.CustomMods = ReadCustomMods (data, start, out start);
424
ElementType flag = (ElementType) Utilities.ReadCompressedInteger (data, start, out start);
426
case ElementType.TypedByRef :
430
case ElementType.ByRef :
431
p.TypedByRef = false;
434
if (p.CustomMods == null || p.CustomMods.Length == 0)
435
p.CustomMods = ReadCustomMods (data, start, out start);
437
p.Type = ReadType (data, start, out start);
440
p.TypedByRef = false;
442
p.Type = ReadType (data, curs, out start);
448
SigType ReadType (byte [] data, int pos, out int start)
451
ElementType element = (ElementType) Utilities.ReadCompressedInteger (data, start, out start);
453
case ElementType.ValueType :
454
VALUETYPE vt = new VALUETYPE ();
455
vt.Type = Utilities.GetMetadataToken(CodedIndex.TypeDefOrRef,
456
(uint) Utilities.ReadCompressedInteger (data, start, out start));
458
case ElementType.Class :
459
CLASS c = new CLASS ();
460
c.Type = Utilities.GetMetadataToken (CodedIndex.TypeDefOrRef,
461
(uint) Utilities.ReadCompressedInteger (data, start, out start));
463
case ElementType.Ptr :
466
int flag = Utilities.ReadCompressedInteger (data, start, out start);
467
p.Void = flag == (int) ElementType.Void;
471
p.CustomMods = ReadCustomMods (data, start, out start);
472
p.PtrType = ReadType (data, start, out start);
474
case ElementType.FnPtr :
475
FNPTR fp = new FNPTR ();
476
if ((data [start] & 0x5) != 0) {
477
MethodRefSig mr = new MethodRefSig ((uint) start);
478
ReadMethodRefSig (mr, data, start, out start);
481
MethodDefSig md = new MethodDefSig ((uint) start);
482
ReadMethodDefSig (md, data, start, out start);
486
case ElementType.Array :
487
ARRAY ary = new ARRAY ();
488
ary.CustomMods = ReadCustomMods (data, start, out start);
489
ArrayShape shape = new ArrayShape ();
490
ary.Type = ReadType (data, start, out start);
491
shape.Rank = Utilities.ReadCompressedInteger (data, start, out start);
492
shape.NumSizes = Utilities.ReadCompressedInteger (data, start, out start);
493
shape.Sizes = new int [shape.NumSizes];
494
for (int i = 0; i < shape.NumSizes; i++)
495
shape.Sizes [i] = Utilities.ReadCompressedInteger (data, start, out start);
496
shape.NumLoBounds = Utilities.ReadCompressedInteger (data, start, out start);
497
shape.LoBounds = new int [shape.NumLoBounds];
498
for (int i = 0; i < shape.NumLoBounds; i++)
499
shape.LoBounds [i] = Utilities.ReadCompressedInteger (data, start, out start);
502
case ElementType.SzArray :
503
SZARRAY sa = new SZARRAY ();
504
sa.CustomMods = ReadCustomMods (data, start, out start);
505
sa.Type = ReadType (data, start, out start);
507
case ElementType.Var:
508
return new VAR (Utilities.ReadCompressedInteger (data, start, out start));
509
case ElementType.MVar:
510
return new MVAR (Utilities.ReadCompressedInteger (data, start, out start));
511
case ElementType.GenericInst:
512
GENERICINST ginst = new GENERICINST ();
514
ginst.ValueType = ((ElementType) Utilities.ReadCompressedInteger (
515
data, start, out start)) == ElementType.ValueType;
517
ginst.Type = Utilities.GetMetadataToken (CodedIndex.TypeDefOrRef,
518
(uint) Utilities.ReadCompressedInteger (data, start, out start));
520
ginst.Signature = ReadGenericInstSignature (data, start, out start);
524
return new SigType (element);
528
GenericInstSignature ReadGenericInstSignature (byte [] data, int pos, out int start)
531
GenericInstSignature gis = new GenericInstSignature ();
532
gis.Arity = Utilities.ReadCompressedInteger (data, start, out start);
533
gis.Types = new GenericArg [gis.Arity];
534
for (int i = 0; i < gis.Arity; i++)
535
gis.Types [i] = ReadGenericArg (data, start, out start);
540
GenericArg ReadGenericArg (byte[] data, int pos, out int start)
543
CustomMod [] mods = ReadCustomMods (data, start, out start);
544
GenericArg arg = new GenericArg (ReadType (data, start, out start));
545
arg.CustomMods = mods;
549
CustomMod [] ReadCustomMods (byte [] data, int pos, out int start)
551
ArrayList cmods = new ArrayList ();
555
ElementType flag = (ElementType) Utilities.ReadCompressedInteger (data, start, out start);
557
if (!((flag == ElementType.CModOpt) || (flag == ElementType.CModReqD)))
559
cmods.Add (ReadCustomMod (data, start, out start));
561
return cmods.ToArray (typeof (CustomMod)) as CustomMod [];
564
CustomMod ReadCustomMod (byte [] data, int pos, out int start)
566
CustomMod cm = new CustomMod ();
568
ElementType cmod = (ElementType) Utilities.ReadCompressedInteger (data, start, out start);
569
if (cmod == ElementType.CModOpt)
570
cm.CMOD = CustomMod.CMODType.OPT;
571
else if (cmod == ElementType.CModReqD)
572
cm.CMOD = CustomMod.CMODType.REQD;
574
cm.CMOD = CustomMod.CMODType.None;
575
cm.TypeDefOrRef = Utilities.GetMetadataToken (CodedIndex.TypeDefOrRef,
576
(uint) Utilities.ReadCompressedInteger (data, start, out start));
580
CustomAttrib ReadCustomAttrib (int pos, MethodReference ctor, bool resolve)
582
int start, length = Utilities.ReadCompressedInteger (m_blobData, pos, out start);
583
byte [] data = new byte [length];
584
Buffer.BlockCopy (m_blobData, start, data, 0, length);
586
return ReadCustomAttrib (new BinaryReader (
587
new MemoryStream (data)), data, ctor, resolve);
589
CustomAttrib ca = new CustomAttrib (ctor);
595
CustomAttrib ReadCustomAttrib (BinaryReader br, byte [] data, MethodReference ctor, bool resolve)
597
CustomAttrib ca = new CustomAttrib (ctor);
598
if (data.Length == 0) {
599
ca.FixedArgs = new CustomAttrib.FixedArg [0];
600
ca.NamedArgs = new CustomAttrib.NamedArg [0];
606
ca.Prolog = br.ReadUInt16 ();
607
if (ca.Prolog != CustomAttrib.StdProlog)
608
throw new MetadataFormatException ("Non standard prolog for custom attribute");
610
ca.FixedArgs = new CustomAttrib.FixedArg [ctor.Parameters.Count];
611
for (int i = 0; i < ca.FixedArgs.Length && read; i++)
612
ca.FixedArgs [i] = ReadFixedArg (data, br,
613
ctor.Parameters [i].ParameterType, ref read, resolve);
615
if (br.BaseStream.Position == br.BaseStream.Length)
623
ca.NumNamed = br.ReadUInt16 ();
624
ca.NamedArgs = new CustomAttrib.NamedArg [ca.NumNamed];
625
for (int i = 0; i < ca.NumNamed && read; i++)
626
ca.NamedArgs [i] = ReadNamedArg (data, br, ref read, resolve);
632
CustomAttrib.FixedArg ReadFixedArg (byte [] data, BinaryReader br,
633
TypeReference param, ref bool read, bool resolve)
635
CustomAttrib.FixedArg fa = new CustomAttrib.FixedArg ();
636
if (param is ArrayType) {
637
param = ((ArrayType) param).ElementType;
639
fa.NumElem = br.ReadUInt32 ();
641
if (fa.NumElem == 0 || fa.NumElem == 0xffffffff) {
642
fa.Elems = new CustomAttrib.Elem [0];
647
fa.Elems = new CustomAttrib.Elem [fa.NumElem];
648
for (int i = 0; i < fa.NumElem; i++)
649
fa.Elems [i] = ReadElem (data, br, param, ref read, resolve);
651
fa.Elems = new CustomAttrib.Elem [] { ReadElem (data, br, param, ref read, resolve) };
656
TypeReference CreateEnumTypeReference (string enumName)
658
string asmName = null;
659
int asmStart = enumName.IndexOf (',');
660
if (asmStart != -1) {
661
asmName = enumName.Substring (asmStart + 1);
662
enumName = enumName.Substring (0, asmStart);
664
// Inner class style is reflection style.
665
enumName = enumName.Replace ('+', '/');
666
AssemblyNameReference asm;
667
if (asmName == null) {
668
// If no assembly is given then the ECMA standard says the
669
// assembly is either the current one or mscorlib.
670
if (m_reflectReader.Module.Types.Contains (enumName))
671
return m_reflectReader.Module.Types [enumName];
673
asm = m_reflectReader.Corlib;
675
asm = AssemblyNameReference.Parse (asmName);
677
string [] outers = enumName.Split ('/');
678
string outerfullname = outers [0];
680
int nsIndex = outerfullname.LastIndexOf ('.');
682
ns = outerfullname.Substring (0, nsIndex);
683
string name = outerfullname.Substring (nsIndex + 1);
684
TypeReference decType = new TypeReference (name, ns, asm);
685
for (int i = 1; i < outers.Length; i++) {
686
TypeReference t = new TypeReference (outers [i], null, asm);
687
t.DeclaringType = decType;
690
decType.IsValueType = true;
695
TypeReference ReadTypeReference (byte [] data, BinaryReader br, out ElementType elemType)
698
elemType = (ElementType) br.ReadByte ();
699
if (elemType == ElementType.SzArray) {
700
elemType = (ElementType) br.ReadByte ();
705
if (elemType == ElementType.Enum)
706
res = CreateEnumTypeReference (ReadUTF8String (data, br));
708
res = TypeReferenceFromElemType (elemType);
711
res = new ArrayType (res);
716
TypeReference TypeReferenceFromElemType (ElementType elemType)
719
case ElementType.Boxed :
720
return m_reflectReader.SearchCoreType (Constants.Object);
721
case ElementType.String :
722
return m_reflectReader.SearchCoreType (Constants.String);
723
case ElementType.Type :
724
return m_reflectReader.SearchCoreType (Constants.Type);
725
case ElementType.Boolean :
726
return m_reflectReader.SearchCoreType (Constants.Boolean);
727
case ElementType.Char :
728
return m_reflectReader.SearchCoreType (Constants.Char);
729
case ElementType.R4 :
730
return m_reflectReader.SearchCoreType (Constants.Single);
731
case ElementType.R8 :
732
return m_reflectReader.SearchCoreType (Constants.Double);
733
case ElementType.I1 :
734
return m_reflectReader.SearchCoreType (Constants.SByte);
735
case ElementType.I2 :
736
return m_reflectReader.SearchCoreType (Constants.Int16);
737
case ElementType.I4 :
738
return m_reflectReader.SearchCoreType (Constants.Int32);
739
case ElementType.I8 :
740
return m_reflectReader.SearchCoreType (Constants.Int64);
741
case ElementType.U1 :
742
return m_reflectReader.SearchCoreType (Constants.Byte);
743
case ElementType.U2 :
744
return m_reflectReader.SearchCoreType (Constants.UInt16);
745
case ElementType.U4 :
746
return m_reflectReader.SearchCoreType (Constants.UInt32);
747
case ElementType.U8 :
748
return m_reflectReader.SearchCoreType (Constants.UInt64);
750
throw new MetadataFormatException ("Non valid type in CustomAttrib.Elem: 0x{0}",
751
((byte) elemType).ToString("x2"));
755
internal CustomAttrib.NamedArg ReadNamedArg (byte [] data, BinaryReader br, ref bool read, bool resolve)
757
CustomAttrib.NamedArg na = new CustomAttrib.NamedArg ();
758
byte kind = br.ReadByte ();
759
if (kind == 0x53) { // field
762
} else if (kind == 0x54) { // property
766
throw new MetadataFormatException ("Wrong kind of namedarg found: 0x" + kind.ToString("x2"));
768
TypeReference elemType = ReadTypeReference (data, br, out na.FieldOrPropType);
769
na.FieldOrPropName = ReadUTF8String (data, br);
770
na.FixedArg = ReadFixedArg (data, br, elemType, ref read, resolve);
775
CustomAttrib.Elem ReadElem (byte [] data, BinaryReader br, TypeReference elemType, ref bool read, bool resolve)
777
CustomAttrib.Elem elem = new CustomAttrib.Elem ();
779
string elemName = elemType.FullName;
781
if (elemName == Constants.Object) {
782
elemType = ReadTypeReference (data, br, out elem.FieldOrPropType);
783
if (elemType is ArrayType) {
784
read = false; // Don't know how to represent arrays as an object value.
786
} else if (elemType.FullName == Constants.Object)
787
throw new MetadataFormatException ("Non valid type in CustomAttrib.Elem after boxed prefix: 0x{0}",
788
((byte) elem.FieldOrPropType).ToString("x2"));
790
elem = ReadElem (data, br, elemType, ref read, resolve);
791
elem.String = elem.Simple = elem.Type = false;
792
elem.BoxedValueType = true;
796
elem.ElemType = elemType;
798
if (elemName == Constants.Type || elemName == Constants.String) {
799
switch (elemType.FullName) {
800
case Constants.String:
802
elem.BoxedValueType = elem.Simple = elem.Type = false;
806
elem.BoxedValueType = elem.Simple = elem.String = false;
810
if (data [br.BaseStream.Position] == 0xff) { // null
812
br.BaseStream.Position++;
814
elem.Value = ReadUTF8String (data, br);
819
elem.String = elem.Type = elem.BoxedValueType = false;
820
if (!ReadSimpleValue (br, ref elem, elem.ElemType)) {
821
if (!resolve) { // until enums writing is implemented
825
TypeReference typeRef = GetEnumUnderlyingType (elem.ElemType, resolve);
826
if (typeRef == null || !ReadSimpleValue (br, ref elem, typeRef))
833
TypeReference GetEnumUnderlyingType (TypeReference enumType, bool resolve)
835
TypeDefinition type = enumType as TypeDefinition;
836
if (type == null && resolve && AssemblyResolver != null) {
837
if (enumType.Scope is ModuleDefinition)
838
throw new NotSupportedException ();
840
AssemblyDefinition asm = AssemblyResolver.Resolve (
841
((AssemblyNameReference) enumType.Scope).FullName);
842
type = asm.MainModule.Types [enumType.FullName];
845
if (type != null && type.IsEnum)
846
return type.Fields.GetField ("value__").FieldType;
851
bool ReadSimpleValue (BinaryReader br, ref CustomAttrib.Elem elem, TypeReference type)
853
switch (type.FullName) {
854
case Constants.Boolean :
855
elem.Value = br.ReadByte () == 1;
857
case Constants.Char :
858
elem.Value = (char) br.ReadUInt16 ();
860
case Constants.Single :
861
elem.Value = br.ReadSingle ();
863
case Constants.Double :
864
elem.Value = br.ReadDouble ();
866
case Constants.Byte :
867
elem.Value = br.ReadByte ();
869
case Constants.Int16 :
870
elem.Value = br.ReadInt16 ();
872
case Constants.Int32 :
873
elem.Value = br.ReadInt32 ();
875
case Constants.Int64 :
876
elem.Value = br.ReadInt64 ();
878
case Constants.SByte :
879
elem.Value = br.ReadSByte ();
881
case Constants.UInt16 :
882
elem.Value = br.ReadUInt16 ();
884
case Constants.UInt32 :
885
elem.Value = br.ReadUInt32 ();
887
case Constants.UInt64 :
888
elem.Value = br.ReadUInt64 ();
897
MarshalSig ReadMarshalSig (byte [] data)
900
MarshalSig ms = new MarshalSig ((NativeType) Utilities.ReadCompressedInteger (data, 0, out start));
901
switch (ms.NativeInstrinsic) {
902
case NativeType.ARRAY:
903
MarshalSig.Array ar = new MarshalSig.Array ();
904
ar.ArrayElemType = (NativeType) Utilities.ReadCompressedInteger (data, start, out start);
905
if (start < data.Length)
906
ar.ParamNum = Utilities.ReadCompressedInteger (data, start, out start);
907
if (start < data.Length)
908
ar.NumElem = Utilities.ReadCompressedInteger (data, start, out start);
909
if (start < data.Length)
910
ar.ElemMult = Utilities.ReadCompressedInteger (data, start, out start);
913
case NativeType.CUSTOMMARSHALER:
914
MarshalSig.CustomMarshaler cm = new MarshalSig.CustomMarshaler ();
915
cm.Guid = ReadUTF8String (data, start, out start);
916
cm.UnmanagedType = ReadUTF8String (data, start, out start);
917
cm.ManagedType = ReadUTF8String (data, start, out start);
918
cm.Cookie = ReadUTF8String (data, start, out start);
921
case NativeType.FIXEDARRAY:
922
MarshalSig.FixedArray fa = new MarshalSig.FixedArray ();
923
fa.NumElem = Utilities.ReadCompressedInteger (data, start, out start);
924
if (start < data.Length)
925
fa.ArrayElemType = (NativeType) Utilities.ReadCompressedInteger (data, start, out start);
928
case NativeType.SAFEARRAY:
929
MarshalSig.SafeArray sa = new MarshalSig.SafeArray ();
930
if (start < data.Length)
931
sa.ArrayElemType = (VariantType) Utilities.ReadCompressedInteger (data, start, out start);
934
case NativeType.FIXEDSYSSTRING:
935
MarshalSig.FixedSysString fss = new MarshalSig.FixedSysString ();
936
if (start < data.Length)
937
fss.Size = Utilities.ReadCompressedInteger (data, start, out start);
944
static internal string ReadUTF8String (byte [] data, BinaryReader br)
946
int start = (int)br.BaseStream.Position;
947
string val = ReadUTF8String (data, start, out start);
948
br.BaseStream.Position = start;
952
static internal string ReadUTF8String (byte [] data, int pos, out int start)
954
int length = Utilities.ReadCompressedInteger (data, pos, out start);
957
// COMPACT FRAMEWORK NOTE: Encoding.GetString (byte[]) is not supported.
958
return Encoding.UTF8.GetString (data, pos, length);