|
40 | 40 |
|
41 | 41 | namespace RabbitMQ.Client.Impl
|
42 | 42 | {
|
43 |
| - // * DESCRIPTION TAKEN FROM MS REFERENCE SOURCE * |
44 |
| - // https://github.com/microsoft/referencesource/blob/master/mscorlib/system/decimal.cs |
45 |
| - // The lo, mid, hi, and flags fields contain the representation of the |
46 |
| - // Decimal value. The lo, mid, and hi fields contain the 96-bit integer |
47 |
| - // part of the Decimal. Bits 0-15 (the lower word) of the flags field are |
48 |
| - // unused and must be zero; bits 16-23 contain must contain a value between |
49 |
| - // 0 and 28, indicating the power of 10 to divide the 96-bit integer part |
50 |
| - // by to produce the Decimal value; bits 24-30 are unused and must be zero; |
51 |
| - // and finally bit 31 indicates the sign of the Decimal value, 0 meaning |
52 |
| - // positive and 1 meaning negative. |
53 |
| - readonly struct DecimalData |
| 43 | + internal static class WireFormatting |
54 | 44 | {
|
55 |
| - public readonly uint Flags; |
56 |
| - public readonly uint Hi; |
57 |
| - public readonly uint Lo; |
58 |
| - public readonly uint Mid; |
59 |
| - |
60 |
| - internal DecimalData(uint flags, uint hi, uint lo, uint mid) |
| 45 | + // * DESCRIPTION TAKEN FROM MS REFERENCE SOURCE * |
| 46 | + // https://github.com/microsoft/referencesource/blob/master/mscorlib/system/decimal.cs |
| 47 | + // The lo, mid, hi, and flags fields contain the representation of the |
| 48 | + // Decimal value. The lo, mid, and hi fields contain the 96-bit integer |
| 49 | + // part of the Decimal. Bits 0-15 (the lower word) of the flags field are |
| 50 | + // unused and must be zero; bits 16-23 contain must contain a value between |
| 51 | + // 0 and 28, indicating the power of 10 to divide the 96-bit integer part |
| 52 | + // by to produce the Decimal value; bits 24-30 are unused and must be zero; |
| 53 | + // and finally bit 31 indicates the sign of the Decimal value, 0 meaning |
| 54 | + // positive and 1 meaning negative. |
| 55 | + readonly struct DecimalData |
61 | 56 | {
|
62 |
| - Flags = flags; |
63 |
| - Hi = hi; |
64 |
| - Lo = lo; |
65 |
| - Mid = mid; |
| 57 | + public readonly uint Flags; |
| 58 | + public readonly uint Hi; |
| 59 | + public readonly uint Lo; |
| 60 | + public readonly uint Mid; |
| 61 | + |
| 62 | + internal DecimalData(uint flags, uint hi, uint lo, uint mid) |
| 63 | + { |
| 64 | + Flags = flags; |
| 65 | + Hi = hi; |
| 66 | + Lo = lo; |
| 67 | + Mid = mid; |
| 68 | + } |
66 | 69 | }
|
67 |
| - } |
68 | 70 |
|
69 |
| - internal static class WireFormatting |
70 |
| - { |
71 | 71 | [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
72 | 72 | public static decimal ReadDecimal(ReadOnlySpan<byte> span)
|
73 | 73 | {
|
74 | 74 | byte scale = span[0];
|
75 |
| - ValidateDecimalScale(scale); |
76 |
| - uint unsignedMantissa = NetworkOrderDeserializer.ReadUInt32(span.Slice(1)); |
77 |
| - var data = new DecimalData(((uint)(scale << 16)) | unsignedMantissa & 0x80000000, 0, unsignedMantissa & 0x7FFFFFFF, 0); |
78 |
| - return Unsafe.As<DecimalData, decimal>(ref data); |
79 |
| - } |
80 |
| - |
81 |
| - private static void ValidateDecimalScale(byte scale) |
82 |
| - { |
83 | 75 | if (scale > 28)
|
84 | 76 | {
|
85 |
| - throw new SyntaxErrorException($"Unrepresentable AMQP decimal table field: scale={scale}"); |
| 77 | + ThrowInvalidDecimalScale(scale); |
86 | 78 | }
|
| 79 | + |
| 80 | + uint unsignedMantissa = NetworkOrderDeserializer.ReadUInt32(span.Slice(1)); |
| 81 | + var data = new DecimalData(((uint)(scale << 16)) | unsignedMantissa & 0x80000000, 0, unsignedMantissa & 0x7FFFFFFF, 0); |
| 82 | + return Unsafe.As<DecimalData, decimal>(ref data); |
87 | 83 | }
|
88 | 84 |
|
89 | 85 | public static IList ReadArray(ReadOnlySpan<byte> span, out int bytesRead)
|
@@ -880,5 +876,10 @@ private static int ThrowWireFormattingException(decimal value)
|
880 | 876 | {
|
881 | 877 | throw new WireFormattingException("Decimal overflow in AMQP encoding", value);
|
882 | 878 | }
|
| 879 | + |
| 880 | + private static decimal ThrowInvalidDecimalScale(int scale) |
| 881 | + { |
| 882 | + throw new SyntaxErrorException($"Unrepresentable AMQP decimal table field: scale={scale}"); |
| 883 | + } |
883 | 884 | }
|
884 | 885 | }
|
0 commit comments