Merge branch 'bdf-javadocs' into 'master'

Add BDF javadocs

See merge request briar/briar!1801
This commit is contained in:
Torsten Grote
2023-08-07 14:16:22 +00:00
9 changed files with 298 additions and 0 deletions

View File

@@ -31,6 +31,12 @@ public abstract class BdfMessageValidator implements MessageValidator {
protected final Clock clock;
protected final boolean canonical;
/**
* Transitional alternative to
* {@link #BdfMessageValidator(ClientHelper, MetadataEncoder, Clock)} that
* accepts messages in non-canonical form, for backward compatibility.
*/
@Deprecated
protected BdfMessageValidator(ClientHelper clientHelper,
MetadataEncoder metadataEncoder, Clock clock, boolean canonical) {
this.clientHelper = clientHelper;

View File

@@ -49,6 +49,15 @@ public interface ClientHelper {
BdfList getMessageAsList(Transaction txn, MessageId m) throws DbException,
FormatException;
/**
* Transitional alternative to
* {@link #getMessageAsList(Transaction, MessageId)} that allows the
* message to be in non-canonical form, for backward compatibility.
*
* @param canonical True if the message must be in canonical form (a
* {@link FormatException} will be thrown if it's not.
*/
@Deprecated
BdfList getMessageAsList(Transaction txn, MessageId m, boolean canonical)
throws DbException, FormatException;
@@ -109,6 +118,14 @@ public interface ClientHelper {
BdfList toList(Message m) throws FormatException;
/**
* Transitional alternative to {@link #toList(Message)} that allows the
* message to be in non-canonical form, for backward compatibility.
*
* @param canonical True if the message must be in canonical form (a
* {@link FormatException} will be thrown if it's not.
*/
@Deprecated
BdfList toList(Message m, boolean canonical) throws FormatException;
BdfList toList(Author a);

View File

@@ -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).
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* 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<String, Object> {
@@ -80,12 +101,33 @@ public final class BdfDictionary extends TreeMap<String, Object> {
return value == null ? defaultValue : value;
}
/**
* Returns the integer with the specified key.
* <p>
* This method should be used in preference to
* <code>getLong(key).intValue()</code> 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.
* <p>
* This method should be used in preference to
* <code>getOptionalLong(key).intValue()</code> 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<String, Object> {
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.
* <p>
* This method should be used in preference to
* <code>getLong(key, defaultValue).intValue()</code> 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);

View File

@@ -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<String, Object>, Comparable<BdfEntry> {

View File

@@ -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).
* <p>
* 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.
* <p>
* The getX() methods throw {@link FormatException} if the object at the
* specified index is null or does not have the requested type.
* <p>
* 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.
* <p>
* 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.
* <p>
* All of the getters throw {@link FormatException} if the specified index is
* out of range.
*/
@NotThreadSafe
public final class BdfList extends ArrayList<Object> {
@@ -82,12 +105,34 @@ public final class BdfList extends ArrayList<Object> {
return value == null ? defaultValue : value;
}
/**
* Returns the integer at the specified index.
* <p>
* This method should be used in preference to
* <code>getLong(index).intValue()</code> 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.
* <p>
* This method should be used in preference to
* <code>getOptionalLong(index).intValue()</code> 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<Object> {
return value.intValue();
}
/**
* Returns the integer at the specified index, or the given default value
* if the object at the specified index is null.
* <p>
* This method should be used in preference to
* <code>getLong(index, defaultValue).intValue()</code> 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);

View File

@@ -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.
* <p>
* 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;
}

View File

@@ -9,6 +9,12 @@ public interface BdfReaderFactory {
BdfReader createReader(InputStream in);
/**
* Transitional alternative to {@link #createReader(InputStream)} that
* can create a reader that accepts non-canonical input, for backward
* compatibility.
*/
@Deprecated
BdfReader createReader(InputStream in, boolean canonical);
BdfReader createReader(InputStream in, int nestedLimit,

View File

@@ -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;
}

View File

@@ -311,6 +311,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
if (latest == null) {
merged = new TransportProperties(p);
Iterator<String> it = merged.values().iterator();
//noinspection Java8CollectionRemoveIf
while (it.hasNext()) {
if (isNullOrEmpty(it.next())) it.remove();
}