diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/JsonWriter.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/JsonWriter.java
deleted file mode 100644
index e379b568c68..00000000000
--- a/ReactAndroid/src/main/java/com/facebook/react/bridge/JsonWriter.java
+++ /dev/null
@@ -1,212 +0,0 @@
-/**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- *
This source code is licensed under the MIT license found in the LICENSE file in the root
- * directory of this source tree.
- */
-package com.facebook.react.bridge;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.io.Writer;
-import java.util.ArrayDeque;
-import java.util.Deque;
-
-/** Simple Json generator that does no validation. */
-public class JsonWriter implements Closeable {
- private final Writer mWriter;
- private final Deque mScopes;
-
- public JsonWriter(Writer writer) {
- mWriter = writer;
- mScopes = new ArrayDeque<>();
- }
-
- public JsonWriter beginArray() throws IOException {
- open(Scope.EMPTY_ARRAY, '[');
- return this;
- }
-
- public JsonWriter endArray() throws IOException {
- close(']');
- return this;
- }
-
- public JsonWriter beginObject() throws IOException {
- open(Scope.EMPTY_OBJECT, '{');
- return this;
- }
-
- public JsonWriter endObject() throws IOException {
- close('}');
- return this;
- }
-
- public JsonWriter name(String name) throws IOException {
- if (name == null) {
- throw new NullPointerException("name can not be null");
- }
- beforeName();
- string(name);
- mWriter.write(':');
- return this;
- }
-
- public JsonWriter value(String value) throws IOException {
- if (value == null) {
- return nullValue();
- }
- beforeValue();
- string(value);
- return this;
- }
-
- public JsonWriter nullValue() throws IOException {
- beforeValue();
- mWriter.write("null");
- return this;
- }
-
- public JsonWriter rawValue(String json) throws IOException {
- beforeValue();
- mWriter.write(json);
- return this;
- }
-
- public JsonWriter value(boolean value) throws IOException {
- beforeValue();
- mWriter.write(value ? "true" : "false");
- return this;
- }
-
- public JsonWriter value(double value) throws IOException {
- beforeValue();
- mWriter.append(Double.toString(value));
- return this;
- }
-
- public JsonWriter value(long value) throws IOException {
- beforeValue();
- mWriter.write(Long.toString(value));
- return this;
- }
-
- public JsonWriter value(Number value) throws IOException {
- if (value == null) {
- return nullValue();
- }
- beforeValue();
- mWriter.append(value.toString());
- return this;
- }
-
- @Override
- public void close() throws IOException {
- mWriter.close();
- }
-
- private void beforeValue() throws IOException {
- Scope scope = mScopes.peek();
- switch (scope) {
- case EMPTY_ARRAY:
- replace(Scope.ARRAY);
- break;
- case EMPTY_OBJECT:
- throw new IllegalArgumentException(Scope.EMPTY_OBJECT.name());
- case ARRAY:
- mWriter.write(',');
- break;
- case OBJECT:
- break;
- default:
- throw new IllegalStateException("Unknown scope: " + scope);
- }
- }
-
- private void beforeName() throws IOException {
- Scope scope = mScopes.peek();
- switch (scope) {
- case EMPTY_ARRAY:
- case ARRAY:
- throw new IllegalStateException("name not allowed in array");
- case EMPTY_OBJECT:
- replace(Scope.OBJECT);
- break;
- case OBJECT:
- mWriter.write(',');
- break;
- default:
- throw new IllegalStateException("Unknown scope: " + scope);
- }
- }
-
- private void open(Scope scope, char bracket) throws IOException {
- mScopes.push(scope);
- mWriter.write(bracket);
- }
-
- private void close(char bracket) throws IOException {
- mScopes.pop();
- mWriter.write(bracket);
- }
-
- private void string(String string) throws IOException {
- mWriter.write('"');
- for (int i = 0, length = string.length(); i < length; i++) {
- char c = string.charAt(i);
- switch (c) {
- case '\t':
- mWriter.write("\\t");
- break;
-
- case '\b':
- mWriter.write("\\b");
- break;
-
- case '\n':
- mWriter.write("\\n");
- break;
-
- case '\r':
- mWriter.write("\\r");
- break;
-
- case '\f':
- mWriter.write("\\f");
- break;
-
- case '"':
- case '\\':
- mWriter.write('\\');
- mWriter.write(c);
- break;
-
- case '\u2028':
- case '\u2029':
- mWriter.write(String.format("\\u%04x", (int) c));
- break;
-
- default:
- if (c <= 0x1F) {
- mWriter.write(String.format("\\u%04x", (int) c));
- } else {
- mWriter.write(c);
- }
- break;
- }
- }
- mWriter.write('"');
- }
-
- private void replace(Scope scope) {
- mScopes.pop();
- mScopes.push(scope);
- }
-
- private enum Scope {
- EMPTY_OBJECT,
- OBJECT,
- EMPTY_ARRAY,
- ARRAY
- }
-}
diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/JsonWriterHelper.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/JsonWriterHelper.java
index ab46dc7f72d..d91dc0220b9 100644
--- a/ReactAndroid/src/main/java/com/facebook/react/bridge/JsonWriterHelper.java
+++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/JsonWriterHelper.java
@@ -6,22 +6,121 @@
*/
package com.facebook.react.bridge;
+import android.util.JsonWriter;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/** Helper for generating JSON for lists and maps. */
-class JsonWriterHelper {
+public class JsonWriterHelper {
public static void value(JsonWriter writer, Object value) throws IOException {
if (value instanceof Map) {
mapValue(writer, (Map) value);
} else if (value instanceof List) {
listValue(writer, (List) value);
+ } else if (value instanceof ReadableMap) {
+ readableMapValue(writer, (ReadableMap) value);
+ } else if (value instanceof ReadableArray) {
+ readableArrayValue(writer, (ReadableArray) value);
+ } else if (value instanceof Dynamic) {
+ dynamicValue(writer, (Dynamic) value);
} else {
objectValue(writer, value);
}
}
+ private static void dynamicValue(JsonWriter writer, Dynamic value) throws IOException {
+ switch (value.getType()) {
+ case Null:
+ writer.nullValue();
+ break;
+ case Boolean:
+ writer.value(value.asBoolean());
+ break;
+ case Number:
+ writer.value(value.asDouble());
+ break;
+ case String:
+ writer.value(value.asString());
+ break;
+ case Map:
+ readableMapValue(writer, value.asMap());
+ break;
+ case Array:
+ readableArrayValue(writer, value.asArray());
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown data type: " + value.getType());
+ }
+ }
+
+ private static void readableMapValue(JsonWriter writer, ReadableMap value) throws IOException {
+ writer.beginObject();
+ try {
+ ReadableMapKeySetIterator iterator = value.keySetIterator();
+ while (iterator.hasNextKey()) {
+ String key = iterator.nextKey();
+ writer.name(key);
+ switch (value.getType(key)) {
+ case Null:
+ writer.nullValue();
+ break;
+ case Boolean:
+ writer.value(value.getBoolean(key));
+ break;
+ case Number:
+ writer.value(value.getDouble(key));
+ break;
+ case String:
+ writer.value(value.getString(key));
+ break;
+ case Map:
+ readableMapValue(writer, value.getMap(key));
+ break;
+ case Array:
+ readableArrayValue(writer, value.getArray(key));
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown data type: " + value.getType(key));
+ }
+ }
+ } finally {
+ writer.endObject();
+ }
+ }
+
+ public static void readableArrayValue(JsonWriter writer, ReadableArray value) throws IOException {
+ writer.beginArray();
+ try {
+ for (int key = 0; key < value.size(); ++key) {
+ switch (value.getType(key)) {
+ case Null:
+ writer.nullValue();
+ break;
+ case Boolean:
+ writer.value(value.getBoolean(key));
+ break;
+ case Number:
+ writer.value(value.getDouble(key));
+ break;
+ case String:
+ writer.value(value.getString(key));
+ break;
+ case Map:
+ readableMapValue(writer, value.getMap(key));
+ break;
+ case Array:
+ readableArrayValue(writer, value.getArray(key));
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown data type: " + value.getType(key));
+ }
+ }
+ } finally {
+ writer.endArray();
+ }
+ }
+
private static void mapValue(JsonWriter writer, Map, ?> map) throws IOException {
writer.beginObject();
for (Map.Entry entry : map.entrySet()) {
diff --git a/ReactAndroid/src/test/java/com/facebook/react/bridge/JsonWriterTest.java b/ReactAndroid/src/test/java/com/facebook/react/bridge/JsonWriterTest.java
deleted file mode 100644
index ea031b3c28d..00000000000
--- a/ReactAndroid/src/test/java/com/facebook/react/bridge/JsonWriterTest.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the LICENSE file in the root
- * directory of this source tree.
- */
-package com.facebook.react.bridge;
-
-import static org.fest.assertions.api.Assertions.assertThat;
-
-import java.io.IOException;
-import java.io.StringWriter;
-import org.junit.Test;
-
-public class JsonWriterTest {
- private final StringWriter mStringWriter;
- private final JsonWriter mWriter;
-
- public JsonWriterTest() {
- mStringWriter = new StringWriter();
- mWriter = new JsonWriter(mStringWriter);
- }
-
- @Test
- public void emptyObject() throws IOException {
- mWriter.beginObject();
- mWriter.endObject();
- verify("{}");
- }
-
- @Test
- public void emptyNestedObject() throws IOException {
- mWriter.beginObject();
- mWriter.beginObject();
- mWriter.endObject();
- mWriter.endObject();
- verify("{{}}");
- }
-
- @Test
- public void emptyArray() throws IOException {
- mWriter.beginArray();
- mWriter.endArray();
- verify("[]");
- }
-
- @Test
- public void emptyNestedArray() throws IOException {
- mWriter.beginArray();
- mWriter.beginArray();
- mWriter.endArray();
- mWriter.endArray();
- verify("[[]]");
- }
-
- @Test
- public void smallObject() throws IOException {
- mWriter.beginObject();
- mWriter.name("hello").value(true);
- mWriter.name("hello_again").value("hi!");
- mWriter.endObject();
- verify("{\"hello\":true,\"hello_again\":\"hi!\"}");
- }
-
- @Test
- public void smallArray() throws IOException {
- mWriter.beginArray();
- mWriter.value(true);
- mWriter.value(1);
- mWriter.value(1.0);
- mWriter.value("hi!");
- mWriter.endArray();
- verify("[true,1,1.0,\"hi!\"]");
- }
-
- @Test
- public void string() throws IOException {
- mWriter.beginObject();
- mWriter.name("string").value("hello!");
- mWriter.endObject();
- verify("{\"string\":\"hello!\"}");
- }
-
- @Test
- public void complexString() throws IOException {
- mWriter.beginObject();
- mWriter.name("string").value("\t\uD83D\uDCA9");
- mWriter.endObject();
- verify("{\"string\":\"\\t\uD83D\uDCA9\"}");
- }
-
- private void verify(String expected) throws IOException {
- mWriter.close();
- assertThat(mStringWriter.getBuffer().toString()).isEqualTo(expected);
- }
-}