-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathparser.js
More file actions
78 lines (62 loc) · 1.89 KB
/
Copy pathparser.js
File metadata and controls
78 lines (62 loc) · 1.89 KB
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
class RESPParser {
constructor() {
this.buffer = Buffer.alloc(0);
}
append(data) {
this.buffer = Buffer.concat([this.buffer, data]);
}
*parse() {
let offset = 0;
while (offset < this.buffer.length) {
const type = this.buffer[offset];
if (type === 42) {
// '*' Array
const result = this.parseArray(offset);
if (!result) break;
offset = result.offset;
yield result.value;
} else {
// Unknown or incomplete
break;
}
}
this.buffer = this.buffer.slice(offset);
}
parseArray(offset) {
let currentOffset = offset + 1;
const lineEnd = this.buffer.indexOf("\r\n", currentOffset);
if (lineEnd === -1) return null;
const countStr = this.buffer.toString("utf8", currentOffset, lineEnd);
const count = parseInt(countStr, 10);
currentOffset = lineEnd + 2;
const array = [];
for (let i = 0; i < count; i++) {
const result = this.parseBulkString(currentOffset);
if (!result) return null;
array.push(result.value);
currentOffset = result.offset;
}
return { value: array, offset: currentOffset };
}
parseBulkString(offset) {
if (this.buffer[offset] !== 36) return null; // '$'
let currentOffset = offset + 1;
const lineEnd = this.buffer.indexOf("\r\n", currentOffset);
if (lineEnd === -1) return null;
const lengthStr = this.buffer.toString("utf8", currentOffset, lineEnd);
const length = parseInt(lengthStr, 10);
currentOffset = lineEnd + 2;
if (length === -1) {
return { value: null, offset: currentOffset };
}
if (this.buffer.length < currentOffset + length + 2) return null;
const value = this.buffer.toString(
"utf8",
currentOffset,
currentOffset + length,
);
currentOffset += length + 2;
return { value, offset: currentOffset };
}
}
module.exports = RESPParser;