@jsonjoy.com/json-pack
Version:
High-performance JSON serialization library
110 lines • 5.09 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.RpcMessageDecoder = void 0;
const Reader_1 = require("@jsonjoy.com/buffers/lib/Reader");
const errors_1 = require("./errors");
const messages_1 = require("./messages");
const EMPTY_BUFFER = new Uint8Array(0);
const EMPTY_READER = new Reader_1.Reader(EMPTY_BUFFER);
class RpcMessageDecoder {
decodeMessage(reader) {
const startPos = reader.x;
try {
if (reader.size() < 8)
return undefined;
const xid = reader.u32();
const msgType = reader.u32();
if (msgType === 0 /* RpcMsgType.CALL */) {
if (reader.size() < 20)
return (reader.x = startPos), undefined;
const rpcvers = reader.u32();
// if (rpcvers !== RPC_VERSION) throw new RpcDecodingError(`Unsupported RPC version: ${rpcvers}`);
const prog = reader.u32();
const vers = reader.u32();
const proc = reader.u32();
const cred = this.readOpaqueAuth(reader);
if (!cred)
return (reader.x = startPos), undefined;
const verf = this.readOpaqueAuth(reader);
if (!verf)
return (reader.x = startPos), undefined;
const params = reader.size() > 0 ? reader.cut(reader.size()) : undefined;
return new messages_1.RpcCallMessage(xid, rpcvers, prog, vers, proc, cred, verf, params);
}
else if (msgType === 1 /* RpcMsgType.REPLY */) {
if (reader.size() < 4)
return (reader.x = startPos), undefined;
const replyStat = reader.u32();
if (replyStat === 0 /* RpcReplyStat.MSG_ACCEPTED */) {
const verf = this.readOpaqueAuth(reader);
if (!verf || reader.size() < 4)
return (reader.x = startPos), undefined;
const acceptStat = reader.u32();
let mismatchInfo;
if (acceptStat === 2 /* RpcAcceptStat.PROG_MISMATCH */) {
if (reader.size() < 8)
return (reader.x = startPos), undefined;
const low = reader.u32();
const high = reader.u32();
mismatchInfo = new messages_1.RpcMismatchInfo(low, high);
}
const results = reader.size() > 0 ? reader.cut(reader.size()) : undefined;
return new messages_1.RpcAcceptedReplyMessage(xid, verf, acceptStat, mismatchInfo, results);
}
else if (replyStat === 1 /* RpcReplyStat.MSG_DENIED */) {
if (reader.size() < 4)
return (reader.x = startPos), undefined;
const rejectStat = reader.u32();
let mismatchInfo;
let authStat;
if (rejectStat === 0 /* RpcRejectStat.RPC_MISMATCH */) {
if (reader.size() < 8)
return (reader.x = startPos), undefined;
const low = reader.u32();
const high = reader.u32();
mismatchInfo = new messages_1.RpcMismatchInfo(low, high);
if (!mismatchInfo)
return (reader.x = startPos), undefined;
}
else if (rejectStat === 1 /* RpcRejectStat.AUTH_ERROR */) {
if (reader.size() < 4)
return (reader.x = startPos), undefined;
authStat = reader.u32();
}
return new messages_1.RpcRejectedReplyMessage(xid, rejectStat, mismatchInfo, authStat);
}
else {
throw new errors_1.RpcDecodingError('Invalid reply_stat');
}
}
else {
throw new errors_1.RpcDecodingError('Invalid msg_type');
}
}
catch (err) {
if (err instanceof RangeError) {
reader.x = startPos;
return undefined;
}
throw err;
}
}
readOpaqueAuth(reader) {
if (reader.size() < 8)
return undefined;
const flavor = reader.u32();
const length = reader.u32();
if (length > 400)
throw new errors_1.RpcDecodingError('Auth body too large');
const paddedLength = (length + 3) & ~3;
if (reader.size() < paddedLength)
return undefined;
const body = length > 0 ? reader.cut(length) : EMPTY_READER;
const padding = paddedLength - length;
if (padding > 0)
reader.skip(padding);
return new messages_1.RpcOpaqueAuth(flavor, body);
}
}
exports.RpcMessageDecoder = RpcMessageDecoder;
//# sourceMappingURL=RpcMessageDecoder.js.map