All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.craft.atom.util.ByteUtil Maven / Gradle / Ivy

There is a newer version: 3.1.2
Show newest version
package io.craft.atom.util;

/**
 * A byte utility class that manipulates bytes.
 * 
 * @author  mindwind
 * @version 1.0, 2011-8-2
 */
public class ByteUtil {

	/**
	 * Returns the first target occurrence position in the source byte array.
	 * 
	 * @param source
	 * @param target
	 * @return if occurs, return the index of the first byte; if it does not occur, -1 is returned.
	 */
	public static int indexOf(final byte[] source, final byte[] target) {
		if (source == null || target == null) {
			return -1;
		}

		if (target.length == 1) {
			return indexOf(source, target[0]);
		} else {
			return indexOf(source, 0, source.length, target, 0, target.length, 0);
		}
	}

	/**
	 * Returns the first target occurrence position in the source byte array.
	 * 
	 * @param source
	 * @param target
	 * @param fromIndex the index to start the search from, inclusive
	 * @return if occurs, return the index of the first byte; if it does not occur, -1 is returned.
	 */
	public static int indexOf(final byte[] source, final byte[] target, int fromIndex) {
		if (source == null || target == null) {
			return -1;
		}
		
		if (target.length == 1) {
			return indexOf(source, target[0], fromIndex);
		} else {
			return ByteUtil.indexOf(source, 0, source.length, target, 0, target.length, fromIndex);
		}
	}
	
	/**
	 * Returns the first target occurrence position in the source byte array.
	 * 
	 * @param source
	 * @param target
	 * @param fromIndex the index to start the search from, inclusive
	 * @param endIndex the index to finish the search at, exclusive
	 * @return if occurs, return the index of the first byte; if it does not occur, -1 is returned.
	 */
	public static int indexOf(final byte[] source, final byte[] target, int fromIndex, int endIndex) {
		if (source == null || target == null || fromIndex >= endIndex) {
			return -1;
		}
		
		if (target.length == 1) {
			return indexOf(source, target[0], fromIndex, endIndex);
		} else {
			int sourceCount = endIndex - fromIndex;
			return ByteUtil.indexOf(source, 0, sourceCount, target, 0, target.length, fromIndex);
		}
	}

	/**
	 * Returns the first target occurrence position in the source byte array
	 * 
	 * @param source
	 * @param target
	 * @return if occurs, return the index of the first byte; if it does not occur, -1 is returned.
	 */
	public static int indexOf(byte[] source, byte target) {
		if (source == null || source.length == 0) {
			return -1;
		}

		for (int i = 0; i < source.length; i++) {
			if (source[i] == target) {
				return i;
			}
		}
		return -1;
	}
	
	/**
	 * Returns the first target occurrence position in the source byte array, search from fromIndex.
	 * 
	 * @param source
	 * @param target
	 * @param fromIndex the index to start the search from, inclusive
	 * @return if occurs, return the index of the first byte; if it does not occur, -1 is returned.
	 */
	public static int indexOf(byte[] source, byte target, int fromIndex) {
		if (source == null || source.length == 0 || fromIndex >= source.length) {
			return -1;
		}
		if (fromIndex < 0) {
			fromIndex = 0;
		}
		
		for (int i = fromIndex; i < source.length; i++) {
			if (source[i] == target) {
				return i;
			}
		}
		return -1;
	}
	
