package iamrescue.communication.messages.codec;
import java.io.UnsupportedEncodingException;
import org.apache.commons.lang.Validate;
public class CodecUtils {
private final static String CHARACTER_ENCODING = "US-ASCII";
public static final int INT_SIZE = Integer.SIZE / 8;
public static final int BYTE_SIZE = Byte.SIZE / 8;
public static final int SHORT_SIZE = Short.SIZE / 8;
private CodecUtils() {
}
/**
* Decode a byte from a buffer
*
* @param buffer
* The buffer we are looking at
* @param off
* The offset into the buffer to start decoding from
* @return The next byte in the buffer
*/
public static byte decodeByte(byte[] buffer, int off) {
return buffer[off];
}
/**
* Decode a byte array from a buffer
*
* @param buffer
* The buffer we are looking at
* @param off
* The offset into the buffer to start decoding from
* @param length
* The number of bytes to read
* @return The next byte array in the buffer
*/
public static byte[] decodeBytes(byte[] buffer, int off, int length) {
byte[] result = new byte[length];
System.arraycopy(buffer, off, result, 0, length);
return result;
}
/**
* Decode a short from a buffer
*
* @param buffer
* The buffer we are looking at
* @param off
* The offset into the buffer to start decoding from
* @return The next short in the buffer
*/
public static short decodeShort(byte[] buffer, int off) {
int result = ((buffer[off] << 8) & 0x0000FF00)
| (buffer[off + 1] & 0x000000FF);
return (short) result;
}
/**
* Decode an int from a buffer
*
* @param buffer
* The buffer we are looking at
* @param off
* The offset into the buffer to start decoding from
* @return The next int in the buffer
*/
public static int decodeInt(byte[] buffer, int off) {
int result = ((buffer[off] << 24) & 0xFF000000)
| ((buffer[off + 1] << 16) & 0x00FF0000)
| ((buffer[off + 2] << 8) & 0x0000FF00)
| (buffer[off + 3] & 0x000000FF);
return result;
}
/**
* Decode a String from a buffer
*
* @param buffer
* The buffer we are looking at
* @param off
* The offset into the buffer to start decoding from
* @param length
* The number of characters in the String
* @return The next String in the buffer
*/
public static String decodeString(byte[] buffer, int off, int length) {
int realLength = Math.min(length, buffer.length - off);
byte[] data = new byte[realLength];
System.arraycopy(buffer, off, data, 0, realLength);
try {
return new String(data, CHARACTER_ENCODING);
} catch (UnsupportedEncodingException e) {
return new String(data);
}
}
/**
* Encode a byte into a byte array
*
* @param value
* The byte to encode
* @return A byte array representation of the input value
*/
public static byte[] encodeByte(byte value) {
return new byte[] { value };
}
/**
* Encode a byte into a buffer
*
* @param value
* The byte to encode
* @param buf
* The buffer to write the result into
* @param off
* The offset to start writing at
*/
public static void encodeByte(int value, byte[] buf, int off) {
buf[off] = (byte) (value & 0xFF);
}
/**
* Encode a byte arrray into a buffer
*
* @param bytes
* The byte array to encode
* @param buf
* The buffer to write the result into
* @param off
* The offset to start writing at
*/
public static void encodeBytes(byte[] bytes, byte[] buf, int off) {
System.arraycopy(bytes, 0, buf, off, bytes.length);
}
/**
* Encode part of a byte array into a buffer
*
* @param bytes
* The byte arrray to encode
* @param bytesOffset
* The offset into bytes to start writing from
* @param bytesLength
* The number of bytes to write
* @param buf
* The buffer to write the result into
* @param off
* The offset to start writing at
*/
public static void encodeBytes(byte[] bytes, int bytesOffset,
int bytesLength, byte[] buf, int off) {
System.arraycopy(bytes, bytesOffset, buf, off, bytesLength);
}
/**
* Encode a short into a byte array
*
* @param value
* The short to encode
* @return A byte array representation of the input value
*/
public static byte[] encodeShort(int value) {
Validate.isTrue(value <= Short.MAX_VALUE);
byte[] result = new byte[2];
result[0] = (byte) (value >> 8 & 0xFF);
result[1] = (byte) (value & 0xFF);
return result;
}
/**
* Encode a short into a buffer
*
* @param value
* The short to encode
* @param buf
* The buffer to write the result into
* @param off
* The offset to start writing at
*/
public static void encodeShort(int value, byte[] buf, int off) {
buf[off] = (byte) (value >> 8 & 0xFF);
buf[off + 1] = (byte) (value & 0xFF);
}
/**
* Encode an int into a byte array
*
* @param value
* The int to encode
* @return A byte array representation of the input value
*/
public static byte[] encodeInt(int value) {
byte[] result = new byte[4];
result[0] = (byte) (value >> 24 & 0xFF);
result[1] = (byte) (value >> 16 & 0xFF);
result[2] = (byte) (value >> 8 & 0xFF);
result[3] = (byte) (value & 0xFF);
return result;
}
/**
* Encode an int into a buffer
*
* @param value
* The int to encode
* @param buf
* The buffer to write the result into
* @param off
* The offset to start writing at
*/
public static void encodeInt(int value, byte[] buf, int off) {
buf[off] = (byte) (value >> 24 & 0xFF);
buf[off + 1] = (byte) (value >> 16 & 0xFF);
buf[off + 2] = (byte) (value >> 8 & 0xFF);
buf[off + 3] = (byte) (value & 0xFF);
}
public static int decodeTimestamp(int b, int timeStep) {
int timeStamp = b & 0xFF;
if (timeStamp < 50 && timeStep > 255)
return 256 + timeStamp;
else
return timeStamp;
}
public static byte[] encodeTimestamp(short timestep) {
return encodeByte((byte) timestep);
}
public static byte[] encodeIntAsByte(int number) {
return encodeIntAsByte(number, Integer.MIN_VALUE, Integer.MAX_VALUE);
}
public static byte[] encodeIntAsByte(int number, int minValue, int maxValue) {
// TODO Auto-generated method stub
return null;
}
private static int byteRange = Byte.MAX_VALUE - Byte.MIN_VALUE;
private static int shortRange = Short.MAX_VALUE - Short.MIN_VALUE;
/**
* Converts a byte to a percentage (between 0.0 and 1.0), where
* Byte.MIN_VALUE is mapped to 0.0 and Byte.MAX_VALUE is mapped to 1.0
*
* @param percentage
* @return
*/
public static double convertByteToPercentage(byte b) {
return (b - Byte.MIN_VALUE) / (double) byteRange;
}
/**
* Converts a percentage (between 0.0 and 1.0) to a byte, where 0.0 is
* mapped to Byte.MIN_VALUE and 1.0 is mapped to Byte.MAX_VALUE
*
* @param percentage
* @return
*/
public static byte convertPercentageToByte(double percentage) {
if (percentage > 1 || percentage < 0)
throw new IllegalArgumentException("Value out of range "
+ percentage);
return (byte) (Math.round(percentage * byteRange) + Byte.MIN_VALUE);
}
public static boolean equals(Number object1, Number object2, double delta) {
double d1 = object1.doubleValue();
double d2 = object2.doubleValue();
if (d1 == d2)
return true;
return (Math.max(d1, d2) / Math.min(d1, d2) - 1) < delta;
}
public static boolean almostEquals(Number number, Number number2, double d,
int i) {
if (!equals(number, number2, d))
return (Math.abs(number.doubleValue() - number2.doubleValue()) < i);
else
return true;
}
/**
* Converts a byte to a percentage (between 0.0 and 1.0), where
* Byte.MIN_VALUE is mapped to 0.0 and Byte.MAX_VALUE is mapped to 1.0
*
* @param percentage
* @return
*/
public static double convertShortToPercentage(short b) {
return (b - Short.MIN_VALUE) / (double) shortRange;
}
/**
* Converts a percentage (between 0.0 and 1.0) to a byte, where 0.0 is
* mapped to Byte.MIN_VALUE and 1.0 is mapped to Byte.MAX_VALUE
*
* @param percentage
* @return
*/
public static short convertPercentageToShort(double percentage) {
if (percentage > 1 || percentage < 0)
throw new IllegalArgumentException("Value out of range "
+ percentage);
return (short) (Math.round(percentage * shortRange) + Short.MIN_VALUE);
}
public static double computePercentage(double value, double min, double max) {
Validate.isTrue(value >= min);
Validate.isTrue(value <= max);
return (value - min) / (max - min);
}
public static double computeValue(double percentage, double min, double max) {
return percentage * (max - min) + min;
}
}