Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.sirix.utils.Calc Maven / Gradle / Ivy
package io.sirix.utils;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
/**
* Swiss army knife for encoding/decoding of basic data types.
*
* @author Sebastian Baechle
*
*/
public final class Calc {
private Calc() {}
private static final String ERROR_MSG = "Input byte array cannot be null";
private static final Charset UTF8 = StandardCharsets.UTF_8;
private static final int MAX_INT = Integer.MAX_VALUE;
public static byte[] fromBigDecimal(BigDecimal i) {
BigInteger bi = i.unscaledValue();
byte[] tmp = bi.toByteArray();
int scale = i.scale();
if ((scale <= 0x3F) && (scale > -0x3F)) {
// 6 bits are sufficient to encode
// scale unsigned
// encode sign
byte[] b = new byte[1 + tmp.length];
b[0] = (byte) ((scale >= 0) ? 0x0 : 0x40);
b[0] |= (byte) (scale & 0x3F);
System.arraycopy(tmp, 0, b, 1, tmp.length);
return b;
}
byte[] b = new byte[5 + tmp.length];
b[0] = (byte) 0x80; // set bit 0
fromInt(scale, b, 1);
System.arraycopy(tmp, 0, b, 5, tmp.length);
return b;
}
public static BigDecimal toBigDecimal(byte[] b) {
if (b == null) {
throw new IllegalArgumentException(ERROR_MSG);
}
if ((b[0] & 0x80) == 0) {
// bit 0 not set: 6 bits are sufficient
// to encode scale unsigned
// bit 1 encodes sign
int sign = ((b[0] & 0x40) == 0) ? 1 : -1;
// bits 2-7 encode unsigned scale
int scale = sign * (b[0] & 0x3F);
BigInteger bi = toBigInteger(b, 1, b.length - 1);
return new BigDecimal(bi, scale);
}
int scale = toInt(b, 1);
BigInteger bi = toBigInteger(b, 5, b.length - 5);
return new BigDecimal(bi, scale);
}
public static BigDecimal toBigDecimal(byte[] b, int off, int len) {
if ((b[off] & 0x80) == 0) {
// bit 0 not set: 6 bits are sufficient to encode scale
// bit 1 encodes sign
int sign = ((b[off] & 0x40) == 0) ? 1 : -1;
// bits 2-7 encode unsigned scale
int scale = sign * (b[off] & 0x3F);
BigInteger bi = toBigInteger(b, off + 1, len - 1);
return new BigDecimal(bi, scale);
}
int scale = toInt(b, 1);
BigInteger bi = toBigInteger(b, off + 5, len - 5);
return new BigDecimal(bi, scale);
}
public static BigInteger toBigInteger(byte[] b) {
return new BigInteger(b);
}
public static BigInteger toBigInteger(byte[] b, int off, int len) {
return new BigInteger(Arrays.copyOfRange(b, off, off + len));
}
public static byte[] fromBigInteger(BigInteger i) {
return i.toByteArray();
}
public static void fromBigInteger(BigInteger i, byte[] b, int off) {
byte[] tmp = i.toByteArray();
System.arraycopy(tmp, 0, b, off, tmp.length);
}
public static String toString(byte[] s) {
return new String(s, UTF8);
}
public static String toString(byte[] s, int off, int len) {
return new String(s, off, len, UTF8);
}
public static byte[] fromString(String s) {
return s.getBytes(UTF8);
}
public static void fromString(String s, byte[] b, int off) {
byte[] tmp = s.getBytes(UTF8);
System.arraycopy(tmp, 0, b, off, tmp.length);
}
public static int toUIntVar(byte[] b) {
if (b == null) {
throw new IllegalArgumentException(ERROR_MSG);
}
int len = b.length;
if (len == 1) {
return b[0] & 0xFF;
}
if (len == 2) {
return ((b[0] & 0xFF) << 8) | b[1] & 0xFF;
}
if (len == 3) {
return ((b[0] & 0xFF) << 16) | ((b[1] & 0xFF) << 8) | b[2] & 0xFF;
}
return ((b[0] & 0xFF) << 24) | ((b[1] & 0xFF) << 16) | ((b[2] & 0xFF) << 8) | b[3] & 0xFF;
}
public static int toInt(byte[] b, int off, int len) {
if (len == 1) {
return b[off] & 0xFF;
}
if (len == 2) {
return ((b[off++] & 0xFF) << 8) | b[off] & 0xFF;
}
if (len == 3) {
return ((b[off++] & 0xFF) << 16) | ((b[off++] & 0xFF) << 8) | b[off++] & 0xFF;
}
return ((b[off++] & 0xFF) << 24) | ((b[off++] & 0xFF) << 16) | ((b[off++] & 0xFF) << 8)
| b[off] & 0xFF;
}
public static byte[] fromUIntVar(int i) {
if ((i & 0xFFFFFF00) == 0) {
return new byte[] {(byte) i};
}
if ((i & 0xFFFF0000) == 0) {
return new byte[] {(byte) ((i >> 8) & 0xFF), (byte) i};
}
if ((i & 0xFF000000) == 0) {
return new byte[] {(byte) ((i >> 16) & 0xFF), (byte) ((i >> 8) & 0xFF), (byte) i};
}
if (i < 0) {
throw new IllegalArgumentException(String.valueOf(i));
}
return new byte[] {(byte) ((i >> 24) & 0xFF), (byte) ((i >> 16) & 0xFF),
(byte) ((i >> 8) & 0xFF), (byte) i};
}
public static int toInt(byte[] b) {
return ((b[0] & 0xFF) << 24) | ((b[1] & 0xFF) << 16) | ((b[2] & 0xFF) << 8) | b[3] & 0xFF;
}
public static int toInt(byte[] b, int off) {
if (b == null) {
throw new IllegalArgumentException(ERROR_MSG);
}
return ((b[off++] & 0xFF) << 24) | ((b[off++] & 0xFF) << 16) | ((b[off++] & 0xFF) << 8)
| (b[off++] & 0xFF);
}
public static byte[] fromInt(int i) {
return new byte[] {(byte) ((i >> 24) & 0xFF), (byte) ((i >> 16) & 0xFF),
(byte) ((i >> 8) & 0xFF), (byte) i};
}
public static void fromInt(int i, byte[] b, int off) {
b[off++] = (byte) ((i >> 24) & 0xFF);
b[off++] = (byte) ((i >> 16) & 0xFF);
b[off++] = (byte) ((i >> 8) & 0xFF);
b[off] = (byte) i;
}
public static long toLong(byte[] b) {
return ((((long) b[0] & 0xFF) << 56) | (((long) b[1] & 0xFF) << 48)
| (((long) b[2] & 0xFF) << 40) | (((long) b[3] & 0xFF) << 32) | (((long) b[4] & 0xFF) << 24)
| (((long) b[5] & 0xFF) << 16) | (((long) b[6] & 0xFF) << 8) | ((long) b[7] & 0xFF));
}
public static long toLong(byte[] b, int off) {
if (b == null) {
throw new IllegalArgumentException(ERROR_MSG);
}
return ((((long) b[off++] & 0xFF) << 56) | (((long) b[off++] & 0xFF) << 48)
| (((long) b[off++] & 0xFF) << 40) | (((long) b[off++] & 0xFF) << 32)
| (((long) b[off++] & 0xFF) << 24) | (((long) b[off++] & 0xFF) << 16)
| (((long) b[off++] & 0xFF) << 8) | ((long) b[off++] & 0xFF));
}
public static byte[] fromLong(long i) {
return new byte[] {(byte) ((i >> 56) & 0xFF), (byte) ((i >> 48) & 0xFF),
(byte) ((i >> 40) & 0xFF), (byte) ((i >> 32) & 0xFF), (byte) ((i >> 24) & 0xFF),
(byte) ((i >> 16) & 0xFF), (byte) ((i >> 8) & 0xFF), (byte) i};
}
public static void fromLong(long i, byte[] b, int off) {
b[off++] = (byte) ((i >> 56) & 0xFF);
b[off++] = (byte) ((i >> 48) & 0xFF);
b[off++] = (byte) ((i >> 40) & 0xFF);
b[off++] = (byte) ((i >> 32) & 0xFF);
b[off++] = (byte) ((i >> 24) & 0xFF);
b[off++] = (byte) ((i >> 16) & 0xFF);
b[off++] = (byte) ((i >> 8) & 0xFF);
b[off++] = (byte) (i);
}
public static double toDouble(byte[] b) {
return Double.longBitsToDouble(toLong(b));
}
public static double toDouble(byte[] b, int off) {
return Double.longBitsToDouble(toLong(b, off));
}
public static byte[] fromDouble(double i) {
return fromLong(Double.doubleToRawLongBits(i));
}
public static void fromDouble(double i, byte[] b, int off) {
fromLong(Double.doubleToRawLongBits(i), b, off);
}
public static float toFloat(byte[] b) {
return Float.intBitsToFloat(toInt(b));
}
public static float toFloat(byte[] b, int off) {
return Float.intBitsToFloat(toInt(b, off));
}
public static byte[] fromFloat(float i) {
return fromLong(Float.floatToRawIntBits(i));
}
public static void fromDouble(float i, byte[] b, int off) {
fromInt(Float.floatToRawIntBits(i), b, off);
}
public static int compare(byte[] v1, byte[] v2) {
// a null value is interpreted as EOF (= highest possible value)
if(comparisonOfNull(v1, v2) != MAX_INT)
return comparisonOfNull(v1, v2);
int len1 = v1.length;
int len2 = v2.length;
int len = Math.min(len1, len2);
int pos = -1;
while (++pos < len) {
byte b1 = v1[pos];
byte b2 = v2[pos];
if (b1 != b2) {
return b1 - b2;
}
}
return len1 - len2;
}
public static int compare(byte[] v1, int off1, int len1, byte[] v2, int off2, int len2) {
// a null value is interpreted as EOF (= highest possible value)
if(comparisonOfNull(v1, v2) != MAX_INT)
return comparisonOfNull(v1, v2);
int len = Math.min(len1, len2);
int pos = -1;
while (++pos < len) {
byte b1 = v1[off1 + pos];
byte b2 = v2[off2 + pos];
if (b1 != b2) {
return b1 - b2;
}
}
return len1 - len2;
}
/**
* Nulls in this project are viewed as EOF, thus it is often of interest when comparing two values which one is
* greatest to check if one is null or possible both and return which.
* @param v1 the first value to be tested.
* @param v2 the second value to be tested.
* @return -1, if v2 is null but not v1, 1 for vice versa, 0 for both being null, and int max for when neither is null.
*/
private static int comparisonOfNull(byte[] v1, byte[] v2){
if(v1 == null && v2 == null)
return 0;
else if(v1 != null && v2 == null)
return -1;
else if(v1 == null)
return 1;
else
return MAX_INT;
}
public static int compareAsPrefix(byte[] v1, byte[] v2) {
// a null value is interpreted as EOF (= highest possible value)
if(comparisonOfNull(v1, v2) != MAX_INT)
return comparisonOfNull(v1, v2);
int len1 = v1.length;
int len2 = v2.length;
int len = Math.min(len1, len2);
int pos = -1;
while (++pos < len) {
if (v1[pos] != v2[pos]) {
return v1[pos] - v2[pos];
}
}
return (len1 <= len2) ? 0 : 1;
}
public static int compareU(byte[] v1, byte[] v2) {
// a null value is interpreted as EOF (= highest possible value)
return compareU(v1, 0, v1.length, v2, 0, v2.length);
}
public static int compareU(byte[] v1, int off1, int len1, byte[] v2, int off2, int len2) {
// a null value is interpreted as EOF (= highest possible value)
if(comparisonOfNull(v1, v2) != MAX_INT)
return comparisonOfNull(v1, v2);
int len = Math.min(len1, len2);
int pos = -1;
while (++pos < len) {
int b1 = v1[off1 + pos] & 0xFF;
int b2 = v2[off2 + pos] & 0xFF;
if (b1 != b2) {
return b1 - b2;
}
}
return len1 - len2;
}
public static int compareUAsPrefix(byte[] v1, byte[] v2) {
// a null value is interpreted as EOF (= highest possible value)
if(comparisonOfNull(v1, v2) != Integer.MAX_VALUE)
return comparisonOfNull(v1, v2);
int len1 = v1.length;
int len2 = v2.length;
int len = Math.min(len1, len2);
int pos = -1;
while (++pos < len) {
int b1 = v1[pos] & 0xFF;
int b2 = v2[pos] & 0xFF;
if (b1 != b2) {
return b1 - b2;
}
}
return (len1 <= len2) ? 0 : 1;
}
public static int compareUIntVar(byte[] v1, byte[] v2) {
// a null value is interpreted as EOF (= highest possible value)
if(comparisonOfNull(v1, v2) != MAX_INT)
return comparisonOfNull(v1, v2);
int i1 = toUIntVar(v1);
int i2 = toUIntVar(v2);
return Integer.compare(i1, i2);
}
public static int compareInt(byte[] v1, byte[] v2) {
// a null value is interpreted as EOF (= highest possible value)
return compareInt(v1, 0, v2, 0);
}
public static int compareInt(byte[] v1, int off1, byte[] v2, int off2) {
// a null value is interpreted as EOF (= highest possible value)
if(comparisonOfNull(v1, v2) != MAX_INT)
return comparisonOfNull(v1, v2);
int i1 = toInt(v1, off1);
int i2 = toInt(v2, off2);
return Integer.compare(i1, i2);
}
public static int compareLong(byte[] v1, byte[] v2) {
// a null value is interpreted as EOF (= highest possible value)
return compareLong(v1, 0, v2, 0);
}
public static int compareLong(byte[] v1, int off1, byte[] v2, int off2) {
// a null value is interpreted as EOF (= highest possible value)
if(comparisonOfNull(v1, v2) != MAX_INT)
return comparisonOfNull(v1, v2);
long i1 = toLong(v1, off1);
long i2 = toLong(v2, off2);
return Long.compare(i1, i2);
}
public static int compareDouble(byte[] v1, byte[] v2) {
// a null value is interpreted as EOF (= highest possible value)
if(comparisonOfNull(v1, v2) != MAX_INT)
return comparisonOfNull(v1, v2);
double d1 = toDouble(v1);
double d2 = toDouble(v2);
return Double.compare(d1, d2);
}
public static int compareFloat(byte[] v1, byte[] v2) {
// a null value is interpreted as EOF (= highest possible value)
if(comparisonOfNull(v1, v2) != MAX_INT)
return comparisonOfNull(v1, v2);
float f1 = toFloat(v1);
float f2 = toFloat(v2);
return Float.compare(f1, f2);
}
public static int compareBigInteger(byte[] v1, byte[] v2) {
// a null value is interpreted as EOF (= highest possible value)
if(comparisonOfNull(v1, v2) != MAX_INT)
return comparisonOfNull(v1, v2);
BigInteger i1 = toBigInteger(v1);
BigInteger i2 = toBigInteger(v2);
return i1.compareTo(i2);
}
public static int compareBigDecimal(byte[] v1, byte[] v2) {
// a null value is interpreted as EOF (= highest possible value)
if (comparisonOfNull(v1, v2) != MAX_INT)
return comparisonOfNull(v1, v2);
BigDecimal i1 = toBigDecimal(v1);
BigDecimal i2 = toBigDecimal(v2);
return i1.compareTo(i2);
}
}