Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/base/node/nodeStreams.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
import { Transform } from 'stream';
6
import { binaryIndexOf } from '../common/buffer.js';
7
8
/**
9
* A Transform stream that splits the input on the "splitter" substring.
10
* The resulting chunks will contain (and trail with) the splitter match.
11
* The last chunk when the stream ends will be emitted even if a splitter
12
* is not encountered.
13
*/
14
export class StreamSplitter extends Transform {
15
private buffer: Buffer | undefined;
16
private readonly splitter: Buffer | number;
17
private readonly spitterLen: number;
18
19
constructor(splitter: string | number | Buffer) {
20
super();
21
if (typeof splitter === 'number') {
22
this.splitter = splitter;
23
this.spitterLen = 1;
24
} else {
25
const buf = Buffer.isBuffer(splitter) ? splitter : Buffer.from(splitter);
26
this.splitter = buf.length === 1 ? buf[0] : buf;
27
this.spitterLen = buf.length;
28
}
29
}
30
31
override _transform(chunk: Buffer, _encoding: string, callback: (error?: Error | null, data?: Buffer) => void): void {
32
if (!this.buffer) {
33
this.buffer = chunk;
34
} else {
35
this.buffer = Buffer.concat([this.buffer, chunk]);
36
}
37
38
let offset = 0;
39
while (offset < this.buffer.length) {
40
const index = typeof this.splitter === 'number'
41
? this.buffer.indexOf(this.splitter, offset)
42
: binaryIndexOf(this.buffer, this.splitter, offset);
43
if (index === -1) {
44
break;
45
}
46
47
this.push(this.buffer.slice(offset, index + this.spitterLen));
48
offset = index + this.spitterLen;
49
}
50
51
this.buffer = offset === this.buffer.length ? undefined : this.buffer.slice(offset);
52
callback();
53
}
54
55
override _flush(callback: (error?: Error | null, data?: Buffer) => void): void {
56
if (this.buffer) {
57
this.push(this.buffer);
58
}
59
60
callback();
61
}
62
}
63
64