org.h2.util.Bits Maven / Gradle / Ivy
/*
* Copyright 2004-2022 H2 Group. Multiple-Licensed under the MPL 2.0,
* and the EPL 1.0 (https://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.h2.util;
import java.util.UUID;
/**
* Manipulations with bytes and arrays. This class can be overridden in
* multi-release JAR with more efficient implementation for a newer versions of
* Java.
*/
public final class Bits {
/*
* Signatures of methods should match with
* h2/src/java9/src/org/h2/util/Bits.java and precompiled
* h2/src/java9/precompiled/org/h2/util/Bits.class.
*/
/**
* Compare the contents of two char arrays. If the content or length of the
* first array is smaller than the second array, -1 is returned. If the content
* or length of the second array is smaller than the first array, 1 is returned.
* If the contents and lengths are the same, 0 is returned.
*
* @param data1
* the first char array (must not be null)
* @param data2
* the second char array (must not be null)
* @return the result of the comparison (-1, 1 or 0)
*/
public static int compareNotNull(char[] data1, char[] data2) {
if (data1 == data2) {
return 0;
}
int len = Math.min(data1.length, data2.length);
for (int i = 0; i < len; i++) {
char b = data1[i];
char b2 = data2[i];
if (b != b2) {
return b > b2 ? 1 : -1;
}
}
return Integer.signum(data1.length - data2.length);
}
/**
* Compare the contents of two byte arrays. If the content or length of the
* first array is smaller than the second array, -1 is returned. If the content
* or length of the second array is smaller than the first array, 1 is returned.
* If the contents and lengths are the same, 0 is returned.
*
*
* This method interprets bytes as signed.
*
*
* @param data1
* the first byte array (must not be null)
* @param data2
* the second byte array (must not be null)
* @return the result of the comparison (-1, 1 or 0)
*/
public static int compareNotNullSigned(byte[] data1, byte[] data2) {
if (data1 == data2) {
return 0;
}
int len = Math.min(data1.length, data2.length);
for (int i = 0; i < len; i++) {
byte b = data1[i];
byte b2 = data2[i];
if (b != b2) {
return b > b2 ? 1 : -1;
}
}
return Integer.signum(data1.length - data2.length);
}
/**
* Compare the contents of two byte arrays. If the content or length of the
* first array is smaller than the second array, -1 is returned. If the content
* or length of the second array is smaller than the first array, 1 is returned.
* If the contents and lengths are the same, 0 is returned.
*
*
* This method interprets bytes as unsigned.
*
*
* @param data1
* the first byte array (must not be null)
* @param data2
* the second byte array (must not be null)
* @return the result of the comparison (-1, 1 or 0)
*/
public static int compareNotNullUnsigned(byte[] data1, byte[] data2) {
if (data1 == data2) {
return 0;
}
int len = Math.min(data1.length, data2.length);
for (int i = 0; i < len; i++) {
int b = data1[i] & 0xff;
int b2 = data2[i] & 0xff;
if (b != b2) {
return b > b2 ? 1 : -1;
}
}
return Integer.signum(data1.length - data2.length);
}
/**
* Reads a int value from the byte array at the given position in big-endian
* order.
*
* @param buff
* the byte array
* @param pos
* the position
* @return the value
*/
public static int readInt(byte[] buff, int pos) {
return (buff[pos++] << 24) + ((buff[pos++] & 0xff) << 16) + ((buff[pos++] & 0xff) << 8) + (buff[pos] & 0xff);
}
/**
* Reads a int value from the byte array at the given position in
* little-endian order.
*
* @param buff
* the byte array
* @param pos
* the position
* @return the value
*/
public static int readIntLE(byte[] buff, int pos) {
return (buff[pos++] & 0xff) + ((buff[pos++] & 0xff) << 8) + ((buff[pos++] & 0xff) << 16) + (buff[pos] << 24);
}
/**
* Reads a long value from the byte array at the given position in
* big-endian order.
*
* @param buff
* the byte array
* @param pos
* the position
* @return the value
*/
public static long readLong(byte[] buff, int pos) {
return (((long) readInt(buff, pos)) << 32) + (readInt(buff, pos + 4) & 0xffff_ffffL);
}
/**
* Reads a long value from the byte array at the given position in
* little-endian order.
*
* @param buff
* the byte array
* @param pos
* the position
* @return the value
*/
public static long readLongLE(byte[] buff, int pos) {
return (readIntLE(buff, pos) & 0xffff_ffffL) + (((long) readIntLE(buff, pos + 4)) << 32);
}
/**
* Reads a double value from the byte array at the given position in
* big-endian order.
*
* @param buff
* the byte array
* @param pos
* the position
* @return the value
*/
public static double readDouble(byte[] buff, int pos) {
return Double.longBitsToDouble(readLong(buff, pos));
}
/**
* Reads a double value from the byte array at the given position in
* little-endian order.
*
* @param buff
* the byte array
* @param pos
* the position
* @return the value
*/
public static double readDoubleLE(byte[] buff, int pos) {
return Double.longBitsToDouble(readLongLE(buff, pos));
}
/**
* Converts UUID value to byte array in big-endian order.
*
* @param msb
* most significant part of UUID
* @param lsb
* least significant part of UUID
* @return byte array representation
*/
public static byte[] uuidToBytes(long msb, long lsb) {
byte[] buff = new byte[16];
for (int i = 0; i < 8; i++) {
buff[i] = (byte) ((msb >> (8 * (7 - i))) & 0xff);
buff[8 + i] = (byte) ((lsb >> (8 * (7 - i))) & 0xff);
}
return buff;
}
/**
* Converts UUID value to byte array in big-endian order.
*
* @param uuid
* UUID value
* @return byte array representation
*/
public static byte[] uuidToBytes(UUID uuid) {
return uuidToBytes(uuid.getMostSignificantBits(), uuid.getLeastSignificantBits());
}
/**
* Writes a int value to the byte array at the given position in big-endian
* order.
*
* @param buff
* the byte array
* @param pos
* the position
* @param x
* the value to write
*/
public static void writeInt(byte[] buff, int pos, int x) {
buff[pos++] = (byte) (x >> 24);
buff[pos++] = (byte) (x >> 16);
buff[pos++] = (byte) (x >> 8);
buff[pos] = (byte) x;
}
/**
* Writes a int value to the byte array at the given position in
* little-endian order.
*
* @param buff
* the byte array
* @param pos
* the position
* @param x
* the value to write
*/
public static void writeIntLE(byte[] buff, int pos, int x) {
buff[pos++] = (byte) x;
buff[pos++] = (byte) (x >> 8);
buff[pos++] = (byte) (x >> 16);
buff[pos] = (byte) (x >> 24);
}
/**
* Writes a long value to the byte array at the given position in big-endian
* order.
*
* @param buff
* the byte array
* @param pos
* the position
* @param x
* the value to write
*/
public static void writeLong(byte[] buff, int pos, long x) {
writeInt(buff, pos, (int) (x >> 32));
writeInt(buff, pos + 4, (int) x);
}
/**
* Writes a long value to the byte array at the given position in
* little-endian order.
*
* @param buff
* the byte array
* @param pos
* the position
* @param x
* the value to write
*/
public static void writeLongLE(byte[] buff, int pos, long x) {
writeIntLE(buff, pos, (int) x);
writeIntLE(buff, pos + 4, (int) (x >> 32));
}
/**
* Writes a double value to the byte array at the given position in
* big-endian order.
*
* @param buff
* the byte array
* @param pos
* the position
* @param x
* the value to write
*/
public static void writeDouble(byte[] buff, int pos, double x) {
writeLong(buff, pos, Double.doubleToRawLongBits(x));
}
/**
* Writes a double value to the byte array at the given position in
* little-endian order.
*
* @param buff
* the byte array
* @param pos
* the position
* @param x
* the value to write
*/
public static void writeDoubleLE(byte[] buff, int pos, double x) {
writeLongLE(buff, pos, Double.doubleToRawLongBits(x));
}
private Bits() {
}
}