private void Write(TypeSig typeSig) { const ElementType DEFAULT_ELEMENT_TYPE = ElementType.Boolean; if (typeSig == null) { helper.Error("TypeSig is null"); writer.Write((byte)DEFAULT_ELEMENT_TYPE); return; } if (!recursionCounter.Increment()) { helper.Error("Infinite recursion"); writer.Write((byte)DEFAULT_ELEMENT_TYPE); return; } uint count; switch (typeSig.ElementType) { case ElementType.Void: case ElementType.Boolean: case ElementType.Char: case ElementType.I1: case ElementType.U1: case ElementType.I2: case ElementType.U2: case ElementType.I4: case ElementType.U4: case ElementType.I8: case ElementType.U8: case ElementType.R4: case ElementType.R8: case ElementType.String: case ElementType.TypedByRef: case ElementType.I: case ElementType.U: case ElementType.Object: case ElementType.Sentinel: writer.Write((byte)typeSig.ElementType); break; case ElementType.Ptr: case ElementType.ByRef: case ElementType.SZArray: case ElementType.Pinned: writer.Write((byte)typeSig.ElementType); Write(typeSig.Next); break; case ElementType.ValueType: case ElementType.Class: writer.Write((byte)typeSig.ElementType); Write(((TypeDefOrRefSig)typeSig).TypeDefOrRef); break; case ElementType.Var: case ElementType.MVar: writer.Write((byte)typeSig.ElementType); WriteCompressedUInt32(((GenericSig)typeSig).Number); break; case ElementType.Array: writer.Write((byte)typeSig.ElementType); var ary = (ArraySig)typeSig; Write(ary.Next); WriteCompressedUInt32(ary.Rank); if (ary.Rank == 0) { break; } count = WriteCompressedUInt32((uint)ary.Sizes.Count); for (uint i = 0; i < count; i++) { WriteCompressedUInt32(ary.Sizes[(int)i]); } count = WriteCompressedUInt32((uint)ary.LowerBounds.Count); for (uint i = 0; i < count; i++) { WriteCompressedInt32(ary.LowerBounds[(int)i]); } break; case ElementType.GenericInst: writer.Write((byte)typeSig.ElementType); var gis = (GenericInstSig)typeSig; Write(gis.GenericType); count = WriteCompressedUInt32((uint)gis.GenericArguments.Count); for (uint i = 0; i < count; i++) { Write(gis.GenericArguments[(int)i]); } break; case ElementType.ValueArray: writer.Write((byte)typeSig.ElementType); Write(typeSig.Next); WriteCompressedUInt32((typeSig as ValueArraySig).Size); break; case ElementType.FnPtr: writer.Write((byte)typeSig.ElementType); Write((typeSig as FnPtrSig).Signature); break; case ElementType.CModReqd: case ElementType.CModOpt: writer.Write((byte)typeSig.ElementType); Write((typeSig as ModifierSig).Modifier); Write(typeSig.Next); break; case ElementType.Module: writer.Write((byte)typeSig.ElementType); WriteCompressedUInt32((typeSig as ModuleSig).Index); Write(typeSig.Next); break; case ElementType.End: case ElementType.R: case ElementType.Internal: default: helper.Error("Unknown or unsupported element type"); writer.Write((byte)DEFAULT_ELEMENT_TYPE); break; } recursionCounter.Decrement(); }
uint WriteCompressedUInt32(uint value) { if (value >= 0x1FFFFFFF) { helper.Error("UInt32 value is too big and can't be compressed"); value = 0x1FFFFFFF; } writer.WriteCompressedUInt32(value); return(value); }