| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.iotdb.tsfile.utils; |
| |
| import org.apache.iotdb.tsfile.common.conf.TSFileConfig; |
| |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.util.List; |
| |
| /** |
| * BytesUtils is a utility class. It provides conversion among byte array and other type including |
| * integer, long, float, boolean, double and string. <br> |
| * It also provide other usable function as follows:<br> |
| * reading function which receives InputStream. <br> |
| * concat function to join a list of byte array to one.<br> |
| * get and set one bit in a byte array. |
| */ |
| public class BytesUtils { |
| |
| private BytesUtils() {} |
| |
| private static final Logger LOG = LoggerFactory.getLogger(BytesUtils.class); |
| |
| /** |
| * integer convert to byte[4]. |
| * |
| * @param i integer to convert |
| * @return byte[4] for integer |
| */ |
| public static byte[] intToBytes(int i) { |
| return new byte[] { |
| (byte) ((i >> 24) & 0xFF), |
| (byte) ((i >> 16) & 0xFF), |
| (byte) ((i >> 8) & 0xFF), |
| (byte) (i & 0xFF) |
| }; |
| } |
| |
| /** |
| * integer convert to byte array, then write four bytes to parameter desc start from index:offset. |
| * |
| * @param i integer to convert |
| * @param desc byte array be written |
| * @param offset position in desc byte array that conversion result should start |
| * @return byte array |
| */ |
| public static byte[] intToBytes(int i, byte[] desc, int offset) { |
| if (desc.length - offset < 4) { |
| throw new IllegalArgumentException("Invalid input: desc.length - offset < 4"); |
| } |
| desc[0 + offset] = (byte) ((i >> 24) & 0xFF); |
| desc[1 + offset] = (byte) ((i >> 16) & 0xFF); |
| desc[2 + offset] = (byte) ((i >> 8) & 0xFF); |
| desc[3 + offset] = (byte) (i & 0xFF); |
| return desc; |
| } |
| |
| /** |
| * convert an integer to a byte array which length is width, then copy this array to the parameter |
| * result from pos. |
| * |
| * @param srcNum input integer variable. All but the lowest {@code width} bits are 0. |
| * @param result byte array to convert |
| * @param pos start position |
| * @param width bit-width |
| */ |
| public static void intToBytes(int srcNum, byte[] result, int pos, int width) { |
| int cnt = pos & 0x07; |
| int index = pos >> 3; |
| try { |
| while (width > 0) { |
| int m = width + cnt >= 8 ? 8 - cnt : width; |
| width -= m; |
| int mask = 1 << (8 - cnt); |
| cnt += m; |
| byte y = (byte) (srcNum >>> width); |
| y = (byte) (y << (8 - cnt)); |
| mask = ~(mask - (1 << (8 - cnt))); |
| result[index] = (byte) (result[index] & mask | y); |
| srcNum = srcNum & ~(-1 << width); |
| if (cnt == 8) { |
| index++; |
| cnt = 0; |
| } |
| } |
| } catch (Exception e) { |
| LOG.error( |
| "tsfile-common BytesUtils: cannot convert an integer {} to a byte array, " |
| + "pos {}, width {}", |
| srcNum, |
| pos, |
| width, |
| e); |
| } |
| } |
| |
| /** |
| * divide int to two bytes. |
| * |
| * @param i int |
| * @return two bytes in byte[] structure |
| */ |
| public static byte[] intToTwoBytes(int i) { |
| if (i > 0xFFFF) { |
| throw new IllegalArgumentException("Invalid input: " + i + " > 0xFFFF"); |
| } |
| byte[] ret = new byte[2]; |
| ret[1] = (byte) (i & 0xFF); |
| ret[0] = (byte) ((i >> 8) & 0xFF); |
| return ret; |
| } |
| |
| /** |
| * concatenate two bytes to int. |
| * |
| * @param ret byte[] |
| * @return int value |
| */ |
| public static int twoBytesToInt(byte[] ret) { |
| if (ret.length != 2) { |
| throw new IllegalArgumentException("Invalid input: ret.length != 2"); |
| } |
| int value = 0; |
| value |= ret[0]; |
| value = value << 8; |
| value |= ret[1]; |
| return value; |
| } |
| |
| /** |
| * byte[4] convert to integer. |
| * |
| * @param bytes input byte[] |
| * @return integer |
| */ |
| public static int bytesToInt(byte[] bytes) { |
| // compatible to long |
| |
| int length = bytes.length; |
| long r = 0; |
| for (int i = 0; i < length; i++) { |
| r += ((bytes[length - 1 - i] & 0xFF) << (i * 8)); |
| } |
| |
| if (r > Integer.MAX_VALUE) { |
| throw new RuntimeException("Row count is larger than Integer.MAX_VALUE"); |
| } |
| |
| return (int) r; |
| } |
| |
| /** |
| * convert four-bytes byte array cut from parameters to integer. |
| * |
| * @param bytes source bytes which length should be greater than 4 |
| * @param offset position in parameter byte array that conversion result should start |
| * @return integer |
| */ |
| public static int bytesToInt(byte[] bytes, int offset) { |
| if (bytes.length - offset < 4) { |
| throw new IllegalArgumentException("Invalid input: bytes.length - offset < 4"); |
| } |
| |
| int value = 0; |
| // high bit to low |
| for (int i = 0; i < 4; i++) { |
| int shift = (4 - 1 - i) * 8; |
| value += (bytes[offset + i] & 0x000000FF) << shift; |
| } |
| return value; |
| } |
| |
| /** |
| * given a byte array, read width bits from specified position bits and convert it to an integer. |
| * |
| * @param result input byte array |
| * @param pos bit offset rather than byte offset |
| * @param width bit-width |
| * @return integer variable |
| */ |
| public static int bytesToInt(byte[] result, int pos, int width) { |
| int ret = 0; |
| int cnt = pos & 0x07; |
| int index = pos >> 3; |
| while (width > 0) { |
| int m = width + cnt >= 8 ? 8 - cnt : width; |
| width -= m; |
| ret = ret << m; |
| byte y = (byte) (result[index] & (0xff >> cnt)); |
| y = (byte) ((y & 0xff) >>> (8 - cnt - m)); |
| ret = ret | (y & 0xff); |
| cnt += m; |
| if (cnt == 8) { |
| cnt = 0; |
| index++; |
| } |
| } |
| return ret; |
| } |
| |
| /** |
| * convert float to byte array. |
| * |
| * @param x float |
| * @return byte[4] |
| */ |
| public static byte[] floatToBytes(float x) { |
| byte[] b = new byte[4]; |
| int l = Float.floatToIntBits(x); |
| for (int i = 3; i >= 0; i--) { |
| b[i] = (byte) l; |
| l = l >> 8; |
| } |
| return b; |
| } |
| |
| /** |
| * float convert to boolean, then write four bytes to parameter desc start from index:offset. |
| * |
| * @param x float |
| * @param desc byte array be written |
| * @param offset position in desc byte array that conversion result should start |
| */ |
| public static void floatToBytes(float x, byte[] desc, int offset) { |
| if (desc.length - offset < 4) { |
| throw new IllegalArgumentException("Invalid input: desc.length - offset < 4"); |
| } |
| int l = Float.floatToIntBits(x); |
| for (int i = 3 + offset; i >= offset; i--) { |
| desc[i] = (byte) l; |
| l = l >> 8; |
| } |
| } |
| |
| /** |
| * convert byte[4] to float. |
| * |
| * @param b byte[4] |
| * @return float |
| */ |
| public static float bytesToFloat(byte[] b) { |
| if (b.length != 4) { |
| throw new IllegalArgumentException("Invalid input: b.length != 4"); |
| } |
| |
| int l; |
| l = b[3]; |
| l &= 0xff; |
| l |= ((long) b[2] << 8); |
| l &= 0xffff; |
| l |= ((long) b[1] << 16); |
| l &= 0xffffff; |
| l |= ((long) b[0] << 24); |
| return Float.intBitsToFloat(l); |
| } |
| |
| /** |
| * convert four-bytes byte array cut from parameters to float. |
| * |
| * @param b source bytes which length should be greater than 4 |
| * @param offset position in parameter byte array that conversion result should start |
| * @return float |
| */ |
| public static float bytesToFloat(byte[] b, int offset) { |
| if (b.length - offset < 4) { |
| throw new IllegalArgumentException("Invalid input: b.length - offset < 4"); |
| } |
| |
| int l; |
| l = b[offset + 3]; |
| l &= 0xff; |
| l |= ((long) b[offset + 2] << 8); |
| l &= 0xffff; |
| l |= ((long) b[offset + 1] << 16); |
| l &= 0xffffff; |
| l |= ((long) b[offset] << 24); |
| return Float.intBitsToFloat(l); |
| } |
| |
| /** |
| * convert double to byte array. |
| * |
| * @param data double |
| * @return byte[8] |
| */ |
| public static byte[] doubleToBytes(double data) { |
| byte[] bytes = new byte[8]; |
| long value = Double.doubleToLongBits(data); |
| for (int i = 7; i >= 0; i--) { |
| bytes[i] = (byte) value; |
| value = value >> 8; |
| } |
| return bytes; |
| } |
| |
| /** |
| * convert double to byte into the given byte array started from offset. |
| * |
| * @param d input double |
| * @param bytes target byte[] |
| * @param offset start pos |
| */ |
| public static void doubleToBytes(double d, byte[] bytes, int offset) { |
| if (bytes.length - offset < 8) { |
| throw new IllegalArgumentException("Invalid input: bytes.length - offset < 8"); |
| } |
| |
| long value = Double.doubleToLongBits(d); |
| for (int i = 7; i >= 0; i--) { |
| bytes[offset + i] = (byte) value; |
| value = value >> 8; |
| } |
| } |
| |
| /** |
| * convert byte array to double. |
| * |
| * @param bytes byte[8] |
| * @return double |
| */ |
| public static double bytesToDouble(byte[] bytes) { |
| long value = bytes[7]; |
| value &= 0xff; |
| value |= ((long) bytes[6] << 8); |
| value &= 0xffff; |
| value |= ((long) bytes[5] << 16); |
| value &= 0xffffff; |
| value |= ((long) bytes[4] << 24); |
| value &= 0xffffffffL; |
| value |= ((long) bytes[3] << 32); |
| value &= 0xffffffffffL; |
| value |= ((long) bytes[2] << 40); |
| value &= 0xffffffffffffL; |
| value |= ((long) bytes[1] << 48); |
| value &= 0xffffffffffffffL; |
| value |= ((long) bytes[0] << 56); |
| return Double.longBitsToDouble(value); |
| } |
| |
| /** |
| * convert eight-bytes byte array cut from parameters to double. |
| * |
| * @param bytes source bytes which length should be greater than 8 |
| * @param offset position in parameter byte array that conversion result should start |
| * @return double |
| */ |
| public static double bytesToDouble(byte[] bytes, int offset) { |
| if (bytes.length - offset < 8) { |
| throw new IllegalArgumentException("Invalid input: bytes.length - offset < 8"); |
| } |
| long value = bytes[offset + 7]; |
| value &= 0xff; |
| value |= ((long) bytes[offset + 6] << 8); |
| value &= 0xffff; |
| value |= ((long) bytes[offset + 5] << 16); |
| value &= 0xffffff; |
| value |= ((long) bytes[offset + 4] << 24); |
| value &= 0xffffffffL; |
| value |= ((long) bytes[offset + 3] << 32); |
| value &= 0xffffffffffL; |
| value |= ((long) bytes[offset + 2] << 40); |
| value &= 0xffffffffffffL; |
| value |= ((long) bytes[offset + 1] << 48); |
| value &= 0xffffffffffffffL; |
| value |= ((long) bytes[offset] << 56); |
| return Double.longBitsToDouble(value); |
| } |
| |
| /** |
| * convert boolean to byte[1]. |
| * |
| * @param x boolean |
| * @return byte[] |
| */ |
| public static byte[] boolToBytes(boolean x) { |
| byte[] b = new byte[1]; |
| if (x) { |
| b[0] = 1; |
| } else { |
| b[0] = 0; |
| } |
| return b; |
| } |
| |
| public static byte boolToByte(boolean x) { |
| if (x) { |
| return 1; |
| } else { |
| return 0; |
| } |
| } |
| |
| public static boolean byteToBool(byte b) { |
| return b == 1; |
| } |
| |
| /** |
| * boolean convert to byte array, then write four bytes to parameter desc start from index:offset. |
| * |
| * @param x input boolean |
| * @param desc byte array be written |
| * @param offset position in desc byte array that conversion result should start |
| * @return byte[1] |
| */ |
| public static byte[] boolToBytes(boolean x, byte[] desc, int offset) { |
| if (x) { |
| desc[offset] = 1; |
| } else { |
| desc[offset] = 0; |
| } |
| return desc; |
| } |
| |
| /** |
| * byte array to boolean. |
| * |
| * @param b input byte[1] |
| * @return boolean |
| */ |
| public static boolean bytesToBool(byte[] b) { |
| if (b.length != 1) { |
| throw new IllegalArgumentException("Invalid input: b.length != 1"); |
| } |
| |
| return b[0] != 0; |
| } |
| |
| /** |
| * convert one-bytes byte array cut from parameters to boolean. |
| * |
| * @param b source bytes which length should be greater than 1 |
| * @param offset position in parameter byte array that conversion result should start |
| * @return boolean |
| */ |
| public static boolean bytesToBool(byte[] b, int offset) { |
| if (b.length - offset < 1) { |
| throw new IllegalArgumentException("Invalid input: b.length - offset < 1"); |
| } |
| return b[offset] != 0; |
| } |
| |
| /** |
| * long to byte array with default converting length 8. It means the length of result byte array |
| * is 8. |
| * |
| * @param num long variable to be converted |
| * @return byte[8] |
| */ |
| public static byte[] longToBytes(long num) { |
| return longToBytes(num, 8); |
| } |
| |
| /** |
| * specify the result array length. then, convert long to Big-Endian byte from low to high. <br> |
| * e.g.<br> |
| * the binary presentation of long number 1000L is {6 bytes equal 0000000} 00000011 11101000<br> |
| * if len = 2, it will return byte array :{00000011 11101000}(Big-Endian) if len = 1, it will |
| * return byte array :{11101000}. |
| * |
| * @param num long variable to be converted |
| * @param len length of result byte array |
| * @return byte array which length equals with parameter len |
| */ |
| public static byte[] longToBytes(long num, int len) { |
| byte[] byteNum = new byte[len]; |
| for (int ix = 0; ix < len; ix++) { |
| byteNum[len - ix - 1] = (byte) ((num >> ix * 8) & 0xFF); |
| } |
| return byteNum; |
| } |
| |
| /** |
| * long convert to byte array, then write four bytes to parameter desc start from index:offset. |
| * |
| * @param num input long variable |
| * @param desc byte array be written |
| * @param offset position in desc byte array that conversion result should start |
| * @return byte array |
| */ |
| public static byte[] longToBytes(long num, byte[] desc, int offset) { |
| for (int ix = 0; ix < 8; ++ix) { |
| int i = 64 - (ix + 1) * 8; |
| desc[ix + offset] = (byte) ((num >> i) & 0xff); |
| } |
| return desc; |
| } |
| |
| /** |
| * convert a long to a byte array which length is width, then copy this array to the parameter |
| * result from pos. |
| * |
| * @param srcNum input long variable. All but the lowest {@code width} bits are 0. |
| * @param result byte array to convert |
| * @param pos start position |
| * @param width bit-width |
| */ |
| public static void longToBytes(long srcNum, byte[] result, int pos, int width) { |
| int cnt = pos & 0x07; |
| int index = pos >> 3; |
| try { |
| while (width > 0) { |
| int m = width + cnt >= 8 ? 8 - cnt : width; |
| width -= m; |
| int mask = 1 << (8 - cnt); |
| cnt += m; |
| byte y = (byte) (srcNum >>> width); |
| y = (byte) (y << (8 - cnt)); |
| mask = ~(mask - (1 << (8 - cnt))); |
| result[index] = (byte) (result[index] & mask | y); |
| srcNum = srcNum & ~(-1L << width); |
| if (cnt == 8) { |
| index++; |
| cnt = 0; |
| } |
| } |
| } catch (Exception e) { |
| LOG.error( |
| "tsfile-common BytesUtils: cannot convert a long {} to a byte array, " |
| + "pos {}, width {}", |
| srcNum, |
| pos, |
| width, |
| e); |
| } |
| } |
| |
| /** |
| * convert byte array to long with default length 8. namely. |
| * |
| * @param byteNum input byte array |
| * @return long |
| */ |
| public static long bytesToLong(byte[] byteNum) { |
| return bytesToLong(byteNum, byteNum.length); |
| } |
| |
| /** |
| * specify the input byte array length. then, convert byte array to long value from low to high. |
| * <br> |
| * e.g.<br> |
| * the input byte array is {00000011 11101000}. if len = 2, return 1000 if len = 1, return |
| * 232(only calculate the low byte). |
| * |
| * @param byteNum byte array to be converted |
| * @param len length of input byte array to be converted |
| * @return long |
| */ |
| public static long bytesToLong(byte[] byteNum, int len) { |
| long num = 0; |
| for (int ix = 0; ix < len; ix++) { |
| num <<= 8; |
| num |= (byteNum[ix] & 0xff); |
| } |
| return num; |
| } |
| |
| /** |
| * given a byte array, read width bits from specified pos bits and convert it to an long. |
| * |
| * @param result input byte array |
| * @param pos bit offset rather than byte offset |
| * @param width bit-width |
| * @return long variable |
| */ |
| public static long bytesToLong(byte[] result, int pos, int width) { |
| long ret = 0; |
| int cnt = pos & 0x07; |
| int index = pos >> 3; |
| while (width > 0) { |
| int m = width + cnt >= 8 ? 8 - cnt : width; |
| width -= m; |
| ret = ret << m; |
| byte y = (byte) (result[index] & (0xff >> cnt)); |
| y = (byte) ((y & 0xff) >>> (8 - cnt - m)); |
| ret = ret | (y & 0xff); |
| cnt += m; |
| if (cnt == 8) { |
| cnt = 0; |
| index++; |
| } |
| } |
| return ret; |
| } |
| |
| /** |
| * convert eight-bytes byte array cut from parameters to long. |
| * |
| * @param byteNum source bytes which length should be greater than 8 |
| * @param len length of input byte array to be converted |
| * @param offset position in parameter byte array that conversion result should start |
| * @return long |
| */ |
| public static long bytesToLongFromOffset(byte[] byteNum, int len, int offset) { |
| if (byteNum.length - offset < len) { |
| throw new IllegalArgumentException("Invalid input: byteNum.length - offset < len"); |
| } |
| long num = 0; |
| for (int ix = 0; ix < len; ix++) { |
| num <<= 8; |
| num |= (byteNum[offset + ix] & 0xff); |
| } |
| return num; |
| } |
| |
| /** |
| * convert string to byte array using UTF-8 encoding. |
| * |
| * @param str input string |
| * @return byte array |
| */ |
| public static byte[] stringToBytes(String str) { |
| return str.getBytes(TSFileConfig.STRING_CHARSET); |
| } |
| |
| /** |
| * convert byte array to string using UTF-8 encoding. |
| * |
| * @param byteStr input byte array |
| * @return string |
| */ |
| public static String bytesToString(byte[] byteStr) { |
| return new String(byteStr, TSFileConfig.STRING_CHARSET); |
| } |
| |
| /** |
| * join two byte arrays to one. |
| * |
| * @param a one of byte array |
| * @param b another byte array |
| * @return byte array after joining |
| */ |
| public static byte[] concatByteArray(byte[] a, byte[] b) { |
| byte[] c = new byte[a.length + b.length]; |
| System.arraycopy(a, 0, c, 0, a.length); |
| System.arraycopy(b, 0, c, a.length, b.length); |
| return c; |
| } |
| |
| /** |
| * join a list of byte arrays into one array. |
| * |
| * @param list a list of byte array to join |
| * @return byte array after joining |
| */ |
| public static byte[] concatByteArrayList(List<byte[]> list) { |
| int size = list.size(); |
| int len = 0; |
| for (byte[] cs : list) { |
| len += cs.length; |
| } |
| byte[] result = new byte[len]; |
| int pos = 0; |
| for (int i = 0; i < size; i++) { |
| int l = list.get(i).length; |
| System.arraycopy(list.get(i), 0, result, pos, l); |
| pos += l; |
| } |
| return result; |
| } |
| |
| /** |
| * Return the deepCopy of the given byte array. |
| * |
| * @param src input byte array |
| * @return byte array |
| */ |
| public static byte[] deepCopy(byte[] src) { |
| return subBytes(src, 0, src.length); |
| } |
| |
| /** |
| * cut out specified length byte array from parameter start from input byte array src and return. |
| * |
| * @param src input byte array |
| * @param start start index of src |
| * @param length cut off length |
| * @return byte array |
| */ |
| public static byte[] subBytes(byte[] src, int start, int length) { |
| if ((start + length) > src.length) { |
| return new byte[0]; |
| } |
| if (length <= 0) { |
| return new byte[0]; |
| } |
| byte[] result = new byte[length]; |
| System.arraycopy(src, start, result, 0, length); |
| return result; |
| } |
| |
| /** |
| * get one bit in input integer. the offset is from low to high and start with 0<br> |
| * e.g.<br> |
| * data:1000(00000000 00000000 00000011 11101000), if offset is 4, return 0(111 "0" 1000) if |
| * offset is 9, return 1(00000 "1" 1 11101000). |
| * |
| * @param data input int variable |
| * @param offset bit offset |
| * @return 0 or 1 |
| */ |
| public static int getIntN(int data, int offset) { |
| offset %= 32; |
| if ((data & (1 << (offset))) != 0) { |
| return 1; |
| } else { |
| return 0; |
| } |
| } |
| |
| /** |
| * set one bit in input integer. the offset is from low to high and start with index 0<br> |
| * e.g.<br> |
| * data:1000({00000000 00000000 00000011 11101000}), if offset is 4, value is 1, return |
| * 1016({00000000 00000000 00000011 111 "1" 1000}) if offset is 9, value is 0 return 488({00000000 |
| * 00000000 000000 "0" 1 11101000}) if offset is 0, value is 0 return 1000(no change). |
| * |
| * @param data input int variable |
| * @param offset bit offset |
| * @param value value to set |
| * @return int variable |
| */ |
| public static int setIntN(int data, int offset, int value) { |
| offset %= 32; |
| if (value == 1) { |
| return (data | (1 << (offset))); |
| } else { |
| return (data & ~(1 << (offset))); |
| } |
| } |
| |
| /** |
| * get one bit in input byte. the offset is from high to low and start with 0<br> |
| * e.g.<br> |
| * data:16(00010000), if offset is 3, return 1(000 "1" 0000) if offset is 0, return 0("0" |
| * 0010000). |
| * |
| * @param data input byte variable |
| * @param offset bit offset |
| * @return 0/1 |
| */ |
| public static int getByteN(byte data, int offset) { |
| offset %= 8; |
| if (((0xff & data) & (1 << (7 - offset))) != 0) { |
| return 1; |
| } else { |
| return 0; |
| } |
| } |
| |
| /** |
| * set one bit in input byte. the offset is from high to low and start with index 0<br> |
| * e.g.<br> |
| * data:16(00010000), if offset is 3, value is 0, return 0({000 "0" 0000}) if offset is 6, value |
| * is 1, return 18({00010010}) if offset is 0, value is 0, return 16(no change). |
| * |
| * @param data input byte variable |
| * @param offset bit offset |
| * @param value value to set |
| * @return byte variable |
| */ |
| public static byte setByteN(byte data, int offset, int value) { |
| offset %= 8; |
| if (value == 1) { |
| return (byte) ((0xff & data) | (1 << (7 - offset))); |
| } else { |
| return (byte) ((0xff & data) & ~(1 << (7 - offset))); |
| } |
| } |
| |
| /** |
| * get one bit in input long. the offset is from low to high and start with 0. |
| * |
| * @param data input long variable |
| * @param offset bit offset |
| * @return 0/1 |
| */ |
| public static int getLongN(long data, int offset) { |
| offset %= 64; |
| if ((data & (1L << (offset))) != 0) { |
| return 1; |
| } else { |
| return 0; |
| } |
| } |
| |
| /** |
| * set one bit in input long. the offset is from low to high and start with index 0. |
| * |
| * @param data input long variable |
| * @param offset bit offset |
| * @param value value to set |
| * @return long variable |
| */ |
| public static long setLongN(long data, int offset, int value) { |
| offset %= 64; |
| if (value == 1) { |
| return (data | (1L << (offset))); |
| } else { |
| return (data & ~(1L << (offset))); |
| } |
| } |
| |
| /** |
| * read 8-byte array from an InputStream and convert it to a double number. |
| * |
| * @param in InputStream |
| * @return double |
| * @throws IOException cannot read double from InputStream |
| */ |
| public static double readDouble(InputStream in) throws IOException { |
| byte[] b = safeReadInputStreamToBytes(8, in); |
| return BytesUtils.bytesToDouble(b); |
| } |
| |
| /** |
| * read 4-byte array from an InputStream and convert it to a float number. |
| * |
| * @param in InputStream |
| * @return float |
| * @throws IOException cannot read float from InputStream |
| */ |
| public static float readFloat(InputStream in) throws IOException { |
| byte[] b = safeReadInputStreamToBytes(4, in); |
| return BytesUtils.bytesToFloat(b); |
| } |
| |
| /** |
| * read 1-byte array from an InputStream and convert it to a integer number. |
| * |
| * @param in InputStream |
| * @return boolean |
| * @throws IOException cannot read boolean from InputStream |
| */ |
| public static boolean readBool(InputStream in) throws IOException { |
| byte[] b = safeReadInputStreamToBytes(1, in); |
| return BytesUtils.bytesToBool(b); |
| } |
| |
| /** |
| * read 4-byte array from an InputStream and convert it to a integer number. |
| * |
| * @param in InputStream |
| * @return integer |
| * @throws IOException cannot read int from InputStream |
| */ |
| public static int readInt(InputStream in) throws IOException { |
| byte[] b = safeReadInputStreamToBytes(4, in); |
| return BytesUtils.bytesToInt(b); |
| } |
| |
| /** |
| * read 8-byte array from an InputStream and convert it to a long number. |
| * |
| * @param in InputStream |
| * @return long |
| * @throws IOException cannot read long from InputStream |
| */ |
| public static long readLong(InputStream in) throws IOException { |
| byte[] b = safeReadInputStreamToBytes(8, in); |
| return BytesUtils.bytesToLong(b); |
| } |
| |
| /** |
| * read bytes specified length from InputStream safely. |
| * |
| * @param count number of byte to read |
| * @param in InputStream |
| * @return byte array |
| * @throws IOException cannot read from InputStream |
| */ |
| public static byte[] safeReadInputStreamToBytes(int count, InputStream in) throws IOException { |
| byte[] bytes = new byte[count]; |
| int readCount = 0; |
| while (readCount < count) { |
| readCount += in.read(bytes, readCount, count - readCount); |
| } |
| return bytes; |
| } |
| |
| /** |
| * we modify the order of serialization for fitting ByteBuffer.putShort() |
| * |
| * @param number input short number |
| * @return Bytes |
| */ |
| public static byte[] shortToBytes(short number) { |
| int temp = number; |
| byte[] b = new byte[2]; |
| for (int i = b.length - 1; i >= 0; i--) { |
| b[i] = (byte) temp; |
| temp = temp >> 8; |
| } |
| |
| return b; |
| } |
| |
| /** |
| * we modify the order of serialization for fitting ByteBuffer.getShort() |
| * |
| * @param b bytes |
| * @return short number |
| */ |
| public static short bytesToShort(byte[] b) { |
| short s0 = (short) (b[1] & 0xff); |
| short s1 = (short) (b[0] & 0xff); |
| s1 <<= 8; |
| short s = (short) (s0 | s1); |
| return s; |
| } |
| |
| public static Binary valueOf(String value) { |
| return new Binary(stringToBytes(value)); |
| } |
| } |