/// <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 is null)
            {
                helper.Error("Custom attribute: Arg type is null");
                argType = value.Type;
                if (argType is 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.WriteBoolean(ToUInt64(value.Value) != 0);
                }
                else
                {
                    writer.WriteBoolean((bool)value.Value);
                }
                break;

            case ElementType.Char:
                if (!VerifyTypeAndValue(value, ElementType.Char))
                {
                    writer.WriteUInt16((ushort)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteUInt16((ushort)(char)value.Value);
                }
                break;

            case ElementType.I1:
                if (!VerifyTypeAndValue(value, ElementType.I1))
                {
                    writer.WriteSByte((sbyte)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteSByte((sbyte)value.Value);
                }
                break;

            case ElementType.U1:
                if (!VerifyTypeAndValue(value, ElementType.U1))
                {
                    writer.WriteByte((byte)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteByte((byte)value.Value);
                }
                break;

            case ElementType.I2:
                if (!VerifyTypeAndValue(value, ElementType.I2))
                {
                    writer.WriteInt16((short)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteInt16((short)value.Value);
                }
                break;

            case ElementType.U2:
                if (!VerifyTypeAndValue(value, ElementType.U2))
                {
                    writer.WriteUInt16((ushort)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteUInt16((ushort)value.Value);
                }
                break;

            case ElementType.I4:
                if (!VerifyTypeAndValue(value, ElementType.I4))
                {
                    writer.WriteInt32((int)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteInt32((int)value.Value);
                }
                break;

            case ElementType.U4:
                if (!VerifyTypeAndValue(value, ElementType.U4))
                {
                    writer.WriteUInt32((uint)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteUInt32((uint)value.Value);
                }
                break;

            case ElementType.I8:
                if (!VerifyTypeAndValue(value, ElementType.I8))
                {
                    writer.WriteInt64((long)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteInt64((long)value.Value);
                }
                break;

            case ElementType.U8:
                if (!VerifyTypeAndValue(value, ElementType.U8))
                {
                    writer.WriteUInt64(ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteUInt64((ulong)value.Value);
                }
                break;

            case ElementType.R4:
                if (!VerifyTypeAndValue(value, ElementType.R4))
                {
                    writer.WriteSingle((float)ToDouble(value.Value));
                }
                else
                {
                    writer.WriteSingle((float)value.Value);
                }
                break;

            case ElementType.R8:
                if (!VerifyTypeAndValue(value, ElementType.R8))
                {
                    writer.WriteDouble(ToDouble(value.Value));
                }
                else
                {
                    writer.WriteDouble((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 is 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;
Exemple #2
0
        /// <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("Custom attribute: 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.WriteBoolean(ToUInt64(value.Value) != 0);
                }
                else
                {
                    writer.WriteBoolean((bool)value.Value);
                }
                break;

            case ElementType.Char:
                if (!VerifyTypeAndValue(value, ElementType.Char))
                {
                    writer.WriteUInt16((ushort)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteUInt16((ushort)(char)value.Value);
                }
                break;

            case ElementType.I1:
                if (!VerifyTypeAndValue(value, ElementType.I1))
                {
                    writer.WriteSByte((sbyte)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteSByte((sbyte)value.Value);
                }
                break;

            case ElementType.U1:
                if (!VerifyTypeAndValue(value, ElementType.U1))
                {
                    writer.WriteByte((byte)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteByte((byte)value.Value);
                }
                break;

            case ElementType.I2:
                if (!VerifyTypeAndValue(value, ElementType.I2))
                {
                    writer.WriteInt16((short)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteInt16((short)value.Value);
                }
                break;

            case ElementType.U2:
                if (!VerifyTypeAndValue(value, ElementType.U2))
                {
                    writer.WriteUInt16((ushort)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteUInt16((ushort)value.Value);
                }
                break;

            case ElementType.I4:
                if (!VerifyTypeAndValue(value, ElementType.I4))
                {
                    writer.WriteInt32((int)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteInt32((int)value.Value);
                }
                break;

            case ElementType.U4:
                if (!VerifyTypeAndValue(value, ElementType.U4))
                {
                    writer.WriteUInt32((uint)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteUInt32((uint)value.Value);
                }
                break;

            case ElementType.I8:
                if (!VerifyTypeAndValue(value, ElementType.I8))
                {
                    writer.WriteInt64((long)ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteInt64((long)value.Value);
                }
                break;

            case ElementType.U8:
                if (!VerifyTypeAndValue(value, ElementType.U8))
                {
                    writer.WriteUInt64(ToUInt64(value.Value));
                }
                else
                {
                    writer.WriteUInt64((ulong)value.Value);
                }
                break;

            case ElementType.R4:
                if (!VerifyTypeAndValue(value, ElementType.R4))
                {
                    writer.WriteSingle((float)ToDouble(value.Value));
                }
                else
                {
                    writer.WriteSingle((float)value.Value);
                }
                break;

            case ElementType.R8:
                if (!VerifyTypeAndValue(value, ElementType.R8))
                {
                    writer.WriteDouble(ToDouble(value.Value));
                }
                else
                {
                    writer.WriteDouble((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"))
                    {
                        if (value.Value is TypeSig ts)
                        {
                            WriteType(ts);
                        }
                        else if (value.Value == null)
                        {
                            WriteUTF8String(null);
                        }
                        else
                        {
                            helper.Error("Custom attribute value is not a type");
                            WriteUTF8String(UTF8String.Empty);
                        }
                    }
                    else
                    {
                        helper.Error("Custom attribute 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();
        }