diff --git a/briar-api/src/org/briarproject/api/data/BdfDictionary.java b/briar-api/src/org/briarproject/api/data/BdfDictionary.java index 54a20f6f51b71fffb9f63e5d6b4c1c8e5430d7b3..ed0d5b98f95492b6d77668183053afc6ab963096 100644 --- a/briar-api/src/org/briarproject/api/data/BdfDictionary.java +++ b/briar-api/src/org/briarproject/api/data/BdfDictionary.java @@ -1,13 +1,39 @@ package org.briarproject.api.data; +import org.briarproject.api.Bytes; import org.briarproject.api.FormatException; import java.util.Hashtable; +import java.util.Map; +import java.util.Map.Entry; public class BdfDictionary extends Hashtable<String, Object> { public static final Object NULL_VALUE = new Object(); + /** + * Factory method for constructing dictionaries inline. + * <pre> + * BdfDictionary.of( + * new BdfEntry("foo", foo), + * new BdfEntry("bar", bar) + * ); + * </pre> + */ + public static BdfDictionary of(Entry<String, Object>... entries) { + BdfDictionary d = new BdfDictionary(); + for (Entry<String, Object> e : entries) d.put(e.getKey(), e.getValue()); + return d; + } + + public BdfDictionary() { + super(); + } + + public BdfDictionary(Map<String, Object> m) { + super(m); + } + public Boolean getBoolean(String key) throws FormatException { Object o = get(key); if (o instanceof Boolean) return (Boolean) o; @@ -23,24 +49,32 @@ public class BdfDictionary extends Hashtable<String, Object> { public Long getInteger(String key) throws FormatException { Object o = get(key); if (o instanceof Long) return (Long) o; + if (o instanceof Integer) return ((Integer) o).longValue(); + if (o instanceof Short) return ((Short) o).longValue(); + if (o instanceof Byte) return ((Byte) o).longValue(); throw new FormatException(); } public Long getInteger(String key, Long defaultValue) { Object o = get(key); if (o instanceof Long) return (Long) o; + if (o instanceof Integer) return ((Integer) o).longValue(); + if (o instanceof Short) return ((Short) o).longValue(); + if (o instanceof Byte) return ((Byte) o).longValue(); return defaultValue; } public Double getFloat(String key) throws FormatException { Object o = get(key); if (o instanceof Double) return (Double) o; + if (o instanceof Float) return ((Float) o).doubleValue(); throw new FormatException(); } public Double getFloat(String key, Double defaultValue) { Object o = get(key); if (o instanceof Double) return (Double) o; + if (o instanceof Float) return ((Float) o).doubleValue(); return defaultValue; } @@ -59,12 +93,14 @@ public class BdfDictionary extends Hashtable<String, Object> { public byte[] getRaw(String key) throws FormatException { Object o = get(key); if (o instanceof byte[]) return (byte[]) o; + if (o instanceof Bytes) return ((Bytes) o).getBytes(); throw new FormatException(); } public byte[] getRaw(String key, byte[] defaultValue) { Object o = get(key); if (o instanceof byte[]) return (byte[]) o; + if (o instanceof Bytes) return ((Bytes) o).getBytes(); return defaultValue; } diff --git a/briar-api/src/org/briarproject/api/data/BdfEntry.java b/briar-api/src/org/briarproject/api/data/BdfEntry.java new file mode 100644 index 0000000000000000000000000000000000000000..0168d2a3c5672661b4896ea300ed587765b160bd --- /dev/null +++ b/briar-api/src/org/briarproject/api/data/BdfEntry.java @@ -0,0 +1,32 @@ +package org.briarproject.api.data; + +import java.util.Map.Entry; + +// This class is not thread-safe +public class BdfEntry implements Entry<String, Object> { + + private final String key; + private Object value; + + public BdfEntry(String key, Object value) { + this.key = key; + this.value = value; + } + + @Override + public String getKey() { + return key; + } + + @Override + public Object getValue() { + return value; + } + + @Override + public Object setValue(Object value) { + Object oldValue = this.value; + this.value = value; + return oldValue; + } +} diff --git a/briar-api/src/org/briarproject/api/data/BdfList.java b/briar-api/src/org/briarproject/api/data/BdfList.java index 2caa597ec65103c4da429867c878bfa82ca0ac16..2d58bcd388c0e33cc8f9b2b0c767efb8437bac04 100644 --- a/briar-api/src/org/briarproject/api/data/BdfList.java +++ b/briar-api/src/org/briarproject/api/data/BdfList.java @@ -1,11 +1,32 @@ package org.briarproject.api.data; +import org.briarproject.api.Bytes; import org.briarproject.api.FormatException; +import java.util.Arrays; +import java.util.List; import java.util.Vector; public class BdfList extends Vector<Object> { + /** + * Factory method for constructing lists inline. + * <pre> + * BdfList.of(1, 2, 3); + * </pre> + */ + public static BdfList of(Object... items) { + return new BdfList(Arrays.asList(items)); + } + + public BdfList() { + super(); + } + + public BdfList(List<Object> items) { + super(items); + } + public Boolean getBoolean(int index) throws FormatException { Object o = get(index); if (o instanceof Boolean) return (Boolean) o; @@ -21,24 +42,32 @@ public class BdfList extends Vector<Object> { public Long getInteger(int index) throws FormatException { Object o = get(index); if (o instanceof Long) return (Long) o; + if (o instanceof Integer) return ((Integer) o).longValue(); + if (o instanceof Short) return ((Short) o).longValue(); + if (o instanceof Byte) return ((Byte) o).longValue(); throw new FormatException(); } public Long getInteger(int index, Long defaultValue) { Object o = get(index); if (o instanceof Long) return (Long) o; + if (o instanceof Integer) return ((Integer) o).longValue(); + if (o instanceof Short) return ((Short) o).longValue(); + if (o instanceof Byte) return ((Byte) o).longValue(); return defaultValue; } public Double getFloat(int index) throws FormatException { Object o = get(index); if (o instanceof Double) return (Double) o; + if (o instanceof Float) return ((Float) o).doubleValue(); throw new FormatException(); } public Double getFloat(int index, Double defaultValue) { Object o = get(index); if (o instanceof Double) return (Double) o; + if (o instanceof Float) return ((Float) o).doubleValue(); return defaultValue; } @@ -57,12 +86,14 @@ public class BdfList extends Vector<Object> { public byte[] getRaw(int index) throws FormatException { Object o = get(index); if (o instanceof byte[]) return (byte[]) o; + if (o instanceof Bytes) return ((Bytes) o).getBytes(); throw new FormatException(); } public byte[] getRaw(int index, byte[] defaultValue) { Object o = get(index); if (o instanceof byte[]) return (byte[]) o; + if (o instanceof Bytes) return ((Bytes) o).getBytes(); return defaultValue; } diff --git a/briar-core/src/org/briarproject/data/MetadataEncoderImpl.java b/briar-core/src/org/briarproject/data/MetadataEncoderImpl.java index e70070391bdbcad505ac24eaf7b640e55890fca9..1de4c8ef62e41cb0c538e0ffcb0c58b08cd0eefb 100644 --- a/briar-core/src/org/briarproject/data/MetadataEncoderImpl.java +++ b/briar-core/src/org/briarproject/data/MetadataEncoderImpl.java @@ -1,5 +1,6 @@ package org.briarproject.data; +import org.briarproject.api.Bytes; import org.briarproject.api.FormatException; import org.briarproject.api.data.BdfDictionary; import org.briarproject.api.data.MetadataEncoder; @@ -62,6 +63,7 @@ class MetadataEncoderImpl implements MetadataEncoder { else if (o instanceof Double) encodeFloat(out, (Double) o); else if (o instanceof String) encodeString(out, (String) o); else if (o instanceof byte[]) encodeRaw(out, (byte[]) o); + else if (o instanceof Bytes) encodeRaw(out, ((Bytes) o).getBytes()); else if (o instanceof List) encodeList(out, (List) o); else if (o instanceof Map) encodeDictionary(out, (Map) o); else throw new FormatException(); diff --git a/briar-tests/src/org/briarproject/data/BdfDictionaryTest.java b/briar-tests/src/org/briarproject/data/BdfDictionaryTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0e2c9d8dfae2e9315b74c8e18a29e0a98ad9e501 --- /dev/null +++ b/briar-tests/src/org/briarproject/data/BdfDictionaryTest.java @@ -0,0 +1,65 @@ +package org.briarproject.data; + +import org.briarproject.BriarTestCase; +import org.briarproject.api.Bytes; +import org.briarproject.api.data.BdfDictionary; +import org.briarproject.api.data.BdfEntry; +import org.junit.Test; + +import java.util.Collections; + +import static org.briarproject.api.data.BdfDictionary.NULL_VALUE; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +public class BdfDictionaryTest extends BriarTestCase { + + @Test + public void testConstructors() { + assertEquals(Collections.emptyMap(), new BdfDictionary()); + assertEquals(Collections.singletonMap("foo", NULL_VALUE), + new BdfDictionary(Collections.singletonMap("foo", NULL_VALUE))); + } + + @Test + public void testFactoryMethod() { + assertEquals(Collections.emptyMap(), BdfDictionary.of()); + assertEquals(Collections.singletonMap("foo", NULL_VALUE), + BdfDictionary.of(new BdfEntry("foo", NULL_VALUE))); + } + + @Test + public void testIntegerPromotion() throws Exception { + BdfDictionary d = new BdfDictionary(); + d.put("foo", (byte) 1); + d.put("bar", (short) 2); + d.put("baz", 3); + d.put("bam", 4L); + assertEquals(Long.valueOf(1), d.getInteger("foo")); + assertEquals(Long.valueOf(2), d.getInteger("bar")); + assertEquals(Long.valueOf(3), d.getInteger("baz")); + assertEquals(Long.valueOf(4), d.getInteger("bam")); + } + + @Test + public void testFloatPromotion() throws Exception { + BdfDictionary d = new BdfDictionary(); + d.put("foo", 1F); + d.put("bar", 2D); + assertEquals(Double.valueOf(1), d.getFloat("foo")); + assertEquals(Double.valueOf(2), d.getFloat("bar")); + } + + @Test + public void testByteArrayUnwrapping() throws Exception { + BdfDictionary d = new BdfDictionary(); + d.put("foo", new byte[123]); + d.put("bar", new Bytes(new byte[123])); + byte[] foo = d.getRaw("foo"); + assertEquals(123, foo.length); + assertArrayEquals(new byte[123], foo); + byte[] bar = d.getRaw("bar"); + assertEquals(123, bar.length); + assertArrayEquals(new byte[123], bar); + } +} diff --git a/briar-tests/src/org/briarproject/data/BdfListTest.java b/briar-tests/src/org/briarproject/data/BdfListTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b1954e8164aa61ff17b2543617b7d23a0f0056d5 --- /dev/null +++ b/briar-tests/src/org/briarproject/data/BdfListTest.java @@ -0,0 +1,65 @@ +package org.briarproject.data; + +import org.briarproject.BriarTestCase; +import org.briarproject.api.Bytes; +import org.briarproject.api.data.BdfList; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; + +import static org.briarproject.api.data.BdfDictionary.NULL_VALUE; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; + +public class BdfListTest extends BriarTestCase { + + @Test + public void testConstructors() { + assertEquals(Collections.emptyList(), new BdfList()); + assertEquals(Arrays.asList(1, 2, NULL_VALUE), + new BdfList(Arrays.asList(1, 2, NULL_VALUE))); + } + + @Test + public void testFactoryMethod() { + assertEquals(Collections.emptyList(), BdfList.of()); + assertEquals(Arrays.asList(1, 2, NULL_VALUE), + BdfList.of(1, 2, NULL_VALUE)); + } + + @Test + public void testIntegerPromotion() throws Exception { + BdfList list = new BdfList(); + list.add((byte) 1); + list.add((short) 2); + list.add(3); + list.add(4L); + assertEquals(Long.valueOf(1), list.getInteger(0)); + assertEquals(Long.valueOf(2), list.getInteger(1)); + assertEquals(Long.valueOf(3), list.getInteger(2)); + assertEquals(Long.valueOf(4), list.getInteger(3)); + } + + @Test + public void testFloatPromotion() throws Exception { + BdfList list = new BdfList(); + list.add(1F); + list.add(2D); + assertEquals(Double.valueOf(1), list.getFloat(0)); + assertEquals(Double.valueOf(2), list.getFloat(1)); + } + + @Test + public void testByteArrayUnwrapping() throws Exception { + BdfList list = new BdfList(); + list.add(new byte[123]); + list.add(new Bytes(new byte[123])); + byte[] first = list.getRaw(0); + assertEquals(123, first.length); + assertArrayEquals(new byte[123], first); + byte[] second = list.getRaw(1); + assertEquals(123, second.length); + assertArrayEquals(new byte[123], second); + } +}