com.hfg.util.ByteUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com_hfg Show documentation
Show all versions of com_hfg Show documentation
com.hfg xml, html, svg, and bioinformatics utility library
package com.hfg.util;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.nio.*;
import com.hfg.util.io.ByteSource;
//------------------------------------------------------------------------------
/**
* General byte utility functions.
*
* @author J. Alex Taylor, hairyfatguy.com
*/
//------------------------------------------------------------------------------
// com.hfg XML/HTML Coding Library
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library 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
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
// [email protected]
//------------------------------------------------------------------------------
public class ByteUtil
{
private static final int BIT1 = 1;
private static final int BIT2 = 2;
private static final int BIT3 = 4;
private static final int BIT4 = 8;
private static final int BIT5 = 16;
private static final int BIT6 = 32;
private static final int BIT7 = 64;
private static final int BIT8 = 128;
private static final byte[] bit = new byte[8];
static
{
bit[0] = BIT1;
bit[1] = BIT2;
bit[2] = BIT3;
bit[3] = BIT4;
bit[4] = BIT5;
bit[5] = BIT6;
bit[6] = BIT7;
bit[7] = (byte)BIT8;
}
private static final char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();
//**************************************************************************
// PUBLIC FUNCTIONS
//**************************************************************************
//--------------------------------------------------------------------------
/**
Returns a string like "10110011" to represent the specified 8-bit byte.
@param inByte the byte to be represented as a bit string
@return the bit string representing the specified byte
*/
public static String getBitString(byte inByte)
{
StringBuilder buffer = new StringBuilder();
buffer.append(((inByte & BIT8) > 0 ? "1" : "0"));
buffer.append(((inByte & BIT7) > 0 ? "1" : "0"));
buffer.append(((inByte & BIT6) > 0 ? "1" : "0"));
buffer.append(((inByte & BIT5) > 0 ? "1" : "0"));
buffer.append(((inByte & BIT4) > 0 ? "1" : "0"));
buffer.append(((inByte & BIT3) > 0 ? "1" : "0"));
buffer.append(((inByte & BIT2) > 0 ? "1" : "0"));
buffer.append(((inByte & BIT1) > 0 ? "1" : "0"));
return buffer.toString();
}
//--------------------------------------------------------------------------
/**
Returns the 8-bit byte corresponding to a specified string like "10110011".
@param inByteString the bit string to be converted to a byte
@return the byte represented by the specified bit string
*/
public static byte getByteFromBitString(String inByteString)
{
int outByte = 0;
for (int i = 0; i < 8; i++)
{
if (inByteString.charAt(i) == '1') outByte += bit[7 - i];
}
return (byte) outByte;
}
//--------------------------------------------------------------------------
/**
Decomposes a byte (8-bits) into two 4-bit bytes.
@param inByte the source byte to be converted
@return the byte array (length of 2) of 4-bit bytes
*/
public static byte[] get4bitBytes(byte inByte)
{
byte[] bytes = new byte[1];
bytes[0] = inByte;
return marshallBytes(bytes, 8, 4);
}
//--------------------------------------------------------------------------
/**
Decomposes a byte[] into 5-bit bytes.
@param inBytes the source byte[] to be converted
@return the byte array of 5-bit bytes
*/
public static byte[] get5bitBytes(byte[] inBytes)
{
return marshallBytes(inBytes, 8, 5);
}
//--------------------------------------------------------------------------
/**
Returns a hex string representing the given byte array.
@param inBytes the source byte array
@return the hexadecimal string represented by the specified byte array.
*/
public static String getHexString(byte[] inBytes)
{
char[] chars = new char[2 * inBytes.length];
for (int i = 0; i < inBytes.length; ++i)
{
chars[2 * i] = HEX_CHARS[(inBytes[i] & 0xF0) >>> 4];
chars[2 * i + 1] = HEX_CHARS[inBytes[i] & 0x0F];
}
return new String(chars);
}
//--------------------------------------------------------------------------
/**
Returns an int from the given byte array.
@param inBytes the source byte array
@param inOffset the offset within the source byte array from which to extract the int
@param inByteOrder the byte order of the int
@return the integer represented by the specified byte array.
*/
public static int getInt(byte[] inBytes, int inOffset, ByteOrder inByteOrder)
{
return ByteBuffer.wrap(inBytes, inOffset, 4).order(inByteOrder).getInt();
}
//--------------------------------------------------------------------------
/**
Returns an int from the given byte array.
@param inStream the InputStream source of bytes
@param inByteOrder the byte order of the int
@return the integer represented by the next 4 bytes from the specified InputStream
*/
public static int getInt(InputStream inStream, ByteOrder inByteOrder)
throws IOException
{
byte[] bytes = new byte[4];
inStream.read(bytes);
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes, 0, 4);
return byteBuffer.order(inByteOrder).getInt();
}
//--------------------------------------------------------------------------
/**
Returns an int from the current position of the specified RandomAccessFile.
@param inRandomAccessFile the source of bytes
@return the integer represented in the next 4 bytes of the specified RandomAccessFile
*/
public static int getInt(RandomAccessFile inRandomAccessFile)
throws IOException
{
byte[] bytes = new byte[4];
inRandomAccessFile.read(bytes);
return ByteBuffer.wrap(bytes, 0, 4).getInt();
}
//--------------------------------------------------------------------------
/**
Returns an int from the current position of the specified RandomAccessFile.
@param inRandomAccessFile the source of bytes
@param inByteOrder the byte order of the int
@return the integer represented in the next 4 bytes of the specified RandomAccessFile
*/
public static int getInt(RandomAccessFile inRandomAccessFile, ByteOrder inByteOrder)
throws IOException
{
byte[] bytes = new byte[4];
inRandomAccessFile.read(bytes);
return ByteBuffer.wrap(bytes, 0, 4).order(inByteOrder).getInt();
}
//--------------------------------------------------------------------------
/**
Returns an int from the current position of the specified ByteSource.
@param inByteSource the source of bytes
@param inByteOrder the byte order of the int
@return the integer represented in the next 4 bytes of the specified ByteSource
*/
public static int getInt(ByteSource inByteSource, ByteOrder inByteOrder)
throws IOException
{
byte[] bytes = new byte[4];
inByteSource.read(bytes);
return ByteBuffer.wrap(bytes, 0, 4).order(inByteOrder).getInt();
}
//--------------------------------------------------------------------------
/**
Returns an long from the current position of the specified RandomAccessFile.
@param inRandomAccessFile the source of bytes
@param inByteOrder the byte order of the long
@return the long represented in the next 8 bytes of the specified RandomAccessFile
*/
public static long getLong(RandomAccessFile inRandomAccessFile, ByteOrder inByteOrder)
throws IOException
{
byte[] bytes = new byte[8];
inRandomAccessFile.read(bytes);
return ByteBuffer.wrap(bytes, 0, 8).order(inByteOrder).getLong();
}
//--------------------------------------------------------------------------
/**
Returns an long from the current position of the specified ByteSource.
@param inByteSource the source of bytes
@param inByteOrder the byte order of the long
@return the long represented in the next 8 bytes of the specified ByteSource
*/
public static long getLong(ByteSource inByteSource, ByteOrder inByteOrder)
throws IOException
{
byte[] bytes = new byte[8];
inByteSource.read(bytes);
return ByteBuffer.wrap(bytes, 0, 8).order(inByteOrder).getLong();
}
//--------------------------------------------------------------------------
/**
Returns a 2-byte int from the given byte array.
@param inBytes the source byte array
@return the 2-byte integer represented in the first two bytes of the specified byte array
*/
public static int get2ByteInt(byte[] inBytes)
{
return get2ByteInt(inBytes, 0);
}
//--------------------------------------------------------------------------
/**
Returns a 2-byte int from the given byte[].
@param inBytes the source byte array
@param inByteOrder the byte order of the int
@return the 2-byte integer represented in the first two bytes of the specified byte array
*/
public static int get2ByteInt(byte[] inBytes, ByteOrder inByteOrder)
throws IOException
{
return get2ByteInt(inBytes, 0, inByteOrder);
}
//--------------------------------------------------------------------------
/**
Returns a 2-byte int from the given byte[].
@param inBytes the source byte array
@param inOffset the offset within the source byte array from which to extract the int
@param inByteOrder the byte order of the int
@return the 2-byte integer represented in the first two bytes of the specified byte array
*/
public static int get2ByteInt(byte[] inBytes, int inOffset, ByteOrder inByteOrder)
throws IOException
{
return (int) ByteBuffer.wrap(inBytes, inOffset, 2).order(inByteOrder).getShort();
}
//--------------------------------------------------------------------------
/**
Returns a 2-byte int from the given InputStream.
@param inStream the InputStream source of bytes
@return the 2-byte integer represented in the next two bytes of the specified stream
*/
public static int get2ByteInt(InputStream inStream)
throws IOException
{
byte[] bytes = new byte[2];
inStream.read(bytes);
return get2ByteInt(bytes, 0);
}
//--------------------------------------------------------------------------
/**
Returns a 2-byte int from the given InputStream.
@param inStream the InputStream source of bytes
@param inByteOrder the byte order of the int
@return the 2-byte integer represented in the next two bytes of the specified stream
*/
public static int get2ByteInt(InputStream inStream, ByteOrder inByteOrder)
throws IOException
{
byte[] bytes = new byte[2];
inStream.read(bytes);
return (int) ByteBuffer.wrap(bytes, 0, 2).order(inByteOrder).getShort();
}
//--------------------------------------------------------------------------
/**
Returns a 2-byte int from the current position of the specified RandomAccessFile.
@param inRandomAccessFile the source of bytes
@param inByteOrder the byte order of the int
@return the 2-byte integer represented in the next two bytes of the specified stream
*/
public static int get2ByteInt(RandomAccessFile inRandomAccessFile, ByteOrder inByteOrder)
throws IOException
{
return get2ByteInt(new ByteSource(inRandomAccessFile), inByteOrder);
}
//--------------------------------------------------------------------------
/**
Returns a 2-byte int from the current position of the specified ByteSource.
@param inByteSource the source of bytes
@param inByteOrder the byte order of the int
@return the 2-byte integer represented in the next two bytes of the specified ByteSource
*/
public static int get2ByteInt(ByteSource inByteSource, ByteOrder inByteOrder)
throws IOException
{
byte[] bytes = new byte[2];
inByteSource.read(bytes);
return (int) ByteBuffer.wrap(bytes, 0, 2).order(inByteOrder).getShort();
}
//--------------------------------------------------------------------------
/**
Returns a 2-byte int from the given byte array.
@param inBytes the source byte array
@param inOffset the offset within the source byte array from which to extract the int
@return the 2-byte integer represented in the first two bytes at the specified offset of the specified byte array
*/
public static int get2ByteInt(byte[] inBytes, int inOffset)
{
return (int) ByteBuffer.wrap(inBytes, inOffset, inOffset + 2).getShort();
}
//--------------------------------------------------------------------------
/**
Returns a 1-byte int from the given byte array.
@param inBytes the source byte array
@param inOffset the offset within the source byte array from which to extract the int
@return the 1-byte integer represented in the first byte of the specified byte array
*/
public static int get1ByteInt(byte[] inBytes, int inOffset)
{
return inBytes[inOffset] & 0xff;
}
//--------------------------------------------------------------------------
/**
Returns a short from the first 2 bytes of the given byte array.
@param inBytes the source byte array
@return the sort represented in the first two bytes of the specified byte array
*/
public static short getShort(byte[] inBytes)
{
return getShort(inBytes, 0);
}
//--------------------------------------------------------------------------
/**
Returns a short from the first 2 bytes of the given byte array.
@param inBytes the source byte array
@param inOffset the offset within the source byte array from which to extract the int
@return the short represented in the first two bytes at the specified offset of the specified byte array
*/
public static short getShort(byte[] inBytes, int inOffset)
{
return (short) (inBytes[inOffset]<<8 | inBytes[inOffset + 1] & 0xFF);
}
//--------------------------------------------------------------------------
/**
Returns a short from the first 2 bytes of the given byte array.
@param inBytes the source byte array
@param inOffset the offset within the source byte array from which to extract the int
@param inByteOrder the byte order of the short
@return the short represented in the first two bytes at the specified offset of the specified byte array
*/
public static short getShort(byte[] inBytes, int inOffset, ByteOrder inByteOrder)
{
return ByteBuffer.wrap(inBytes, inOffset, 2).order(inByteOrder).getShort();
}
//--------------------------------------------------------------------------
/**
Returns a float from the given byte array.
@param inStream the InputStream source of bytes
@param inByteOrder the byte order of the float
@return the float represented by the next 4 bytes from the specified InputStream
*/
public static float getFloat(InputStream inStream, ByteOrder inByteOrder)
throws IOException
{
byte[] bytes = new byte[4];
inStream.read(bytes);
ByteBuffer byteBuffer = ByteBuffer.wrap(bytes, 0, 4);
return byteBuffer.order(inByteOrder).getFloat();
}
//--------------------------------------------------------------------------
/**
Returns a string from the bytes.
@param inBytes the source byte array
@param inOffset the offset within the source byte array from which to extract the String
@param inLength the number of bytes to include in the String
@param inByteOrder the byte order of the string
@return the String represented at the specified offset of the specified byte array
*/
public static String getString(byte[] inBytes, int inOffset, int inLength, ByteOrder inByteOrder)
{
String result = ByteBuffer.wrap(inBytes, inOffset, inLength).order(inByteOrder).asCharBuffer().toString();
int index = result.indexOf(0x00);
if (index >= 0)
{
result = result.substring(0, index);
}
return result;
}
//--------------------------------------------------------------------------
/**
Returns a string from the bytes.
@param inStream the InputStream source of bytes
@param inLength the number of bytes to include in the String
@return the String represented at the specified offset of the specified byte array
*/
public static String getString(InputStream inStream, int inLength)
throws IOException
{
byte[] bytes = new byte[inLength];
inStream.read(bytes);
String result = new String(bytes);
int index = result.indexOf(0x00);
if (index >= 0)
{
result = result.substring(0, index);
}
return result;
}
//--------------------------------------------------------------------------
/**
Returns a String from the current position of the specified RandomAccessFile.
@param inRandomAccessFile the source of bytes
@param inLength the number of bytes to include in the String
@return the String represented at the specified offset of the specified RandomAccessFile
*/
public static String getString(RandomAccessFile inRandomAccessFile, int inLength)
throws IOException
{
byte[] bytes = new byte[inLength];
inRandomAccessFile.read(bytes);
String result = new String(bytes);
int index = result.indexOf(0x00);
if (index >= 0)
{
result = result.substring(0, index);
}
return result;
}
//--------------------------------------------------------------------------
/**
Returns a String from the current position of the specified ByteSource.
@param inByteSource the source of bytes
@param inLength the number of bytes to include in the String
@return the String represented at the specified offset of the specified ByteSource
*/
public static String getString(ByteSource inByteSource, int inLength)
throws IOException
{
byte[] bytes = new byte[inLength];
inByteSource.read(bytes);
String result = new String(bytes);
int index = result.indexOf(0x00);
if (index >= 0)
{
result = result.substring(0, index);
}
return result;
}
//--------------------------------------------------------------------------
/**
Returns a byte[] corresponding to an int.
@param inValue the int to decompose into an array of 4 bytes
@return the byte[] represented by the specified int
*/
public static byte[] getBytesFromInt(int inValue)
throws IOException
{
return ByteBuffer.allocate(4).putInt(inValue).array();
}
//--------------------------------------------------------------------------
/**
Returns a short[] derived from the specified byte[].
@param inBytes the source byte array
@param inNumValues the number of shorts to extract from the source byte array
@param inByteOrder the byte order of the string
@return a short[] derived from the specified byte[]
*/
public static short[] getShortArray(byte[] inBytes, int inNumValues, ByteOrder inByteOrder)
{
short[] array = new short[inNumValues];
for (int i = 0; i < inNumValues; i++)
{
array[i] = getShort(inBytes, i * 2, inByteOrder);
}
return array;
}
//--------------------------------------------------------------------------
/**
Returns a short[] derived from the specified RandomAccessFile.
@param inRandomAccessFile the source of bytes; assumes that the file is already set to the proper position
@param inNumValues the number of shorts to extract from the source byte array
@param inByteOrder the byte order of the string
@return a short[] derived from the specified RandomAccessFile
*/
public static short[] getShortArray(RandomAccessFile inRandomAccessFile, int inNumValues, ByteOrder inByteOrder)
throws IOException
{
return getShortArray(new ByteSource(inRandomAccessFile), inNumValues, inByteOrder);
}
//--------------------------------------------------------------------------
/**
Returns a short[] derived from the specified ByteSource.
@param inByteSource the source of bytes; assumes that the file is already set to the proper position
@param inNumValues the number of shorts to extract from the source byte array
@param inByteOrder the byte order of the string
@return a short[] derived from the specified ByteSource
*/
public static short[] getShortArray(ByteSource inByteSource, int inNumValues, ByteOrder inByteOrder)
throws IOException
{
byte[] bytes = new byte[2 * inNumValues];
inByteSource.read(bytes);
return getShortArray(bytes, inNumValues, inByteOrder);
}
//--------------------------------------------------------------------------
/**
Returns a char[] derived from the specified RandomAccessFile.
@param inRandomAccessFile the source of bytes; assumes that the file is already set to the proper position
@param inNumValues the number of shorts to extract from the source byte array
@return a char[] derived from the specified RandomAccessFile
*/
public static char[] getCharArray(RandomAccessFile inRandomAccessFile, int inNumValues)
throws IOException
{
return getCharArray(new ByteSource(inRandomAccessFile), inNumValues);
}
//--------------------------------------------------------------------------
/**
Returns a char[] derived from the specified ByteSource.
@param inByteSource the source of bytes; assumes that the file is already set to the proper position
@param inNumValues the number of shorts to extract from the source byte array
@return a char[] derived from the specified ByteSource
*/
public static char[] getCharArray(ByteSource inByteSource, int inNumValues)
throws IOException
{
byte[] bytes = new byte[inNumValues];
inByteSource.read(bytes);
char[] chars = new char[inNumValues];
for (int i = 0; i < bytes.length; i++)
{
chars[i] = (char) bytes[i];
}
return chars;
}
//--------------------------------------------------------------------------
/**
Take bytes in one size and chunks them into bytes of the desired size.
@param inBytes the input byte array
@param inOrigBitsPerByte the number of (significant) bits per byte in the input byte array
@param inOutBitsPerByte the desired number of (significant) bits per byte in the output byte array
@return the returned byte array
*/
public static byte[] marshallBytes(byte[] inBytes, int inOrigBitsPerByte, int inOutBitsPerByte)
{
int totalOutBits = inBytes.length * inOrigBitsPerByte;
int outBytesLength;
if (inOrigBitsPerByte > inOutBitsPerByte)
{
outBytesLength = (int) Math.ceil(totalOutBits / (float) inOutBitsPerByte);
}
else
{
outBytesLength = (int) Math.floor(totalOutBits / (float) inOutBitsPerByte);
}
byte[] outBytes = new byte[outBytesLength];
int oldByteIdx = 0;
byte oldByte = inBytes[oldByteIdx];
int oldBit = inOrigBitsPerByte;
for (int newByteIdx = 0; newByteIdx < outBytesLength; newByteIdx++)
{
int outByte = 0;
for (int newBit = inOutBitsPerByte; newBit > 0; newBit--)
{
if ((oldByte & bit[oldBit - 1]) != 0)
{
outByte += bit[newBit - 1];
}
oldBit--;
if (oldBit <= 0)
{
oldByteIdx++;
if (oldByteIdx >= inBytes.length)
{
break;
}
oldByte = inBytes[oldByteIdx];
oldBit = inOrigBitsPerByte;
}
}
outBytes[newByteIdx] = (byte) outByte;
}
return outBytes;
}
}