Java ByteBuffer Serialize serializeBigDecimal(BigDecimal bd, ByteBuffer buf)

Here you can find the source of serializeBigDecimal(BigDecimal bd, ByteBuffer buf)

Description

Serialize the java.math.BigDecimal BigDecimal to Volt's fixed precision and scale 16-byte format.

License

Open Source License

Parameter

Parameter Description
bd java.math.BigDecimal BigDecimal to serialize
buf java.nio.ByteBuffer ByteBuffer to serialize the <code>BigDecimal</code> to

Exception

Parameter Description
RuntimeException Thrown if the precision or scale is out of range

Declaration

static public void serializeBigDecimal(BigDecimal bd, ByteBuffer buf) 

Method Source Code

//package com.java2s;
/* This file is part of VoltDB.
 * Copyright (C) 2008-2014 VoltDB Inc.//www. j  a v  a 2  s . com
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with VoltDB.  If not, see <http://www.gnu.org/licenses/>.
 */

import java.math.BigDecimal;
import java.math.BigInteger;

import java.nio.ByteBuffer;

public class Main {
    /**
     * The scale of decimals in Volt
     */
    public static final int kDefaultScale = 12;
    /**
     * Array containing the smallest 16-byte twos complement value that is used
     * as SQL null.
     */
    private static final byte[] NULL_INDICATOR = new BigInteger("-170141183460469231731687303715884105728")
            .toByteArray();
    /**
     * Array of scale factors used to scale up <code>BigInteger</code>s retrieved from
     * <code>BigDecimal</code>s
     */
    private static final BigInteger scaleFactors[] = new BigInteger[] { BigInteger.ONE, BigInteger.TEN,
            BigInteger.TEN.pow(2), BigInteger.TEN.pow(3), BigInteger.TEN.pow(4), BigInteger.TEN.pow(5),
            BigInteger.TEN.pow(6), BigInteger.TEN.pow(7), BigInteger.TEN.pow(8), BigInteger.TEN.pow(9),
            BigInteger.TEN.pow(10), BigInteger.TEN.pow(11), BigInteger.TEN.pow(12) };

    /**
     * Serialize the {@link java.math.BigDecimal BigDecimal} to Volt's fixed precision and scale 16-byte format.
     * @param bd {@link java.math.BigDecimal BigDecimal} to serialize
     * @param buf {@link java.nio.ByteBuffer ByteBuffer} to serialize the <code>BigDecimal</code> to
     * @throws RuntimeException Thrown if the precision or scale is out of range
     */
    static public void serializeBigDecimal(BigDecimal bd, ByteBuffer buf) {
        if (bd == null) {
            serializeNull(buf);
            return;
        }
        final int scale = bd.scale();
        final int precision = bd.precision();
        if (scale > 12) {
            throw new RuntimeException("Scale of " + bd + " is " + scale + " and the max is 12");
        }
        final int precisionMinusScale = precision - scale;
        if (precisionMinusScale > 26) {
            throw new RuntimeException("Precision of " + bd + " to the left of the decimal point is "
                    + precisionMinusScale + " and the max is 26");
        }
        final int scaleFactor = kDefaultScale - bd.scale();
        BigInteger unscaledBI = bd.unscaledValue().multiply(scaleFactors[scaleFactor]);
        boolean isNegative = false;
        if (unscaledBI.signum() < 0) {
            isNegative = true;
        }
        final byte unscaledValue[] = unscaledBI.toByteArray();
        if (unscaledValue.length > 16) {
            throw new RuntimeException("Precision of " + bd + " is >38 digits");
        }
        buf.put(expandToLength16(unscaledValue, isNegative));
    }

    /**
     * Serialize the null decimal sigil to a the provided {@link java.nio.ByteBuffer ByteBuffer}
     * @param buf <code>ByteBuffer</code> to serialize the decimal into
     */
    static public void serializeNull(ByteBuffer buf) {
        buf.put(NULL_INDICATOR);
    }

    /**
     * Converts BigInteger's byte representation containing a scaled magnitude to a fixed size 16 byte array
     * and set the sign in the most significant byte's most significant bit.
     * @param scaledValue Scaled twos complement representation of the decimal
     * @param isNegative Determines whether the sign bit is set
     * @return
     */
    private static final byte[] expandToLength16(byte scaledValue[], final boolean isNegative) {
        if (scaledValue.length == 16) {
            return scaledValue;
        }
        byte replacement[] = new byte[16];
        if (isNegative) {
            java.util.Arrays.fill(replacement, (byte) -1);
        }
        for (int ii = 15; 15 - ii < scaledValue.length; ii--) {
            replacement[ii] = scaledValue[ii - (replacement.length - scaledValue.length)];
        }
        return replacement;
    }
}

Related

  1. deserialize(ByteBuffer b)
  2. deserialize(ByteBuffer byteBuffer)
  3. deserializeBoolean(ByteBuffer buf)
  4. deserializeFromByteBufferNoHeader(ByteBuffer bytes)
  5. deserializeObject(ByteBuffer obj)
  6. serializeNull(ByteBuffer buf)
  7. serializeString(final String value, ByteBuffer buffer)
  8. serializeStringArray(ByteBuffer buf, String[] strArray)