package com.android.dvci.util; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import com.android.dvci.auto.Cfg; public class ByteArray { private static final String TAG = "ByteArray"; /** * Converts a Buffer to a DataInputStream. * * @param buffer * : Input buffer * @return DataInputStream, must be closed by the caller. */ static final DataInputStream BufferToDataInputStream(final byte[] buffer) { final ByteArrayInputStream bufferByteStream = new ByteArrayInputStream(buffer); final DataInputStream bufferDataStream = new DataInputStream(bufferByteStream); try { bufferByteStream.close(); } catch (final IOException ioe) { if (Cfg.EXCEPTION) { Check.log(ioe); } if (Cfg.DEBUG) { Check.log(ioe);//$NON-NLS-1$ } if (Cfg.DEBUG) { Check.log(TAG + " IOException() caught in Utils.BufferToDataInputStream()");//$NON-NLS-1$ } } return bufferDataStream; } /** * Converts a Buffer to a ByteBuffer. * * @param buffer * : Input buffer * @param order * : ByteOrder, LITTLE_ENDIAN or BIG_ENDIAN * @return ByteBuffer. */ public static final ByteBuffer bufferToByteBuffer(final byte[] buffer, final ByteOrder order) { final ByteBuffer retBuff = ByteBuffer.wrap(buffer); retBuff.order(order); return retBuff; } /** * Converts a Buffer to a ByteBuffer with boundary constraints. * * @param buffer * : Input buffer * @param order * : ByteOrder, LITTLE_ENDIAN or BIG_ENDIAN * @param start * : Offset from which to start the buffer creation * @param len * : Length at which the conversion will stop * @return ByteBuffer. */ static final ByteBuffer BufferToByteBuffer(final byte[] buffer, final ByteOrder order, final int start, final int len) { final ByteBuffer retBuff = ByteBuffer.wrap(buffer, start, len); retBuff.order(order); return retBuff; } /** * Converts an InputStream into a buffer. * * @param iStream * : InputStream that will be converted * @param offset * : Used to discard _offset_ bytes from the resource * @return byte[], an array filled with data from InpustrStream. */ public static final byte[] inputStreamToBuffer(final InputStream iStream, final int offset) { try { int i; final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1024); byte[] buffer = new byte[1024]; if (offset > 0) { byte[] discard = new byte[offset]; iStream.read(discard); discard = null; } while ((i = iStream.read(buffer)) != -1) { byteArrayOutputStream.write(buffer, 0, i); } iStream.close(); return byteArrayOutputStream.toByteArray(); } catch (final IOException e) { if (Cfg.EXCEPTION) { Check.log(e); } if (Cfg.DEBUG) { Check.log(e);//$NON-NLS-1$ } if (Cfg.DEBUG) { Check.log(TAG + " IOException() caught in Utils.RawResourceToBuffer()");//$NON-NLS-1$ } return null; } } /** * Compare BufferA with BufferB and return the result. * * @param bufferA * : first buffer * @param offsetA * : index from which to start * @param bufferB * : second buffer * @param offsetB * : index from which to start * @param len * : number of bytes to compare * @return false when the buffers are different, true if they're the sam */ public static boolean equals(final byte[] bufferA, final int offsetA, final byte[] bufferB, final int offsetB, final int len) { if (len < 0) { return false; } if (offsetA < 0 || offsetA > bufferA.length) { return false; } if (offsetB < 0 || offsetB > bufferB.length) { return false; } if (offsetA + len > bufferA.length) { return false; } if (offsetB + len > bufferB.length) { return false; } for (int i = 0; i < len; i++) { if (bufferA[offsetA + i] != bufferB[offsetB + i]) { return false; } } return true; } /** * Search a buffer looking for a token, returns token's index. * * @param buffer * : buffer to search * @param token * : token to look for * @return start position of token into the buffer, -1 if token is not found */ public static int getIndex(final byte[] buffer, final byte[] token) { for (int i = 0; i < buffer.length; i++) { if (equals(buffer, i, token, 0, token.length)) { return i; } } return -1; } /** * Byte array to int. * * @param buffer * the buffer * @param offset * the offset * @return the int */ public static int byteArrayToInt(final byte[] buffer, final int offset) { if (Cfg.DEBUG) { Check.requires(buffer.length >= offset + 4, "short buffer"); //$NON-NLS-1$ } try { final DataBuffer databuffer = new DataBuffer(buffer, offset, buffer.length - offset); final int value = databuffer.readInt(); return value; } catch (final IOException ex) { if (Cfg.EXCEPTION) { Check.log(ex); } if (Cfg.DEBUG) { Check.log(TAG + " Error: " + ex.toString());//$NON-NLS-1$ } } return 0; } public static long byteArrayToLong(final byte[] buffer, final int offset) { if (Cfg.DEBUG) { Check.requires(buffer.length >= offset + 8, "short buffer"); //$NON-NLS-1$ } try { final DataBuffer databuffer = new DataBuffer(buffer, offset, buffer.length - offset); final long value = databuffer.readLong(); return value; } catch (final IOException ex) { if (Cfg.EXCEPTION) { Check.log(ex); } if (Cfg.DEBUG) { Check.log(TAG + " Error: " + ex.toString());//$NON-NLS-1$ } } return 0; } /** * Int to byte array. * * @param value * the value * @return the byte[] */ public static byte[] intToByteArray(final int value) { final byte[] output = new byte[4]; final DataBuffer buffer = new DataBuffer(output, 0, 4); buffer.writeInt(value); return output; } /** * Long to byte array. * * @param value * the value * @return the byte[] */ public static byte[] longToByteArray(final long value) { final byte[] output = new byte[8]; final DataBuffer buffer = new DataBuffer(output, 0, 8); buffer.writeLong(value); return output; } /** * Byte array to hex. * * @param data * the data * @return the string */ public static String byteArrayToHex(final byte[] data) { return byteArrayToHex(data, 0, data.length); } /** * Converte un array di byte in una stringa che ne rappresenta il contenuto * in formato esadecimale. * * @param data * the data * @param offset * the offset * @param length * the length * @return the string */ public static String byteArrayToHex(final byte[] data, final int offset, final int length) { final StringBuffer buf = new StringBuffer(); for (int i = offset; i < offset + length; i++) { int halfbyte = (data[i] >>> 4) & 0x0F; int twohalfs = 0; do { if ((0 <= halfbyte) && (halfbyte <= 9)) { buf.append((char) ('0' + halfbyte)); } else { buf.append((char) ('a' + (halfbyte - 10))); } halfbyte = data[i] & 0x0F; } while (twohalfs++ < 1); } return buf.toString(); } public static byte[] hexStringToByteArray(String s) { int len = s.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16)); } return data; } public static byte[] hexStringToByteArray(final String s, int offset, int len) { byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(s.charAt(i + offset), 16) << 4) + Character.digit(s.charAt(i + offset + 1), 16)); } return data; } /** * Concatena first e second. * * @param first * the first * @param lenFirst * the len first * @param second * the second * @param lenSecond * the len second * @return the byte[] */ public static byte[] concat(final byte[] first, final int lenFirst, final byte[] second, final int lenSecond) { final byte[] sum = new byte[lenFirst + lenSecond]; System.arraycopy(first, 0, sum, 0, lenFirst); System.arraycopy(second, 0, sum, lenFirst, lenSecond); return sum; } /** * Concat. * * @param first * the first * @param second * the second * @return the byte[] */ public static byte[] concat(final byte[] first, final byte[] second) { return concat(first, first.length, second, second.length); } /** * Restituisce una copia della parte dell'array specificata. * * @param payload * the payload * @param offset * the offset * @param length * the length * @return the byte[] */ // COMPAT public static byte[] copy(final byte[] payload, final int offset, final int length) { final byte[] buffer = new byte[length]; System.arraycopy(payload, offset, buffer, 0, length); return buffer; } /** * Duplicate array. * * @param ct * the ct * @return the byte[] */ // COMPAT public static byte[] copy(final byte[] ct) { return copy(ct, 0, ct.length); } /** * Restituisce la codifica default del messaggio paddato di zeri per la * lunghezza specificata. * * @param byteAddress * the byte address * @param len * the len * @return the byte[] */ public static byte[] padByteArray(final byte[] byteAddress, final int len) { final byte[] padAddress = new byte[len]; System.arraycopy(byteAddress, 0, padAddress, 0, Math.min(len, byteAddress.length)); if (Cfg.DEBUG) { Check.ensures(padAddress.length == len, "padByteArray wrong len: " + padAddress.length); //$NON-NLS-1$ } return padAddress; } }