internal static object UnmarshalNumeric(Stream stream) { char[] chars; int byte_length = ReadByte(stream); NumericFlags flags = (NumericFlags)ReadByte(stream); int byte_integer_length = ReadByte(stream); byte_length -= 2; int length = byte_length * 2; int integer_length = byte_integer_length * 2; if (length == 0 && integer_length == 0 && flags == 0) { chars = new char[1]; chars[0] = '0'; } else { if ((flags & NumericFlags.NDF_LEAD0) != 0) { length--; integer_length--; } if ((flags & NumericFlags.NDF_TRAIL0) != 0) { length--; } int fraction_length = length - integer_length; if (fraction_length != 0) { length++; // for decimal point } chars = new char[length]; int i = 0; byte read; if ((flags & NumericFlags.NDF_LEAD0) != 0) { read = ReadByte(stream); chars[i++] = (char)((read & 0x0f) + '0'); } while (i < integer_length) { read = ReadByte(stream); chars[i++] = (char)(((read >> 4) & 0x0f) + '0'); chars[i++] = (char)((read & 0x0f) + '0'); } if (fraction_length != 0) { chars[i++] = '.'; int even_fraction_length = ((flags & NumericFlags.NDF_TRAIL0) != 0 ? length - 1 : length); while (i < even_fraction_length) { read = ReadByte(stream); chars[i++] = (char)(((read >> 4) & 0x0f) + '0'); chars[i++] = (char)((read & 0x0f) + '0'); } if (i < length) { read = (byte)ReadByte(stream); chars[i++] = (char)(((read >> 4) & 0x0f) + '0'); } } if ((flags & NumericFlags.NDF_NAN) != 0) { throw new InvalidCastException("Cannot convert a NAN value to Decimal."); } if ((flags & NumericFlags.NDF_INF) != 0) { throw new InvalidCastException("Cannot convert an INF value to Decimal."); } } String s = new String(chars); Decimal value = Decimal.Parse(s, NumberStyles.AllowDecimalPoint, NumberFormatInfo.InvariantInfo); if ((flags & NumericFlags.NDF_NEG) != 0) { value = -value; } return(value); }
internal static void MarshalNumeric(Stream stream, decimal value) { NumericFlags flags = 0; if (value < 0) { flags |= NumericFlags.NDF_NEG; value = -value; } string s = value.ToString(); int length = s.Length; int point_index = s.IndexOf('.'); int integer_length = point_index < 0 ? length : point_index; int byte_length = length / 2; int byte_integer_length = integer_length / 2; if ((integer_length & 1) != 0) { byte_length++; byte_integer_length++; flags |= NumericFlags.NDF_LEAD0; } int fraction_length = point_index < 0 ? 0 : length - point_index - 1; if ((fraction_length & 1) != 0) { byte_length++; flags |= NumericFlags.NDF_TRAIL0; } stream.WriteByte((byte)BoxTag.DV_NUMERIC); stream.WriteByte((byte)(byte_length + 2)); stream.WriteByte((byte)flags); stream.WriteByte((byte)byte_integer_length); int i = 0; if ((flags & NumericFlags.NDF_LEAD0) != 0) { stream.WriteByte((byte)(s[i++] - '0')); } for (; i < integer_length; i += 2) { stream.WriteByte((byte)(((s[i] - '0') << 4) | (s[i + 1] - '0'))); } if (fraction_length == 0) { return; } int even_end = (flags & NumericFlags.NDF_TRAIL0) != 0 ? length - 1 : length; for (i++; i < even_end; i += 2) { stream.WriteByte((byte)(((s[i] - '0') << 4) | (s[i + 1] - '0'))); } if (i < length) { stream.WriteByte((byte)((s[i] - '0') << 4)); } }