2019-12-29 10:47:35 +01:00
|
|
|
package envoy.util;
|
|
|
|
|
2020-01-06 17:41:23 +01:00
|
|
|
import java.io.*;
|
2019-12-29 10:47:35 +01:00
|
|
|
|
|
|
|
/**
|
2020-06-13 18:32:24 +02:00
|
|
|
* Defines utility methods related to serialization.
|
2019-12-30 18:49:48 +01:00
|
|
|
*
|
2019-12-29 10:47:35 +01:00
|
|
|
* @author Kai S. K. Engelbart
|
|
|
|
* @since Envoy Common v0.2-alpha
|
|
|
|
*/
|
2020-08-22 13:37:07 +02:00
|
|
|
public final class SerializationUtils {
|
2019-12-29 10:47:35 +01:00
|
|
|
|
2020-01-03 16:08:07 +01:00
|
|
|
private SerializationUtils() {}
|
|
|
|
|
2020-01-06 17:41:23 +01:00
|
|
|
/**
|
|
|
|
* Converts an integer into a byte array.
|
|
|
|
*
|
|
|
|
* @param n the integer to convert
|
|
|
|
* @return a byte array of length 4
|
|
|
|
* @since Envoy Common v0.2-alpha
|
|
|
|
*/
|
2020-10-19 18:17:51 +02:00
|
|
|
public static byte[] intToBytes(int n) {
|
|
|
|
return new byte[] { (byte) (n >>> 24), (byte) (n >>> 16), (byte) (n >>> 8), (byte) n };
|
|
|
|
}
|
2020-01-06 17:41:23 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts four bytes in byte array to an integer
|
|
|
|
*
|
|
|
|
* @param bytes the bytes to convert from
|
|
|
|
* @param offset the offset at which four bytes are read
|
|
|
|
* @return the converted integer
|
|
|
|
* @since Envoy Common v0.2-alpha
|
|
|
|
*/
|
|
|
|
public static int bytesToInt(byte[] bytes, int offset) {
|
2020-10-19 18:17:51 +02:00
|
|
|
return (bytes[offset] & 0xFF) << 24 | (bytes[offset + 1] & 0xFF) << 16
|
|
|
|
| (bytes[offset + 2] & 0xFF) << 8
|
|
|
|
| (bytes[offset + 3] & 0xFF) << 0;
|
2020-01-06 17:41:23 +01:00
|
|
|
}
|
2019-12-29 10:47:35 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Deserializes an arbitrary {@link Serializable} object from a file.
|
2019-12-30 18:49:48 +01:00
|
|
|
*
|
2020-01-03 16:08:07 +01:00
|
|
|
* @param <T> the type of the serialized object
|
2019-12-30 18:49:48 +01:00
|
|
|
* @param file the file to deserialize from
|
2019-12-29 10:47:35 +01:00
|
|
|
* @param serializedClass the class of the object to deserialize
|
|
|
|
* @return the deserialized object
|
2020-10-19 18:17:51 +02:00
|
|
|
* @throws IOException if something failed while deserializing the object
|
|
|
|
* @throws ClassNotFoundException if the deserialized object can not be linked to a class
|
2019-12-29 10:47:35 +01:00
|
|
|
* @since Envoy Common v0.2-alpha
|
|
|
|
*/
|
2020-10-19 18:17:51 +02:00
|
|
|
public static <T extends Serializable> T read(File file, Class<T> serializedClass)
|
|
|
|
throws IOException, ClassNotFoundException {
|
|
|
|
if (file == null)
|
|
|
|
throw new NullPointerException("File is null");
|
2019-12-29 11:53:16 +01:00
|
|
|
return read(new FileInputStream(file), serializedClass);
|
|
|
|
}
|
|
|
|
|
2019-12-30 18:49:48 +01:00
|
|
|
/**
|
2020-01-03 16:08:07 +01:00
|
|
|
* Deserializes an arbitrary {@link Serializable} object from a byte array.
|
2020-01-06 17:41:23 +01:00
|
|
|
*
|
2020-01-03 16:08:07 +01:00
|
|
|
* @param <T> the type of the serialized object
|
|
|
|
* @param bytes the array in which the serialized object is stored
|
|
|
|
* @param serializedClass the class of the serialized object
|
|
|
|
* @return the deserialized object
|
2020-10-19 18:17:51 +02:00
|
|
|
* @throws IOException if something failed while deserializing the object
|
|
|
|
* @throws ClassNotFoundException if the deserialized object can not be linked to a class
|
2020-01-03 16:08:07 +01:00
|
|
|
* @since Envoy Common v0.2-alpha
|
|
|
|
*/
|
2020-10-19 18:17:51 +02:00
|
|
|
public static <T extends Serializable> T read(byte[] bytes, Class<T> serializedClass)
|
|
|
|
throws IOException, ClassNotFoundException {
|
2020-01-03 16:08:07 +01:00
|
|
|
return read(new ByteArrayInputStream(bytes), serializedClass);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Deserializes an arbitrary {@link Serializable} object from a stream.
|
2020-01-06 17:41:23 +01:00
|
|
|
*
|
2020-01-03 16:08:07 +01:00
|
|
|
* @param <T> the type of the serialized object
|
2019-12-30 18:49:48 +01:00
|
|
|
* @param in the {@link InputStream} of a serialized Object
|
2020-10-19 18:17:51 +02:00
|
|
|
* @param serializedClass the object type to convert the deserialized object into
|
2019-12-30 18:49:48 +01:00
|
|
|
* @return the deserialized object
|
2020-10-19 18:17:51 +02:00
|
|
|
* @throws IOException if something failed while deserializing the object
|
|
|
|
* @throws ClassNotFoundException if the deserialized object can not be linked to a class
|
2019-12-30 18:49:48 +01:00
|
|
|
* @since Envoy Common v0.2-alpha
|
|
|
|
*/
|
2020-10-19 18:17:51 +02:00
|
|
|
public static <T extends Serializable> T read(InputStream in, Class<T> serializedClass)
|
|
|
|
throws IOException, ClassNotFoundException {
|
2019-12-29 11:53:16 +01:00
|
|
|
try (ObjectInputStream oin = new ObjectInputStream(in)) {
|
|
|
|
return serializedClass.cast(oin.readObject());
|
2019-12-29 10:47:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2020-06-13 18:32:24 +02:00
|
|
|
* Serializes arbitrary objects to a file.
|
2019-12-30 18:49:48 +01:00
|
|
|
*
|
2019-12-29 10:47:35 +01:00
|
|
|
* @param file the file to serialize to
|
2020-06-13 18:32:24 +02:00
|
|
|
* @param objs the objects to serialize
|
2019-12-29 10:47:35 +01:00
|
|
|
* @throws IOException if an error occurred during serialization
|
|
|
|
* @since Envoy Common v0.2-alpha
|
|
|
|
*/
|
2020-06-13 18:32:24 +02:00
|
|
|
public static void write(File file, Object... objs) throws IOException {
|
2020-10-19 18:17:51 +02:00
|
|
|
if (file == null)
|
|
|
|
throw new NullPointerException("File is null");
|
|
|
|
if (objs == null)
|
|
|
|
throw new NullPointerException("Null array passed to serialize");
|
2019-12-29 10:47:35 +01:00
|
|
|
if (!file.exists()) {
|
|
|
|
file.getParentFile().mkdirs();
|
|
|
|
file.createNewFile();
|
|
|
|
}
|
|
|
|
try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file))) {
|
2020-10-17 16:40:13 +02:00
|
|
|
for (var obj : objs)
|
2020-06-13 18:32:24 +02:00
|
|
|
out.writeObject(obj);
|
2019-12-29 10:47:35 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-03 16:08:07 +01:00
|
|
|
/**
|
|
|
|
* Serializes an arbitrary object to a byte array.
|
2020-01-06 17:41:23 +01:00
|
|
|
*
|
2020-01-03 16:08:07 +01:00
|
|
|
* @param obj the object to serialize
|
|
|
|
* @return a byte array containing the serialized object
|
|
|
|
* @throws IOException if the serialization failed
|
|
|
|
* @since Envoy Common v0.2-alpha
|
|
|
|
*/
|
|
|
|
public static byte[] writeToByteArray(Object obj) throws IOException {
|
2020-10-17 16:40:13 +02:00
|
|
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
2020-01-03 16:08:07 +01:00
|
|
|
try (ObjectOutputStream oout = new ObjectOutputStream(baos)) {
|
|
|
|
oout.writeObject(obj);
|
|
|
|
}
|
|
|
|
return baos.toByteArray();
|
|
|
|
}
|
|
|
|
|
2019-12-29 10:47:35 +01:00
|
|
|
/**
|
2020-10-19 18:17:51 +02:00
|
|
|
* Serializes an object and writes it into an output stream preceded by 4 bytes containing the
|
|
|
|
* number of serialized bytes.
|
2019-12-30 18:49:48 +01:00
|
|
|
*
|
2019-12-29 10:47:35 +01:00
|
|
|
* @param obj the object to serialize
|
|
|
|
* @param out the output stream to serialize to
|
|
|
|
* @throws IOException if an error occurred during serialization
|
2020-01-03 16:08:07 +01:00
|
|
|
* @since Envoy Common v0.2-alpha
|
2019-12-29 10:47:35 +01:00
|
|
|
*/
|
|
|
|
public static void writeBytesWithLength(Object obj, OutputStream out) throws IOException {
|
|
|
|
// Serialize object to byte array
|
2020-10-17 16:40:13 +02:00
|
|
|
byte[] objBytes = writeToByteArray(obj);
|
2019-12-29 10:47:35 +01:00
|
|
|
|
|
|
|
// Get length of byte array in bytes
|
2020-10-17 16:40:13 +02:00
|
|
|
byte[] objLen = intToBytes(objBytes.length);
|
2019-12-29 10:47:35 +01:00
|
|
|
|
|
|
|
// Write length and byte array
|
|
|
|
out.write(objLen);
|
|
|
|
out.write(objBytes);
|
|
|
|
}
|
2020-03-22 14:52:38 +01:00
|
|
|
}
|