protobufjs 8.1.6-experimental → 8.2.0
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 +219 -565
- package/dist/light/protobuf.js +1986 -1483
- 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 +1122 -861
- 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 +2089 -1513
- 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 -191
- package/ext/descriptor/index.js +1 -1161
- package/ext/descriptor.d.ts +309 -0
- package/ext/descriptor.js +1236 -0
- package/ext/textformat.d.ts +30 -0
- package/ext/textformat.js +1249 -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 +590 -476
- package/package.json +23 -38
- package/src/converter.js +60 -24
- package/src/decoder.js +122 -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 +23 -12
- package/src/object.js +24 -19
- package/src/oneof.js +2 -0
- package/src/parse.js +114 -46
- package/src/reader.js +145 -30
- package/src/reader_buffer.js +24 -3
- package/src/root.js +7 -4
- package/src/service.js +12 -6
- package/src/tokenize.js +6 -1
- package/src/type.js +48 -25
- 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 +67 -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 +104 -0
- package/src/util.js +30 -13
- package/src/verifier.js +7 -4
- package/src/wrappers.js +4 -3
- package/src/writer.js +27 -4
- package/src/writer_buffer.js +12 -0
- 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,8 @@ function parse(source, root, options) {
|
|
|
301
311
|
}
|
|
302
312
|
|
|
303
313
|
|
|
304
|
-
function parseCommon(parent, token) {
|
|
314
|
+
function parseCommon(parent, token, depth) {
|
|
315
|
+
depth = util.checkDepth(depth);
|
|
305
316
|
switch (token) {
|
|
306
317
|
|
|
307
318
|
case "option":
|
|
@@ -310,19 +321,35 @@ function parse(source, root, options) {
|
|
|
310
321
|
return true;
|
|
311
322
|
|
|
312
323
|
case "message":
|
|
313
|
-
parseType(parent, token);
|
|
324
|
+
parseType(parent, token, depth + 1);
|
|
314
325
|
return true;
|
|
315
326
|
|
|
316
327
|
case "enum":
|
|
317
328
|
parseEnum(parent, token);
|
|
318
329
|
return true;
|
|
319
330
|
|
|
331
|
+
case "export":
|
|
332
|
+
case "local":
|
|
333
|
+
if (edition < "2024") {
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
token = next();
|
|
337
|
+
if (token === "export" || token === "local") {
|
|
338
|
+
return false;
|
|
339
|
+
}
|
|
340
|
+
if (token !== "message" && token !== "enum") {
|
|
341
|
+
return false;
|
|
342
|
+
}
|
|
343
|
+
/* eslint-disable no-warning-comments */
|
|
344
|
+
// TODO: actually enforce visiblity modifiers like protoc does.
|
|
345
|
+
return parseCommon(parent, token, depth);
|
|
346
|
+
|
|
320
347
|
case "service":
|
|
321
|
-
parseService(parent, token);
|
|
348
|
+
parseService(parent, token, depth + 1);
|
|
322
349
|
return true;
|
|
323
350
|
|
|
324
351
|
case "extend":
|
|
325
|
-
parseExtension(parent, token);
|
|
352
|
+
parseExtension(parent, token, depth);
|
|
326
353
|
return true;
|
|
327
354
|
}
|
|
328
355
|
return false;
|
|
@@ -350,7 +377,8 @@ function parse(source, root, options) {
|
|
|
350
377
|
}
|
|
351
378
|
}
|
|
352
379
|
|
|
353
|
-
function parseType(parent, token) {
|
|
380
|
+
function parseType(parent, token, depth) {
|
|
381
|
+
depth = util.checkDepth(depth);
|
|
354
382
|
|
|
355
383
|
/* istanbul ignore if */
|
|
356
384
|
if (!nameRe.test(token = next()))
|
|
@@ -358,11 +386,14 @@ function parse(source, root, options) {
|
|
|
358
386
|
|
|
359
387
|
var type = new Type(token);
|
|
360
388
|
ifBlock(type, function parseType_block(token) {
|
|
361
|
-
if (parseCommon(type, token))
|
|
389
|
+
if (parseCommon(type, token, depth))
|
|
362
390
|
return;
|
|
363
391
|
|
|
364
392
|
switch (token) {
|
|
365
393
|
|
|
394
|
+
case ";":
|
|
395
|
+
break;
|
|
396
|
+
|
|
366
397
|
case "map":
|
|
367
398
|
parseMapField(type, token);
|
|
368
399
|
break;
|
|
@@ -372,22 +403,22 @@ function parse(source, root, options) {
|
|
|
372
403
|
throw illegal(token);
|
|
373
404
|
/* eslint-disable no-fallthrough */
|
|
374
405
|
case "repeated":
|
|
375
|
-
parseField(type, token);
|
|
406
|
+
parseField(type, token, undefined, depth + 1);
|
|
376
407
|
break;
|
|
377
408
|
|
|
378
409
|
case "optional":
|
|
379
410
|
/* istanbul ignore if */
|
|
380
411
|
if (edition === "proto3") {
|
|
381
|
-
parseField(type, "proto3_optional");
|
|
412
|
+
parseField(type, "proto3_optional", undefined, depth + 1);
|
|
382
413
|
} else if (edition !== "proto2") {
|
|
383
414
|
throw illegal(token);
|
|
384
415
|
} else {
|
|
385
|
-
parseField(type, "optional");
|
|
416
|
+
parseField(type, "optional", undefined, depth + 1);
|
|
386
417
|
}
|
|
387
418
|
break;
|
|
388
419
|
|
|
389
420
|
case "oneof":
|
|
390
|
-
parseOneOf(type, token);
|
|
421
|
+
parseOneOf(type, token, depth + 1);
|
|
391
422
|
break;
|
|
392
423
|
|
|
393
424
|
case "extensions":
|
|
@@ -405,7 +436,7 @@ function parse(source, root, options) {
|
|
|
405
436
|
}
|
|
406
437
|
|
|
407
438
|
push(token);
|
|
408
|
-
parseField(type, "optional");
|
|
439
|
+
parseField(type, "optional", undefined, depth + 1);
|
|
409
440
|
break;
|
|
410
441
|
}
|
|
411
442
|
});
|
|
@@ -415,10 +446,10 @@ function parse(source, root, options) {
|
|
|
415
446
|
}
|
|
416
447
|
}
|
|
417
448
|
|
|
418
|
-
function parseField(parent, rule, extend) {
|
|
449
|
+
function parseField(parent, rule, extend, depth) {
|
|
419
450
|
var type = next();
|
|
420
451
|
if (type === "group") {
|
|
421
|
-
parseGroup(parent, rule);
|
|
452
|
+
parseGroup(parent, rule, extend, depth);
|
|
422
453
|
return;
|
|
423
454
|
}
|
|
424
455
|
// Type names can consume multiple tokens, in multiple variants:
|
|
@@ -475,7 +506,8 @@ function parse(source, root, options) {
|
|
|
475
506
|
}
|
|
476
507
|
}
|
|
477
508
|
|
|
478
|
-
function parseGroup(parent, rule) {
|
|
509
|
+
function parseGroup(parent, rule, extend, depth) {
|
|
510
|
+
depth = util.checkDepth(depth);
|
|
479
511
|
if (edition >= 2023) {
|
|
480
512
|
throw illegal("group");
|
|
481
513
|
}
|
|
@@ -492,31 +524,34 @@ function parse(source, root, options) {
|
|
|
492
524
|
var id = parseId(next());
|
|
493
525
|
var type = new Type(name);
|
|
494
526
|
type.group = true;
|
|
495
|
-
var field = new Field(fieldName, id, name, rule);
|
|
527
|
+
var field = new Field(fieldName, id, name, rule, extend);
|
|
496
528
|
field.filename = parse.filename;
|
|
497
529
|
ifBlock(type, function parseGroup_block(token) {
|
|
498
530
|
switch (token) {
|
|
499
531
|
|
|
532
|
+
case ";":
|
|
533
|
+
break;
|
|
534
|
+
|
|
500
535
|
case "option":
|
|
501
536
|
parseOption(type, token);
|
|
502
537
|
skip(";");
|
|
503
538
|
break;
|
|
504
539
|
case "required":
|
|
505
540
|
case "repeated":
|
|
506
|
-
parseField(type, token);
|
|
541
|
+
parseField(type, token, undefined, depth + 1);
|
|
507
542
|
break;
|
|
508
543
|
|
|
509
544
|
case "optional":
|
|
510
545
|
/* istanbul ignore if */
|
|
511
546
|
if (edition === "proto3") {
|
|
512
|
-
parseField(type, "proto3_optional");
|
|
547
|
+
parseField(type, "proto3_optional", undefined, depth + 1);
|
|
513
548
|
} else {
|
|
514
|
-
parseField(type, "optional");
|
|
549
|
+
parseField(type, "optional", undefined, depth + 1);
|
|
515
550
|
}
|
|
516
551
|
break;
|
|
517
552
|
|
|
518
553
|
case "message":
|
|
519
|
-
parseType(type, token);
|
|
554
|
+
parseType(type, token, depth + 1);
|
|
520
555
|
break;
|
|
521
556
|
|
|
522
557
|
case "enum":
|
|
@@ -527,6 +562,24 @@ function parse(source, root, options) {
|
|
|
527
562
|
readRanges(type.reserved || (type.reserved = []), true);
|
|
528
563
|
break;
|
|
529
564
|
|
|
565
|
+
case "export":
|
|
566
|
+
case "local":
|
|
567
|
+
if (edition < "2024") {
|
|
568
|
+
throw illegal(token);
|
|
569
|
+
}
|
|
570
|
+
token = next();
|
|
571
|
+
switch (token) {
|
|
572
|
+
case "message":
|
|
573
|
+
parseType(type, token, depth + 1);
|
|
574
|
+
break;
|
|
575
|
+
case "enum":
|
|
576
|
+
parseType(type, token, depth + 1);
|
|
577
|
+
break;
|
|
578
|
+
default:
|
|
579
|
+
throw illegal(token);
|
|
580
|
+
}
|
|
581
|
+
break;
|
|
582
|
+
|
|
530
583
|
/* istanbul ignore next */
|
|
531
584
|
default:
|
|
532
585
|
throw illegal(token); // there are no groups with proto3 semantics
|
|
@@ -534,6 +587,10 @@ function parse(source, root, options) {
|
|
|
534
587
|
});
|
|
535
588
|
parent.add(type)
|
|
536
589
|
.add(field);
|
|
590
|
+
if (parent === ptr) {
|
|
591
|
+
topLevelObjects.push(type);
|
|
592
|
+
topLevelObjects.push(field);
|
|
593
|
+
}
|
|
537
594
|
}
|
|
538
595
|
|
|
539
596
|
function parseMapField(parent) {
|
|
@@ -575,7 +632,7 @@ function parse(source, root, options) {
|
|
|
575
632
|
parent.add(field);
|
|
576
633
|
}
|
|
577
634
|
|
|
578
|
-
function parseOneOf(parent, token) {
|
|
635
|
+
function parseOneOf(parent, token, depth) {
|
|
579
636
|
|
|
580
637
|
/* istanbul ignore if */
|
|
581
638
|
if (!nameRe.test(token = next()))
|
|
@@ -588,7 +645,7 @@ function parse(source, root, options) {
|
|
|
588
645
|
skip(";");
|
|
589
646
|
} else {
|
|
590
647
|
push(token);
|
|
591
|
-
parseField(oneof, "optional");
|
|
648
|
+
parseField(oneof, "optional", undefined, depth);
|
|
592
649
|
}
|
|
593
650
|
});
|
|
594
651
|
parent.add(oneof);
|
|
@@ -603,6 +660,9 @@ function parse(source, root, options) {
|
|
|
603
660
|
var enm = new Enum(token);
|
|
604
661
|
ifBlock(enm, function parseEnum_block(token) {
|
|
605
662
|
switch(token) {
|
|
663
|
+
case ";":
|
|
664
|
+
break;
|
|
665
|
+
|
|
606
666
|
case "option":
|
|
607
667
|
parseOption(enm, token);
|
|
608
668
|
skip(";");
|
|
@@ -693,7 +753,8 @@ function parse(source, root, options) {
|
|
|
693
753
|
setParsedOption(parent, option, optionValue, propName);
|
|
694
754
|
}
|
|
695
755
|
|
|
696
|
-
function parseOptionValue(parent, name) {
|
|
756
|
+
function parseOptionValue(parent, name, depth) {
|
|
757
|
+
depth = util.checkDepth(depth);
|
|
697
758
|
// { a: "foo" b { c: "bar" } }
|
|
698
759
|
if (skip("{", true)) {
|
|
699
760
|
var objectResult = {};
|
|
@@ -716,18 +777,20 @@ function parse(source, root, options) {
|
|
|
716
777
|
// option (my_option) = {
|
|
717
778
|
// repeated_value: [ "foo", "bar" ]
|
|
718
779
|
// };
|
|
719
|
-
value = parseOptionValue(parent, name + "." + token);
|
|
780
|
+
value = parseOptionValue(parent, name + "." + token, depth + 1);
|
|
720
781
|
} else if (peek() === "[") {
|
|
721
782
|
value = [];
|
|
722
783
|
var lastValue;
|
|
723
784
|
if (skip("[", true)) {
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
785
|
+
if (!skip("]", true)) {
|
|
786
|
+
do {
|
|
787
|
+
lastValue = readValue(true);
|
|
788
|
+
value.push(lastValue);
|
|
789
|
+
} while (skip(",", true));
|
|
790
|
+
skip("]");
|
|
791
|
+
if (typeof lastValue !== "undefined") {
|
|
792
|
+
setOption(parent, name + "." + token, lastValue);
|
|
793
|
+
}
|
|
731
794
|
}
|
|
732
795
|
}
|
|
733
796
|
} else {
|
|
@@ -740,7 +803,8 @@ function parse(source, root, options) {
|
|
|
740
803
|
if (prevValue)
|
|
741
804
|
value = [].concat(prevValue).concat(value);
|
|
742
805
|
|
|
743
|
-
|
|
806
|
+
if (propName !== "__proto__")
|
|
807
|
+
objectResult[propName] = value;
|
|
744
808
|
|
|
745
809
|
// Semicolons and commas can be optional
|
|
746
810
|
skip(",", true);
|
|
@@ -780,7 +844,8 @@ function parse(source, root, options) {
|
|
|
780
844
|
return parent;
|
|
781
845
|
}
|
|
782
846
|
|
|
783
|
-
function parseService(parent, token) {
|
|
847
|
+
function parseService(parent, token, depth) {
|
|
848
|
+
depth = util.checkDepth(depth);
|
|
784
849
|
|
|
785
850
|
/* istanbul ignore if */
|
|
786
851
|
if (!nameRe.test(token = next()))
|
|
@@ -788,11 +853,13 @@ function parse(source, root, options) {
|
|
|
788
853
|
|
|
789
854
|
var service = new Service(token);
|
|
790
855
|
ifBlock(service, function parseService_block(token) {
|
|
791
|
-
if (parseCommon(service, token)) {
|
|
856
|
+
if (parseCommon(service, token, depth)) {
|
|
792
857
|
return;
|
|
793
858
|
}
|
|
794
859
|
|
|
795
860
|
/* istanbul ignore else */
|
|
861
|
+
if (token === ";")
|
|
862
|
+
return;
|
|
796
863
|
if (token === "rpc")
|
|
797
864
|
parseMethod(service, token);
|
|
798
865
|
else
|
|
@@ -844,6 +911,8 @@ function parse(source, root, options) {
|
|
|
844
911
|
ifBlock(method, function parseMethod_block(token) {
|
|
845
912
|
|
|
846
913
|
/* istanbul ignore else */
|
|
914
|
+
if (token === ";")
|
|
915
|
+
return;
|
|
847
916
|
if (token === "option") {
|
|
848
917
|
parseOption(method, token);
|
|
849
918
|
skip(";");
|
|
@@ -854,7 +923,7 @@ function parse(source, root, options) {
|
|
|
854
923
|
parent.add(method);
|
|
855
924
|
}
|
|
856
925
|
|
|
857
|
-
function parseExtension(parent, token) {
|
|
926
|
+
function parseExtension(parent, token, depth) {
|
|
858
927
|
|
|
859
928
|
/* istanbul ignore if */
|
|
860
929
|
if (!typeRefRe.test(token = next()))
|
|
@@ -866,15 +935,15 @@ function parse(source, root, options) {
|
|
|
866
935
|
|
|
867
936
|
case "required":
|
|
868
937
|
case "repeated":
|
|
869
|
-
parseField(parent, token, reference);
|
|
938
|
+
parseField(parent, token, reference, depth + 1);
|
|
870
939
|
break;
|
|
871
940
|
|
|
872
941
|
case "optional":
|
|
873
942
|
/* istanbul ignore if */
|
|
874
943
|
if (edition === "proto3") {
|
|
875
|
-
parseField(parent, "proto3_optional", reference);
|
|
944
|
+
parseField(parent, "proto3_optional", reference, depth + 1);
|
|
876
945
|
} else {
|
|
877
|
-
parseField(parent, "optional", reference);
|
|
946
|
+
parseField(parent, "optional", reference, depth + 1);
|
|
878
947
|
}
|
|
879
948
|
break;
|
|
880
949
|
|
|
@@ -883,7 +952,7 @@ function parse(source, root, options) {
|
|
|
883
952
|
if (edition === "proto2" || !typeRefRe.test(token))
|
|
884
953
|
throw illegal(token);
|
|
885
954
|
push(token);
|
|
886
|
-
parseField(parent, "optional", reference);
|
|
955
|
+
parseField(parent, "optional", reference, depth + 1);
|
|
887
956
|
break;
|
|
888
957
|
}
|
|
889
958
|
});
|
|
@@ -893,6 +962,9 @@ function parse(source, root, options) {
|
|
|
893
962
|
while ((token = next()) !== null) {
|
|
894
963
|
switch (token) {
|
|
895
964
|
|
|
965
|
+
case ";":
|
|
966
|
+
break;
|
|
967
|
+
|
|
896
968
|
case "package":
|
|
897
969
|
|
|
898
970
|
/* istanbul ignore if */
|
|
@@ -904,10 +976,6 @@ function parse(source, root, options) {
|
|
|
904
976
|
|
|
905
977
|
case "import":
|
|
906
978
|
|
|
907
|
-
/* istanbul ignore if */
|
|
908
|
-
if (!head)
|
|
909
|
-
throw illegal(token);
|
|
910
|
-
|
|
911
979
|
parseImport();
|
|
912
980
|
break;
|
|
913
981
|
|
|
@@ -935,7 +1003,7 @@ function parse(source, root, options) {
|
|
|
935
1003
|
default:
|
|
936
1004
|
|
|
937
1005
|
/* istanbul ignore else */
|
|
938
|
-
if (parseCommon(ptr, token)) {
|
|
1006
|
+
if (parseCommon(ptr, token, 0)) {
|
|
939
1007
|
head = false;
|
|
940
1008
|
continue;
|
|
941
1009
|
}
|
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:
|
package/src/reader_buffer.js
CHANGED
|
@@ -30,15 +30,36 @@ BufferReader._configure = function () {
|
|
|
30
30
|
BufferReader.prototype._slice = util.Buffer.prototype.slice;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Returns raw bytes from the backing buffer without advancing the reader.
|
|
35
|
+
* @name BufferReader#raw
|
|
36
|
+
* @function
|
|
37
|
+
* @param {number} start Start offset
|
|
38
|
+
* @param {number} end End offset
|
|
39
|
+
* @returns {Buffer} Raw bytes
|
|
40
|
+
*/
|
|
41
|
+
BufferReader.prototype.raw = function read_raw_buffer(start, end) {
|
|
42
|
+
if (start === end)
|
|
43
|
+
return util.Buffer.alloc(0);
|
|
44
|
+
return this._slice.call(this.buf, start, end);
|
|
45
|
+
};
|
|
33
46
|
|
|
34
47
|
/**
|
|
35
48
|
* @override
|
|
36
49
|
*/
|
|
37
50
|
BufferReader.prototype.string = function read_string_buffer() {
|
|
38
|
-
var len = this.uint32()
|
|
51
|
+
var len = this.uint32(), // modifies pos
|
|
52
|
+
start = this.pos,
|
|
53
|
+
end = this.pos + len;
|
|
54
|
+
|
|
55
|
+
/* istanbul ignore if */
|
|
56
|
+
if (end > this.len)
|
|
57
|
+
throw RangeError("index out of range: " + this.pos + " + " + len + " > " + this.len);
|
|
58
|
+
|
|
59
|
+
this.pos = end;
|
|
39
60
|
return this.buf.utf8Slice
|
|
40
|
-
? this.buf.utf8Slice(
|
|
41
|
-
: this.buf.toString("utf-8",
|
|
61
|
+
? this.buf.utf8Slice(start, end)
|
|
62
|
+
: this.buf.toString("utf-8", start, end);
|
|
42
63
|
};
|
|
43
64
|
|
|
44
65
|
/**
|