cbor-x 0.8.0 → 0.9.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/.vscode/launch.json +22 -0
- package/README.md +49 -45
- package/SECURITY.md +11 -0
- package/{unpack.d.ts → decode.d.ts} +12 -11
- package/decode.js +86 -33
- package/dist/index.js +194 -49
- package/dist/index.min.js +65 -51
- package/dist/node.cjs +228 -81
- package/dist/test.js +33 -1
- package/encode.d.ts +6 -0
- package/encode.js +31 -18
- package/index.d.ts +7 -6
- package/index.js +2 -2
- package/iterators.js +85 -0
- package/node-index.js +24 -0
- package/package.json +16 -17
- package/rollup.config.js +5 -5
- package/stream.js +20 -22
- package/tests/benchmark.cjs +13 -7
- package/tests/{test-compatibility.js → test-compatibility.cjs} +7 -12
- package/tests/test-incomplete.js +41 -0
- package/tests/test-node-iterators.js +72 -0
- package/tests/test-node-stream.js +17 -5
- package/tests/test.js +33 -2
- package/index.mjs +0 -35
- package/node.js +0 -25
- package/pack.d.ts +0 -9
- package/tests/test.mjs +0 -31
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
(function (global, factory) {
|
|
2
2
|
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
3
3
|
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
4
|
-
(global = global || self, factory(global.
|
|
4
|
+
(global = global || self, factory(global.CBOR = {}));
|
|
5
5
|
}(this, (function (exports) { 'use strict';
|
|
6
6
|
|
|
7
7
|
let decoder;
|
|
@@ -21,10 +21,12 @@
|
|
|
21
21
|
let referenceMap;
|
|
22
22
|
let currentExtensions = [];
|
|
23
23
|
let dataView;
|
|
24
|
+
let restoreMapsAsObject;
|
|
24
25
|
let defaultOptions = {
|
|
25
26
|
useRecords: false,
|
|
26
27
|
mapsAsObjects: true
|
|
27
28
|
};
|
|
29
|
+
let sequentialMode = false;
|
|
28
30
|
|
|
29
31
|
class Decoder {
|
|
30
32
|
constructor(options) {
|
|
@@ -36,12 +38,12 @@
|
|
|
36
38
|
}
|
|
37
39
|
Object.assign(this, options);
|
|
38
40
|
}
|
|
39
|
-
decode(source, end
|
|
41
|
+
decode(source, end) {
|
|
40
42
|
if (src) {
|
|
41
43
|
// re-entrant execution, save the state and restore it after we do this decode
|
|
42
44
|
return saveState(() => {
|
|
43
45
|
clearSource();
|
|
44
|
-
return this ? this.decode(source, end
|
|
46
|
+
return this ? this.decode(source, end) : Decoder.prototype.decode.call(defaultOptions, source, end)
|
|
45
47
|
})
|
|
46
48
|
}
|
|
47
49
|
srcEnd = end > -1 ? end : source.length;
|
|
@@ -57,17 +59,7 @@
|
|
|
57
59
|
currentDecoder = this;
|
|
58
60
|
if (this.structures) {
|
|
59
61
|
currentStructures = this.structures;
|
|
60
|
-
|
|
61
|
-
return read()
|
|
62
|
-
} finally {
|
|
63
|
-
if (position >= srcEnd || !continueReading) {
|
|
64
|
-
// finished reading this source, cleanup references
|
|
65
|
-
currentStructures = null;
|
|
66
|
-
src = null;
|
|
67
|
-
if (referenceMap)
|
|
68
|
-
referenceMap = null;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
62
|
+
return checkedRead()
|
|
71
63
|
} else if (!currentStructures || currentStructures.length > 0) {
|
|
72
64
|
currentStructures = [];
|
|
73
65
|
}
|
|
@@ -76,26 +68,19 @@
|
|
|
76
68
|
if (!currentStructures || currentStructures.length > 0)
|
|
77
69
|
currentStructures = [];
|
|
78
70
|
}
|
|
79
|
-
|
|
80
|
-
return read()
|
|
81
|
-
} finally {
|
|
82
|
-
if (position >= srcEnd || !continueReading) {
|
|
83
|
-
src = null;
|
|
84
|
-
if (referenceMap)
|
|
85
|
-
referenceMap = null;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
71
|
+
return checkedRead()
|
|
88
72
|
}
|
|
89
73
|
decodeMultiple(source, forEach) {
|
|
74
|
+
let values, lastPosition = 0;
|
|
90
75
|
try {
|
|
91
|
-
let decoder = this;
|
|
92
76
|
let size = source.length;
|
|
93
|
-
|
|
94
|
-
let
|
|
77
|
+
sequentialMode = true;
|
|
78
|
+
let value = this ? this.decode(source, size) : defaultDecoder.decode(source, size);
|
|
95
79
|
if (forEach) {
|
|
96
80
|
forEach(value);
|
|
97
81
|
while(position < size) {
|
|
98
|
-
|
|
82
|
+
lastPosition = position;
|
|
83
|
+
if (forEach(checkedRead()) === false) {
|
|
99
84
|
return
|
|
100
85
|
}
|
|
101
86
|
}
|
|
@@ -103,15 +88,48 @@
|
|
|
103
88
|
else {
|
|
104
89
|
values = [ value ];
|
|
105
90
|
while(position < size) {
|
|
106
|
-
|
|
91
|
+
lastPosition = position;
|
|
92
|
+
values.push(checkedRead());
|
|
107
93
|
}
|
|
108
94
|
return values
|
|
109
95
|
}
|
|
96
|
+
} catch(error) {
|
|
97
|
+
error.lastPosition = lastPosition;
|
|
98
|
+
error.values = values;
|
|
99
|
+
throw error
|
|
110
100
|
} finally {
|
|
101
|
+
sequentialMode = false;
|
|
111
102
|
clearSource();
|
|
112
103
|
}
|
|
113
104
|
}
|
|
114
105
|
}
|
|
106
|
+
function checkedRead() {
|
|
107
|
+
try {
|
|
108
|
+
let result = read();
|
|
109
|
+
if (position == srcEnd) {
|
|
110
|
+
// finished reading this source, cleanup references
|
|
111
|
+
currentStructures = null;
|
|
112
|
+
src = null;
|
|
113
|
+
if (referenceMap)
|
|
114
|
+
referenceMap = null;
|
|
115
|
+
} else if (position > srcEnd) {
|
|
116
|
+
// over read
|
|
117
|
+
let error = new Error('Unexpected end of CBOR data');
|
|
118
|
+
error.incomplete = true;
|
|
119
|
+
throw error
|
|
120
|
+
} else if (!sequentialMode) {
|
|
121
|
+
throw new Error('Data read, but end of buffer not reached')
|
|
122
|
+
}
|
|
123
|
+
// else more to read, but we are reading sequentially, so don't clear source yet
|
|
124
|
+
return result
|
|
125
|
+
} catch(error) {
|
|
126
|
+
clearSource();
|
|
127
|
+
if (error instanceof RangeError || error.message.startsWith('Unexpected end of buffer')) {
|
|
128
|
+
error.incomplete = true;
|
|
129
|
+
}
|
|
130
|
+
throw error
|
|
131
|
+
}
|
|
132
|
+
}
|
|
115
133
|
|
|
116
134
|
function read() {
|
|
117
135
|
let token = src[position++];
|
|
@@ -176,6 +194,10 @@
|
|
|
176
194
|
object[key] = read();
|
|
177
195
|
return object
|
|
178
196
|
} else {
|
|
197
|
+
if (restoreMapsAsObject) {
|
|
198
|
+
currentDecoder.mapsAsObjects = true;
|
|
199
|
+
restoreMapsAsObject = false;
|
|
200
|
+
}
|
|
179
201
|
let map = new Map();
|
|
180
202
|
while ((key = read()) != STOP_CODE)
|
|
181
203
|
map.set(key, read());
|
|
@@ -222,6 +244,10 @@
|
|
|
222
244
|
}
|
|
223
245
|
return object
|
|
224
246
|
} else {
|
|
247
|
+
if (restoreMapsAsObject) {
|
|
248
|
+
currentDecoder.mapsAsObjects = true;
|
|
249
|
+
restoreMapsAsObject = false;
|
|
250
|
+
}
|
|
225
251
|
let map = new Map();
|
|
226
252
|
for (let i = 0; i < token; i++) {
|
|
227
253
|
map.set(read(), read());
|
|
@@ -693,6 +719,16 @@
|
|
|
693
719
|
};
|
|
694
720
|
|
|
695
721
|
currentExtensions[258] = (array) => new Set(array); // https://github.com/input-output-hk/cbor-sets-spec/blob/master/CBOR_SETS.md
|
|
722
|
+
(currentExtensions[259] = (read) => {
|
|
723
|
+
// https://github.com/shanewholloway/js-cbor-codec/blob/master/docs/CBOR-259-spec
|
|
724
|
+
// for decoding as a standard Map
|
|
725
|
+
if (currentDecoder.mapsAsObjects) {
|
|
726
|
+
currentDecoder.mapsAsObjects = false;
|
|
727
|
+
restoreMapsAsObject = true;
|
|
728
|
+
}
|
|
729
|
+
return read()
|
|
730
|
+
}).handlesRead = true;
|
|
731
|
+
|
|
696
732
|
|
|
697
733
|
const typedArrays = ['Uint8', 'Uint8Clamped', 'Uint16', 'Uint32', 'BigUint64','Int8', 'Int16', 'Int32', 'BigInt64', 'Float32', 'Float64'].map(type => type + 'Array');
|
|
698
734
|
const typedArrayTags = [64, 68, 69, 70, 71, 72, 77, 78, 79, 81, 82];
|
|
@@ -719,6 +755,7 @@
|
|
|
719
755
|
let savedSrc = new Uint8Array(src.slice(0, srcEnd)); // we copy the data in case it changes while external data is processed
|
|
720
756
|
let savedStructures = currentStructures;
|
|
721
757
|
let savedDecoder = currentDecoder;
|
|
758
|
+
let savedSequentialMode = sequentialMode;
|
|
722
759
|
let value = callback();
|
|
723
760
|
srcEnd = savedSrcEnd;
|
|
724
761
|
position = savedPosition;
|
|
@@ -727,6 +764,7 @@
|
|
|
727
764
|
srcString = savedSrcString;
|
|
728
765
|
referenceMap = savedReferenceMap;
|
|
729
766
|
src = savedSrc;
|
|
767
|
+
sequentialMode = savedSequentialMode;
|
|
730
768
|
currentStructures = savedStructures;
|
|
731
769
|
currentDecoder = savedDecoder;
|
|
732
770
|
dataView = new DataView(src.buffer, src.byteOffset, src.byteLength);
|
|
@@ -742,7 +780,7 @@
|
|
|
742
780
|
currentExtensions[extension.tag] = extension.decode;
|
|
743
781
|
}
|
|
744
782
|
|
|
745
|
-
|
|
783
|
+
const mult10 = new Array(147); // this is a table matching binary exponents to the multiplier to determine significant digit rounding
|
|
746
784
|
for (let i = 0; i < 256; i++) {
|
|
747
785
|
mult10[i] = +('1e' + Math.floor(45.15 - i * 0.30103));
|
|
748
786
|
}
|
|
@@ -754,7 +792,14 @@
|
|
|
754
792
|
ALWAYS: 1,
|
|
755
793
|
DECIMAL_ROUND: 3,
|
|
756
794
|
DECIMAL_FIT: 4
|
|
757
|
-
};
|
|
795
|
+
};
|
|
796
|
+
let f32Array = new Float32Array(1);
|
|
797
|
+
let u8Array = new Uint8Array(f32Array.buffer, 0, 4);
|
|
798
|
+
function roundFloat32(float32Number) {
|
|
799
|
+
f32Array[0] = float32Number;
|
|
800
|
+
let multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)];
|
|
801
|
+
return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier
|
|
802
|
+
}
|
|
758
803
|
|
|
759
804
|
let textEncoder;
|
|
760
805
|
try {
|
|
@@ -799,11 +844,8 @@
|
|
|
799
844
|
let recordIdsToRemove = [];
|
|
800
845
|
let transitionsCount = 0;
|
|
801
846
|
let serializationsSinceTransitionRebuild = 0;
|
|
802
|
-
if (this.structures && this.structures.length > maxSharedStructures) {
|
|
803
|
-
throw new Error('Too many shared structures')
|
|
804
|
-
}
|
|
805
847
|
|
|
806
|
-
this.encode = function(value) {
|
|
848
|
+
this.encode = function(value, encodeOptions) {
|
|
807
849
|
if (!target) {
|
|
808
850
|
target = new ByteArrayAllocate(8192);
|
|
809
851
|
targetView = new DataView(target.buffer, 0, 8192);
|
|
@@ -816,7 +858,8 @@
|
|
|
816
858
|
targetView = new DataView(target.buffer, 0, target.length);
|
|
817
859
|
safeEnd = target.length - 10;
|
|
818
860
|
position$1 = 0;
|
|
819
|
-
}
|
|
861
|
+
} else if (encodeOptions === REUSE_BUFFER_MODE)
|
|
862
|
+
position$1 = (position$1 + 7) & 0x7ffffff8; // Word align to make any future copying of this buffer faster
|
|
820
863
|
start = position$1;
|
|
821
864
|
referenceMap = encoder.structuredClone ? new Map() : null;
|
|
822
865
|
sharedStructures = encoder.structures;
|
|
@@ -824,7 +867,7 @@
|
|
|
824
867
|
if (sharedStructures.uninitialized)
|
|
825
868
|
encoder.structures = sharedStructures = encoder.getStructures();
|
|
826
869
|
let sharedStructuresLength = sharedStructures.length;
|
|
827
|
-
if (sharedStructuresLength >
|
|
870
|
+
if (sharedStructuresLength > maxSharedStructures && !isSequential)
|
|
828
871
|
sharedStructuresLength = maxSharedStructures;
|
|
829
872
|
if (!sharedStructures.transitions) {
|
|
830
873
|
// rebuild our structure transitions
|
|
@@ -834,8 +877,8 @@
|
|
|
834
877
|
if (!keys)
|
|
835
878
|
continue
|
|
836
879
|
let nextTransition, transition = sharedStructures.transitions;
|
|
837
|
-
for (let
|
|
838
|
-
let key = keys[
|
|
880
|
+
for (let j = 0, l = keys.length; j < l; j++) {
|
|
881
|
+
let key = keys[j];
|
|
839
882
|
nextTransition = transition[key];
|
|
840
883
|
if (!nextTransition) {
|
|
841
884
|
nextTransition = transition[key] = Object.create(null);
|
|
@@ -864,7 +907,12 @@
|
|
|
864
907
|
referenceMap = null;
|
|
865
908
|
return serialized
|
|
866
909
|
}
|
|
867
|
-
|
|
910
|
+
if (encodeOptions === REUSE_BUFFER_MODE) {
|
|
911
|
+
target.start = start;
|
|
912
|
+
target.end = position$1;
|
|
913
|
+
return target
|
|
914
|
+
}
|
|
915
|
+
return target.subarray(start, position$1) // position can change if we call pack again in saveStructures, so we get the buffer now
|
|
868
916
|
} finally {
|
|
869
917
|
if (sharedStructures) {
|
|
870
918
|
if (serializationsSinceTransitionRebuild < 10)
|
|
@@ -878,7 +926,7 @@
|
|
|
878
926
|
recordIdsToRemove = [];
|
|
879
927
|
} else if (recordIdsToRemove.length > 0 && !isSequential) {
|
|
880
928
|
for (let i = 0, l = recordIdsToRemove.length; i < l; i++) {
|
|
881
|
-
recordIdsToRemove[i][RECORD_SYMBOL] =
|
|
929
|
+
recordIdsToRemove[i][RECORD_SYMBOL] = undefined;
|
|
882
930
|
}
|
|
883
931
|
recordIdsToRemove = [];
|
|
884
932
|
}
|
|
@@ -886,13 +934,15 @@
|
|
|
886
934
|
if (encoder.structures.length > maxSharedStructures) {
|
|
887
935
|
encoder.structures = encoder.structures.slice(0, maxSharedStructures);
|
|
888
936
|
}
|
|
889
|
-
|
|
937
|
+
// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
|
|
938
|
+
let returnBuffer = target.subarray(start, position$1);
|
|
890
939
|
if (encoder.saveStructures(encoder.structures, lastSharedStructuresLength) === false) {
|
|
891
940
|
// get updated structures and try again if the update failed
|
|
892
941
|
encoder.structures = encoder.getStructures() || [];
|
|
893
942
|
return encoder.encode(value)
|
|
894
943
|
}
|
|
895
944
|
lastSharedStructuresLength = encoder.structures.length;
|
|
945
|
+
return returnBuffer
|
|
896
946
|
}
|
|
897
947
|
}
|
|
898
948
|
}
|
|
@@ -1013,7 +1063,7 @@
|
|
|
1013
1063
|
targetView.setFloat32(position$1, value);
|
|
1014
1064
|
let xShifted;
|
|
1015
1065
|
if (useFloat32 < 4 ||
|
|
1016
|
-
|
|
1066
|
+
// this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
|
|
1017
1067
|
((xShifted = value * mult10[((target[position$1] & 0x7f) << 1) | (target[position$1 + 1] >> 7)]) >> 0) === xShifted) {
|
|
1018
1068
|
position$1 += 4;
|
|
1019
1069
|
return
|
|
@@ -1059,6 +1109,12 @@
|
|
|
1059
1109
|
encode(value[i]);
|
|
1060
1110
|
}
|
|
1061
1111
|
} else if (constructor === Map) {
|
|
1112
|
+
if (this.mapsAsObjects ? this.useTag259ForMaps !== false : this.useTag259ForMaps) {
|
|
1113
|
+
// use Tag 259 (https://github.com/shanewholloway/js-cbor-codec/blob/master/docs/CBOR-259-spec--explicit-maps.md) for maps if the user wants it that way
|
|
1114
|
+
target[position$1++] = 0xd9;
|
|
1115
|
+
target[position$1++] = 1;
|
|
1116
|
+
target[position$1++] = 3;
|
|
1117
|
+
}
|
|
1062
1118
|
length = value.size;
|
|
1063
1119
|
if (length < 0x18) {
|
|
1064
1120
|
target[position$1++] = 0xa0 | length;
|
|
@@ -1136,10 +1192,9 @@
|
|
|
1136
1192
|
}
|
|
1137
1193
|
position$1 += 8;
|
|
1138
1194
|
} else if (type === 'undefined') {
|
|
1139
|
-
//target[position++] = 0xc1 // this is the "never-used" byte
|
|
1140
1195
|
target[position$1++] = 0xf7;
|
|
1141
1196
|
} else {
|
|
1142
|
-
throw new Error('Unknown type ' + type)
|
|
1197
|
+
throw new Error('Unknown type: ' + type)
|
|
1143
1198
|
}
|
|
1144
1199
|
};
|
|
1145
1200
|
|
|
@@ -1228,7 +1283,7 @@
|
|
|
1228
1283
|
let nextTransition, transition = structures.transitions || (structures.transitions = Object.create(null));
|
|
1229
1284
|
let newTransitions = 0;
|
|
1230
1285
|
let length = keys.length;
|
|
1231
|
-
for (let i =0; i < length; i++) {
|
|
1286
|
+
for (let i = 0; i < length; i++) {
|
|
1232
1287
|
let key = keys[i];
|
|
1233
1288
|
nextTransition = transition[key];
|
|
1234
1289
|
if (!nextTransition) {
|
|
@@ -1238,7 +1293,7 @@
|
|
|
1238
1293
|
transition = nextTransition;
|
|
1239
1294
|
}
|
|
1240
1295
|
let recordId = transition[RECORD_SYMBOL];
|
|
1241
|
-
if (recordId) {
|
|
1296
|
+
if (recordId !== undefined) {
|
|
1242
1297
|
target[position$1++] = 0xd9; // tag two byte
|
|
1243
1298
|
target[position$1++] = RECORD_STARTING_ID_PREFIX;
|
|
1244
1299
|
target[position$1++] = recordId;
|
|
@@ -1265,7 +1320,7 @@
|
|
|
1265
1320
|
transitionsCount += serializationsSinceTransitionRebuild * newTransitions;
|
|
1266
1321
|
// record the removal of the id, we can maintain our shared structure
|
|
1267
1322
|
if (recordIdsToRemove.length >= MAX_STRUCTURES - maxSharedStructures)
|
|
1268
|
-
recordIdsToRemove.shift()[RECORD_SYMBOL] =
|
|
1323
|
+
recordIdsToRemove.shift()[RECORD_SYMBOL] = undefined; // we are cycling back through, and have to remove old ones
|
|
1269
1324
|
recordIdsToRemove.push(transition);
|
|
1270
1325
|
if (length < 0x16)
|
|
1271
1326
|
target[position$1++] = 0x82 + length; // array header, length of values + 2
|
|
@@ -1405,7 +1460,9 @@
|
|
|
1405
1460
|
}
|
|
1406
1461
|
function writeBuffer(buffer, makeRoom) {
|
|
1407
1462
|
let length = buffer.byteLength;
|
|
1408
|
-
if (length <
|
|
1463
|
+
if (length < 0x18) {
|
|
1464
|
+
target[position$1++] = 0x40 + length;
|
|
1465
|
+
} else if (length < 0x100) {
|
|
1409
1466
|
target[position$1++] = 0x58;
|
|
1410
1467
|
target[position$1++] = length;
|
|
1411
1468
|
} else if (length < 0x10000) {
|
|
@@ -1460,7 +1517,91 @@
|
|
|
1460
1517
|
}
|
|
1461
1518
|
let defaultEncoder = new Encoder({ useRecords: false });
|
|
1462
1519
|
const encode = defaultEncoder.encode;
|
|
1463
|
-
const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS;
|
|
1520
|
+
const { NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS;
|
|
1521
|
+
const REUSE_BUFFER_MODE = 1000;
|
|
1522
|
+
|
|
1523
|
+
/**
|
|
1524
|
+
* Given an Iterable first argument, returns an Iterable where each value is encoded as a Buffer
|
|
1525
|
+
* If the argument is only Async Iterable, the return value will be an Async Iterable.
|
|
1526
|
+
* @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object
|
|
1527
|
+
* @param {options} [options] - cbor-x Encoder options
|
|
1528
|
+
* @returns {IterableIterator|Promise.<AsyncIterableIterator>}
|
|
1529
|
+
*/
|
|
1530
|
+
function encodeIter (objectIterator, options = {}) {
|
|
1531
|
+
if (!objectIterator || typeof objectIterator !== 'object') {
|
|
1532
|
+
throw new Error('first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable')
|
|
1533
|
+
} else if (typeof objectIterator[Symbol.iterator] === 'function') {
|
|
1534
|
+
return encodeIterSync(objectIterator, options)
|
|
1535
|
+
} else if (typeof objectIterator.then === 'function' || typeof objectIterator[Symbol.asyncIterator] === 'function') {
|
|
1536
|
+
return encodeIterAsync(objectIterator, options)
|
|
1537
|
+
} else {
|
|
1538
|
+
throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise')
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
function * encodeIterSync (objectIterator, options) {
|
|
1543
|
+
const encoder = new Encoder(options);
|
|
1544
|
+
for (const value of objectIterator) {
|
|
1545
|
+
yield encoder.encode(value);
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
|
|
1549
|
+
async function * encodeIterAsync (objectIterator, options) {
|
|
1550
|
+
const encoder = new Encoder(options);
|
|
1551
|
+
for await (const value of objectIterator) {
|
|
1552
|
+
yield encoder.encode(value);
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
/**
|
|
1557
|
+
* Given an Iterable/Iterator input which yields buffers, returns an IterableIterator which yields sync decoded objects
|
|
1558
|
+
* Or, given an Async Iterable/Iterator which yields promises resolving in buffers, returns an AsyncIterableIterator.
|
|
1559
|
+
* @param {Iterable|Iterator|AsyncIterable|AsyncIterableIterator} bufferIterator
|
|
1560
|
+
* @param {object} [options] - Decoder options
|
|
1561
|
+
* @returns {IterableIterator|Promise.<AsyncIterableIterator}
|
|
1562
|
+
*/
|
|
1563
|
+
function decodeIter (bufferIterator, options = {}) {
|
|
1564
|
+
if (!bufferIterator || typeof bufferIterator !== 'object') {
|
|
1565
|
+
throw new Error('first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a promise')
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
const decoder = new Decoder(options);
|
|
1569
|
+
let incomplete;
|
|
1570
|
+
const parser = (chunk) => {
|
|
1571
|
+
let yields;
|
|
1572
|
+
// if there's incomplete data from previous chunk, concatinate and try again
|
|
1573
|
+
if (incomplete) {
|
|
1574
|
+
chunk = Buffer.concat([incomplete, chunk]);
|
|
1575
|
+
incomplete = undefined;
|
|
1576
|
+
}
|
|
1577
|
+
|
|
1578
|
+
try {
|
|
1579
|
+
yields = decoder.decodeMultiple(chunk);
|
|
1580
|
+
} catch (err) {
|
|
1581
|
+
if (err.incomplete) {
|
|
1582
|
+
incomplete = chunk.slice(err.lastPosition);
|
|
1583
|
+
yields = err.values;
|
|
1584
|
+
} else {
|
|
1585
|
+
throw err
|
|
1586
|
+
}
|
|
1587
|
+
}
|
|
1588
|
+
return yields
|
|
1589
|
+
};
|
|
1590
|
+
|
|
1591
|
+
if (typeof bufferIterator[Symbol.iterator] === 'function') {
|
|
1592
|
+
return (function * iter () {
|
|
1593
|
+
for (const value of bufferIterator) {
|
|
1594
|
+
yield * parser(value);
|
|
1595
|
+
}
|
|
1596
|
+
})()
|
|
1597
|
+
} else if (typeof bufferIterator[Symbol.asyncIterator] === 'function') {
|
|
1598
|
+
return (async function * iter () {
|
|
1599
|
+
for await (const value of bufferIterator) {
|
|
1600
|
+
yield * parser(value);
|
|
1601
|
+
}
|
|
1602
|
+
})()
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1464
1605
|
|
|
1465
1606
|
const useRecords = false;
|
|
1466
1607
|
const mapsAsObjects = true;
|
|
@@ -1474,10 +1615,14 @@
|
|
|
1474
1615
|
exports.NEVER = NEVER;
|
|
1475
1616
|
exports.Tag = Tag;
|
|
1476
1617
|
exports.addExtension = addExtension$1;
|
|
1618
|
+
exports.clearSource = clearSource;
|
|
1477
1619
|
exports.decode = decode;
|
|
1620
|
+
exports.decodeIter = decodeIter;
|
|
1478
1621
|
exports.decodeMultiple = decodeMultiple;
|
|
1479
1622
|
exports.encode = encode;
|
|
1623
|
+
exports.encodeIter = encodeIter;
|
|
1480
1624
|
exports.mapsAsObjects = mapsAsObjects;
|
|
1625
|
+
exports.roundFloat32 = roundFloat32;
|
|
1481
1626
|
exports.useRecords = useRecords;
|
|
1482
1627
|
|
|
1483
1628
|
Object.defineProperty(exports, '__esModule', { value: true });
|