/// <summary> /// Write a value /// </summary> /// <param name="argType">The ctor arg type, field type, or property type</param> /// <param name="value">The value to write</param> void WriteElem(TypeSig argType, CAArgument value) { if (argType == null) { helper.Error("Arg type is null"); argType = value.Type; if (argType == null) return; } if (!recursionCounter.Increment()) { helper.Error("Infinite recursion"); return; } TypeSig underlyingType; ITypeDefOrRef tdr; switch (argType.ElementType) { case ElementType.Boolean: if (!VerifyTypeAndValue(value, ElementType.Boolean)) writer.Write(ToUInt64(value.Value) != 0); else writer.Write((bool)value.Value); break; case ElementType.Char: if (!VerifyTypeAndValue(value, ElementType.Char)) writer.Write((ushort)ToUInt64(value.Value)); else writer.Write((ushort)(char)value.Value); break; case ElementType.I1: if (!VerifyTypeAndValue(value, ElementType.I1)) writer.Write((sbyte)ToUInt64(value.Value)); else writer.Write((sbyte)value.Value); break; case ElementType.U1: if (!VerifyTypeAndValue(value, ElementType.U1)) writer.Write((byte)ToUInt64(value.Value)); else writer.Write((byte)value.Value); break; case ElementType.I2: if (!VerifyTypeAndValue(value, ElementType.I2)) writer.Write((short)ToUInt64(value.Value)); else writer.Write((short)value.Value); break; case ElementType.U2: if (!VerifyTypeAndValue(value, ElementType.U2)) writer.Write((ushort)ToUInt64(value.Value)); else writer.Write((ushort)value.Value); break; case ElementType.I4: if (!VerifyTypeAndValue(value, ElementType.I4)) writer.Write((int)ToUInt64(value.Value)); else writer.Write((int)value.Value); break; case ElementType.U4: if (!VerifyTypeAndValue(value, ElementType.U4)) writer.Write((uint)ToUInt64(value.Value)); else writer.Write((uint)value.Value); break; case ElementType.I8: if (!VerifyTypeAndValue(value, ElementType.I8)) writer.Write((long)ToUInt64(value.Value)); else writer.Write((long)value.Value); break; case ElementType.U8: if (!VerifyTypeAndValue(value, ElementType.U8)) writer.Write(ToUInt64(value.Value)); else writer.Write((ulong)value.Value); break; case ElementType.R4: if (!VerifyTypeAndValue(value, ElementType.R4)) writer.Write((float)ToDouble(value.Value)); else writer.Write((float)value.Value); break; case ElementType.R8: if (!VerifyTypeAndValue(value, ElementType.R8)) writer.Write(ToDouble(value.Value)); else writer.Write((double)value.Value); break; case ElementType.String: if (VerifyTypeAndValue(value, ElementType.String, typeof(UTF8String))) WriteUTF8String((UTF8String)value.Value); else if (VerifyTypeAndValue(value, ElementType.String, typeof(string))) WriteUTF8String((string)value.Value); else WriteUTF8String(UTF8String.Empty); break; case ElementType.ValueType: tdr = ((TypeDefOrRefSig)argType).TypeDefOrRef; underlyingType = GetEnumUnderlyingType(argType); if (underlyingType != null) WriteElem(underlyingType, value); else if (tdr is TypeRef && TryWriteEnumUnderlyingTypeValue(value.Value)) { // No error. Assume it's an enum that couldn't be resolved. } else helper.Error("Custom attribute value is not an enum"); break; case ElementType.Class: tdr = ((TypeDefOrRefSig)argType).TypeDefOrRef; if (CheckCorLibType(argType, "Type")) { if (CheckCorLibType(value.Type, "Type")) { var ts = value.Value as TypeSig; if (ts != null) WriteType(ts); else { helper.Error("CA value is not a type"); WriteUTF8String(UTF8String.Empty); } } else { helper.Error("CA value type is not System.Type"); WriteUTF8String(UTF8String.Empty); } break; } else if (tdr is TypeRef && TryWriteEnumUnderlyingTypeValue(value.Value)) { // No error. Assume it's an enum that couldn't be resolved. break; } goto default; case ElementType.SZArray: WriteValue(argType, value); break; case ElementType.Object: WriteFieldOrPropType(value.Type); WriteElem(value.Type, value); break; case ElementType.End: case ElementType.Void: case ElementType.Ptr: case ElementType.ByRef: case ElementType.Var: case ElementType.Array: case ElementType.GenericInst: case ElementType.TypedByRef: case ElementType.ValueArray: case ElementType.I: case ElementType.U: case ElementType.R: case ElementType.FnPtr: case ElementType.MVar: case ElementType.CModReqd: case ElementType.CModOpt: case ElementType.Internal: case ElementType.Module: case ElementType.Sentinel: case ElementType.Pinned: default: helper.Error("Invalid or unsupported element type in custom attribute"); break; } recursionCounter.Decrement(); }
bool VerifyTypeAndValue(CAArgument value, ElementType etype, Type valueType) { if (!VerifyType(value.Type, etype)) { helper.Error("Custom attribute arg type != value.Type"); return false; } return value.Value == null || value.Value.GetType() == valueType; }
bool VerifyTypeAndValue(CAArgument value, ElementType etype) { if (!VerifyType(value.Type, etype)) { helper.Error("Custom attribute arg type != value.Type"); return false; } if (!VerifyValue(value.Value, etype)) { helper.Error("Custom attribute value.Value's type != value.Type"); return false; } return true; }
void WriteValue(TypeSig argType, CAArgument value) { if (argType == null || value.Type == null) { helper.Error("Argument type is null"); return; } if (!recursionCounter.Increment()) { helper.Error("Infinite recursion"); return; } var arrayType = argType as SZArraySig; if (arrayType != null) { var argsArray = value.Value as IList<CAArgument>; if (argsArray == null && value.Value != null) helper.Error("Value is not null or an array"); WriteArrayValue(arrayType, argsArray); } else WriteElem(argType, value); recursionCounter.Decrement(); }
void Add(CAArgument arg) { // It's a struct so can't be null Add(arg.Type); }
public ConstructorArgumentWrapper(CAArgument ca) { Value = ca.Value; }