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
- deserialize(ByteBuffer b)
- deserialize(ByteBuffer byteBuffer)
- deserializeBoolean(ByteBuffer buf)
- deserializeFromByteBufferNoHeader(ByteBuffer bytes)
- deserializeObject(ByteBuffer obj)
- serializeNull(ByteBuffer buf)
- serializeString(final String value, ByteBuffer buffer)
- serializeStringArray(ByteBuffer buf, String[] strArray)