package com.openxc.messages.formatters;
import java.io.IOException;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
/**
* Utility functions to read byte arrays from JSON strings.
*/
public class ByteAdapter extends TypeAdapter<byte[]> {
public byte[] read(JsonReader reader) throws IOException {
if (reader.peek() == JsonToken.NULL) {
reader.nextNull();
return null;
}
String payload = reader.nextString();
payload = payload.replace("\"", "").replace("0x", "");
return hexStringToByteArray(payload);
}
public void write(JsonWriter writer, byte[] bytes) throws IOException {
if (bytes == null) {
writer.nullValue();
return;
}
writer.value(byteArrayToHexString(bytes));
}
//adapted from stackoverflow.com/questions/9655181/convert-from-byte-array-to-hex-string-in-java
private static final char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String byteArrayToHexString(byte[] bytes) {
if(bytes == null) {
return "";
}
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
//adapted from stackoverflow.com/questions/140131/convert-a-string-representation-of-a-hex-dump-to-a-byte-array-using-java
//the benefit of this over using a BigInteger(s, 16).toByteArray() is that leading zeroes are not lost
public static byte[] hexStringToByteArray(String s) {
int length = s.length();
byte[] data = new byte[length / 2];
for (int i = 0; i < length; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
}