diff --git a/README.md b/README.md index 9ed1599..53f33b5 100644 --- a/README.md +++ b/README.md @@ -48,3 +48,21 @@ class Main { } } ``` + +## Module System +If using the Java Platform Module System (JPMS), then you should add an +**opens** declaration to open any packages containing your records to the +record-net module. For example, suppose I have defined my serializable +records in `com.example.app.data`. Then my `module-info.java` might look like this: + +```java +module com.example.app { + // Require record-net as a dependency: + requires com.andrewlalis.record_net; + // Allow record-net to inspect our records: + opens com.example.app.data to com.andrewlalis.record_net; +} +``` + +For more info on the module system, consult this helpful article: +https://www.oracle.com/corporate/features/understanding-java-9-modules.html diff --git a/src/main/java/com/andrewlalis/record_net/IOUtil.java b/src/main/java/com/andrewlalis/record_net/IOUtil.java index eb40e1a..2a64faf 100644 --- a/src/main/java/com/andrewlalis/record_net/IOUtil.java +++ b/src/main/java/com/andrewlalis/record_net/IOUtil.java @@ -13,12 +13,24 @@ import java.util.UUID; public final class IOUtil { private IOUtil() {} + /** + * Determines if a type is a primitive, or a wrapper type for a primitive. + * @param type The type to check. + * @return True if the type is primitive or a wrapper. + */ public static boolean isPrimitiveOrWrapper(Class type) { final Set> types = Set.of(Byte.class, Short.class, Integer.class, Character.class, Float.class, Double.class, Long.class, Boolean.class); return type.isPrimitive() || types.contains(type); } + /** + * Reads a primitive type from an input stream. + * @param type The type to read. + * @param dIn The stream to read from. + * @return The object representation of the primitive that was read. + * @throws IOException If an error occurs. + */ public static Object readPrimitive(Class type, DataInputStream dIn) throws IOException { if (type.equals(Integer.class) || type.equals(int.class)) return dIn.readInt(); if (type.equals(Short.class) || type.equals(short.class)) return dIn.readShort(); @@ -31,6 +43,12 @@ public final class IOUtil { throw new IllegalArgumentException("Type " + type.getSimpleName() + " is not primitive."); } + /** + * Writes a primitive object to an output stream. + * @param obj The primitive (wrapped in an object) to write. + * @param dOut The stream to write to. + * @throws IOException If an error occurs. + */ public static void writePrimitive(Object obj, DataOutputStream dOut) throws IOException { switch (obj) { case Integer n -> dOut.writeInt(n); @@ -45,25 +63,62 @@ public final class IOUtil { } } + /** + * Reads a string from an input stream. + * @see java.io.DataInput#readUTF() + * @param dIn The stream to read from. + * @return The string that was read. + * @throws IOException If an error occurs. + */ public static String readString(DataInputStream dIn) throws IOException { return dIn.readUTF(); } + /** + * Writes a string to an output stream. + * @see java.io.DataOutput#writeUTF(String) + * @param s The string to write. + * @param dOut The stream to write to. + * @throws IOException If an error occurs. + */ public static void writeString(String s, DataOutputStream dOut) throws IOException { dOut.writeUTF(s); } + /** + * Reads a UUID as two longs being the most significant, and least + * significant bits, respectively. + * @param dIn The input stream to read from. + * @return The UUID that was read. + * @throws IOException If an error occurs. + */ public static UUID readUUID(DataInputStream dIn) throws IOException { long n1 = dIn.readLong(); long n2 = dIn.readLong(); return new UUID(n1, n2); } + /** + * Writes a UUID as two longs with the most significant bits first, and + * then the least significant bits. + * @param uuid The UUID to write. + * @param dOut The output stream to write to. + * @throws IOException If an error occurs. + */ public static void writeUUID(UUID uuid, DataOutputStream dOut) throws IOException { dOut.writeLong(uuid.getMostSignificantBits()); dOut.writeLong(uuid.getLeastSignificantBits()); } + /** + * Reads an enum value from an input stream. Uses the enum value's ordinal + * integer value to convert, or -1 in the case of null. + * @param type The enum type to read. + * @param dIn The stream to read from. + * @return The enum type that was read. + * @param The type of the enum. + * @throws IOException If an error occurs. + */ @SuppressWarnings("unchecked") public static > T readEnum(Class type, DataInputStream dIn) throws IOException { if (!type.isEnum()) throw new IllegalArgumentException("Type must be an enum."); @@ -72,6 +127,13 @@ public final class IOUtil { return (T) type.getEnumConstants()[ordinal]; } + /** + * Writes an enum value to an output stream. Uses the enum value's ordinal + * integer value, or -1 in the case of null. + * @param value The enum value to write. + * @param dOut The stream to write to. + * @throws IOException If an error occurs. + */ public static void writeEnum(Enum value, DataOutputStream dOut) throws IOException { if (value == null) { dOut.writeInt(-1); @@ -80,6 +142,19 @@ public final class IOUtil { } } + /** + * Reads an array of primitive values of a given type from a stream. + *

+ * Note that because Java doesn't support primitive generics yet, we + * return an Object which can be cast to the primitive + * array type you're expecting. + *

+ * @param type The primitive array type. + * @param dIn The stream to read from. + * @return The array that was read. + * @throws IOException If an error occurs. + * @throws IllegalArgumentException If the given type is not a primitive array. + */ public static Object readPrimitiveArray(Class type, DataInputStream dIn) throws IOException { final var cType = type.getComponentType(); if (cType.equals(byte.class)) return readByteArray(dIn); @@ -93,6 +168,13 @@ public final class IOUtil { throw new IllegalArgumentException("Type " + type + " is not a primitive array."); } + /** + * Writes an array of primitive values to a stream. + * @param array The array to write. + * @param dOut The stream to write to. + * @throws IOException If an error occurs. + * @throws IllegalArgumentException If the given type is not a primitive array. + */ public static void writePrimitiveArray(Object array, DataOutputStream dOut) throws IOException { switch (array) { case byte[] a -> writeByteArray(a, dOut); @@ -107,19 +189,19 @@ public final class IOUtil { } } - public static byte[] readByteArray(DataInputStream dIn) throws IOException { + private static byte[] readByteArray(DataInputStream dIn) throws IOException { int length = dIn.readInt(); byte[] array = new byte[length]; dIn.readFully(array); return array; } - public static void writeByteArray(byte[] array, DataOutputStream dOut) throws IOException { + private static void writeByteArray(byte[] array, DataOutputStream dOut) throws IOException { dOut.writeInt(array.length); for (var element : array) dOut.writeByte(element); } - public static short[] readShortArray(DataInputStream dIn) throws IOException { + private static short[] readShortArray(DataInputStream dIn) throws IOException { int length = dIn.readInt(); short[] array = new short[length]; for (int i = 0; i < length; i++) { @@ -128,12 +210,12 @@ public final class IOUtil { return array; } - public static void writeShortArray(short[] array, DataOutputStream dOut) throws IOException { + private static void writeShortArray(short[] array, DataOutputStream dOut) throws IOException { dOut.writeInt(array.length); for (var element : array) dOut.writeShort(element); } - public static int[] readIntArray(DataInputStream dIn) throws IOException { + private static int[] readIntArray(DataInputStream dIn) throws IOException { int length = dIn.readInt(); int[] array = new int[length]; for (int i = 0; i < length; i++) { @@ -142,12 +224,12 @@ public final class IOUtil { return array; } - public static void writeIntArray(int[] array, DataOutputStream dOut) throws IOException { + private static void writeIntArray(int[] array, DataOutputStream dOut) throws IOException { dOut.writeInt(array.length); for (var element : array) dOut.writeInt(element); } - public static long[] readLongArray(DataInputStream dIn) throws IOException { + private static long[] readLongArray(DataInputStream dIn) throws IOException { int length = dIn.readInt(); long[] array = new long[length]; for (int i = 0; i < length; i++) { @@ -156,12 +238,12 @@ public final class IOUtil { return array; } - public static void writeLongArray(long[] array, DataOutputStream dOut) throws IOException { + private static void writeLongArray(long[] array, DataOutputStream dOut) throws IOException { dOut.writeInt(array.length); for (var element : array) dOut.writeLong(element); } - public static float[] readFloatArray(DataInputStream dIn) throws IOException { + private static float[] readFloatArray(DataInputStream dIn) throws IOException { int length = dIn.readInt(); float[] array = new float[length]; for (int i = 0; i < length; i++) { @@ -170,12 +252,12 @@ public final class IOUtil { return array; } - public static void writeFloatArray(float[] array, DataOutputStream dOut) throws IOException { + private static void writeFloatArray(float[] array, DataOutputStream dOut) throws IOException { dOut.writeInt(array.length); for (var element : array) dOut.writeFloat(element); } - public static double[] readDoubleArray(DataInputStream dIn) throws IOException { + private static double[] readDoubleArray(DataInputStream dIn) throws IOException { int length = dIn.readInt(); double[] array = new double[length]; for (int i = 0; i < length; i++) { @@ -184,12 +266,12 @@ public final class IOUtil { return array; } - public static void writeDoubleArray(double[] array, DataOutputStream dOut) throws IOException { + private static void writeDoubleArray(double[] array, DataOutputStream dOut) throws IOException { dOut.writeInt(array.length); for (var element : array) dOut.writeDouble(element); } - public static boolean[] readBooleanArray(DataInputStream dIn) throws IOException { + private static boolean[] readBooleanArray(DataInputStream dIn) throws IOException { int length = dIn.readInt(); boolean[] array = new boolean[length]; for (int i = 0; i < length; i++) { @@ -198,12 +280,12 @@ public final class IOUtil { return array; } - public static void writeBooleanArray(boolean[] array, DataOutputStream dOut) throws IOException { + private static void writeBooleanArray(boolean[] array, DataOutputStream dOut) throws IOException { dOut.writeInt(array.length); for (var element : array) dOut.writeBoolean(element); } - public static char[] readCharArray(DataInputStream dIn) throws IOException { + private static char[] readCharArray(DataInputStream dIn) throws IOException { int length = dIn.readInt(); char[] array = new char[length]; for (int i = 0; i < length; i++) { @@ -212,7 +294,7 @@ public final class IOUtil { return array; } - public static void writeCharArray(char[] array, DataOutputStream dOut) throws IOException { + private static void writeCharArray(char[] array, DataOutputStream dOut) throws IOException { dOut.writeInt(array.length); for (var element : array) dOut.writeChar(element); }