	/**
	 * Returns the first target occurrence position in the source byte array, search from fromIndex.
	 * 
	 * @param source
	 * @param target
	 * @param fromIndex the index to start the search from, inclusive
	 * @param endIndex the index to finish the search at, exclusive
	 * @return if occurs, return the index of the first byte; if it does not occur, -1 is returned.
	 */
	public static int indexOf(byte[] source, byte target, int fromIndex, int endIndex) {
		if (source == null || source.length == 0 || fromIndex >= endIndex) {
			return -1;
		}
		if (fromIndex < 0) {
			fromIndex = 0;
		}
		if (endIndex > source.length) {
			endIndex = source.length;
		}
		
		for (int i = fromIndex; i < endIndex; i++) {
			if (source[i] == target) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * The source is the byte array being searched, and the target is the bytes being searched for.
	 * 
	 * @param source
	 *            the byte array being searched.
	 * @param sourceOffset
	 *            offset of the source byte array.
	 * @param sourceCount
	 *            count of the byte.
	 * @param target
	 *            the bytes being searched for.
	 * @param targetOffset
	 *            offset of the target bytes.
	 * @param targetCount
	 *            count of the target bytes.
	 * @param fromIndex
	 *            the index to begin searching from.
	 */
	private static int indexOf(byte[] source, int sourceOffset, int sourceCount, byte[] target, int targetOffset, int targetCount, int fromIndex) {
		if (fromIndex >= sourceCount) {
			return (targetCount == 0 ? sourceCount : -1);
		}
		if (fromIndex < 0) {
			fromIndex = 0;
		}
		if (targetCount == 0) {
			return fromIndex;
		}

		byte first = target[targetOffset];
		int max = sourceOffset + (sourceCount - targetCount);
		for (int i = sourceOffset + fromIndex; i <= max; i++) {
			/* Look for first character. */
			if (source[i] != first) {
				while (++i <= max && source[i] != first);
			}

			/* Found first character, now look at the rest of v2 */
			if (i <= max) {
				int j = i + 1;
				int end = j + targetCount - 1;
				for (int k = targetOffset + 1; j < end && source[j] == target[k]; j++, k++);

				if (j == end) {
					/* Found whole string. */
					return i - sourceOffset;
				}
			}
		}
		
		return -1;
	}

	/**
	 * Returns a new byte array between start and end index.
	 * 
	 * @param bytes
	 *            to be splited
	 * @param start
	 *            the start index, inclusive.
	 * @param end
	 *            the ending index, exclusive.
	 * @return splited byte array
	 */
	public static byte[] split(byte[] bytes, int start, int end) {
		if (bytes == null) {
			return null;
		}

		if (start < 0) {
			throw new IllegalArgumentException("start < 0");
		}
		if (end > bytes.length) {
			throw new IllegalArgumentException("end > size");
		}
		if (start > end) {
			throw new IllegalArgumentException("start > end");
		}

		int len = end - start;
		byte[] dest = new byte[len];
		System.arraycopy(bytes, start, dest, 0, len);

		return dest;
	}

	/**
	 * Reverse src byte array.
	 * 
	 * @param src
	 * @return the reversed byte array.
	 */
	public static byte[] reverse(byte[] src) {
		if (src == null) {
			return null;
		}

		byte[] dst = new byte[src.length];
		int j = 0;
		for (int i = src.length - 1; i >= 0; i--) {
			dst[j] = src[i];
			j++;
		}
		return dst;
	}

	/**
	 * Returns a hexadecimal representation of the given byte array.
	 * 
	 * @param bytes
	 *            the array to output to an hex string
	 * @return the hex representation as a string
	 */
	public static String asHex(byte[] bytes) {
		return asHex(bytes, null);
	}

	/**
	 * Returns a hexadecimal representation of the given byte array.
	 * 
	 * @param bytes
	 *            the array to output to an hex string
	 * @param separator
	 *            the separator to use between each byte in the output string. If null no char is inserted between each byte value.
	 * @return the hex representation as a string
	 */
	public static String asHex(byte[] bytes, String separator) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < bytes.length; i++) {
			String code = Integer.toHexString(bytes[i] & 0xFF);
			if ((bytes[i] & 0xFF) < 16) {
				sb.append('0');
			}

			sb.append(code);

			if (separator != null && i < bytes.length - 1) {
				sb.append(separator);
			}
		}

		return sb.toString();
	}

	/**
	 * Encodes an integer into up to 4 bytes in network byte order.
	 * 
	 * @param num
	 *            the int to convert to a byte array
	 * @param count
	 *            the number of reserved bytes for the write operation
	 * @return the resulting byte array
	 */
	public static byte[] intToNetworkByteOrder(int num, int count) {
		byte[] buf = new byte[count];
		intToNetworkByteOrder(num, buf, 0, count);

		return buf;
	}

	/**
	 * Encodes an integer into up to 4 bytes in network byte order in the supplied buffer, 
	 * starting at start offset and writing count bytes.
	 * 
	 * @param num the int to convert to a byte array
	 * @param buf the buffer to write the bytes to
	 * @param start the offset from beginning for the write operation
	 * @param count the number of reserved bytes for the write operation
	 * @return the resulting byte array
	 */
	private static void intToNetworkByteOrder(int num, byte[] buf, int start, int count) {
		if (count > 4) {
			throw new IllegalArgumentException("Cannot handle more than 4 bytes");
		}

		for (int i = count - 1; i >= 0; i--) {
			buf[start + i] = (byte) (num & 0xff);
			num >>>= 8;
		}
	}
	
