From ed23bd6c11f8866ab7ceea5518d308ca828e2404 Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Tue, 5 Jan 2016 11:04:15 +0000
Subject: [PATCH] Allow nulls in BdfList, BdfDictionary.

BdfList and BdfDictionary are no longer thread-safe, they require external locking. Metadata (which is the class that will be passed across API boundaries) is still thread-safe.
---
 .../briarproject/api/data/BdfDictionary.java  |  5 ++--
 .../org/briarproject/api/data/BdfList.java    |  5 ++--
 .../src/org/briarproject/api/db/Metadata.java |  5 ++++
 .../data/MetadataEncoderImpl.java             | 24 ++++++++++---------
 .../briarproject/data/MetadataParserImpl.java |  4 ++--
 5 files changed, 26 insertions(+), 17 deletions(-)

diff --git a/briar-api/src/org/briarproject/api/data/BdfDictionary.java b/briar-api/src/org/briarproject/api/data/BdfDictionary.java
index b37cfc6067..eecea996c1 100644
--- a/briar-api/src/org/briarproject/api/data/BdfDictionary.java
+++ b/briar-api/src/org/briarproject/api/data/BdfDictionary.java
@@ -1,8 +1,9 @@
 package org.briarproject.api.data;
 
-import java.util.Hashtable;
+import java.util.HashMap;
 
-public class BdfDictionary extends Hashtable<String, Object> {
+// This class is not thread-safe
+public class BdfDictionary extends HashMap<String, Object> {
 
 	public Boolean getBoolean(String key, Boolean defaultValue) {
 		Object o = get(key);
diff --git a/briar-api/src/org/briarproject/api/data/BdfList.java b/briar-api/src/org/briarproject/api/data/BdfList.java
index d39588d0d6..949d414676 100644
--- a/briar-api/src/org/briarproject/api/data/BdfList.java
+++ b/briar-api/src/org/briarproject/api/data/BdfList.java
@@ -1,8 +1,9 @@
 package org.briarproject.api.data;
 
-import java.util.Vector;
+import java.util.ArrayList;
 
-public class BdfList extends Vector<Object> {
+// This class is not thread-safe
+public class BdfList extends ArrayList<Object> {
 
 	public Boolean getBoolean(int index, Boolean defaultValue) {
 		Object o = get(index);
diff --git a/briar-api/src/org/briarproject/api/db/Metadata.java b/briar-api/src/org/briarproject/api/db/Metadata.java
index c54d15cff7..b70df227f9 100644
--- a/briar-api/src/org/briarproject/api/db/Metadata.java
+++ b/briar-api/src/org/briarproject/api/db/Metadata.java
@@ -3,4 +3,9 @@ package org.briarproject.api.db;
 import java.util.Hashtable;
 
 public class Metadata extends Hashtable<String, byte[]> {
+
+	/**
+	 * Special value to indicate that a key is being removed.
+	 */
+	public static final byte[] REMOVE = new byte[0];
 }
diff --git a/briar-core/src/org/briarproject/data/MetadataEncoderImpl.java b/briar-core/src/org/briarproject/data/MetadataEncoderImpl.java
index 313b62f4b1..fc7dc3f9dc 100644
--- a/briar-core/src/org/briarproject/data/MetadataEncoderImpl.java
+++ b/briar-core/src/org/briarproject/data/MetadataEncoderImpl.java
@@ -2,14 +2,16 @@ package org.briarproject.data;
 
 import org.briarproject.api.FormatException;
 import org.briarproject.api.data.BdfDictionary;
-import org.briarproject.api.data.BdfList;
 import org.briarproject.api.data.MetadataEncoder;
 import org.briarproject.api.db.Metadata;
 import org.briarproject.util.StringUtils;
 
 import java.io.ByteArrayOutputStream;
+import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 
+import static org.briarproject.api.db.Metadata.REMOVE;
 import static org.briarproject.data.Types.DICTIONARY;
 import static org.briarproject.data.Types.END;
 import static org.briarproject.data.Types.FALSE;
@@ -34,10 +36,10 @@ class MetadataEncoderImpl implements MetadataEncoder {
 	public Metadata encode(BdfDictionary d) throws FormatException {
 		Metadata m = new Metadata();
 		ByteArrayOutputStream out = new ByteArrayOutputStream();
-		for (Map.Entry<String, Object> e : d.entrySet()) {
+		for (Entry<String, Object> e : d.entrySet()) {
 			if (e.getValue() == null) {
 				// Special case: if the value is null, the key is being removed
-				m.put(e.getKey(), null);
+				m.put(e.getKey(), REMOVE);
 			} else {
 				encodeObject(out, e.getValue());
 				m.put(e.getKey(), out.toByteArray());
@@ -59,9 +61,8 @@ 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 BdfList) encodeList(out, (BdfList) o);
-		else if (o instanceof BdfDictionary) encodeDictionary(out,
-				(BdfDictionary) o);
+		else if (o instanceof List) encodeList(out, (List) o);
+		else if (o instanceof Map) encodeDictionary(out, (Map) o);
 		else throw new FormatException();
 	}
 
@@ -154,18 +155,19 @@ class MetadataEncoderImpl implements MetadataEncoder {
 		out.write(b, 0, b.length);
 	}
 
-	private void encodeList(ByteArrayOutputStream out, BdfList list)
+	private void encodeList(ByteArrayOutputStream out, List list)
 			throws FormatException {
 		out.write(LIST);
 		for (Object o : list) encodeObject(out, o);
 		out.write(END);
 	}
 
-	private void encodeDictionary(ByteArrayOutputStream out,
-			BdfDictionary dict) throws FormatException {
+	private void encodeDictionary(ByteArrayOutputStream out, Map<?, ?> map)
+			throws FormatException {
 		out.write(DICTIONARY);
-		for (Map.Entry<String, Object> e : dict.entrySet()) {
-			encodeString(out, e.getKey());
+		for (Entry<?, ?> e : map.entrySet()) {
+			if (!(e.getKey() instanceof String)) throw new FormatException();
+			encodeString(out, (String) e.getKey());
 			encodeObject(out, e.getValue());
 		}
 		out.write(END);
diff --git a/briar-core/src/org/briarproject/data/MetadataParserImpl.java b/briar-core/src/org/briarproject/data/MetadataParserImpl.java
index e705bcca59..ff9258f149 100644
--- a/briar-core/src/org/briarproject/data/MetadataParserImpl.java
+++ b/briar-core/src/org/briarproject/data/MetadataParserImpl.java
@@ -8,7 +8,7 @@ import org.briarproject.api.db.Metadata;
 import org.briarproject.util.StringUtils;
 
 import java.io.ByteArrayInputStream;
-import java.util.Map;
+import java.util.Map.Entry;
 
 import static org.briarproject.data.Types.DICTIONARY;
 import static org.briarproject.data.Types.END;
@@ -33,7 +33,7 @@ class MetadataParserImpl implements MetadataParser {
 	@Override
 	public BdfDictionary parse(Metadata m) throws FormatException {
 		BdfDictionary dict = new BdfDictionary();
-		for (Map.Entry<String, byte[]> e : m.entrySet())
+		for (Entry<String, byte[]> e : m.entrySet())
 			dict.put(e.getKey(), parseObject(e.getValue()));
 		return dict;
 	}
-- 
GitLab