public static byte[] convertBytes(ArrayBuffer buffer) {
Uint8Array array = TypedArrays.createUint8Array(buffer);
byte[] res = new byte[array.length()];
for (int i = 0; i < res.length; i++) {
res[i] = (byte) (array.get(i));
}
return res;
}
/**
* Tranfer of byte arrays is very memory consuming
* --> idea: create a string out of it and transfer it in one chuck.
* But: creating strings with many bytes does not work either properly (in Chrome and FF at least)
* So we create several smaller strings out of the byte array and transfer that one.
*
*/
@SuppressWarnings("UnusedDeclaration")
public class AByteArray_CustomFieldSerializer extends CustomFieldSerializer<AByteArray> {
private static final int CHUNK_SIZE = 50000;
@Override
public void deserializeInstance(SerializationStreamReader serializationStreamReader, AByteArray instance) throws SerializationException {
deserialize(serializationStreamReader, instance);
}
@Override
public void serializeInstance(SerializationStreamWriter serializationStreamWriter, AByteArray instance) throws SerializationException {
serialize(serializationStreamWriter, instance);
}
@SuppressWarnings("unused")
public static void deserialize(SerializationStreamReader reader, AByteArray instance) throws SerializationException {
// nothing here
}
public static void serialize(SerializationStreamWriter writer, AByteArray instance) throws SerializationException {
try {
writeBytes(writer, instance.getBytes());
} catch (UnsupportedEncodingException e) {
ICommonLogger.Logger.error(e.getMessage(), e);
}
}
private static void writeBytes(SerializationStreamWriter writer, byte[] bytes) throws UnsupportedEncodingException, SerializationException {
int length = bytes.length;
writer.writeInt(length);
int pos = 0;
while (pos < length) {
String string = createString(bytes, pos, Math.min(CHUNK_SIZE, length-pos));
writer.writeString(string);
pos += CHUNK_SIZE;
}
}
static String createString(byte[] bytes, int from, int len) throws UnsupportedEncodingException {
byte subBytes[] = getSubArray(bytes, from, len);
return ABase64.createString(ABase64.encode(subBytes));
}
private static byte[] getSubArray(byte[] source, int from, int len) {
byte[] ret = new byte[len];
// System.arraycopy() is slow in GWT
//noinspection ManualArrayCopy
for (int i = 0; i < ret.length; i++) {
ret[i] = source[from+i];
}
return ret;
}
@Override
public boolean hasCustomInstantiateInstance() {
return true;
}
public static AByteArray instantiate(SerializationStreamReader reader) throws SerializationException {
try {
return AByteArray.create(readByteArray(reader));
} catch (UnsupportedEncodingException e) {
ICommonLogger.Logger.error(e.getMessage(), e);
return null;
}
}
private static byte[] readByteArray(SerializationStreamReader reader) throws SerializationException, UnsupportedEncodingException {
int size = reader.readInt();
byte[] bytes = new byte[size];
int pos = 0;
while (pos < size) {
String string = reader.readString();
byte[] subBytes = ABase64.decode(ABase64.getBytes(string));
append(bytes, subBytes, pos);
pos += subBytes.length;
}
return bytes;
}
private static void append(byte[] target, byte[] source, int pos) {
for (int i = 0; i < source.length; i++) {
target[pos + i] = source[i];
}
}
@Override
public AByteArray instantiateInstance(SerializationStreamReader streamReader) throws SerializationException {
return instantiate(streamReader);
}
}
byte[]
if you're worried at all about payload size (byte[] will be on average something like 3-4x to send it though it will compress well at least, whereas base64 is always about 1.3x bigger than the original data)
@niloc132 the code is from 2013. I don't remember exactly anymore what was the reason. Yeah we have our own base64 implementation. But If I remember correctly the problem was in ABase64.createString(byte[] bytes)
which only uses new String(bytes, IStandardEncoding.STANDARD_ENCODING)
public static String createString(byte[] bytes) throws UnsupportedEncodingException {
return new String(bytes, IStandardEncoding.STANDARD_ENCODING);
}
I also remember that System.arraycopy() was always slow in GWT. But this seems to be fixed in the trunk now.