Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | 2x 2x 2x 5x 5x 1580x 1644x 1644x 1640x 1640x 1640x 155x 155x 1485x 1485x 1485x 1x 1x 1x 1x 1x 1x 1x 70x 70x 70x 70x 70x 70x 70x | import {StreamingReader} from '@jsonjoy.com/buffers/lib/StreamingReader';
import {RespDecoder} from './RespDecoder';
/**
* Streaming decoder for RESP protocol. Can be used to decode data from
* a stream where messages are arbitrary split into chunks.
*
* Example:
*
* ```ts
* const decoder = new RespStreamingDecoder();
*
* decoder.push(new Uint8Array([43, 49, 13, 10]));
*
* let val;
* while ((val = decoder.read()) !== undefined) {
* console.log(val);
* }
* ```
*/
export class RespStreamingDecoder {
protected readonly reader = new StreamingReader();
protected readonly decoder = new RespDecoder(this.reader);
/**
* When set to true, the decoder will attempt to decode RESP Bulk strings
* (which are binary strings, i.e. Uint8Array) as UTF-8 strings. If the
* string is not valid UTF-8, it will be returned as a Uint8Array.
*/
public get tryUtf8(): boolean {
return this.decoder.tryUtf8;
}
public set tryUtf8(value: boolean) {
this.decoder.tryUtf8 = value;
}
/**
* Add a chunk of data to be decoded.
* @param uint8 `Uint8Array` chunk of data to be decoded.
*/
public push(uint8: Uint8Array): void {
this.reader.push(uint8);
}
/**
* Decode one value from the stream. If `undefined` is returned, then
* there is not enough data to decode or the stream is finished.
*
* There could be multiple values in the stream, so this method should be
* called in a loop until `undefined` is returned.
*
* @return Decoded value or `undefined` if there is not enough data to decode.
*/
public read(): unknown | undefined {
const reader = this.reader;
if (reader.size() === 0) return undefined;
const x = reader.x;
try {
const val = this.decoder.readAny();
reader.consume();
return val;
} catch (error) {
if (error instanceof RangeError) {
reader.x = x;
return undefined;
} else Ethrow error;
}
}
/**
* Decode only one RESP command from the stream, if the value is not a
* command, an error will be thrown.
*
* @returns Redis command and its arguments or `undefined` if there is
* not enough data to decode.
*/
public readCmd(): [cmd: string, ...args: Uint8Array[]] | undefined {
const reader = this.reader;
Iif (reader.size() === 0) return undefined;
const x = reader.x;
try {
const args = this.decoder.readCmd();
reader.consume();
return args;
} catch (error) {
if (error instanceof RangeError) {
reader.x = x;
return undefined;
} else throw error;
}
}
/**
* Skips one value from the stream. If `undefined` is returned, then
* there is not enough data to skip or the stream is finished.
* @returns `null` if a value was skipped, `undefined` if there is not
* enough data to skip.
*/
public skip(): null | undefined {
const reader = this.reader;
Iif (reader.size() === 0) return undefined;
const x = reader.x;
try {
this.decoder.skipAny();
reader.consume();
return null;
} catch (error) {
if (error instanceof RangeError) {
reader.x = x;
return undefined;
} else throw error;
}
}
}
|