org.eclipse.swt.browser.JSON Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.eclipse.swt.gtk.linux.aarch64 Show documentation
Show all versions of org.eclipse.swt.gtk.linux.aarch64 Show documentation
Standard Widget Toolkit for GTK on aarch64
The newest version!
/*******************************************************************************
* Copyright (c) 2020 Nikita Nemkin and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Nikita Nemkin - initial implementation
*******************************************************************************/
package org.eclipse.swt.browser;
import java.util.*;
import org.eclipse.swt.*;
class JSON {
// Note: supported types are limited, see Browser.evaluate and BrowserFunction.function.
static class Reader {
char[] input;
int pos, end;
StringBuilder sb;
public Reader(char[] input, int start, int end) {
this.input = input;
this.pos = start;
this.end = end;
}
static enum Control {
END, ARRAY_END, COMMA
}
char nextChar() {
return (pos < end) ? input[pos++] : '\0';
}
void error() {
SWT.error(SWT.ERROR_INVALID_ARGUMENT, null, " [decoding error at " + (pos - 1) +"]");
}
void readLiteral(String literal) {
for (int i = 0, len = literal.length(); i < len; i++) {
if (nextChar() != literal.charAt(i)) {
error();
}
}
}
int nextHexDigit() {
char c = nextChar();
if ('0' <= c && c <= '9') return c - '0';
if ('a' <= c && c <= 'f') return c - 'a' + 10;
if ('A' <= c && c <= 'F') return c - 'A' + 10;
error();
return 0;
}
char readEscape() {
char c = nextChar();
switch (c) {
case '"':
case '\\':
case '/': break;
case 'b': c = '\b'; break;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'u':
c = (char)((nextHexDigit() << 12) | (nextHexDigit() << 8)
| (nextHexDigit() << 4) | nextHexDigit());
break;
default: error();
}
return c;
}
String readString() {
char c;
int start = pos;
do {
c = nextChar();
if (c < 0x20) error();
if (c == '\\') {
if (sb == null) sb = new StringBuilder();
sb.append(input, start, pos - start - 1);
sb.append(readEscape());
start = pos;
}
} while (c != '"');
if (sb != null) {
sb.append(input, start, pos - 1 - start);
String result = sb.toString();
sb.setLength(0);
return result;
}
return String.valueOf(input, start, pos - start - 1);
}
double readNumber() {
int start = pos - 1;
while (true) {
char c = nextChar();
switch (c) {
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
case 'e':
case 'E':
case '+':
case '-': continue;
default:
pos--;
case '\0':
try {
return Double.parseDouble(String.valueOf(input, start, pos - start));
} catch (NumberFormatException e) {
error();
}
}
}
}
Object readAny() {
while (true) {
char c = nextChar();
switch (c) {
case ' ':
case '\t':
case '\r':
case '\n': continue;
case '\0': return Control.END;
case '[': return readArray();
case ']': return Control.ARRAY_END;
case ',': return Control.COMMA;
case '"': return readString();
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '-': return readNumber();
case 'n': readLiteral("ull"); return null;
case 't': readLiteral("rue"); return true;
case 'f': readLiteral("alse"); return false;
default: error();
}
}
}
Object readArray() {
Object item = readAny();
if (item == Control.ARRAY_END) return new Object[0];
if (item instanceof Control) error();
List