Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
class JSON {

// Note: supported types are limited, see Browser.evaluate and BrowserFunction.function.
// javascript objects are decoded as java.util.LinkedHashMap<String, Object> (insertion order preserved).
// Any java.util.Map with String keys can be encoded back into a javascript object.
// Note: this JSON codec is only used by the Edge (win32) and WebKitGTK BrowserFunction
// argument/return marshalling. Browser#evaluate() on WebKitGTK and both directions on
// Cocoa (WebKit1/WebView) and Internet Explorer go through native value conversion code
// that does not use this class and does not currently support javascript objects/maps.

static class Reader {
char[] input;
Expand Down Expand Up @@ -147,6 +153,7 @@ Object readAny() {
case '\0': return Control.END;
case '[': return readArray();
case ']': return Control.ARRAY_END;
case '{': return readObject();
case ',': return Control.COMMA;
case '"': return readString();
case '0':
Expand Down Expand Up @@ -185,6 +192,39 @@ Object readArray() {
return items.toArray();
}

Object readObject() {
Map<String, Object> map = new LinkedHashMap<>();
char c = nextNonSpaceChar();
if (c == '}') return map;
while (true) {
if (c != '"') error();
String key = readString();
c = nextNonSpaceChar();
if (c != ':') error();
Object value = readAny();
if (value instanceof Control) error();
map.put(key, value);
c = nextNonSpaceChar();
if (c == '}') break;
if (c != ',') error();
c = nextNonSpaceChar();
}
return map;
}

char nextNonSpaceChar() {
while (true) {
char c = nextChar();
switch (c) {
case ' ':
case '\t':
case '\r':
case '\n': continue;
default: return c;
}
}
}

Object readTop() {
Object item = readAny();
if (item instanceof Control) error();
Expand Down Expand Up @@ -235,6 +275,8 @@ void writeAny(Object object) {
writeString(object.toString());
} else if (object instanceof Object[]) {
writeArray((Object[])object);
} else if (object instanceof Map) {
writeMap((Map<?, ?>)object);
} else {
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, " [object not encodable: " + object.getClass() + "]");
}
Expand Down Expand Up @@ -266,6 +308,23 @@ void writeArray(Object[] array) {
sb.append(']');
}

void writeMap(Map<?, ?> map) {
sb.append('{');
boolean first = true;
for (Map.Entry<?, ?> entry : map.entrySet()) {
Object key = entry.getKey();
if (!(key instanceof String)) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, " [map key not encodable: " + (key != null ? key.getClass() : "null") + "]");
}
if (!first) sb.append(',');
writeString((String)key);
sb.append(':');
writeAny(entry.getValue());
first = false;
}
sb.append('}');
}

@Override
public String toString() {
return sb.toString();
Expand Down
Loading