Support white-space between tokens

This commit is contained in:
Vladimir Grichina 2019-01-06 02:59:36 -08:00
parent e4757490a7
commit a4a11af1a8
2 changed files with 42 additions and 15 deletions

View File

@ -49,7 +49,7 @@ export class ThrowingJSONHandler extends JSONHandler {
}
setBoolean(name: string, value: bool): void {
assert(false, 'Unexpected boolean field ' + name + ' : ' + (value ? 'true' : 'false'));
assert(false, 'Unexpected bool field ' + name + ' : ' + (value ? 'true' : 'false'));
}
setNull(name: string): void {
@ -97,6 +97,7 @@ export class JSONDecoder<JSONHandlerT extends JSONHandler> {
this.lastKey = null
assert(this.parseValue(), "Cannot parse JSON");
// TODO: Error if input left
}
private peekChar(): i32 {
@ -108,22 +109,25 @@ export class JSONDecoder<JSONHandlerT extends JSONHandler> {
return this.buffer[this.readIndex++];
}
private parseValue(): boolean {
return this.parseObject()
private parseValue(): bool {
this.skipWhitespace();
let result = this.parseObject()
|| this.parseArray()
|| this.parseString()
|| this.parseBoolean()
|| this.parseNumber()
|| this.parseNull()
// TODO: Error if input left
this.skipWhitespace();
return result;
}
private parseObject(): boolean {
private parseObject(): bool {
if (this.peekChar() != "{".charCodeAt(0)) {
return false;
}
this.handler.pushObject(this.lastKey);
this.readChar();
this.skipWhitespace();
let firstItem = true;
while (this.peekChar() != "}".charCodeAt(0)) {
@ -141,16 +145,18 @@ export class JSONDecoder<JSONHandlerT extends JSONHandler> {
}
private parseKey(): void {
this.skipWhitespace();
this.lastKey = this.readString();
this.skipWhitespace();
assert(this.readChar() == ":".charCodeAt(0), "Expected ':'");
}
private parseArray(): boolean {
private parseArray(): bool {
// TODO
return false;
}
private parseString(): boolean {
private parseString(): bool {
if (this.peekChar() != '"'.charCodeAt(0)) {
return false;
}
@ -158,7 +164,7 @@ export class JSONDecoder<JSONHandlerT extends JSONHandler> {
return true;
}
private readString(): String {
private readString(): string {
assert(this.readChar() == '"'.charCodeAt(0), "Expected double-quoted string");
let savedIndex = this.readIndex;
for (;;) {
@ -183,7 +189,7 @@ export class JSONDecoder<JSONHandlerT extends JSONHandler> {
return "";
}
private parseNumber(): boolean {
private parseNumber(): bool {
// TODO: Parse floats
let number: i32 = 0;
let sign: i32 = 1;
@ -205,7 +211,7 @@ export class JSONDecoder<JSONHandlerT extends JSONHandler> {
return false;
}
private parseBoolean(): boolean {
private parseBoolean(): bool {
if (this.peekChar() == FALSE_STR.charCodeAt(0)) {
this.readAndAssert(FALSE_STR);
this.handler.setBoolean(this.lastKey, false);
@ -220,7 +226,7 @@ export class JSONDecoder<JSONHandlerT extends JSONHandler> {
return false;
}
private parseNull(): boolean {
private parseNull(): bool {
if (this.peekChar() == NULL_STR.charCodeAt(0)) {
this.readAndAssert(NULL_STR);
this.handler.setNull(this.lastKey);
@ -234,4 +240,14 @@ export class JSONDecoder<JSONHandlerT extends JSONHandler> {
assert(str.charCodeAt(i) == this.readChar(), "Expected '" + str + "'");
}
}
private skipWhitespace(): void {
while (this.isWhitespace(this.peekChar())) {
this.readChar();
}
}
private isWhitespace(charCode: i32): bool {
return charCode == 0x9 || charCode == 0xa || charCode == 0xd || charCode == 0x20;
}
}

View File

@ -108,6 +108,10 @@ export class StringConversionTests {
return this.roundripTest("{}");
}
static shouldHandleEmptyObjectWithWhitespace(): bool {
return this.roundripTest("{ }", "{}");
}
static shouldHandleInt32(): bool {
return this.roundripTest('{"int":4660}');
}
@ -140,7 +144,14 @@ export class StringConversionTests {
return this.roundripTest('{"str":"foo","obj":{"a":1,"b":-123456}}');
}
private static roundripTest(jsonString: string): bool {
static shouldHandleWhitespace(): bool {
return this.roundripTest(
' { "str":"foo","obj": {"a":1, "b" :\n -123456} } ',
'{"str":"foo","obj":{"a":1,"b":-123456}}');
}
private static roundripTest(jsonString: string, expectedString: string = null): bool {
expectedString = expectedString || jsonString;
logStr("----------------- " + jsonString );
let buffer: Uint8Array = new Uint8Array(jsonString.lengthUTF8);
let utf8ptr = jsonString.toUTF8();
@ -149,8 +160,8 @@ export class StringConversionTests {
buffer[i] = load<u8>(utf8ptr + i);
}
this.createDecoder().deserialize(buffer);
assert(this.handler.result == jsonString,
"Expected:\n" + jsonString + "\n" + "Actual:\n" + this.handler.result);
assert(this.handler.result == expectedString,
"Expected:\n" + expectedString + "\n" + "Actual:\n" + this.handler.result);
return true;
}
}