From 8cd65468406867b1a35120d219e8adbbd82d9817 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Mon, 20 Feb 2023 13:02:00 +0000 Subject: [PATCH] Add javadocs for BDF classes. --- .../bramble/api/data/BdfDictionary.java | 53 +++++++++ .../bramble/api/data/BdfEntry.java | 5 + .../bramble/api/data/BdfList.java | 56 +++++++++ .../bramble/api/data/BdfReader.java | 108 ++++++++++++++++++ .../bramble/api/data/BdfWriter.java | 46 ++++++++ 5 files changed, 268 insertions(+) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfDictionary.java b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfDictionary.java index 11d6f8a08..2124cd14e 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfDictionary.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfDictionary.java @@ -10,6 +10,27 @@ import java.util.TreeMap; import javax.annotation.Nullable; import javax.annotation.concurrent.NotThreadSafe; +/** + * A BDF dictionary contains zero or more key-value pairs, where the keys + * are strings and the values are BDF objects, which may be primitive types + * (null, boolean, integer, float, string, raw) or nested containers (list, + * dictionary). + *

+ * Note that a BDF integer has the same range as a Java long, while a BDF + * float has the same range as a Java double. Method names in this class + * correspond to the Java types. + *

+ * The getX() methods throw {@link FormatException} if the specified key is + * absent, the value is null, or the value does not have the requested type. + *

+ * The getOptionalX() methods return null if the specified key is absent or + * the value is null, or throw {@link FormatException} if the value does not + * have the requested type. + *

+ * The getX() methods that take a default value return the default value if + * the specified key is absent or the value is null, or throw + * {@link FormatException} if the value does not have the requested type. + */ @NotThreadSafe public final class BdfDictionary extends TreeMap { @@ -80,12 +101,33 @@ public final class BdfDictionary extends TreeMap { return value == null ? defaultValue : value; } + /** + * Returns the integer with the specified key. + *

+ * This method should be used in preference to + * getLong(key).intValue() as it checks for + * overflow/underflow. + * + * @throws FormatException if there is no value at the specified key, + * or if the value is null or cannot be represented as a Java int. + */ public Integer getInt(String key) throws FormatException { Integer value = getOptionalInt(key); if (value == null) throw new FormatException(); return value; } + /** + * Returns the integer with the specified key, or null if the key is + * absent or the value is null. + *

+ * This method should be used in preference to + * getOptionalLong(key).intValue() as it checks for + * overflow/underflow. + * + * @throws FormatException if the value at the specified key is not null + * and cannot be represented as a Java int. + */ @Nullable public Integer getOptionalInt(String key) throws FormatException { Long value = getOptionalLong(key); @@ -96,6 +138,17 @@ public final class BdfDictionary extends TreeMap { return value.intValue(); } + /** + * Returns the integer with the specified key, or the given default + * value if the key is absent or the value is null. + *

+ * This method should be used in preference to + * getLong(key, defaultValue).intValue() as it checks for + * overflow/underflow. + * + * @throws FormatException if the value at the specified key is not null + * and cannot be represented as a Java int. + */ public Integer getInt(String key, Integer defaultValue) throws FormatException { Integer value = getOptionalInt(key); diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfEntry.java b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfEntry.java index 3fb4b2678..42b52fc2e 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfEntry.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfEntry.java @@ -6,6 +6,11 @@ import java.util.Map.Entry; import javax.annotation.concurrent.Immutable; +/** + * A convenience class for building {@link BdfDictionary BdfDictionaries} + * via the {@link BdfDictionary#of(Entry[]) factory method}. Entries in + * BdfDictionaries do not have to be BdfEntries. + */ @Immutable @NotNullByDefault public class BdfEntry implements Entry, Comparable { diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfList.java b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfList.java index 6ba6747cc..bce11b079 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfList.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfList.java @@ -12,6 +12,29 @@ import javax.annotation.concurrent.NotThreadSafe; import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE; +/** + * A BDF list contains zero or more BDF objects, which may be primitive types + * (null, boolean, integer, float, string, raw) or nested containers (list, + * dictionary). + *

+ * Note that a BDF integer has the same range as a Java long, while a BDF + * float has the same range as a Java double. Method names in this class + * correspond to the Java types. + *

+ * The getX() methods throw {@link FormatException} if the object at the + * specified index is null or does not have the requested type. + *

+ * The getOptionalX() methods return null if the object at the specified + * index is null, or throw {@link FormatException} if the object does not + * have the requested type. + *

+ * The getX() methods that take a default value return the default value if + * the object at the specified index is null, or throw + * {@link FormatException} if the object does not have the requested type. + *

+ * All of the getters throw {@link FormatException} if the specified index is + * out of range. + */ @NotThreadSafe public final class BdfList extends ArrayList { @@ -82,12 +105,34 @@ public final class BdfList extends ArrayList { return value == null ? defaultValue : value; } + /** + * Returns the integer at the specified index. + *

+ * This method should be used in preference to + * getLong(index).intValue() as it checks for + * overflow/underflow. + * + * @throws FormatException if the index is out of range, or if the + * value at the specified index is null or cannot be represented as a + * Java int. + */ public Integer getInt(int index) throws FormatException { Integer value = getOptionalInt(index); if (value == null) throw new FormatException(); return value; } + /** + * Returns the integer at the specified index, or null if the object at + * the specified index is null. + *

+ * This method should be used in preference to + * getOptionalLong(index).intValue() as it checks for + * overflow/underflow. + * + * @throws FormatException if the index is out of range, or if the value + * at the specified index cannot be represented as a Java int. + */ @Nullable public Integer getOptionalInt(int index) throws FormatException { Long value = getOptionalLong(index); @@ -98,6 +143,17 @@ public final class BdfList extends ArrayList { return value.intValue(); } + /** + * Returns the integer at the specified index, or the given default value + * if the object at the specified index is null. + *

+ * This method should be used in preference to + * getLong(index, defaultValue).intValue() as it checks for + * overflow/underflow. + * + * @throws FormatException if the index is out of range, or if the value + * at the specified index cannot be represented as a Java int. + */ public Integer getInt(int index, Integer defaultValue) throws FormatException { Integer value = getOptionalInt(index); diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfReader.java b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfReader.java index fe710becd..f134d2614 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfReader.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfReader.java @@ -1,70 +1,178 @@ package org.briarproject.bramble.api.data; +import org.briarproject.bramble.api.FormatException; import org.briarproject.nullsafety.NotNullByDefault; import java.io.IOException; +/** + * An interface for reading BDF objects from an input stream. + *

+ * The readX() methods throw {@link FormatException} if the data is not in + * canonical form, but the hasX() and skipX() methods do not check for + * canonical form. + */ @NotNullByDefault public interface BdfReader { int DEFAULT_NESTED_LIMIT = 5; int DEFAULT_MAX_BUFFER_SIZE = 64 * 1024; + /** + * Returns true if the reader has reached the end of its input stream. + */ boolean eof() throws IOException; + /** + * Closes the reader's input stream. + */ void close() throws IOException; + /** + * Returns true if the next object in the input is a BDF null. + */ boolean hasNull() throws IOException; + /** + * Reads a BDF null from the input. + */ void readNull() throws IOException; + /** + * Skips over a BDF null. + */ void skipNull() throws IOException; + /** + * Returns true if the next object in the input is a BDF boolean. + */ boolean hasBoolean() throws IOException; + /** + * Reads a BDF boolean from the input and returns it. + */ boolean readBoolean() throws IOException; + /** + * Skips over a BDF boolean. + */ void skipBoolean() throws IOException; + /** + * Returns true if the next object in the input is a BDF integer, which + * has the same range as a Java long. + */ boolean hasLong() throws IOException; + /** + * Reads a BDF integer from the input and returns it as a Java long. + */ long readLong() throws IOException; + /** + * Skips over a BDF integer. + */ void skipLong() throws IOException; + /** + * Returns true if the next object in the input is a BDF integer and the + * value would fit within the range of a Java int. + */ boolean hasInt() throws IOException; + /** + * Reads a BDF integer from the input and returns it as a Java int. + * + * @throws FormatException if the value exceeds the range of a Java int. + */ int readInt() throws IOException; + /** + * Skips over a BDF integer. + * + * @throws FormatException if the value exceeds the range of a Java int. + */ void skipInt() throws IOException; + /** + * Returns true if the next object in the input is a BDF float, which has + * the same range as a Java double. + */ boolean hasDouble() throws IOException; + /** + * Reads a BDF float from the input and returns it as a Java double. + */ double readDouble() throws IOException; + /** + * Skips over a BDF float. + */ void skipDouble() throws IOException; + /** + * Returns true if the next object in the input is a BDF string. + */ boolean hasString() throws IOException; + /** + * Reads a BDF string from the input. + * + * @throws IOException If the string is not valid UTF-8. + */ String readString() throws IOException; + /** + * Skips over a BDF string without checking whether it is valid UTF-8. + */ void skipString() throws IOException; + /** + * Returns true if the next object in the input is a BDF raw. + */ boolean hasRaw() throws IOException; + /** + * Reads a BDF raw from the input and returns it as a byte array. + */ byte[] readRaw() throws IOException; + /** + * Skips over a BDF raw. + */ void skipRaw() throws IOException; + /** + * Returns true if the next object in the input is a BDF list. + */ boolean hasList() throws IOException; + /** + * Reads a BDF list from the input and returns it. The list's contents + * are parsed and validated. + */ BdfList readList() throws IOException; + /** + * Skips over a BDF list. The list's contents are parsed (to determine + * their length) but not validated. + */ void skipList() throws IOException; + /** + * Returns true if the next object in the input is a BDF dictionary. + */ boolean hasDictionary() throws IOException; + /** + * Reads a BDF dictionary from the input and returns it. The dictionary's + * contents are parsed and validated. + */ BdfDictionary readDictionary() throws IOException; + /** + * Skips over a BDF dictionary. The dictionary's contents are parsed + * (to determine their length) but not validated. + */ void skipDictionary() throws IOException; } diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfWriter.java b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfWriter.java index 1427859a6..63f3a4357 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfWriter.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/data/BdfWriter.java @@ -1,28 +1,74 @@ package org.briarproject.bramble.api.data; +import org.briarproject.bramble.api.FormatException; + import java.io.IOException; import java.util.Collection; import java.util.Map; +/** + * An interface for writing BDF objects to an output stream. The BDF output + * is in canonical form, ie integers and length fields are represented using + * the minimum number of bytes and dictionary keys are unique and sorted in + * lexicographic order. + */ public interface BdfWriter { + /** + * Flushes the writer's output stream. + */ void flush() throws IOException; + /** + * Closes the writer's output stream. + */ void close() throws IOException; + /** + * Writes a BDF null to the output stream. + */ void writeNull() throws IOException; + /** + * Writes a BDF boolean to the output stream. + */ void writeBoolean(boolean b) throws IOException; + /** + * Writes a BDF integer (which has the same range as a Java long) to the + * output stream. + */ void writeLong(long l) throws IOException; + /** + * Writes a BDF float (which has the same range as a Java double) to the + * output stream. + */ void writeDouble(double d) throws IOException; + /** + * Writes a BDF string (which uses UTF-8 encoding) to the output stream. + */ void writeString(String s) throws IOException; + /** + * Writes a BDF raw to the output stream. + */ void writeRaw(byte[] b) throws IOException; + /** + * Writes a BDF list to the output stream. + * + * @throws FormatException if the contents of the given collection cannot + * be represented as (nested) BDF objects. + */ void writeList(Collection c) throws IOException; + /** + * Writes a BDF dictionary to the output stream. + * + * @throws FormatException if the contents of the given map cannot be + * represented as (nested) BDF objects. + */ void writeDictionary(Map m) throws IOException; }