Define the Volt-specific decimal(38,12) structure over the standard Java-like implementation of BigDecimal. Full operator support provided. Some methods removed, consistent with the fixed-sclae behavior.
All conversion and mathematical operations maintain the fixed scale at 12 digits -> some operations might lose precision or throw overflow exceptions.
        /// <summary>
        /// Reads a Decimal (VoltDB:Decimal).
        /// </summary>
        /// <remarks>No .NET support for the equivalent BigDecimal data type from Java. At this time, this data type is
        /// not supported by the .NET client library.</remarks>
        /// <returns>Value read from the underlying byte buffer.</returns>
        public VoltDecimal?ReadVoltDecimalN()
        {
            // Remark: value = (read == -170141183460469231731687303715884105728.) ? null : read;
            byte[] buffer = new byte[16];
            Buffer.BlockCopy(this.Input, this.Position, buffer, 0, 16);
            this.Position += 16;
            VoltDecimal result = new VoltDecimal(buffer);

            if (result.IsVoltDBNull())
            {
                return(null);
            }
            return(result);
        }
 /// <summary>
 /// Writes a Nullable BigDecimal array.
 /// </summary>
 /// <param name="value">Value to write.</param>
 /// <returns>The serializer instance, ready to chain the next command.</returns>
 public Serializer Write(VoltDecimal?[] value)
 {
     writer.WriteByte(unchecked((byte)DBType.DECIMAL));
     Cnv.PutBytes(_tempBuffer, 0, (short)value.Length);
     writer.Write(_tempBuffer, 0, 2);
     for (int i = 0; i < value.Length; i++)
         writer.Write((value[i] == null) ? VoltDecimal.NullValueBytes : value[i].Value.ToBytes(), 0, 16);
     return this;
 }
 /// <summary>
 /// Writes a Nullable BigDecimal.
 /// </summary>
 /// <param name="value">Value to write.</param>
 /// <returns>The serializer instance, ready to chain the next command.</returns>
 public Serializer Write(VoltDecimal? value)
 {
     writer.Write((value == null) ? VoltDecimal.NullValueBytes : value.Value.ToBytes(), 0, 16);
     return this;
 }
 /// <summary>
 /// Writes a BigDecimal.
 /// </summary>
 /// <param name="value">Value to write.</param>
 /// <returns>The serializer instance, ready to chain the next command.</returns>
 public Serializer Write(VoltDecimal value)
 {
     writer.Write(value.ToBytes(), 0, 16);
     return this;
 }
 /// <summary>
 /// Reads a Decimal (VoltDB:Decimal).
 /// </summary>
 /// <remarks>No .NET support for the equivalent BigDecimal data type from Java. At this time, this data type is
 /// not supported by the .NET client library.</remarks>
 /// <returns>Value read from the underlying byte buffer.</returns>
 public VoltDecimal? ReadVoltDecimalN()
 {
     // Remark: value = (read == -170141183460469231731687303715884105728.) ? null : read;
     byte[] buffer = new byte[16];
     Buffer.BlockCopy(this.Input, this.Position, buffer, 0, 16);
     this.Position += 16;
     VoltDecimal result = new VoltDecimal(buffer);
     if (result.IsVoltDBNull())
         return null;
     return result;
 }
        /// <summary>
        /// Returns a straight data array (boxed) of the requested data type from a single-column Table.
        /// </summary>
        /// <param name="input">The deserializer hoding the response data.</param>
        /// <param name="TResult">The desired output data type of the array elements.</param>
        /// <returns>A boxed array of elements of the requested data type.</returns>
        internal static object FromSingleColumn(Deserializer input, Type TResult)
        {
            // Skip table length, metadata length, status, get column count.
            short columnCount = input.Skip(9).ReadInt16();

            // Validate there is indeed only one column.
            if (columnCount != 1)
            {
                throw new VoltInvalidDataException(Resources.InvalidColumnCount, columnCount);
            }

            // Read column data type.
            DBType columnType = (DBType)input.ReadSByte();

            // Validate the data type matches the .NET casting request.
            if (VoltType.ToDBType(TResult) != columnType)
            {
                throw new VoltInvalidCastException(
                          Resources.InvalidCastException
                          , columnType.ToString()
                          , TResult.ToString()
                          );
            }

            // Skip column name, get Row count.
            int rowCount = input.SkipString().ReadInt32();

            // Load data.
            switch (VoltType.ToNetType(TResult))
            {
            case VoltType.NetType.Byte:
                byte[] dataByte = new byte[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataByte[r] = input.Skip(4).ReadByte();
                }
                return(dataByte);

            case VoltType.NetType.ByteN:
                byte?[] dataByteN = new byte?[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataByteN[r] = input.Skip(4).ReadByteN();
                }
                return(dataByteN);

            case VoltType.NetType.SByte:
                sbyte[] dataSByte = new sbyte[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataSByte[r] = input.Skip(4).ReadSByte();
                }
                return(dataSByte);

            case VoltType.NetType.SByteN:
                sbyte?[] dataSByteN = new sbyte?[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataSByteN[r] = input.Skip(4).ReadSByteN();
                }
                return(dataSByteN);

            case VoltType.NetType.Int16:
                short[] dataInt16 = new short[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataInt16[r] = input.Skip(4).ReadInt16();
                }
                return(dataInt16);

            case VoltType.NetType.Int16N:
                short?[] dataInt16N = new short?[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataInt16N[r] = input.Skip(4).ReadInt16N();
                }
                return(dataInt16N);

            case VoltType.NetType.Int32:
                int[] dataInt32 = new int[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataInt32[r] = input.Skip(4).ReadInt32();
                }
                return(dataInt32);

            case VoltType.NetType.Int32N:
                int?[] dataInt32N = new int?[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataInt32N[r] = input.Skip(4).ReadInt32N();
                }
                return(dataInt32N);

            case VoltType.NetType.Int64:
                long[] dataInt64 = new long[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataInt64[r] = input.Skip(4).ReadInt64();
                }
                return(dataInt64);

            case VoltType.NetType.Int64N:
                long?[] dataInt64N = new long?[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataInt64N[r] = input.Skip(4).ReadInt64N();
                }
                return(dataInt64N);

            case VoltType.NetType.Double:
                double[] dataDouble = new double[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataDouble[r] = input.Skip(4).ReadDouble();
                }
                return(dataDouble);

            case VoltType.NetType.DoubleN:
                double?[] dataDoubleN = new double?[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataDoubleN[r] = input.Skip(4).ReadDoubleN();
                }
                return(dataDoubleN);

            case VoltType.NetType.DateTime:
                DateTime[] dataDateTime = new DateTime[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataDateTime[r] = input.Skip(4).ReadDateTime();
                }
                return(dataDateTime);

            case VoltType.NetType.DateTimeN:
                DateTime?[] dataDateTimeN = new DateTime?[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataDateTimeN[r] = input.Skip(4).ReadDateTimeN();
                }
                return(dataDateTimeN);

            case VoltType.NetType.String:
                string[] dataString = new string[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataString[r] = input.Skip(4).ReadString();
                }
                return(dataString);

            case VoltType.NetType.VoltDecimal:
                VoltDecimal[] dataVoltDecimal = new VoltDecimal[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataVoltDecimal[r] = input.Skip(4).ReadVoltDecimal();
                }
                return(dataVoltDecimal);

            case VoltType.NetType.VoltDecimalN:
                VoltDecimal?[] dataVoltDecimalN = new VoltDecimal?[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataVoltDecimalN[r] = input.Skip(4).ReadVoltDecimalN();
                }
                return(dataVoltDecimalN);

            case VoltType.NetType.Decimal:
                Decimal[] dataDecimal = new Decimal[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataDecimal[r] = input.Skip(4).ReadDecimal();
                }
                return(dataDecimal);

            case VoltType.NetType.DecimalN:
                Decimal?[] dataDecimalN = new Decimal?[rowCount];
                for (int r = 0; r < rowCount; r++)
                {
                    dataDecimalN[r] = input.Skip(4).ReadDecimalN();
                }
                return(dataDecimalN);

            case VoltType.NetType.ByteArray:
                input.Skip(4);
                return(input.ReadByteArray());

            default:
                throw new VoltUnsupportedTypeException(Resources.UnsupportedParameterNETType, TResult.ToString());
            }
        }