mirror of
https://github.com/fluencelabs/assemblyscript-json
synced 2025-03-31 02:11:04 +00:00
124 lines
3.4 KiB
TypeScript
124 lines
3.4 KiB
TypeScript
declare function logStr(str: string): void;
|
|
declare function logF64(val: f64): void;
|
|
|
|
export class JSONEncoder {
|
|
private isFirstKey: bool[] = new Array<bool>(1);
|
|
private result: string[] = new Array<string>();
|
|
|
|
constructor() {
|
|
this.isFirstKey[0] = true;
|
|
}
|
|
|
|
serialize(): Uint8Array {
|
|
// TODO: Write directly to UTF8 bytes
|
|
let result = this.toString();
|
|
let utf8ptr = result.toUTF8();
|
|
let buffer = new Uint8Array(result.lengthUTF8 - 1);
|
|
memory.copy(buffer.buffer.data, utf8ptr, buffer.byteLength);
|
|
return buffer;
|
|
}
|
|
|
|
toString(): String {
|
|
return this.result.join("");
|
|
}
|
|
|
|
setString(name: string, value: string): void {
|
|
this.writeKey(name);
|
|
this.writeString(value);
|
|
}
|
|
|
|
setBoolean(name: string, value: bool): void {
|
|
this.writeKey(name);
|
|
this.writeBoolean(value);
|
|
}
|
|
|
|
setNull(name: string): void {
|
|
this.writeKey(name);
|
|
this.write("null");
|
|
}
|
|
|
|
setInteger(name: string, value: i64): void {
|
|
this.writeKey(name);
|
|
this.writeInteger(value);
|
|
}
|
|
|
|
pushArray(name: string): bool {
|
|
this.writeKey(name);
|
|
this.write("[");
|
|
this.isFirstKey.push(true);
|
|
return true;
|
|
}
|
|
|
|
popArray(): void {
|
|
this.write("]");
|
|
this.isFirstKey.pop();
|
|
}
|
|
|
|
pushObject(name: string): bool {
|
|
this.writeKey(name);
|
|
this.write("{");
|
|
this.isFirstKey.push(true);
|
|
return true;
|
|
}
|
|
|
|
popObject(): void {
|
|
this.write("}");
|
|
this.isFirstKey.pop();
|
|
}
|
|
|
|
private writeKey(str: string): void {
|
|
if (!this.isFirstKey[this.isFirstKey.length - 1]) {
|
|
this.write(",");
|
|
} else {
|
|
this.isFirstKey[this.isFirstKey.length - 1] = false;
|
|
}
|
|
if (str != null) {
|
|
this.writeString(str);
|
|
this.write(":");
|
|
}
|
|
}
|
|
|
|
private writeString(str: string): void {
|
|
this.write('"');
|
|
let savedIndex = 0;
|
|
for (let i = 0; i < str.length; i++) {
|
|
let char = str.charCodeAt(i);
|
|
let needsEscaping = char < 0x20 || char == '"'.charCodeAt(0) || char == '\\'.charCodeAt(0);
|
|
if (needsEscaping) {
|
|
this.write(str.substring(savedIndex, i));
|
|
savedIndex = i + 1;
|
|
if (char == '"'.charCodeAt(0)) {
|
|
this.write('\\"');
|
|
} else if (char == "\\".charCodeAt(0)) {
|
|
this.write("\\\\");
|
|
} else if (char == "\b".charCodeAt(0)) {
|
|
this.write("\\b");
|
|
} else if (char == "\n".charCodeAt(0)) {
|
|
this.write("\\n");
|
|
} else if (char == "\r".charCodeAt(0)) {
|
|
this.write("\\r");
|
|
} else if (char == "\t".charCodeAt(0)) {
|
|
this.write("\\t");
|
|
} else {
|
|
// TODO: Implement encoding for other contol characters
|
|
assert(false, "Unsupported control chracter");
|
|
}
|
|
}
|
|
}
|
|
this.write(str.substring(savedIndex, str.length));
|
|
this.write('"');
|
|
}
|
|
|
|
private writeBoolean(value: bool): void {
|
|
this.write(value ? "true" : "false");
|
|
}
|
|
|
|
private writeInteger(value: i64): void {
|
|
this.write(value.toString());
|
|
}
|
|
|
|
private write(str: string): void {
|
|
this.result.push(str);
|
|
}
|
|
}
|