summaryrefslogtreecommitdiff
path: root/src/main/java/com/amazon/carbonado/raw/DataDecoder.java
diff options
context:
space:
mode:
authorBrian S. O'Neill <bronee@gmail.com>2008-07-19 19:12:01 +0000
committerBrian S. O'Neill <bronee@gmail.com>2008-07-19 19:12:01 +0000
commit6bea245169222895f879a396b1c7c1bdb73642b2 (patch)
tree86524dbd077b8c4ffd2fc49a5476769ac226bea6 /src/main/java/com/amazon/carbonado/raw/DataDecoder.java
parent146e46fb5a19dcd236ccf6be62c90de3bc356795 (diff)
Added utilities for encoding and decoding BigDecimals.
Diffstat (limited to 'src/main/java/com/amazon/carbonado/raw/DataDecoder.java')
-rw-r--r--src/main/java/com/amazon/carbonado/raw/DataDecoder.java57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/main/java/com/amazon/carbonado/raw/DataDecoder.java b/src/main/java/com/amazon/carbonado/raw/DataDecoder.java
index 5ea5c1d..407df0c 100644
--- a/src/main/java/com/amazon/carbonado/raw/DataDecoder.java
+++ b/src/main/java/com/amazon/carbonado/raw/DataDecoder.java
@@ -18,6 +18,7 @@
package com.amazon.carbonado.raw;
+import java.math.BigDecimal;
import java.math.BigInteger;
import java.io.EOFException;
@@ -391,6 +392,62 @@ public class DataDecoder {
}
/**
+ * Decodes a BigDecimal.
+ *
+ * @param src source of encoded data
+ * @param srcOffset offset into encoded data
+ * @param valueRef decoded BigDecimal is stored in element 0, which may be null
+ * @return amount of bytes read from source
+ * @throws CorruptEncodingException if source data is corrupt
+ * @since 1.2
+ */
+ public static int decode(byte[] src, int srcOffset, BigDecimal[] valueRef)
+ throws CorruptEncodingException
+ {
+ try {
+ final int originalOffset = srcOffset;
+
+ int b = src[srcOffset++] & 0xff;
+ if (b >= 0xf8) {
+ valueRef[0] = null;
+ return 1;
+ }
+
+ int scale;
+ if (b <= 0x7f) {
+ scale = b;
+ } else if (b <= 0xbf) {
+ scale = ((b & 0x3f) << 8) | (src[srcOffset++] & 0xff);
+ } else if (b <= 0xdf) {
+ scale = ((b & 0x1f) << 16) | ((src[srcOffset++] & 0xff) << 8) |
+ (src[srcOffset++] & 0xff);
+ } else if (b <= 0xef) {
+ scale = ((b & 0x0f) << 24) | ((src[srcOffset++] & 0xff) << 16) |
+ ((src[srcOffset++] & 0xff) << 8) | (src[srcOffset++] & 0xff);
+ } else {
+ scale = ((src[srcOffset++] & 0xff) << 24) |
+ ((src[srcOffset++] & 0xff) << 16) |
+ ((src[srcOffset++] & 0xff) << 8) | (src[srcOffset++] & 0xff);
+ }
+
+ if ((scale & 1) != 0) {
+ scale = (~(scale >> 1)) | (1 << 31);
+ } else {
+ scale >>>= 1;
+ }
+
+ BigInteger[] unscaledRef = new BigInteger[1];
+ int amt = decode(src, srcOffset, unscaledRef);
+
+ valueRef[0] = new BigDecimal(unscaledRef[0], scale);
+
+ return (srcOffset + amt) - originalOffset;
+ } catch (IndexOutOfBoundsException e) {
+ throw new CorruptEncodingException(null, e);
+ }
+ }
+
+ /**
* Decodes the given byte array.
*
* @param src source of encoded data