| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | // See the LICENSE file in the project root for more information. |
| | | 4 | | |
| | | 5 | | using System.Runtime.InteropServices; |
| | | 6 | | |
| | | 7 | | namespace System |
| | | 8 | | { |
| | | 9 | | // |
| | | 10 | | // Some of the Number code ported from CoreRT used internal Decimal methods that did in-place modifications on Decim |
| | | 11 | | // lose the original perf, we'll do the same here by using Unsafe ref casts to project Decimal's true layout onto th |
| | | 12 | | // This looks really dangerous but the fact is that Decimal is simply the OleAut DECIMAL structure and given that it |
| | | 13 | | // to pass it to OleAut apis via blittable interop, it's not going to change. |
| | | 14 | | // |
| | | 15 | | |
| | | 16 | | [StructLayout(LayoutKind.Sequential)] |
| | | 17 | | internal struct MutableDecimal |
| | | 18 | | { |
| | | 19 | | // Do not reorder these: must match DECIMAL's layout exactly. |
| | | 20 | | public uint Flags; |
| | | 21 | | public uint High; |
| | | 22 | | public uint Low; |
| | | 23 | | public uint Mid; |
| | | 24 | | |
| | | 25 | | public bool IsNegative |
| | | 26 | | { |
| | 3 | 27 | | get { return (Flags & SignMask) != 0; } |
| | 3 | 28 | | set { Flags = (Flags & ~SignMask) | (value ? SignMask : 0); } |
| | | 29 | | } |
| | | 30 | | |
| | | 31 | | public int Scale |
| | | 32 | | { |
| | 3 | 33 | | get { return (byte)(Flags >> ScaleShift); } |
| | 3 | 34 | | set { Flags = (Flags & ~ScaleMask) | ((uint)value << ScaleShift); } |
| | | 35 | | } |
| | | 36 | | |
| | | 37 | | // Sign mask for the flags field. A value of zero in this bit indicates a |
| | | 38 | | // positive Decimal value, and a value of one in this bit indicates a |
| | | 39 | | // negative Decimal value. |
| | | 40 | | // |
| | | 41 | | // Look at OleAut's DECIMAL_NEG constant to check for negative values |
| | | 42 | | // in native code. |
| | | 43 | | private const uint SignMask = 0x80000000; |
| | | 44 | | |
| | | 45 | | // Scale mask for the flags field. This byte in the flags field contains |
| | | 46 | | // the power of 10 to divide the Decimal value by. The scale byte must |
| | | 47 | | // contain a value between 0 and 28 inclusive. |
| | | 48 | | private const uint ScaleMask = 0x00FF0000; |
| | | 49 | | |
| | | 50 | | // Number of bits scale is shifted by. |
| | | 51 | | private const int ScaleShift = 16; |
| | | 52 | | } |
| | | 53 | | } |