@stryker-mutator/core
Version:
The extendable JavaScript mutation testing framework
49 lines (46 loc) • 1.53 kB
text/typescript
const CONTENT_LENGTH_HEADER = 'Content-Length:';
const CARRIAGE_RETURN_CODE = '\r'.charCodeAt(0);
const LINE_FEED_CODE = '\n'.charCodeAt(0);
export class JsonRpcEventDeserializer {
#chunk = Buffer.alloc(0);
deserialize(data: Buffer): unknown[] {
this.#chunk = Buffer.concat([this.#chunk, data]);
const events: unknown[] = [];
do {
const headerInfo = parseHeader(this.#chunk);
if (!headerInfo) {
break;
}
const { header, contentStart } = headerInfo;
const contentLengthIndex = header.indexOf(CONTENT_LENGTH_HEADER);
const contentLength = parseInt(
header
.substring(contentLengthIndex + CONTENT_LENGTH_HEADER.length)
.trim(),
10,
);
const contentEnd = contentStart + contentLength;
if (this.#chunk.length < contentEnd) {
// Not enough data yet, wait for next events
break;
}
const content = this.#chunk.subarray(contentStart, contentEnd).toString();
this.#chunk = this.#chunk.subarray(contentEnd);
events.push(JSON.parse(content));
} while (this.#chunk.length > 0);
return events;
}
}
function parseHeader(chunk: Buffer) {
for (let i = 0; i < chunk.length; i++) {
if (
chunk[i] === CARRIAGE_RETURN_CODE &&
chunk[i + 1] === LINE_FEED_CODE &&
chunk[i + 2] === CARRIAGE_RETURN_CODE &&
chunk[i + 3] === LINE_FEED_CODE
) {
return { header: chunk.subarray(0, i).toString(), contentStart: i + 4 };
}
}
return undefined;
}