/*
* Copyright (c) 2009 - 2014 Deutsches Elektronen-Synchroton,
* Member of the Helmholtz Association, (DESY), HAMBURG, GERMANY
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 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 Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program (see the file COPYING.LIB for more
* details); if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.dcache.utils;
/**
*
* @since 0.0.3
*/
public final class Bytes {
private Bytes() {
}
/**
* Puts a big-endian representation of {@code value} into <code>bytes</code>
* staring from <code>offset</code>.
* @param bytes
* @param offset
* @param value
* @throws IllegalArgumentException there is no enough room for 8 bytes.
*/
public static void putLong(byte[] bytes, int offset, long value)
throws IllegalArgumentException {
if (bytes.length - offset < 8) {
throw new IllegalArgumentException("not enough space to store long");
}
bytes[offset] = (byte) (value >> 56);
bytes[offset + 1] = (byte) (value >> 48);
bytes[offset + 2] = (byte) (value >> 40);
bytes[offset + 3] = (byte) (value >> 32);
bytes[offset + 4] = (byte) (value >> 24);
bytes[offset + 5] = (byte) (value >> 16);
bytes[offset + 6] = (byte) (value >> 8);
bytes[offset + 7] = (byte) value;
}
/**
* Puts a big-endian representation of {@code value} into <code>bytes</code>
* staring from <code>offset</code>.
* @param bytes
* @param offset
* @param value
* @throws IllegalArgumentException there is no enough room for 4 bytes.
*/
public static void putInt(byte[] bytes, int offset, int value)
throws IllegalArgumentException {
if (bytes.length - offset < 4) {
throw new IllegalArgumentException("not enough space to store int");
}
bytes[offset] = (byte) (value >> 24);
bytes[offset + 1] = (byte) (value >> 16);
bytes[offset + 2] = (byte) (value >> 8);
bytes[offset + 3] = (byte) value;
}
/**
* Returns the big-endian {@code long} value whose byte representation is the 8
* bytes of <code>bytes</code> staring <code>offset</code>.
* @param bytes
* @param offset
* @return long value
*/
public static long getLong(byte[] bytes, int offset) {
return (bytes[offset] & 0xFFL) << 56
| (bytes[offset + 1] & 0xFFL) << 48
| (bytes[offset + 2] & 0xFFL) << 40
| (bytes[offset + 3] & 0xFFL) << 32
| (bytes[offset + 4] & 0xFFL) << 24
| (bytes[offset + 5] & 0xFFL) << 16
| (bytes[offset + 6] & 0xFFL) << 8
| (bytes[offset + 7] & 0xFFL);
}
/**
* Returns the big-endian {@code int} value whose byte representation is the 4
* bytes of <code>bytes</code> staring <code>offset</code>.
* @param bytes
* @param offset
* @return int value
*/
public static int getInt(byte[] bytes, int offset) {
return (bytes[offset] & 0xFF) << 24
| (bytes[offset + 1] & 0xFF) << 16
| (bytes[offset + 2] & 0xFF) << 8
| (bytes[offset + 3] & 0xFF);
}
private final static char[] HEX = new char[] {
'0','1','2','3','4','5','6','7',
'8','9','a','b','c','d','e','f'
};
/**
* Returns a hexadecimal representation of given byte array.
*
* @param bytes whose string representation to return
* @return a string representation of <tt>bytes</tt>
*/
public static String toHexString(byte[] bytes) {
char[] chars = new char[bytes.length*2];
int p = 0;
for(byte b : bytes) {
int i = b & 0xff;
chars[p++] = HEX[i / 16];
chars[p++] = HEX[i%16];
}
return new String(chars);
}
/**
* Create a byte array from the given hexadecimal string.
*
* @param s string to convert
* @return byte array
*/
public static byte[] fromHexString(String s) {
if (s.length() % 2 != 0) {
throw new IllegalArgumentException("The string needs to be even-length: " + s);
}
int len = s.length() / 2;
byte[] bytes = new byte[len];
for (int i = 0; i < len; i++) {
final int charIndex = i * 2;
final int d0 = toDigit(s.charAt(charIndex));
final int d1 = toDigit(s.charAt(charIndex + 1));
bytes[i] = (byte) ((d0 << 4) + d1);
}
return bytes;
}
private static int toDigit(char ch) throws NumberFormatException {
if (ch >= '0' && ch <= '9') {
return ch - '0';
}
if (ch >= 'A' && ch <= 'F') {
return ch - 'A' + 10;
}
if (ch >= 'a' && ch <= 'f') {
return ch - 'a' + 10;
}
throw new NumberFormatException("illegal character '" + ch + "'");
}
}