package robombs.clientserver;
import java.util.*;
/**
* A helper class to wrap an array of bytes into one of DataContainers and vice versa. See DataContainer itself
* for more info on how DataContainers are working and being transfered.
*/
public class DataContainerFactory {
/**
* Creates an array for DataContainers from a byte array. Usually, the byte array is what has been transfered
* from client to server or vice versa.
* @param bytes the byte array
* @param zip if true, the data in the array is assumed to be zipped
* @return DataContainer[] the resulting DataContainers
*/
public static DataContainer[] extractContainers(byte[] bytes, boolean zip) {
if (bytes.length > 0) {
List<DataContainer> conts = new ArrayList<DataContainer>();
try {
for (int i = 0; i < bytes.length; ) {
int len = ((bytes[i] & 0xff) << 8) + (bytes[i + 1] & 0xff);
byte[] snip = new byte[len];
System.arraycopy(bytes, i, snip, 0, len);
i += len;
DataContainer dc = new DataContainer(snip, zip);
conts.add(dc);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
DataContainer[] dcs = new DataContainer[conts.size()];
for (int i = 0; i < conts.size(); i++) {
dcs[i] = (DataContainer) conts.get(i);
}
return dcs;
} else {
NetLogger.log("Invalid datagram size: " + bytes.length);
return new DataContainer[0];
}
}
/**
* Create a byte array out of an array of DataContainers.
* @param dcs the containers
* @param zip boolean should the byte array be zipped?
* @return byte[] the resulting byte array.
*/
public static byte[] toByteArray(DataContainer[] dcs, boolean zip) {
int size = 0;
byte[][] cs = new byte[dcs.length][];
for (int i = 0; i < dcs.length; i++) {
byte[] ba = dcs[i].toByteArray(zip);
cs[i] = ba;
size += ba.length;
}
size += 2;
//System.out.println(size);
if (size > 32767) {
throw new RuntimeException("Datagram size must not exceed 32K but is "+size+" bytes!");
}
byte[] res = new byte[size];
int off = 2;
for (int i = 0; i < dcs.length; i++) {
System.arraycopy(cs[i], 0, res, off, cs[i].length);
off += cs[i].length;
}
res[0] = (byte) (size >> 8);
res[1] = (byte) (size & 0xff);
return res;
}
}