Example #1
0
        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);
        }
Example #2
0
        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));
            }
        }