protobufjs 8.1.6-experimental → 8.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +225 -570
- package/dist/light/protobuf.js +2041 -1482
- package/dist/light/protobuf.js.map +1 -1
- package/dist/light/protobuf.min.js +3 -3
- package/dist/light/protobuf.min.js.map +1 -1
- package/dist/minimal/protobuf.js +1167 -863
- package/dist/minimal/protobuf.js.map +1 -1
- package/dist/minimal/protobuf.min.js +3 -3
- package/dist/minimal/protobuf.min.js.map +1 -1
- package/dist/protobuf.js +2173 -1527
- package/dist/protobuf.js.map +1 -1
- package/dist/protobuf.min.js +3 -3
- package/dist/protobuf.min.js.map +1 -1
- package/ext/README.md +81 -0
- package/ext/descriptor/README.md +3 -70
- package/ext/descriptor/index.d.ts +1 -190
- package/ext/descriptor/index.js +1 -1161
- package/ext/descriptor.d.ts +309 -0
- package/ext/descriptor.js +1241 -0
- package/ext/textformat.d.ts +24 -0
- package/ext/textformat.js +1227 -0
- package/google/protobuf/compiler/plugin.json +126 -0
- package/google/protobuf/compiler/plugin.proto +47 -0
- package/google/protobuf/descriptor.json +2 -2
- package/google/protobuf/descriptor.proto +2 -1
- package/index.d.ts +585 -476
- package/package.json +22 -40
- package/src/converter.js +63 -27
- package/src/decoder.js +126 -49
- package/src/encoder.js +10 -2
- package/src/enum.js +4 -1
- package/src/field.js +10 -7
- package/src/mapfield.js +1 -0
- package/src/message.js +7 -6
- package/src/method.js +4 -3
- package/src/namespace.js +31 -12
- package/src/object.js +24 -19
- package/src/oneof.js +2 -0
- package/src/parse.js +128 -46
- package/src/reader.js +145 -30
- package/src/reader_buffer.js +24 -3
- package/src/root.js +10 -4
- package/src/service.js +15 -6
- package/src/tokenize.js +6 -1
- package/src/type.js +57 -27
- package/src/types.js +1 -1
- package/src/util/aspromise.d.ts +13 -0
- package/src/util/aspromise.js +52 -0
- package/src/util/base64.d.ts +32 -0
- package/src/util/base64.js +146 -0
- package/src/util/codegen.d.ts +31 -0
- package/src/util/codegen.js +113 -0
- package/src/util/eventemitter.d.ts +45 -0
- package/src/util/eventemitter.js +84 -0
- package/src/util/fetch.d.ts +56 -0
- package/src/util/fetch.js +112 -0
- package/src/util/float.d.ts +83 -0
- package/src/util/float.js +335 -0
- package/src/util/fs.js +11 -0
- package/src/util/inquire.d.ts +10 -0
- package/src/util/inquire.js +38 -0
- package/src/util/minimal.js +74 -12
- package/src/util/path.d.ts +22 -0
- package/src/util/path.js +72 -0
- package/src/util/patterns.js +8 -0
- package/src/util/pool.d.ts +32 -0
- package/src/util/pool.js +48 -0
- package/src/util/utf8.d.ts +24 -0
- package/src/util/utf8.js +130 -0
- package/src/util.js +18 -13
- package/src/verifier.js +7 -4
- package/src/wrappers.js +4 -3
- package/src/writer.js +33 -5
- package/src/writer_buffer.js +18 -1
- package/tsconfig.json +2 -2
- package/ext/descriptor/test.js +0 -54
package/src/parse.js
CHANGED
|
@@ -23,9 +23,9 @@ var base10Re = /^[1-9][0-9]*$/,
|
|
|
23
23
|
base16NegRe = /^-?0[x][0-9a-fA-F]+$/,
|
|
24
24
|
base8Re = /^0[0-7]+$/,
|
|
25
25
|
base8NegRe = /^-?0[0-7]+$/,
|
|
26
|
-
numberRe =
|
|
26
|
+
numberRe = util.patterns.numberRe,
|
|
27
27
|
nameRe = /^[a-zA-Z_][a-zA-Z_0-9]*$/,
|
|
28
|
-
typeRefRe =
|
|
28
|
+
typeRefRe = util.patterns.typeRefRe;
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Result object returned from {@link parse}.
|
|
@@ -261,6 +261,16 @@ function parse(source, root, options) {
|
|
|
261
261
|
var token = peek();
|
|
262
262
|
var whichImports;
|
|
263
263
|
switch (token) {
|
|
264
|
+
case "option":
|
|
265
|
+
if (edition < "2024") {
|
|
266
|
+
throw illegal("option");
|
|
267
|
+
}
|
|
268
|
+
// Import options are only used for resolving options, which we don't
|
|
269
|
+
// do. We can just throw them out.
|
|
270
|
+
next();
|
|
271
|
+
readString();
|
|
272
|
+
skip(";");
|
|
273
|
+
return;
|
|
264
274
|
case "weak":
|
|
265
275
|
whichImports = weakImports || (weakImports = []);
|
|
266
276
|
next();
|
|
@@ -291,7 +301,7 @@ function parse(source, root, options) {
|
|
|
291
301
|
function parseEdition() {
|
|
292
302
|
skip("=");
|
|
293
303
|
edition = readString();
|
|
294
|
-
const supportedEditions = ["2023"];
|
|
304
|
+
const supportedEditions = ["2023", "2024"];
|
|
295
305
|
|
|
296
306
|
/* istanbul ignore if */
|
|
297
307
|
if (!supportedEditions.includes(edition))
|
|
@@ -301,7 +311,10 @@ function parse(source, root, options) {
|
|
|
301
311
|
}
|
|
302
312
|
|
|
303
313
|
|
|
304
|
-
function parseCommon(parent, token) {
|
|
314
|
+
function parseCommon(parent, token, depth) {
|
|
315
|
+
if (depth === undefined)
|
|
316
|
+
depth = 0;
|
|
317
|
+
// depth is checked by dispatched functions
|
|
305
318
|
switch (token) {
|
|
306
319
|
|
|
307
320
|
case "option":
|
|
@@ -310,19 +323,35 @@ function parse(source, root, options) {
|
|
|
310
323
|
return true;
|
|
311
324
|
|
|
312
325
|
case "message":
|
|
313
|
-
parseType(parent, token);
|
|
326
|
+
parseType(parent, token, depth + 1);
|
|
314
327
|
return true;
|
|
315
328
|
|
|
316
329
|
case "enum":
|
|
317
330
|
parseEnum(parent, token);
|
|
318
331
|
return true;
|
|
319
332
|
|
|
333
|
+
case "export":
|
|
334
|
+
case "local":
|
|
335
|
+
if (edition < "2024") {
|
|
336
|
+
return false;
|
|
337
|
+
}
|
|
338
|
+
token = next();
|
|
339
|
+
if (token === "export" || token === "local") {
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
342
|
+
if (token !== "message" && token !== "enum") {
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
/* eslint-disable no-warning-comments */
|
|
346
|
+
// TODO: actually enforce visiblity modifiers like protoc does.
|
|
347
|
+
return parseCommon(parent, token, depth);
|
|
348
|
+
|
|
320
349
|
case "service":
|
|
321
|
-
parseService(parent, token);
|
|
350
|
+
parseService(parent, token, depth + 1);
|
|
322
351
|
return true;
|
|
323
352
|
|
|
324
353
|
case "extend":
|
|
325
|
-
parseExtension(parent, token);
|
|
354
|
+
parseExtension(parent, token, depth);
|
|
326
355
|
return true;
|
|
327
356
|
}
|
|
328
357
|
return false;
|
|
@@ -350,7 +379,11 @@ function parse(source, root, options) {
|
|
|
350
379
|
}
|
|
351
380
|
}
|
|
352
381
|
|
|
353
|
-
function parseType(parent, token) {
|
|
382
|
+
function parseType(parent, token, depth) {
|
|
383
|
+
if (depth === undefined)
|
|
384
|
+
depth = 0;
|
|
385
|
+
if (depth > util.nestingLimit)
|
|
386
|
+
throw Error("max depth exceeded");
|
|
354
387
|
|
|
355
388
|
/* istanbul ignore if */
|
|
356
389
|
if (!nameRe.test(token = next()))
|
|
@@ -358,11 +391,14 @@ function parse(source, root, options) {
|
|
|
358
391
|
|
|
359
392
|
var type = new Type(token);
|
|
360
393
|
ifBlock(type, function parseType_block(token) {
|
|
361
|
-
if (parseCommon(type, token))
|
|
394
|
+
if (parseCommon(type, token, depth))
|
|
362
395
|
return;
|
|
363
396
|
|
|
364
397
|
switch (token) {
|
|
365
398
|
|
|
399
|
+
case ";":
|
|
400
|
+
break;
|
|
401
|
+
|
|
366
402
|
case "map":
|
|
367
403
|
parseMapField(type, token);
|
|
368
404
|
break;
|
|
@@ -372,22 +408,22 @@ function parse(source, root, options) {
|
|
|
372
408
|
throw illegal(token);
|
|
373
409
|
/* eslint-disable no-fallthrough */
|
|
374
410
|
case "repeated":
|
|
375
|
-
parseField(type, token);
|
|
411
|
+
parseField(type, token, undefined, depth + 1);
|
|
376
412
|
break;
|
|
377
413
|
|
|
378
414
|
case "optional":
|
|
379
415
|
/* istanbul ignore if */
|
|
380
416
|
if (edition === "proto3") {
|
|
381
|
-
parseField(type, "proto3_optional");
|
|
417
|
+
parseField(type, "proto3_optional", undefined, depth + 1);
|
|
382
418
|
} else if (edition !== "proto2") {
|
|
383
419
|
throw illegal(token);
|
|
384
420
|
} else {
|
|
385
|
-
parseField(type, "optional");
|
|
421
|
+
parseField(type, "optional", undefined, depth + 1);
|
|
386
422
|
}
|
|
387
423
|
break;
|
|
388
424
|
|
|
389
425
|
case "oneof":
|
|
390
|
-
parseOneOf(type, token);
|
|
426
|
+
parseOneOf(type, token, depth + 1);
|
|
391
427
|
break;
|
|
392
428
|
|
|
393
429
|
case "extensions":
|
|
@@ -405,7 +441,7 @@ function parse(source, root, options) {
|
|
|
405
441
|
}
|
|
406
442
|
|
|
407
443
|
push(token);
|
|
408
|
-
parseField(type, "optional");
|
|
444
|
+
parseField(type, "optional", undefined, depth + 1);
|
|
409
445
|
break;
|
|
410
446
|
}
|
|
411
447
|
});
|
|
@@ -415,10 +451,10 @@ function parse(source, root, options) {
|
|
|
415
451
|
}
|
|
416
452
|
}
|
|
417
453
|
|
|
418
|
-
function parseField(parent, rule, extend) {
|
|
454
|
+
function parseField(parent, rule, extend, depth) {
|
|
419
455
|
var type = next();
|
|
420
456
|
if (type === "group") {
|
|
421
|
-
parseGroup(parent, rule);
|
|
457
|
+
parseGroup(parent, rule, extend, depth);
|
|
422
458
|
return;
|
|
423
459
|
}
|
|
424
460
|
// Type names can consume multiple tokens, in multiple variants:
|
|
@@ -475,7 +511,11 @@ function parse(source, root, options) {
|
|
|
475
511
|
}
|
|
476
512
|
}
|
|
477
513
|
|
|
478
|
-
function parseGroup(parent, rule) {
|
|
514
|
+
function parseGroup(parent, rule, extend, depth) {
|
|
515
|
+
if (depth === undefined)
|
|
516
|
+
depth = 0;
|
|
517
|
+
if (depth > util.nestingLimit)
|
|
518
|
+
throw Error("max depth exceeded");
|
|
479
519
|
if (edition >= 2023) {
|
|
480
520
|
throw illegal("group");
|
|
481
521
|
}
|
|
@@ -492,31 +532,34 @@ function parse(source, root, options) {
|
|
|
492
532
|
var id = parseId(next());
|
|
493
533
|
var type = new Type(name);
|
|
494
534
|
type.group = true;
|
|
495
|
-
var field = new Field(fieldName, id, name, rule);
|
|
535
|
+
var field = new Field(fieldName, id, name, rule, extend);
|
|
496
536
|
field.filename = parse.filename;
|
|
497
537
|
ifBlock(type, function parseGroup_block(token) {
|
|
498
538
|
switch (token) {
|
|
499
539
|
|
|
540
|
+
case ";":
|
|
541
|
+
break;
|
|
542
|
+
|
|
500
543
|
case "option":
|
|
501
544
|
parseOption(type, token);
|
|
502
545
|
skip(";");
|
|
503
546
|
break;
|
|
504
547
|
case "required":
|
|
505
548
|
case "repeated":
|
|
506
|
-
parseField(type, token);
|
|
549
|
+
parseField(type, token, undefined, depth + 1);
|
|
507
550
|
break;
|
|
508
551
|
|
|
509
552
|
case "optional":
|
|
510
553
|
/* istanbul ignore if */
|
|
511
554
|
if (edition === "proto3") {
|
|
512
|
-
parseField(type, "proto3_optional");
|
|
555
|
+
parseField(type, "proto3_optional", undefined, depth + 1);
|
|
513
556
|
} else {
|
|
514
|
-
parseField(type, "optional");
|
|
557
|
+
parseField(type, "optional", undefined, depth + 1);
|
|
515
558
|
}
|
|
516
559
|
break;
|
|
517
560
|
|
|
518
561
|
case "message":
|
|
519
|
-
parseType(type, token);
|
|
562
|
+
parseType(type, token, depth + 1);
|
|
520
563
|
break;
|
|
521
564
|
|
|
522
565
|
case "enum":
|
|
@@ -527,6 +570,24 @@ function parse(source, root, options) {
|
|
|
527
570
|
readRanges(type.reserved || (type.reserved = []), true);
|
|
528
571
|
break;
|
|
529
572
|
|
|
573
|
+
case "export":
|
|
574
|
+
case "local":
|
|
575
|
+
if (edition < "2024") {
|
|
576
|
+
throw illegal(token);
|
|
577
|
+
}
|
|
578
|
+
token = next();
|
|
579
|
+
switch (token) {
|
|
580
|
+
case "message":
|
|
581
|
+
parseType(type, token, depth + 1);
|
|
582
|
+
break;
|
|
583
|
+
case "enum":
|
|
584
|
+
parseType(type, token, depth + 1);
|
|
585
|
+
break;
|
|
586
|
+
default:
|
|
587
|
+
throw illegal(token);
|
|
588
|
+
}
|
|
589
|
+
break;
|
|
590
|
+
|
|
530
591
|
/* istanbul ignore next */
|
|
531
592
|
default:
|
|
532
593
|
throw illegal(token); // there are no groups with proto3 semantics
|
|
@@ -534,6 +595,10 @@ function parse(source, root, options) {
|
|
|
534
595
|
});
|
|
535
596
|
parent.add(type)
|
|
536
597
|
.add(field);
|
|
598
|
+
if (parent === ptr) {
|
|
599
|
+
topLevelObjects.push(type);
|
|
600
|
+
topLevelObjects.push(field);
|
|
601
|
+
}
|
|
537
602
|
}
|
|
538
603
|
|
|
539
604
|
function parseMapField(parent) {
|
|
@@ -575,7 +640,7 @@ function parse(source, root, options) {
|
|
|
575
640
|
parent.add(field);
|
|
576
641
|
}
|
|
577
642
|
|
|
578
|
-
function parseOneOf(parent, token) {
|
|
643
|
+
function parseOneOf(parent, token, depth) {
|
|
579
644
|
|
|
580
645
|
/* istanbul ignore if */
|
|
581
646
|
if (!nameRe.test(token = next()))
|
|
@@ -588,7 +653,7 @@ function parse(source, root, options) {
|
|
|
588
653
|
skip(";");
|
|
589
654
|
} else {
|
|
590
655
|
push(token);
|
|
591
|
-
parseField(oneof, "optional");
|
|
656
|
+
parseField(oneof, "optional", undefined, depth);
|
|
592
657
|
}
|
|
593
658
|
});
|
|
594
659
|
parent.add(oneof);
|
|
@@ -603,6 +668,9 @@ function parse(source, root, options) {
|
|
|
603
668
|
var enm = new Enum(token);
|
|
604
669
|
ifBlock(enm, function parseEnum_block(token) {
|
|
605
670
|
switch(token) {
|
|
671
|
+
case ";":
|
|
672
|
+
break;
|
|
673
|
+
|
|
606
674
|
case "option":
|
|
607
675
|
parseOption(enm, token);
|
|
608
676
|
skip(";");
|
|
@@ -693,7 +761,11 @@ function parse(source, root, options) {
|
|
|
693
761
|
setParsedOption(parent, option, optionValue, propName);
|
|
694
762
|
}
|
|
695
763
|
|
|
696
|
-
function parseOptionValue(parent, name) {
|
|
764
|
+
function parseOptionValue(parent, name, depth) {
|
|
765
|
+
if (depth === undefined)
|
|
766
|
+
depth = 0;
|
|
767
|
+
if (depth > util.recursionLimit)
|
|
768
|
+
throw Error("max depth exceeded");
|
|
697
769
|
// { a: "foo" b { c: "bar" } }
|
|
698
770
|
if (skip("{", true)) {
|
|
699
771
|
var objectResult = {};
|
|
@@ -716,18 +788,20 @@ function parse(source, root, options) {
|
|
|
716
788
|
// option (my_option) = {
|
|
717
789
|
// repeated_value: [ "foo", "bar" ]
|
|
718
790
|
// };
|
|
719
|
-
value = parseOptionValue(parent, name + "." + token);
|
|
791
|
+
value = parseOptionValue(parent, name + "." + token, depth + 1);
|
|
720
792
|
} else if (peek() === "[") {
|
|
721
793
|
value = [];
|
|
722
794
|
var lastValue;
|
|
723
795
|
if (skip("[", true)) {
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
796
|
+
if (!skip("]", true)) {
|
|
797
|
+
do {
|
|
798
|
+
lastValue = readValue(true);
|
|
799
|
+
value.push(lastValue);
|
|
800
|
+
} while (skip(",", true));
|
|
801
|
+
skip("]");
|
|
802
|
+
if (typeof lastValue !== "undefined") {
|
|
803
|
+
setOption(parent, name + "." + token, lastValue);
|
|
804
|
+
}
|
|
731
805
|
}
|
|
732
806
|
}
|
|
733
807
|
} else {
|
|
@@ -740,7 +814,8 @@ function parse(source, root, options) {
|
|
|
740
814
|
if (prevValue)
|
|
741
815
|
value = [].concat(prevValue).concat(value);
|
|
742
816
|
|
|
743
|
-
|
|
817
|
+
if (propName !== "__proto__")
|
|
818
|
+
objectResult[propName] = value;
|
|
744
819
|
|
|
745
820
|
// Semicolons and commas can be optional
|
|
746
821
|
skip(",", true);
|
|
@@ -780,7 +855,11 @@ function parse(source, root, options) {
|
|
|
780
855
|
return parent;
|
|
781
856
|
}
|
|
782
857
|
|
|
783
|
-
function parseService(parent, token) {
|
|
858
|
+
function parseService(parent, token, depth) {
|
|
859
|
+
if (depth === undefined)
|
|
860
|
+
depth = 0;
|
|
861
|
+
if (depth > util.recursionLimit)
|
|
862
|
+
throw Error("max depth exceeded");
|
|
784
863
|
|
|
785
864
|
/* istanbul ignore if */
|
|
786
865
|
if (!nameRe.test(token = next()))
|
|
@@ -788,11 +867,13 @@ function parse(source, root, options) {
|
|
|
788
867
|
|
|
789
868
|
var service = new Service(token);
|
|
790
869
|
ifBlock(service, function parseService_block(token) {
|
|
791
|
-
if (parseCommon(service, token)) {
|
|
870
|
+
if (parseCommon(service, token, depth)) {
|
|
792
871
|
return;
|
|
793
872
|
}
|
|
794
873
|
|
|
795
874
|
/* istanbul ignore else */
|
|
875
|
+
if (token === ";")
|
|
876
|
+
return;
|
|
796
877
|
if (token === "rpc")
|
|
797
878
|
parseMethod(service, token);
|
|
798
879
|
else
|
|
@@ -844,6 +925,8 @@ function parse(source, root, options) {
|
|
|
844
925
|
ifBlock(method, function parseMethod_block(token) {
|
|
845
926
|
|
|
846
927
|
/* istanbul ignore else */
|
|
928
|
+
if (token === ";")
|
|
929
|
+
return;
|
|
847
930
|
if (token === "option") {
|
|
848
931
|
parseOption(method, token);
|
|
849
932
|
skip(";");
|
|
@@ -854,7 +937,7 @@ function parse(source, root, options) {
|
|
|
854
937
|
parent.add(method);
|
|
855
938
|
}
|
|
856
939
|
|
|
857
|
-
function parseExtension(parent, token) {
|
|
940
|
+
function parseExtension(parent, token, depth) {
|
|
858
941
|
|
|
859
942
|
/* istanbul ignore if */
|
|
860
943
|
if (!typeRefRe.test(token = next()))
|
|
@@ -866,15 +949,15 @@ function parse(source, root, options) {
|
|
|
866
949
|
|
|
867
950
|
case "required":
|
|
868
951
|
case "repeated":
|
|
869
|
-
parseField(parent, token, reference);
|
|
952
|
+
parseField(parent, token, reference, depth + 1);
|
|
870
953
|
break;
|
|
871
954
|
|
|
872
955
|
case "optional":
|
|
873
956
|
/* istanbul ignore if */
|
|
874
957
|
if (edition === "proto3") {
|
|
875
|
-
parseField(parent, "proto3_optional", reference);
|
|
958
|
+
parseField(parent, "proto3_optional", reference, depth + 1);
|
|
876
959
|
} else {
|
|
877
|
-
parseField(parent, "optional", reference);
|
|
960
|
+
parseField(parent, "optional", reference, depth + 1);
|
|
878
961
|
}
|
|
879
962
|
break;
|
|
880
963
|
|
|
@@ -883,7 +966,7 @@ function parse(source, root, options) {
|
|
|
883
966
|
if (edition === "proto2" || !typeRefRe.test(token))
|
|
884
967
|
throw illegal(token);
|
|
885
968
|
push(token);
|
|
886
|
-
parseField(parent, "optional", reference);
|
|
969
|
+
parseField(parent, "optional", reference, depth + 1);
|
|
887
970
|
break;
|
|
888
971
|
}
|
|
889
972
|
});
|
|
@@ -893,6 +976,9 @@ function parse(source, root, options) {
|
|
|
893
976
|
while ((token = next()) !== null) {
|
|
894
977
|
switch (token) {
|
|
895
978
|
|
|
979
|
+
case ";":
|
|
980
|
+
break;
|
|
981
|
+
|
|
896
982
|
case "package":
|
|
897
983
|
|
|
898
984
|
/* istanbul ignore if */
|
|
@@ -904,10 +990,6 @@ function parse(source, root, options) {
|
|
|
904
990
|
|
|
905
991
|
case "import":
|
|
906
992
|
|
|
907
|
-
/* istanbul ignore if */
|
|
908
|
-
if (!head)
|
|
909
|
-
throw illegal(token);
|
|
910
|
-
|
|
911
993
|
parseImport();
|
|
912
994
|
break;
|
|
913
995
|
|
|
@@ -935,7 +1017,7 @@ function parse(source, root, options) {
|
|
|
935
1017
|
default:
|
|
936
1018
|
|
|
937
1019
|
/* istanbul ignore else */
|
|
938
|
-
if (parseCommon(ptr, token)) {
|
|
1020
|
+
if (parseCommon(ptr, token, 0)) {
|
|
939
1021
|
head = false;
|
|
940
1022
|
continue;
|
|
941
1023
|
}
|
package/src/reader.js
CHANGED
|
@@ -78,28 +78,108 @@ Reader.create = create();
|
|
|
78
78
|
|
|
79
79
|
Reader.prototype._slice = util.Array.prototype.subarray || /* istanbul ignore next */ util.Array.prototype.slice;
|
|
80
80
|
|
|
81
|
+
/**
|
|
82
|
+
* Returns raw bytes from the backing buffer without advancing the reader.
|
|
83
|
+
* @param {number} start Start offset
|
|
84
|
+
* @param {number} end End offset
|
|
85
|
+
* @returns {Uint8Array} Raw bytes
|
|
86
|
+
*/
|
|
87
|
+
Reader.prototype.raw = function read_raw(start, end) {
|
|
88
|
+
if (Array.isArray(this.buf)) // plain array
|
|
89
|
+
return this.buf.slice(start, end);
|
|
90
|
+
|
|
91
|
+
if (start === end) // fix for IE 10/Win8 and others' subarray returning array of size 1
|
|
92
|
+
return new this.buf.constructor(0);
|
|
93
|
+
return this._slice.call(this.buf, start, end);
|
|
94
|
+
};
|
|
95
|
+
|
|
81
96
|
/**
|
|
82
97
|
* Reads a varint as an unsigned 32 bit value.
|
|
83
98
|
* @function
|
|
84
99
|
* @returns {number} Value read
|
|
85
100
|
*/
|
|
86
|
-
Reader.prototype.uint32 =
|
|
87
|
-
var
|
|
88
|
-
|
|
89
|
-
value = (
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
101
|
+
Reader.prototype.uint32 = function read_uint32() {
|
|
102
|
+
var buf = this.buf,
|
|
103
|
+
pos = this.pos,
|
|
104
|
+
value = (buf[pos] & 127) >>> 0;
|
|
105
|
+
if (buf[pos++] < 128) {
|
|
106
|
+
this.pos = pos;
|
|
107
|
+
return value;
|
|
108
|
+
}
|
|
109
|
+
value = (value | (buf[pos] & 127) << 7) >>> 0;
|
|
110
|
+
if (buf[pos++] < 128) {
|
|
111
|
+
this.pos = pos;
|
|
112
|
+
return value;
|
|
113
|
+
}
|
|
114
|
+
value = (value | (buf[pos] & 127) << 14) >>> 0;
|
|
115
|
+
if (buf[pos++] < 128) {
|
|
116
|
+
this.pos = pos;
|
|
117
|
+
return value;
|
|
118
|
+
}
|
|
119
|
+
value = (value | (buf[pos] & 127) << 21) >>> 0;
|
|
120
|
+
if (buf[pos++] < 128) {
|
|
121
|
+
this.pos = pos;
|
|
122
|
+
return value;
|
|
123
|
+
}
|
|
124
|
+
value = (value | (buf[pos] & 15) << 28) >>> 0;
|
|
125
|
+
if (buf[pos++] < 128) {
|
|
126
|
+
this.pos = pos;
|
|
127
|
+
return value;
|
|
128
|
+
}
|
|
94
129
|
|
|
130
|
+
for (var i = 0; i < 5; ++i) {
|
|
95
131
|
/* istanbul ignore if */
|
|
96
|
-
if (
|
|
97
|
-
this.pos =
|
|
98
|
-
throw indexOutOfRange(this
|
|
132
|
+
if (pos >= this.len) {
|
|
133
|
+
this.pos = pos;
|
|
134
|
+
throw indexOutOfRange(this);
|
|
135
|
+
}
|
|
136
|
+
if (buf[pos++] < 128) {
|
|
137
|
+
this.pos = pos;
|
|
138
|
+
return value;
|
|
99
139
|
}
|
|
140
|
+
}
|
|
141
|
+
/* istanbul ignore next */
|
|
142
|
+
this.pos = pos;
|
|
143
|
+
throw Error("invalid varint encoding");
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Reads a field tag.
|
|
148
|
+
* @function
|
|
149
|
+
* @returns {number} Tag read
|
|
150
|
+
*/
|
|
151
|
+
Reader.prototype.tag = function read_tag() {
|
|
152
|
+
var buf = this.buf,
|
|
153
|
+
pos = this.pos,
|
|
154
|
+
value = (buf[pos] & 127) >>> 0;
|
|
155
|
+
if (buf[pos++] < 128) {
|
|
156
|
+
this.pos = pos;
|
|
100
157
|
return value;
|
|
101
|
-
}
|
|
102
|
-
|
|
158
|
+
}
|
|
159
|
+
value = (value | (buf[pos] & 127) << 7) >>> 0;
|
|
160
|
+
if (buf[pos++] < 128) {
|
|
161
|
+
this.pos = pos;
|
|
162
|
+
return value;
|
|
163
|
+
}
|
|
164
|
+
value = (value | (buf[pos] & 127) << 14) >>> 0;
|
|
165
|
+
if (buf[pos++] < 128) {
|
|
166
|
+
this.pos = pos;
|
|
167
|
+
return value;
|
|
168
|
+
}
|
|
169
|
+
value = (value | (buf[pos] & 127) << 21) >>> 0;
|
|
170
|
+
if (buf[pos++] < 128) {
|
|
171
|
+
this.pos = pos;
|
|
172
|
+
return value;
|
|
173
|
+
}
|
|
174
|
+
value = (value | (buf[pos] & 15) << 28) >>> 0;
|
|
175
|
+
if (buf[pos] < 128 && (buf[pos] & 112) === 0) {
|
|
176
|
+
this.pos = pos + 1;
|
|
177
|
+
return value;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
this.pos = pos + 1;
|
|
181
|
+
throw Error("invalid tag encoding");
|
|
182
|
+
};
|
|
103
183
|
|
|
104
184
|
/**
|
|
105
185
|
* Reads a varint as a signed 32 bit value.
|
|
@@ -201,7 +281,20 @@ function readLongVarint() {
|
|
|
201
281
|
* @returns {boolean} Value read
|
|
202
282
|
*/
|
|
203
283
|
Reader.prototype.bool = function read_bool() {
|
|
204
|
-
|
|
284
|
+
var value = false,
|
|
285
|
+
b;
|
|
286
|
+
for (var i = 0; i < 10; ++i) {
|
|
287
|
+
/* istanbul ignore if */
|
|
288
|
+
if (this.pos >= this.len)
|
|
289
|
+
throw indexOutOfRange(this);
|
|
290
|
+
b = this.buf[this.pos++];
|
|
291
|
+
if (b & 127)
|
|
292
|
+
value = true;
|
|
293
|
+
if (b < 128)
|
|
294
|
+
return value;
|
|
295
|
+
}
|
|
296
|
+
/* istanbul ignore next */
|
|
297
|
+
throw Error("invalid varint encoding");
|
|
205
298
|
};
|
|
206
299
|
|
|
207
300
|
function readFixed32_end(buf, end) { // note that this uses `end`, not `pos`
|
|
@@ -309,17 +402,8 @@ Reader.prototype.bytes = function read_bytes() {
|
|
|
309
402
|
if (end > this.len)
|
|
310
403
|
throw indexOutOfRange(this, length);
|
|
311
404
|
|
|
312
|
-
this.pos
|
|
313
|
-
|
|
314
|
-
return this.buf.slice(start, end);
|
|
315
|
-
|
|
316
|
-
if (start === end) { // fix for IE 10/Win8 and others' subarray returning array of size 1
|
|
317
|
-
var nativeBuffer = util.Buffer;
|
|
318
|
-
return nativeBuffer
|
|
319
|
-
? nativeBuffer.alloc(0)
|
|
320
|
-
: new this.buf.constructor(0);
|
|
321
|
-
}
|
|
322
|
-
return this._slice.call(this.buf, start, end);
|
|
405
|
+
this.pos = end;
|
|
406
|
+
return this.raw(start, end);
|
|
323
407
|
};
|
|
324
408
|
|
|
325
409
|
/**
|
|
@@ -327,8 +411,16 @@ Reader.prototype.bytes = function read_bytes() {
|
|
|
327
411
|
* @returns {string} Value read
|
|
328
412
|
*/
|
|
329
413
|
Reader.prototype.string = function read_string() {
|
|
330
|
-
var
|
|
331
|
-
|
|
414
|
+
var length = this.uint32(),
|
|
415
|
+
start = this.pos,
|
|
416
|
+
end = this.pos + length;
|
|
417
|
+
|
|
418
|
+
/* istanbul ignore if */
|
|
419
|
+
if (end > this.len)
|
|
420
|
+
throw indexOutOfRange(this, length);
|
|
421
|
+
|
|
422
|
+
this.pos = end;
|
|
423
|
+
return utf8.read(this.buf, start, end);
|
|
332
424
|
};
|
|
333
425
|
|
|
334
426
|
/**
|
|
@@ -352,12 +444,25 @@ Reader.prototype.skip = function skip(length) {
|
|
|
352
444
|
return this;
|
|
353
445
|
};
|
|
354
446
|
|
|
447
|
+
/**
|
|
448
|
+
* Recursion limit.
|
|
449
|
+
* @type {number}
|
|
450
|
+
*/
|
|
451
|
+
Reader.recursionLimit = util.recursionLimit;
|
|
452
|
+
|
|
355
453
|
/**
|
|
356
454
|
* Skips the next element of the specified wire type.
|
|
357
455
|
* @param {number} wireType Wire type received
|
|
456
|
+
* @param {number} [depth] Depth of recursion to control nested calls; 0 if omitted
|
|
457
|
+
* @param {number} [fieldNumber] Field number for validating group end tags
|
|
358
458
|
* @returns {Reader} `this`
|
|
359
459
|
*/
|
|
360
|
-
Reader.prototype.skipType = function(wireType) {
|
|
460
|
+
Reader.prototype.skipType = function(wireType, depth, fieldNumber) {
|
|
461
|
+
if (depth === undefined) depth = 0;
|
|
462
|
+
if (depth > Reader.recursionLimit)
|
|
463
|
+
throw Error("max depth exceeded");
|
|
464
|
+
if (fieldNumber === 0)
|
|
465
|
+
throw Error("illegal tag: field number 0");
|
|
361
466
|
switch (wireType) {
|
|
362
467
|
case 0:
|
|
363
468
|
this.skip();
|
|
@@ -369,8 +474,18 @@ Reader.prototype.skipType = function(wireType) {
|
|
|
369
474
|
this.skip(this.uint32());
|
|
370
475
|
break;
|
|
371
476
|
case 3:
|
|
372
|
-
while (
|
|
373
|
-
this.
|
|
477
|
+
while (true) {
|
|
478
|
+
var tag = this.tag();
|
|
479
|
+
var nestedField = tag >>> 3;
|
|
480
|
+
wireType = tag & 7;
|
|
481
|
+
if (!nestedField)
|
|
482
|
+
throw Error("illegal tag: field number 0");
|
|
483
|
+
if (wireType === 4) {
|
|
484
|
+
if (fieldNumber !== undefined && nestedField !== fieldNumber)
|
|
485
|
+
throw Error("invalid end group tag");
|
|
486
|
+
break;
|
|
487
|
+
}
|
|
488
|
+
this.skipType(wireType, depth + 1, nestedField);
|
|
374
489
|
}
|
|
375
490
|
break;
|
|
376
491
|
case 5:
|