/* See LICENSE for licensing and NOTICE for copyright. */
package org.cryptacular.util;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import org.cryptacular.StreamException;
/**
* Utilities for working with bytes.
*
* @author Middleware Services
*/
public final class ByteUtil
{
/** Default character set for bytes is UTF-8. */
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
/** ASCII charactr set. */
public static final Charset ASCII_CHARSET = Charset.forName("ASCII");
/** Private constructor of utilty class. */
private ByteUtil() {}
/**
* Converts the big-endian representation of a 32-bit integer to the equivalent integer value.
*
* @param data 4-byte array in big-endian format.
*
* @return Long integer value.
*/
public static int toInt(final byte[] data)
{
return (data[0] << 24) | ((data[1] & 0xff) << 16) | ((data[2] & 0xff) << 8) | (data[3] & 0xff);
}
/**
* Reads 4-bytes from the input stream and converts to a 32-bit integer.
*
* @param in Stream from which to read 4 bytes.
*
* @return Integer value.
*
* @throws StreamException on stream IO errors.
*/
public static int readInt(final InputStream in) throws StreamException
{
try {
return (in.read() << 24) | ((in.read() & 0xff) << 16) | ((in.read() & 0xff) << 8) | (in.read() & 0xff);
} catch (IOException e) {
throw new StreamException(e);
}
}
/**
* Converts the big-endian representation of a 64-bit integer to the equivalent long value.
*
* @param data 8-byte array in big-endian format.
*
* @return Long integer value.
*/
public static long toLong(final byte[] data)
{
return
((long) data[0] << 56) | (((long) data[1] & 0xff) << 48) |
(((long) data[2] & 0xff) << 40) | (((long) data[3] & 0xff) << 32) |
(((long) data[4] & 0xff) << 24) | (((long) data[5] & 0xff) << 16) |
(((long) data[6] & 0xff) << 8) | ((long) data[7] & 0xff);
}
/**
* Reads 8-bytes from the input stream and converts to a 64-bit long integer.
*
* @param in Stream from which to read 8 bytes.
*
* @return Long integer value.
*
* @throws StreamException on stream IO errors.
*/
public static long readLong(final InputStream in) throws StreamException
{
try {
return
((long) in.read() << 56) | (((long) in.read() & 0xff) << 48) |
(((long) in.read() & 0xff) << 40) | (((long) in.read() & 0xff) << 32) |
(((long) in.read() & 0xff) << 24) | (((long) in.read() & 0xff) << 16) |
(((long) in.read() & 0xff) << 8) | ((long) in.read() & 0xff);
} catch (IOException e) {
throw new StreamException(e);
}
}
/**
* Converts an integer into a 4-byte big endian array.
*
* @param value Integer value to convert.
*
* @return 4-byte big-endian representation of integer value.
*/
public static byte[] toBytes(final int value)
{
final byte[] bytes = new byte[4];
toBytes(value, bytes, 0);
return bytes;
}
/**
* Converts an integer into a 4-byte big endian array.
*
* @param value Integer value to convert.
* @param output Array into which bytes are placed.
* @param offset Offset into output array at which output bytes start.
*/
public static void toBytes(final int value, final byte[] output, final int offset)
{
int shift = 24;
for (int i = 0; i < 4; i++) {
output[offset + i] = (byte) (value >> shift);
shift -= 8;
}
}
/**
* Converts a long integer into an 8-byte big endian array.
*
* @param value Long integer value to convert.
*
* @return 8-byte big-endian representation of long integer value.
*/
public static byte[] toBytes(final long value)
{
final byte[] bytes = new byte[8];
toBytes(value, bytes, 0);
return bytes;
}
/**
* Converts an integer into a 8-byte big endian array.
*
* @param value Long value to convert.
* @param output Array into which bytes are placed.
* @param offset Offset into output array at which output bytes start.
*/
public static void toBytes(final long value, final byte[] output, final int offset)
{
int shift = 56;
for (int i = 0; i < 8; i++) {
output[offset + i] = (byte) (value >> shift);
shift -= 8;
}
}
/**
* Converts a byte array into a string in the UTF-8 character set.
*
* @param bytes Byte array to convert.
*
* @return UTF-8 string representation of bytes.
*/
public static String toString(final byte[] bytes)
{
return new String(bytes, DEFAULT_CHARSET);
}
/**
* Converts a byte buffer into a string in the UTF-8 character set.
*
* @param buffer Byte buffer to convert.
*
* @return UTF-8 string representation of bytes.
*/
public static String toString(final ByteBuffer buffer)
{
return toCharBuffer(buffer).toString();
}
/**
* Converts a byte buffer into a character buffer.
*
* @param buffer Byte buffer to convert.
*
* @return Character buffer containing UTF-8 string representation of bytes.
*/
public static CharBuffer toCharBuffer(final ByteBuffer buffer)
{
return DEFAULT_CHARSET.decode(buffer);
}
/**
* Converts a string into bytes in the UTF-8 character set.
*
* @param s String to convert.
*
* @return Byte buffer containing byte representation of string.
*/
public static ByteBuffer toByteBuffer(final String s)
{
return DEFAULT_CHARSET.encode(CharBuffer.wrap(s));
}
/**
* Converts a string into bytes in the UTF-8 character set.
*
* @param s String to convert.
*
* @return Byte array containing byte representation of string.
*/
public static byte[] toBytes(final String s)
{
return s.getBytes(DEFAULT_CHARSET);
}
/**
* Converts a byte buffer into a byte array.
*
* @param buffer Byte buffer to convert.
*
* @return Byte array corresponding to bytes of buffer from current position to limit.
*/
public static byte[] toArray(final ByteBuffer buffer)
{
if (buffer.limit() == buffer.capacity()) {
return buffer.array();
}
final byte[] array = new byte[buffer.limit()];
buffer.position(0);
buffer.get(array);
return array;
}
}