die heldin script add
This commit is contained in:
214
node_modules/@stomp/stompjs/esm6/parser.js
generated
vendored
Normal file
214
node_modules/@stomp/stompjs/esm6/parser.js
generated
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const NULL = 0;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const LF = 10;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const CR = 13;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
const COLON = 58;
|
||||
/**
|
||||
* This is an evented, rec descent parser.
|
||||
* A stream of Octets can be passed and whenever it recognizes
|
||||
* a complete Frame or an incoming ping it will invoke the registered callbacks.
|
||||
*
|
||||
* All incoming Octets are fed into _onByte function.
|
||||
* Depending on current state the _onByte function keeps changing.
|
||||
* Depending on the state it keeps accumulating into _token and _results.
|
||||
* State is indicated by current value of _onByte, all states are named as _collect.
|
||||
*
|
||||
* STOMP standards https://stomp.github.io/stomp-specification-1.2.html
|
||||
* imply that all lengths are considered in bytes (instead of string lengths).
|
||||
* So, before actual parsing, if the incoming data is String it is converted to Octets.
|
||||
* This allows faithful implementation of the protocol and allows NULL Octets to be present in the body.
|
||||
*
|
||||
* There is no peek function on the incoming data.
|
||||
* When a state change occurs based on an Octet without consuming the Octet,
|
||||
* the Octet, after state change, is fed again (_reinjectByte).
|
||||
* This became possible as the state change can be determined by inspecting just one Octet.
|
||||
*
|
||||
* There are two modes to collect the body, if content-length header is there then it by counting Octets
|
||||
* otherwise it is determined by NULL terminator.
|
||||
*
|
||||
* Following the standards, the command and headers are converted to Strings
|
||||
* and the body is returned as Octets.
|
||||
* Headers are returned as an array and not as Hash - to allow multiple occurrence of an header.
|
||||
*
|
||||
* This parser does not use Regular Expressions as that can only operate on Strings.
|
||||
*
|
||||
* It handles if multiple STOMP frames are given as one chunk, a frame is split into multiple chunks, or
|
||||
* any combination there of. The parser remembers its state (any partial frame) and continues when a new chunk
|
||||
* is pushed.
|
||||
*
|
||||
* Typically the higher level function will convert headers to Hash, handle unescaping of header values
|
||||
* (which is protocol version specific), and convert body to text.
|
||||
*
|
||||
* Check the parser.spec.js to understand cases that this parser is supposed to handle.
|
||||
*
|
||||
* Part of `@stomp/stompjs`.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export class Parser {
|
||||
constructor(onFrame, onIncomingPing) {
|
||||
this.onFrame = onFrame;
|
||||
this.onIncomingPing = onIncomingPing;
|
||||
this._encoder = new TextEncoder();
|
||||
this._decoder = new TextDecoder();
|
||||
this._token = [];
|
||||
this._initState();
|
||||
}
|
||||
parseChunk(segment, appendMissingNULLonIncoming = false) {
|
||||
let chunk;
|
||||
if (segment instanceof ArrayBuffer) {
|
||||
chunk = new Uint8Array(segment);
|
||||
}
|
||||
else {
|
||||
chunk = this._encoder.encode(segment);
|
||||
}
|
||||
// See https://github.com/stomp-js/stompjs/issues/89
|
||||
// Remove when underlying issue is fixed.
|
||||
//
|
||||
// Send a NULL byte, if the last byte of a Text frame was not NULL.F
|
||||
if (appendMissingNULLonIncoming && chunk[chunk.length - 1] !== 0) {
|
||||
const chunkWithNull = new Uint8Array(chunk.length + 1);
|
||||
chunkWithNull.set(chunk, 0);
|
||||
chunkWithNull[chunk.length] = 0;
|
||||
chunk = chunkWithNull;
|
||||
}
|
||||
// tslint:disable-next-line:prefer-for-of
|
||||
for (let i = 0; i < chunk.length; i++) {
|
||||
const byte = chunk[i];
|
||||
this._onByte(byte);
|
||||
}
|
||||
}
|
||||
// The following implements a simple Rec Descent Parser.
|
||||
// The grammar is simple and just one byte tells what should be the next state
|
||||
_collectFrame(byte) {
|
||||
if (byte === NULL) {
|
||||
// Ignore
|
||||
return;
|
||||
}
|
||||
if (byte === CR) {
|
||||
// Ignore CR
|
||||
return;
|
||||
}
|
||||
if (byte === LF) {
|
||||
// Incoming Ping
|
||||
this.onIncomingPing();
|
||||
return;
|
||||
}
|
||||
this._onByte = this._collectCommand;
|
||||
this._reinjectByte(byte);
|
||||
}
|
||||
_collectCommand(byte) {
|
||||
if (byte === CR) {
|
||||
// Ignore CR
|
||||
return;
|
||||
}
|
||||
if (byte === LF) {
|
||||
this._results.command = this._consumeTokenAsUTF8();
|
||||
this._onByte = this._collectHeaders;
|
||||
return;
|
||||
}
|
||||
this._consumeByte(byte);
|
||||
}
|
||||
_collectHeaders(byte) {
|
||||
if (byte === CR) {
|
||||
// Ignore CR
|
||||
return;
|
||||
}
|
||||
if (byte === LF) {
|
||||
this._setupCollectBody();
|
||||
return;
|
||||
}
|
||||
this._onByte = this._collectHeaderKey;
|
||||
this._reinjectByte(byte);
|
||||
}
|
||||
_reinjectByte(byte) {
|
||||
this._onByte(byte);
|
||||
}
|
||||
_collectHeaderKey(byte) {
|
||||
if (byte === COLON) {
|
||||
this._headerKey = this._consumeTokenAsUTF8();
|
||||
this._onByte = this._collectHeaderValue;
|
||||
return;
|
||||
}
|
||||
this._consumeByte(byte);
|
||||
}
|
||||
_collectHeaderValue(byte) {
|
||||
if (byte === CR) {
|
||||
// Ignore CR
|
||||
return;
|
||||
}
|
||||
if (byte === LF) {
|
||||
this._results.headers.push([this._headerKey, this._consumeTokenAsUTF8()]);
|
||||
this._headerKey = undefined;
|
||||
this._onByte = this._collectHeaders;
|
||||
return;
|
||||
}
|
||||
this._consumeByte(byte);
|
||||
}
|
||||
_setupCollectBody() {
|
||||
const contentLengthHeader = this._results.headers.filter((header) => {
|
||||
return header[0] === 'content-length';
|
||||
})[0];
|
||||
if (contentLengthHeader) {
|
||||
this._bodyBytesRemaining = parseInt(contentLengthHeader[1], 10);
|
||||
this._onByte = this._collectBodyFixedSize;
|
||||
}
|
||||
else {
|
||||
this._onByte = this._collectBodyNullTerminated;
|
||||
}
|
||||
}
|
||||
_collectBodyNullTerminated(byte) {
|
||||
if (byte === NULL) {
|
||||
this._retrievedBody();
|
||||
return;
|
||||
}
|
||||
this._consumeByte(byte);
|
||||
}
|
||||
_collectBodyFixedSize(byte) {
|
||||
// It is post decrement, so that we discard the trailing NULL octet
|
||||
if (this._bodyBytesRemaining-- === 0) {
|
||||
this._retrievedBody();
|
||||
return;
|
||||
}
|
||||
this._consumeByte(byte);
|
||||
}
|
||||
_retrievedBody() {
|
||||
this._results.binaryBody = this._consumeTokenAsRaw();
|
||||
this.onFrame(this._results);
|
||||
this._initState();
|
||||
}
|
||||
// Rec Descent Parser helpers
|
||||
_consumeByte(byte) {
|
||||
this._token.push(byte);
|
||||
}
|
||||
_consumeTokenAsUTF8() {
|
||||
return this._decoder.decode(this._consumeTokenAsRaw());
|
||||
}
|
||||
_consumeTokenAsRaw() {
|
||||
const rawResult = new Uint8Array(this._token);
|
||||
this._token = [];
|
||||
return rawResult;
|
||||
}
|
||||
_initState() {
|
||||
this._results = {
|
||||
command: undefined,
|
||||
headers: [],
|
||||
binaryBody: undefined,
|
||||
};
|
||||
this._token = [];
|
||||
this._headerKey = undefined;
|
||||
this._onByte = this._collectFrame;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=parser.js.map
|
||||
Reference in New Issue
Block a user