@@ -74,6 +74,20 @@ export class Decoder {
7474 this . pos = 0 ;
7575 }
7676
77+ appendBuffer ( buffer : Uint8Array | ArrayLike < number > ) {
78+ if ( this . headByte === HEAD_BYTE_REQUIRED && ! this . hasRemaining ( ) ) {
79+ this . setBuffer ( buffer ) ;
80+ } else {
81+ // retried because data is insufficient
82+ const remainingData = this . bytes . subarray ( this . pos ) ;
83+ const newData = ensureUint8Array ( buffer ) ;
84+ const concated = new Uint8Array ( remainingData . length + newData . length ) ;
85+ concated . set ( remainingData ) ;
86+ concated . set ( newData , remainingData . length ) ;
87+ this . setBuffer ( concated ) ;
88+ }
89+ }
90+
7791 hasRemaining ( size = 1 ) {
7892 return this . view . byteLength - this . pos >= size ;
7993 }
@@ -99,18 +113,7 @@ export class Decoder {
99113 throw this . createNoExtraBytesError ( this . totalPos ) ;
100114 }
101115
102- if ( this . headByte === HEAD_BYTE_REQUIRED && ! this . hasRemaining ( ) ) {
103- this . setBuffer ( buffer ) ;
104- } else {
105- // retried because data is insufficient
106- const remainingData = this . bytes . subarray ( this . pos ) ;
107- const newData = ensureUint8Array ( buffer ) ;
108- const concated = new Uint8Array ( remainingData . length + newData . length ) ;
109- concated . set ( remainingData ) ;
110- concated . set ( newData , remainingData . length ) ;
111- this . setBuffer ( concated ) ;
112- }
113- //console.log("view", this.view, this.headByte);
116+ this . appendBuffer ( buffer ) ;
114117
115118 try {
116119 object = this . decodeSync ( ) ;
@@ -137,6 +140,47 @@ export class Decoder {
137140 ) ;
138141 }
139142
143+ async * decodeArrayStream ( stream : AsyncIterable < ArrayLike < number > | Uint8Array > ) {
144+ let headerParsed = false ;
145+ let decoded = false ;
146+ let itemsLeft = 0 ;
147+
148+ for await ( const buffer of stream ) {
149+ if ( decoded ) {
150+ throw this . createNoExtraBytesError ( this . totalPos ) ;
151+ }
152+
153+ this . appendBuffer ( buffer ) ;
154+
155+ if ( ! headerParsed ) {
156+ itemsLeft = this . readArraySize ( ) ;
157+ headerParsed = true ;
158+ this . complete ( ) ;
159+ }
160+
161+ try {
162+ while ( true ) {
163+ let result = this . decodeSync ( ) ;
164+
165+ yield result ;
166+
167+ itemsLeft -- ;
168+
169+ if ( itemsLeft === 0 ) {
170+ decoded = true ;
171+ break ;
172+ }
173+ }
174+ } catch ( e ) {
175+ if ( ! ( e instanceof DataViewIndexOutOfBoundsError ) ) {
176+ throw e ; // rethrow
177+ }
178+ // fallthrough
179+ }
180+ this . totalPos += this . pos ;
181+ }
182+ }
183+
140184 decodeSync ( ) : unknown {
141185 DECODE: while ( true ) {
142186 const headByte = this . readHeadByte ( ) ;
@@ -363,6 +407,24 @@ export class Decoder {
363407 this . headByte = HEAD_BYTE_REQUIRED ;
364408 }
365409
410+ readArraySize ( ) : number {
411+ const headByte = this . readHeadByte ( ) ;
412+
413+ switch ( headByte ) {
414+ case 0xdc :
415+ return this . readU16 ( ) ;
416+ case 0xdd :
417+ return this . readU32 ( ) ;
418+ default : {
419+ if ( headByte < 0xa0 ) {
420+ return headByte - 0x90 ;
421+ } else {
422+ throw new Error ( `Unrecognized array type byte: ${ prettyByte ( headByte ) } ` ) ;
423+ }
424+ }
425+ }
426+ }
427+
366428 pushMapState ( size : number ) {
367429 if ( size > this . maxMapLength ) {
368430 throw new Error ( `Max length exceeded: map length (${ size } ) > maxMapLengthLength (${ this . maxMapLength } )` ) ;
0 commit comments