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;
}
}