summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Runtime/CompilerServices/DecimalConstantAttribute.cs
blob: 0e2b6f8418010554114acf78773aa4b30213d098 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.


// Note: If you add a new ctor overloads you need to update ParameterInfo.RawDefaultValue

using System.Reflection;
using System.Diagnostics;
using System.Diagnostics.Contracts;
using System.Collections.Generic;

namespace System.Runtime.CompilerServices
{
    [Serializable]
    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
    public sealed class DecimalConstantAttribute : Attribute
    {
        [CLSCompliant(false)]
        public DecimalConstantAttribute(
            byte scale,
            byte sign,
            uint hi,
            uint mid,
            uint low
        )
        {
            dec = new System.Decimal((int)low, (int)mid, (int)hi, (sign != 0), scale);
        }

        public DecimalConstantAttribute(
            byte scale,
            byte sign,
            int hi,
            int mid,
            int low
        )
        {
            dec = new System.Decimal(low, mid, hi, (sign != 0), scale);
        }


        public System.Decimal Value
        {
            get
            {
                return dec;
            }
        }

        internal static Decimal GetRawDecimalConstant(CustomAttributeData attr)
        {
            Contract.Requires(attr.Constructor.DeclaringType == typeof(DecimalConstantAttribute));

            foreach (CustomAttributeNamedArgument namedArgument in attr.NamedArguments)
            {
                if (namedArgument.MemberInfo.Name.Equals("Value"))
                {
                    // This is not possible because Decimal cannot be represented directly in the metadata.
                    Debug.Assert(false, "Decimal cannot be represented directly in the metadata.");
                    return (Decimal)namedArgument.TypedValue.Value;
                }
            }

            ParameterInfo[] parameters = attr.Constructor.GetParameters();
            Debug.Assert(parameters.Length == 5);

            System.Collections.Generic.IList<CustomAttributeTypedArgument> args = attr.ConstructorArguments;
            Debug.Assert(args.Count == 5);

            if (parameters[2].ParameterType == typeof(uint))
            {
                // DecimalConstantAttribute(byte scale, byte sign, uint hi, uint mid, uint low)
                int low = (int)(UInt32)args[4].Value;
                int mid = (int)(UInt32)args[3].Value;
                int hi = (int)(UInt32)args[2].Value;
                byte sign = (byte)args[1].Value;
                byte scale = (byte)args[0].Value;

                return new System.Decimal(low, mid, hi, (sign != 0), scale);
            }
            else
            {
                // DecimalConstantAttribute(byte scale, byte sign, int hi, int mid, int low)
                int low = (int)args[4].Value;
                int mid = (int)args[3].Value;
                int hi = (int)args[2].Value;
                byte sign = (byte)args[1].Value;
                byte scale = (byte)args[0].Value;

                return new System.Decimal(low, mid, hi, (sign != 0), scale);
            }
        }

        private System.Decimal dec;
    }
}