/******************************************************************************* * Copyright (c) 2005-2011, G. Weirich and Elexis * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * G. Weirich - initial implementation * *******************************************************************************/ package ch.rgw.tools; /** * Some helper routines for data conversion, all data is treated in network byte order. */ public class BinConverter { /** * Gets bytes from an array into an integer. * * @param buf * where to get the bytes * @param nOfs * index from where to read the data * @return the 32bit integer */ public final static int byteArrayToInt(byte[] buf, int nOfs){ return (buf[nOfs] << 24) | ((buf[nOfs + 1] & 0x0ff) << 16) | ((buf[nOfs + 2] & 0x0ff) << 8) | (buf[nOfs + 3] & 0x0ff); } // ///////////////////////////////////////////////////////////////////////// /** * Converts an integer to bytes, which are put into an array. * * @param nValue * the 32bit integer to convert * @param buf * the target buf * @param nOfs * where to place the bytes in the buf */ public final static void intToByteArray(int nValue, byte[] buf, int nOfs){ buf[nOfs] = (byte) ((nValue >>> 24) & 0x0ff); buf[nOfs + 1] = (byte) ((nValue >>> 16) & 0x0ff); buf[nOfs + 2] = (byte) ((nValue >>> 8) & 0x0ff); buf[nOfs + 3] = (byte) nValue; } // ///////////////////////////////////////////////////////////////////////// /** * Gets bytes from an array into a long. * * @param buf * where to get the bytes * @param nOfs * index from where to read the data * @return the 64bit integer */ public final static long byteArrayToLong(byte[] buf, int nOfs){ // Looks more complex - but it is faster (at least on 32bit platforms). return ((long) ((buf[nOfs] << 24) | ((buf[nOfs + 1] & 0x0ff) << 16) | ((buf[nOfs + 2] & 0x0ff) << 8) | (buf[nOfs + 3] & 0x0ff)) << 32) | (((buf[nOfs + 4] << 24) | ((buf[nOfs + 5] & 0x0ff) << 16) | ((buf[nOfs + 6] & 0x0ff) << 8) | (buf[nOfs + 7] & 0x0ff)) & 0x0ffffffffL); } // ///////////////////////////////////////////////////////////////////////// /** * Converts a long to bytes, which are put into an array. * * @param lValue * the 64bit integer to convert * @param buf * the target buf * @param nOfs * where to place the bytes in the buf */ public final static void longToByteArray(long lValue, byte[] buf, int nOfs){ int nTmp = (int) (lValue >>> 32); buf[nOfs] = (byte) (nTmp >>> 24); buf[nOfs + 1] = (byte) ((nTmp >>> 16) & 0x0ff); buf[nOfs + 2] = (byte) ((nTmp >>> 8) & 0x0ff); buf[nOfs + 3] = (byte) nTmp; nTmp = (int) lValue; buf[nOfs + 4] = (byte) (nTmp >>> 24); buf[nOfs + 5] = (byte) ((nTmp >>> 16) & 0x0ff); buf[nOfs + 6] = (byte) ((nTmp >>> 8) & 0x0ff); buf[nOfs + 7] = (byte) nTmp; } // ///////////////////////////////////////////////////////////////////////// /** * Converts values from an integer array to a long. * * @param buf * where to get the bytes * @param nOfs * index from where to read the data * @return the 64bit integer */ public final static long intArrayToLong(int[] buf, int nOfs){ return (((long) buf[nOfs]) << 32) | (buf[nOfs + 1] & 0x0ffffffffL); } // ///////////////////////////////////////////////////////////////////////// /** * Converts a long to integers which are put into an array. * * @param lValue * the 64bit integer to convert * @param buf * the target buf * @param nOfs * where to place the bytes in the buf */ public final static void longToIntArray(long lValue, int[] buf, int nOfs){ buf[nOfs] = (int) (lValue >>> 32); buf[nOfs + 1] = (int) lValue; } // ///////////////////////////////////////////////////////////////////////// /** * Makes a long from two integers (treated unsigned). * * @param nLo * lower 32bits * @param nHi * higher 32bits * @return the built long */ public final static long makeLong(int nLo, int nHi){ return (((long) nHi << 32) | (nLo & 0x00000000ffffffffL)); } // ///////////////////////////////////////////////////////////////////////// /** * Gets the lower 32 bits of a long. * * @param lVal * the long integer * @return lower 32 bits */ public final static int longLo32(long lVal){ return (int) lVal; } // ///////////////////////////////////////////////////////////////////////// /** * Gets the higher 32 bits of a long. * * @param lVal * the long integer * @return higher 32 bits */ public final static int longHi32(long lVal){ return (int) (lVal >>> 32); } // ///////////////////////////////////////////////////////////////////////// // our table for hex conversion final static char[] HEXTAB = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; /** * Converts a byte array to a hex string. * * @param data * the byte array * @return the hex string */ public final static String bytesToHexStr(byte[] data){ return bytesToHexStr(data, 0, data.length); } // ///////////////////////////////////////////////////////////////////////// /** * Converts a byte array to a hex string. * * @param data * the byte array * @param nOfs * start index where to get the bytes * @param nLen * number of bytes to convert * @return the hex string */ public final static String bytesToHexStr(byte[] data, int nOfs, int nLen){ StringBuffer sbuf; sbuf = new StringBuffer(); sbuf.setLength(nLen << 1); int nPos = 0; int nC = nOfs + nLen; while (nOfs < nC) { sbuf.setCharAt(nPos++, HEXTAB[(data[nOfs] >> 4) & 0x0f]); sbuf.setCharAt(nPos++, HEXTAB[data[nOfs++] & 0x0f]); } return sbuf.toString(); } // ///////////////////////////////////////////////////////////////////////// /** * Converts a hex string back into a byte array (invalid codes will be skipped). * * @param sHex * hex string * @param data * the target array * @param nSrcOfs * from which character in the string the conversion should begin, remember that * (nSrcPos modulo 2) should equals 0 normally * @param nDstOfs * to store the bytes from which position in the array * @param nLen * number of bytes to extract * @return number of extracted bytes */ public final static int hexStrToBytes(String sHex, byte[] data, int nSrcOfs, int nDstOfs, int nLen){ int nI, nJ, nStrLen, nAvailBytes, nDstOfsBak; byte bActByte; boolean blConvertOK; // check for correct ranges nStrLen = sHex.length(); nAvailBytes = (nStrLen - nSrcOfs) >> 1; if (nAvailBytes < nLen) { nLen = nAvailBytes; } int nOutputCapacity = data.length - nDstOfs; if (nLen > nOutputCapacity) { nLen = nOutputCapacity; } // convert now nDstOfsBak = nDstOfs; for (nI = 0; nI < nLen; nI++) { bActByte = 0; blConvertOK = true; for (nJ = 0; nJ < 2; nJ++) { bActByte <<= 4; char cActChar = sHex.charAt(nSrcOfs++); if ((cActChar >= 'a') && (cActChar <= 'f')) { bActByte |= (byte) (cActChar - 'a') + 10; } else { if ((cActChar >= '0') && (cActChar <= '9')) { bActByte |= (byte) (cActChar - '0'); } else { blConvertOK = false; } } } if (blConvertOK) { data[nDstOfs++] = bActByte; } } return (nDstOfs - nDstOfsBak); } // ///////////////////////////////////////////////////////////////////////// /** * Converts a byte array into a Unicode string. * * @param data * the byte array * @param nOfs * where to begin the conversion * @param nLen * number of bytes to handle * @return the string */ public final static String byteArrayToStr(byte[] data, int nOfs, int nLen){ int nAvailCapacity, nSBufPos; StringBuffer sbuf; // we need two bytes for every character nLen &= ~1; // enough bytes in the buf? nAvailCapacity = data.length - nOfs; if (nAvailCapacity < nLen) { nLen = nAvailCapacity; } sbuf = new StringBuffer(); sbuf.setLength(nLen >> 1); nSBufPos = 0; while (0 < nLen) { sbuf.setCharAt(nSBufPos++, (char) ((data[nOfs] << 8) | (data[nOfs + 1] & 0x0ff))); nOfs += 2; nLen -= 2; } return sbuf.toString(); } }