@jsonjoy.com/json-pack
Version:
High-performance JSON serialization library
388 lines • 10.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RespDecoder = void 0;
const Reader_1 = require("@jsonjoy.com/util/lib/buffers/Reader");
const extensions_1 = require("./extensions");
const isUtf8_1 = require("@jsonjoy.com/util/lib/buffers/utf8/isUtf8");
class RespDecoder {
constructor(reader = new Reader_1.Reader()) {
this.reader = reader;
this.tryUtf8 = false;
}
read(uint8) {
this.reader.reset(uint8);
return this.val();
}
decode(uint8) {
this.reader.reset(uint8);
return this.val();
}
val() {
const reader = this.reader;
const type = reader.u8();
switch (type) {
case 58:
return this.readInt();
case 44:
return this.readFloat();
case 43:
return this.readStrSimple();
case 36:
return this.readStrBulk();
case 35:
return this.readBool();
case 95:
return reader.skip(2), null;
case 37:
return this.readObj();
case 42:
return this.readArr();
case 61:
return this.readStrVerbatim();
case 62:
return new extensions_1.RespPush(this.readArr() || []);
case 40:
return this.readBigint();
case 126:
return this.readSet();
case 45:
return this.readErrSimple();
case 33:
return this.readErrBulk();
case 124:
return new extensions_1.RespAttributes(this.readObj());
}
throw new Error('UNKNOWN_TYPE');
}
readLength() {
const reader = this.reader;
let number = 0;
while (true) {
const c = reader.u8();
if (c === 13)
return reader.skip(1), number;
number = number * 10 + (c - 48);
}
}
readCmd() {
const reader = this.reader;
const type = reader.u8();
if (type !== 42)
throw new Error('INVALID_COMMAND');
const c = reader.peak();
if (c === 45)
throw new Error('INVALID_COMMAND');
const length = this.readLength();
if (length === 0)
throw new Error('INVALID_COMMAND');
const cmd = this.readAsciiAsStrBulk().toUpperCase();
const args = [cmd];
this.tryUtf8 = false;
for (let i = 1; i < length; i++) {
const type = reader.u8();
if (type !== 36)
throw new Error('INVALID_COMMAND');
args.push(this.readStrBulk());
}
return args;
}
readBool() {
const reader = this.reader;
const c = reader.u8();
reader.skip(2);
return c === 116;
}
readInt() {
const reader = this.reader;
let negative = false;
let c = reader.u8();
let number = 0;
if (c === 45) {
negative = true;
}
else if (c !== 43)
number = c - 48;
while (true) {
c = reader.u8();
if (c === 13) {
reader.skip(1);
return negative ? -number : number;
}
number = number * 10 + (c - 48);
}
}
readFloat() {
const reader = this.reader;
const x = reader.x;
while (true) {
const c = reader.u8();
if (c !== 13)
continue;
const length = reader.x - x - 1;
reader.x = x;
const str = reader.ascii(length);
switch (length) {
case 3:
switch (str) {
case 'inf':
return reader.skip(2), Infinity;
case 'nan':
return reader.skip(2), NaN;
}
break;
case 4:
if (str === '-inf') {
return reader.skip(2), -Infinity;
}
break;
}
reader.skip(2);
return Number(str);
}
}
readBigint() {
const reader = this.reader;
const x = reader.x;
while (true) {
const c = reader.u8();
if (c !== 13)
continue;
const length = reader.x - x;
reader.x = x;
const str = reader.ascii(length);
reader.skip(1);
return BigInt(str);
}
}
readStrSimple() {
const reader = this.reader;
const x = reader.x;
while (true) {
const c = reader.u8();
if (c !== 13)
continue;
const size = reader.x - x - 1;
reader.x = x;
const str = reader.utf8(size);
reader.skip(2);
return str;
}
}
readStrBulk() {
const reader = this.reader;
if (reader.peak() === 45) {
reader.skip(4);
return null;
}
const length = this.readLength();
let res;
if (this.tryUtf8 && (0, isUtf8_1.isUtf8)(reader.uint8, reader.x, length))
res = reader.utf8(length);
else
res = reader.buf(length);
reader.skip(2);
return res;
}
readAsciiAsStrBulk() {
const reader = this.reader;
reader.skip(1);
const length = this.readLength();
const buf = reader.ascii(length);
reader.skip(2);
return buf;
}
readStrVerbatim() {
const reader = this.reader;
const length = this.readLength();
const u32 = reader.u32();
const isTxt = u32 === 1954051130;
if (isTxt) {
const str = reader.utf8(length - 4);
reader.skip(2);
return str;
}
const buf = reader.buf(length - 4);
reader.skip(2);
return buf;
}
readErrSimple() {
const reader = this.reader;
const x = reader.x;
while (true) {
const c = reader.u8();
if (c !== 13)
continue;
const size = reader.x - x - 1;
reader.x = x;
const str = reader.utf8(size);
reader.skip(2);
return new Error(str);
}
}
readErrBulk() {
const reader = this.reader;
const length = this.readLength();
const message = reader.utf8(length);
reader.skip(2);
return new Error(message);
}
readArr() {
const reader = this.reader;
const c = reader.peak();
if (c === 45) {
reader.skip(4);
return null;
}
const length = this.readLength();
const arr = [];
for (let i = 0; i < length; i++)
arr.push(this.val());
return arr;
}
readSet() {
const length = this.readLength();
const set = new Set();
for (let i = 0; i < length; i++)
set.add(this.val());
return set;
}
readObj() {
const length = this.readLength();
const obj = {};
for (let i = 0; i < length; i++) {
const key = this.val() + '';
obj[key] = this.val();
}
return obj;
}
skipN(n) {
for (let i = 0; i < n; i++)
this.skipAny();
}
skipAny() {
const reader = this.reader;
const type = reader.u8();
switch (type) {
case 58:
return this.skipInt();
case 44:
return this.skipFloat();
case 43:
return this.skipStrSimple();
case 36:
return this.skipStrBulk();
case 35:
return this.skipBool();
case 95:
return reader.skip(2);
case 37:
return this.skipObj();
case 42:
return this.skipArr();
case 61:
return this.skipStrVerbatim();
case 62:
return this.skipArr();
case 40:
return this.skipBigint();
case 126:
return this.skipSet();
case 45:
return this.skipErrSimple();
case 33:
return this.skipErrBulk();
case 124:
return this.skipObj();
}
throw new Error('UNKNOWN_TYPE');
}
skipBool() {
this.reader.skip(3);
}
skipInt() {
const reader = this.reader;
while (true) {
if (reader.u8() !== 13)
continue;
reader.skip(1);
return;
}
}
skipFloat() {
const reader = this.reader;
while (true) {
if (reader.u8() !== 13)
continue;
reader.skip(1);
return;
}
}
skipBigint() {
const reader = this.reader;
while (true) {
if (reader.u8() !== 13)
continue;
reader.skip(1);
return;
}
}
skipStrSimple() {
const reader = this.reader;
while (true) {
if (reader.u8() !== 13)
continue;
reader.skip(1);
return;
}
}
skipStrBulk() {
const reader = this.reader;
if (reader.peak() === 45) {
reader.skip(4);
return;
}
reader.skip(this.readLength() + 2);
}
skipStrVerbatim() {
const length = this.readLength();
this.reader.skip(length + 2);
}
skipErrSimple() {
const reader = this.reader;
while (true) {
if (reader.u8() !== 13)
continue;
reader.skip(1);
return;
}
}
skipErrBulk() {
const length = this.readLength();
this.reader.skip(length + 2);
}
skipArr() {
const reader = this.reader;
const c = reader.peak();
if (c === 45) {
reader.skip(4);
return;
}
const length = this.readLength();
for (let i = 0; i < length; i++)
this.skipAny();
}
skipSet() {
const length = this.readLength();
for (let i = 0; i < length; i++)
this.skipAny();
}
skipObj() {
const length = this.readLength();
for (let i = 0; i < length; i++) {
this.skipAny();
this.skipAny();
}
}
}
exports.RespDecoder = RespDecoder;
//# sourceMappingURL=RespDecoder.js.map