	/**
	 * Returns the integer represented by up to 4 bytes in network byte order.
	 * 
	 * @param buf
	 * @return the integer represented by up to 4 bytes in network byte order.
	 */
	public static int networkByteOrderToInt(byte[] buf) {
		return networkByteOrderToInt(buf, 0, buf.length);
	}

	/**
	 * Returns the integer represented by up to 4 bytes in network byte order.
	 * 
	 * @param buf
	 *            the buffer to read the bytes from
	 * @param start
	 * @param count
	 * @return the integer represented by up to 4 bytes in network byte order.
	 */
	public static int networkByteOrderToInt(byte[] buf, int start, int count) {
		if (count > 4) {
			throw new IllegalArgumentException("Cannot handle more than 4 bytes");
		}

		int result = 0;

		for (int i = 0; i < count; i++) {
			result <<= 8;
			result |= (buf[start + i] & 0xff);
		}

		return result;
	}

	/**
	 * Checks if a byte array is empty [] or null.
	 * 
	 * 
	 * ByteUtil.isEmpty(null)          = true
	 * ByteUtil.isEmpty(new byte[] {}) = true
	 * 
* * @param bytes * @return true if byte array is empty. */ public static boolean isEmpty(byte[] bytes) { return bytes == null || bytes.length == 0; } /** * Get a short from 2 bytes of the given array at offset 0. * * @param b byte array * @return a short */ public static final short bytes2short(byte[] b) { return bytes2short(b, 0); } /** * Get a short from 2 bytes of the given array at specific offset. * * @param b byte array * @param off offset of the byte array * @return a short */ public static final short bytes2short(byte[] b, int off) { return (short) ((b[off] & 0xff) << 8 | (b[off + 1] & 0xff)); } /** * Get a byte array from a short. * * @param s short * @return a byte array */ public static final byte[] short2bytes(short s) { byte[] b = { 0, 0 }; short2bytes(s, b, 0); return b; } /** * Set a byte array at specific offset from a short. * * @param s short * @param b byte array * @param off offset */ public static void short2bytes(short s, byte[] b, int off) { b[off + 1] = (byte) s; b[off + 0] = (byte) (s >>> 8); } /** * Get a int from 4 bytes of the given array at offset 0. * * @param b byte array * @return a short */ public static final int bytes2int(byte[] b) { return bytes2int(b, 0); } /** * Get a int from 4 bytes of the given array at specific offset. * * @param b byte array * @param off offset of the byte array * @return a short */ public static final int bytes2int(byte[] b, int off) { return b[off] << 24 | (b[off + 1] & 0xff) << 16 | (b[off + 2] & 0xff) << 8 | (b[off + 3] & 0xff); } /** * Get a byte array from an int. * * @param i int * @return a byte array */ public static final byte[] int2bytes(int i) { byte[] b = { 0, 0, 0, 0 }; int2bytes(i, b, 0); return b; } /** * Set a byte array at specific offset from an int. * * @param i int * @param b byte array * @param off offset */ public static void int2bytes(int i, byte[] b, int off) { b[off + 3] = (byte) i; b[off + 2] = (byte) (i >>> 8); b[off + 1] = (byte) (i >>> 16); b[off + 0] = (byte) (i >>> 24); } /** * Get a long from 8 bytes of the given array at offset 0. * * @param b byte array * @return a short */ public static final long bytes2long(byte[] b) { return bytes2long(b, 0); } /** * Get a long from 8 bytes of the given array at specific offset. * * @param b byte array * @param off offset of the byte array * @return a short */ public static final long bytes2long(byte[] b, int off) { return (((long) b[off]) << 56 | ((long) (b[off + 1] & 0xff)) << 48 | ((long) (b[off + 2]) & 0xff) << 40 | ((long) (b[off + 3]) & 0xff) << 32 | (((long) b[off + 4]) & 0xff) << 24 | (((long) b[off + 5]) & 0xff) << 16 | (((long) b[off + 6]) & 0xff) << 8 | (((long) b[off + 7]) & 0xff)); } /** * Get a byte array from a long. * * @param l long * @return a byte array */ public static final byte[] long2bytes(long l) { byte[] b = { 0, 0, 0, 0, 0, 0, 0, 0 }; long2bytes(l, b, 0); return b; } /** * Set a byte array at specific offset from a long. * * @param l long * @param b byte array * @param off offset */ public static void long2bytes(long l, byte[] b, int off) { b[off + 7] = (byte) l; b[off + 6] = (byte) (l >>> 8); b[off + 5] = (byte) (l >>> 16); b[off + 4] = (byte) (l >>> 24); b[off + 3] = (byte) (l >>> 32); b[off + 2] = (byte) (l >>> 40); b[off + 1] = (byte) (l >>> 48); b[off + 0] = (byte) (l >>> 56); } /** * Get a float from 4 bytes of the given array. * * @param b byte array. * @return a float. */ public static float bytes2float(byte[] b) { return bytes2float(b, 0); } /** * Get a float from 4 bytes of the given array at specific offset. * * @param b byte array. * @param off offset. * @return a float. */ public static float bytes2float(byte[] b, int off) { int i = b[off] << 24 | (b[off + 1] & 0xff) << 16 | (b[off + 2] & 0xff) << 8 | (b[off + 3] & 0xff); return Float.intBitsToFloat(i); } /** * Get a byte array from a float. * * @param f float * @return a byte array */ public static final byte[] float2bytes(float f) { byte[] b = { 0, 0, 0, 0 }; float2bytes(f, b, 0); return b; } /** * Set a byte array at specific offset from a float. * * @param f float * @param b byte array * @param off offset */ public static void float2bytes(float f, byte[] b, int off) { int i = Float.floatToIntBits(f); b[off + 3] = (byte) i; b[off + 2] = (byte) (i >>> 8); b[off + 1] = (byte) (i >>> 16); b[off + 0] = (byte) (i >>> 24); } /** * Get a double from 8 bytes of the given array. * * @param b byte array. * @return a double. */ public static double bytes2double(byte[] b) { return bytes2double(b, 0); } /** * Get a double from 8 bytes of the given array at specific offset. * * @param b byte array. * @param off offset. * @return a double. */ public static double bytes2double(byte[] b, int off) { long l = (((long) b[off]) << 56 | ((long) (b[off + 1] & 0xff)) << 48 | ((long) (b[off + 2]) & 0xff) << 40 | ((long) (b[off + 3]) & 0xff) << 32 | (((long) b[off + 4]) & 0xff) << 24 | (((long) b[off + 5]) & 0xff) << 16 | (((long) b[off + 6]) & 0xff) << 8 | (((long) b[off + 7]) & 0xff)); return Double.longBitsToDouble(l); } /** * Get a byte array from a double. * * @param d double * @return a byte array */ public static final byte[] double2bytes(double d) { byte[] b = { 0, 0, 0, 0, 0, 0, 0, 0 }; double2bytes(d, b, 0); return b; } /** * Set a byte array at specific offset from a double. * * @param d double * @param b byte array * @param off offset */ public static void double2bytes(double d, byte[] b, int off) { long l = Double.doubleToLongBits(d); b[off + 7] = (byte) l; b[off + 6] = (byte) (l >>> 8); b[off + 5] = (byte) (l >>> 16); b[off + 4] = (byte) (l >>> 24); b[off + 3] = (byte) (l >>> 32); b[off + 2] = (byte) (l >>> 40); b[off + 1] = (byte) (l >>> 48); b[off + 0] = (byte) (l >>> 56); } // ~ ------------------------------------------------------------------------------------------------------------- /** * @deprecated replace by {@link #bytes2short(byte[])} */ public static final int makeIntFromByte2(byte[] b) { return makeIntFromByte2(b, 0); } /** * @deprecated replace by {@link #bytes2short(byte[], int)} */ public static final int makeIntFromByte2(byte[] b, int off) { return (b[off] & 0xff) << 8 | (b[off + 1] & 0xff); } /** * @deprecated replace by {@link #bytes2int(byte[])} */ public static final int makeIntFromByte4(byte[] b) { return makeIntFromByte4(b, 0); } /** * @deprecated replace by {@link #bytes2int(byte[], int)} */ public static final int makeIntFromByte4(byte[] b, int off) { return b[off] << 24 | (b[off + 1] & 0xff) << 16 | (b[off + 2] & 0xff) << 8 | (b[off + 3] & 0xff); } private ByteUtil() { throw new UnsupportedOperationException(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy