Skip to content

Commit 11c2b3c

Browse files
committed
Converted from a generator to many() for perf.
1 parent ebbb22d commit 11c2b3c

File tree

1 file changed

+42
-41
lines changed

1 file changed

+42
-41
lines changed

src/parser.js

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
'use strict';
44

5-
const {flushable, gen, none} = require('stream-chain');
5+
const {flushable, gen, many, none} = require('stream-chain');
66
const fixUtf8Stream = require('stream-chain/utils/fixUtf8Stream.js');
77

88
const patterns = {
@@ -59,24 +59,27 @@ const jsonParser = options => {
5959

6060
let done = false,
6161
expect = jsonStreaming ? 'done' : 'value',
62-
stack = [],
6362
parent = '',
6463
openNumber = false,
6564
accumulator = '',
6665
buffer = '';
6766

68-
return flushable(function* (buf) {
67+
const stack = [];
68+
69+
return flushable(buf => {
70+
const tokens = [];
71+
6972
if (buf === none) {
7073
done = true;
7174
if (openNumber) {
72-
if (streamNumbers) yield {name: 'endNumber'};
75+
if (streamNumbers) tokens.push( {name: 'endNumber'});
7376
openNumber = false;
7477
if (packNumbers) {
75-
yield {name: 'numberValue', value: accumulator};
78+
tokens.push( {name: 'numberValue', value: accumulator});
7679
accumulator = '';
7780
}
7881
}
79-
return;
82+
return tokens.length ? many(tokens) : none;
8083
}
8184

8285
buffer += buf;
@@ -101,49 +104,47 @@ const jsonParser = options => {
101104
value = match[0];
102105
switch (value) {
103106
case '"':
104-
if (streamStrings) yield {name: 'startString'};
107+
if (streamStrings) tokens.push( {name: 'startString'});
105108
expect = 'string';
106109
break;
107110
case '{':
108-
yield {name: 'startObject'};
111+
tokens.push( {name: 'startObject'});
109112
stack.push(parent);
110113
parent = 'object';
111114
expect = 'key1';
112115
break;
113116
case '[':
114-
yield {name: 'startArray'};
117+
tokens.push( {name: 'startArray'});
115118
stack.push(parent);
116119
parent = 'array';
117120
expect = 'value1';
118121
break;
119122
case ']':
120123
if (expect !== 'value1') throw new Error("Parser cannot parse input: unexpected token ']'");
121124
if (openNumber) {
122-
if (streamNumbers) yield {name: 'endNumber'};
125+
if (streamNumbers) tokens.push( {name: 'endNumber'});
123126
openNumber = false;
124127
if (packNumbers) {
125-
yield {name: 'numberValue', value: accumulator};
128+
tokens.push( {name: 'numberValue', value: accumulator});
126129
accumulator = '';
127130
}
128131
}
129-
yield {name: 'endArray'};
132+
tokens.push( {name: 'endArray'});
130133
parent = stack.pop();
131134
expect = expected[parent];
132135
break;
133136
case '-':
134137
openNumber = true;
135138
if (streamNumbers) {
136-
yield {name: 'startNumber'};
137-
yield {name: 'numberChunk', value: '-'};
139+
tokens.push( {name: 'startNumber'},{name: 'numberChunk', value: '-'});
138140
}
139141
packNumbers && (accumulator = '-');
140142
expect = 'numberStart';
141143
break;
142144
case '0':
143145
openNumber = true;
144146
if (streamNumbers) {
145-
yield {name: 'startNumber'};
146-
yield {name: 'numberChunk', value: '0'};
147+
tokens.push( {name: 'startNumber'},{name: 'numberChunk', value: '0'});
147148
}
148149
packNumbers && (accumulator = '0');
149150
expect = 'numberFraction';
@@ -159,8 +160,7 @@ const jsonParser = options => {
159160
case '9':
160161
openNumber = true;
161162
if (streamNumbers) {
162-
yield {name: 'startNumber'};
163-
yield {name: 'numberChunk', value: value};
163+
tokens.push( {name: 'startNumber'}, {name: 'numberChunk', value: value});
164164
}
165165
packNumbers && (accumulator = value);
166166
expect = 'numberDigit';
@@ -169,7 +169,7 @@ const jsonParser = options => {
169169
case 'false':
170170
case 'null':
171171
if (buffer.length - index === value.length && !done) break main; // wait for more input
172-
yield {name: value + 'Value', value: values[value]};
172+
tokens.push( {name: value + 'Value', value: values[value]});
173173
expect = expected[parent];
174174
break;
175175
// default: // ws
@@ -188,31 +188,31 @@ const jsonParser = options => {
188188
value = match[0];
189189
if (value === '"') {
190190
if (expect === 'keyVal') {
191-
if (streamKeys) yield {name: 'endKey'};
191+
if (streamKeys) tokens.push( {name: 'endKey'});
192192
if (packKeys) {
193-
yield {name: 'keyValue', value: accumulator};
193+
tokens.push( {name: 'keyValue', value: accumulator});
194194
accumulator = '';
195195
}
196196
expect = 'colon';
197197
} else {
198-
if (streamStrings) yield {name: 'endString'};
198+
if (streamStrings) tokens.push( {name: 'endString'});
199199
if (packStrings) {
200-
yield {name: 'stringValue', value: accumulator};
200+
tokens.push( {name: 'stringValue', value: accumulator});
201201
accumulator = '';
202202
}
203203
expect = expected[parent];
204204
}
205205
} else if (value.length > 1 && value.charAt(0) === '\\') {
206206
const t = value.length == 2 ? codes[value.charAt(1)] : fromHex(value);
207207
if (expect === 'keyVal' ? streamKeys : streamStrings) {
208-
yield {name: 'stringChunk', value: t};
208+
tokens.push( {name: 'stringChunk', value: t});
209209
}
210210
if (expect === 'keyVal' ? packKeys : packStrings) {
211211
accumulator += t;
212212
}
213213
} else {
214214
if (expect === 'keyVal' ? streamKeys : streamStrings) {
215-
yield {name: 'stringChunk', value: value};
215+
tokens.push( {name: 'stringChunk', value: value});
216216
}
217217
if (expect === 'keyVal' ? packKeys : packStrings) {
218218
accumulator += value;
@@ -230,11 +230,11 @@ const jsonParser = options => {
230230
}
231231
value = match[0];
232232
if (value === '"') {
233-
if (streamKeys) yield {name: 'startKey'};
233+
if (streamKeys) tokens.push( {name: 'startKey'});
234234
expect = 'keyVal';
235235
} else if (value === '}') {
236236
if (expect !== 'key1') throw new Error("Parser cannot parse input: unexpected token '}'");
237-
yield {name: 'endObject'};
237+
tokens.push( {name: 'endObject'});
238238
parent = stack.pop();
239239
expect = expected[parent];
240240
}
@@ -260,10 +260,10 @@ const jsonParser = options => {
260260
break main; // wait for more input
261261
}
262262
if (openNumber) {
263-
if (streamNumbers) yield {name: 'endNumber'};
263+
if (streamNumbers) tokens.push( {name: 'endNumber'});
264264
openNumber = false;
265265
if (packNumbers) {
266-
yield {name: 'numberValue', value: accumulator};
266+
tokens.push( {name: 'numberValue', value: accumulator});
267267
accumulator = '';
268268
}
269269
}
@@ -274,7 +274,7 @@ const jsonParser = options => {
274274
if (value === '}' ? expect === 'arrayStop' : expect !== 'arrayStop') {
275275
throw new Error("Parser cannot parse input: expected '" + (expect === 'arrayStop' ? ']' : '}') + "'");
276276
}
277-
yield {name: value === '}' ? 'endObject' : 'endArray'};
277+
tokens.push( {name: value === '}' ? 'endObject' : 'endArray'});
278278
parent = stack.pop();
279279
expect = expected[parent];
280280
}
@@ -289,7 +289,7 @@ const jsonParser = options => {
289289
break main; // wait for more input
290290
}
291291
value = match[0];
292-
if (streamNumbers) yield {name: 'numberChunk', value: value};
292+
if (streamNumbers) tokens.push( {name: 'numberChunk', value: value});
293293
packNumbers && (accumulator += value);
294294
expect = value === '0' ? 'numberFraction' : 'numberDigit';
295295
index += value.length;
@@ -303,7 +303,7 @@ const jsonParser = options => {
303303
}
304304
value = match[0];
305305
if (value) {
306-
if (streamNumbers) yield {name: 'numberChunk', value: value};
306+
if (streamNumbers) tokens.push( {name: 'numberChunk', value: value});
307307
packNumbers && (accumulator += value);
308308
index += value.length;
309309
} else {
@@ -329,7 +329,7 @@ const jsonParser = options => {
329329
break main; // wait for more input
330330
}
331331
value = match[0];
332-
if (streamNumbers) yield {name: 'numberChunk', value: value};
332+
if (streamNumbers) tokens.push( {name: 'numberChunk', value: value});
333333
packNumbers && (accumulator += value);
334334
expect = value === '.' ? 'numberFracStart' : 'numberExpSign';
335335
index += value.length;
@@ -342,7 +342,7 @@ const jsonParser = options => {
342342
break main; // wait for more input
343343
}
344344
value = match[0];
345-
if (streamNumbers) yield {name: 'numberChunk', value: value};
345+
if (streamNumbers) tokens.push( {name: 'numberChunk', value: value});
346346
packNumbers && (accumulator += value);
347347
expect = 'numberFracDigit';
348348
index += value.length;
@@ -352,7 +352,7 @@ const jsonParser = options => {
352352
match = patterns.numberFracDigit.exec(buffer);
353353
value = match[0];
354354
if (value) {
355-
if (streamNumbers) yield {name: 'numberChunk', value: value};
355+
if (streamNumbers) tokens.push( {name: 'numberChunk', value: value});
356356
packNumbers && (accumulator += value);
357357
index += value.length;
358358
} else {
@@ -382,7 +382,7 @@ const jsonParser = options => {
382382
break main; // wait for more input
383383
}
384384
value = match[0];
385-
if (streamNumbers) yield {name: 'numberChunk', value: value};
385+
if (streamNumbers) tokens.push( {name: 'numberChunk', value: value});
386386
packNumbers && (accumulator += value);
387387
expect = 'numberExpSign';
388388
index += value.length;
@@ -399,7 +399,7 @@ const jsonParser = options => {
399399
break main; // wait for more input
400400
}
401401
value = match[0];
402-
if (streamNumbers) yield {name: 'numberChunk', value: value};
402+
if (streamNumbers) tokens.push( {name: 'numberChunk', value: value});
403403
packNumbers && (accumulator += value);
404404
expect = 'numberExpStart';
405405
index += value.length;
@@ -412,7 +412,7 @@ const jsonParser = options => {
412412
break main; // wait for more input
413413
}
414414
value = match[0];
415-
if (streamNumbers) yield {name: 'numberChunk', value: value};
415+
if (streamNumbers) tokens.push( {name: 'numberChunk', value: value});
416416
packNumbers && (accumulator += value);
417417
expect = 'numberExpDigit';
418418
index += value.length;
@@ -422,7 +422,7 @@ const jsonParser = options => {
422422
match = patterns.numberExpDigit.exec(buffer);
423423
value = match[0];
424424
if (value) {
425-
if (streamNumbers) yield {name: 'numberChunk', value: value};
425+
if (streamNumbers) tokens.push( {name: 'numberChunk', value: value});
426426
packNumbers && (accumulator += value);
427427
index += value.length;
428428
} else {
@@ -448,10 +448,10 @@ const jsonParser = options => {
448448
}
449449
value = match[0];
450450
if (openNumber) {
451-
if (streamNumbers) yield {name: 'endNumber'};
451+
if (streamNumbers) tokens.push( {name: 'endNumber'});
452452
openNumber = false;
453453
if (packNumbers) {
454-
yield {name: 'numberValue', value: accumulator};
454+
tokens.push( {name: 'numberValue', value: accumulator});
455455
accumulator = '';
456456
}
457457
}
@@ -460,6 +460,7 @@ const jsonParser = options => {
460460
}
461461
}
462462
buffer = buffer.slice(index);
463+
return tokens.length ? many(tokens) : none;
463464
});
464465
};
465466

0 commit comments

Comments
 (0)