package envoy.util; import java.io.*; /** * Defines utility methods related to serialization. * * @author Kai S. K. Engelbart * @since Envoy Common v0.2-alpha */ public final class SerializationUtils { private SerializationUtils() {} /** * 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 */ public static byte[] intToBytes(int n) { return new byte[] { (byte) (n >>> 24), (byte) (n >>> 16), (byte) (n >>> 8), (byte) n }; } /** * 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) { return (bytes[offset] & 0xFF) << 24 | (bytes[offset + 1] & 0xFF) << 16 | (bytes[offset + 2] & 0xFF) << 8 | (bytes[offset + 3] & 0xFF) << 0; } /** * Deserializes an arbitrary {@link Serializable} object from a file. * * @param the type of the serialized object * @param file the file to deserialize from * @param serializedClass the class of the object to deserialize * @return the deserialized object * @throws IOException if something failed while deserializing the object * @throws ClassNotFoundException if the deserialized object can not be linked to a class * @since Envoy Common v0.2-alpha */ public static T read(File file, Class serializedClass) throws IOException, ClassNotFoundException { if (file == null) throw new NullPointerException("File is null"); return read(new FileInputStream(file), serializedClass); } /** * Deserializes an arbitrary {@link Serializable} object from a byte array. * * @param 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 * @throws IOException if something failed while deserializing the object * @throws ClassNotFoundException if the deserialized object can not be linked to a class * @since Envoy Common v0.2-alpha */ public static T read(byte[] bytes, Class serializedClass) throws IOException, ClassNotFoundException { return read(new ByteArrayInputStream(bytes), serializedClass); } /** * Deserializes an arbitrary {@link Serializable} object from a stream. * * @param the type of the serialized object * @param in the {@link InputStream} of a serialized Object * @param serializedClass the object type to convert the deserialized object into * @return the deserialized object * @throws IOException if something failed while deserializing the object * @throws ClassNotFoundException if the deserialized object can not be linked to a class * @since Envoy Common v0.2-alpha */ public static T read(InputStream in, Class serializedClass) throws IOException, ClassNotFoundException { try (ObjectInputStream oin = new ObjectInputStream(in)) { return serializedClass.cast(oin.readObject()); } } /** * Serializes arbitrary objects to a file. * * @param file the file to serialize to * @param objs the objects to serialize * @throws IOException if an error occurred during serialization * @since Envoy Common v0.2-alpha */ public static void write(File file, Object... objs) throws IOException { if (file == null) throw new NullPointerException("File is null"); if (objs == null) throw new NullPointerException("Null array passed to serialize"); if (!file.exists()) { file.getParentFile().mkdirs(); file.createNewFile(); } try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(file))) { for (var obj : objs) out.writeObject(obj); } } /** * Serializes an arbitrary object to a byte array. * * @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 { ByteArrayOutputStream baos = new ByteArrayOutputStream(); try (ObjectOutputStream oout = new ObjectOutputStream(baos)) { oout.writeObject(obj); } return baos.toByteArray(); } /** * Serializes an object and writes it into an output stream preceded by 4 bytes containing the * number of serialized bytes. * * @param obj the object to serialize * @param out the output stream to serialize to * @throws IOException if an error occurred during serialization * @since Envoy Common v0.2-alpha */ public static void writeBytesWithLength(Object obj, OutputStream out) throws IOException { // Serialize object to byte array byte[] objBytes = writeToByteArray(obj); // Get length of byte array in bytes byte[] objLen = intToBytes(objBytes.length); // Write length and byte array out.write(objLen); out.write(objBytes); } }