@@ -33,40 +33,40 @@ export class BufferWriter {
3333 // ----- Writers: -----
3434
3535 public $writeInt8 ( value : number ) : void {
36- this . _$alloc ( 1 ) . setInt8 ( this . _$writeHead , value ) ;
36+ this . _$pre ( 1 ) . setInt8 ( this . _$writeHead , value ) ;
3737 }
3838
3939 public $writeInt16 ( value : number ) : void {
40- this . _$alloc ( 2 ) . setInt16 ( this . _$writeHead , value , true ) ;
40+ this . _$pre ( 2 ) . setInt16 ( this . _$writeHead , value , true ) ;
4141 }
4242
4343 public $writeInt32 ( value : number ) : void {
44- this . _$alloc ( 4 ) . setInt32 ( this . _$writeHead , value , true ) ;
44+ this . _$pre ( 4 ) . setInt32 ( this . _$writeHead , value , true ) ;
4545 }
4646
4747 public $writeUint8 ( value : number ) : void {
48- this . _$alloc ( 1 ) . setUint8 ( this . _$writeHead , value ) ;
48+ this . _$pre ( 1 ) . setUint8 ( this . _$writeHead , value ) ;
4949 }
5050
5151 public $writeUint16 ( value : number ) : void {
52- this . _$alloc ( 2 ) . setUint16 ( this . _$writeHead , value , false ) ; // big-endian for varint
52+ this . _$pre ( 2 ) . setUint16 ( this . _$writeHead , value , false ) ; // big-endian for varint
5353 }
5454
5555 public $writeUint32 ( value : number ) : void {
56- this . _$alloc ( 4 ) . setUint32 ( this . _$writeHead , value , false ) ; // big-endian for varint
56+ this . _$pre ( 4 ) . setUint32 ( this . _$writeHead , value , false ) ; // big-endian for varint
5757 }
5858
5959 public $writeFloat32 ( value : number ) : void {
60- this . _$alloc ( 4 ) . setFloat32 ( this . _$writeHead , value , true ) ;
60+ this . _$pre ( 4 ) . setFloat32 ( this . _$writeHead , value , true ) ;
6161 }
6262
6363 public $writeFloat64 ( value : number ) : void {
64- this . _$alloc ( 8 ) . setFloat64 ( this . _$writeHead , value , true ) ;
64+ this . _$pre ( 8 ) . setFloat64 ( this . _$writeHead , value , true ) ;
6565 }
6666
6767 public $writeBytes ( b : Uint8Array | ArrayBuffer | ArrayBufferView ) : void {
6868 // allocate bytes first
69- this . _$alloc ( b . byteLength ) ;
69+ this . _$pre ( b . byteLength ) ;
7070
7171 let bBytes : Uint8Array = ArrayBuffer . isView ( b )
7272 ? b instanceof Uint8Array
@@ -84,12 +84,15 @@ export class BufferWriter {
8484
8585 // ----- Private methods: -----
8686
87- private _$alloc ( bytes : number ) : DataView {
87+ /**
88+ * Pre-allocate some bytes on the dataview, moving the write head into
89+ * position.
90+ *
91+ * @throws TinybufError
92+ */
93+ private _$pre ( bytes : number ) : DataView {
8894 if ( this . $byteLength + bytes > this . _$dataView . byteLength ) {
89- const minBytesNeeded = this . $byteLength + bytes - this . _$dataView . byteLength ;
90- const requestedNewBytes = Math . ceil ( minBytesNeeded / cfg . encodingBufferIncrement ) * cfg . encodingBufferIncrement ;
91- if ( ! this . _$resizable ) throw new TinybufError ( "exceeded buffer length: " + this . _$dataView . byteLength ) ;
92- this . _$resizeBuffer ( this . _$dataView . byteLength + requestedNewBytes ) ;
95+ this . _$malloc ( bytes ) ;
9396 }
9497
9598 this . _$writeHead = this . $byteLength ;
@@ -98,14 +101,29 @@ export class BufferWriter {
98101 return this . _$dataView ;
99102 }
100103
101- private _$resizeBuffer ( newSize : number ) : void {
102- if ( newSize > cfg . encodingBufferMaxSize ) {
103- // safety check
104- throw new TinybufError ( `exceeded encodingBufferMaxSize: ${ cfg . encodingBufferMaxSize } ` ) ;
104+ /**
105+ * @throws TinybufError
106+ */
107+ private _$malloc ( bytes : number ) : void {
108+ if ( ! this . _$resizable ) {
109+ throw new TinybufError ( "exceeded buffer length: " + this . _$dataView . byteLength ) ;
105110 }
106111
112+ const currentBytes = this . _$dataView . byteLength ;
113+ const minNewBytes = this . $byteLength + bytes - currentBytes ;
114+ const availableBytes = cfg . encodingBufferMaxSize - currentBytes ;
115+
116+ if ( minNewBytes > availableBytes ) {
117+ throw new TinybufError ( "exceeded encodingBufferMaxSize: " + cfg . encodingBufferMaxSize ) ;
118+ }
119+
120+ const increment = cfg . encodingBufferIncrement ;
121+ const newBytes = Math . ceil ( minNewBytes / increment ) * increment ;
122+ const newSize = currentBytes + Math . min ( newBytes , availableBytes ) ;
107123 const buf = new Uint8Array ( newSize ) ;
108- buf . set ( this . _$bytes ) ; // copy bytes
124+
125+ // copy bytes
126+ buf . set ( this . _$bytes ) ;
109127
110128 // update refs
111129 this . _$dataView = new DataView ( buf . buffer ) ;
0 commit comments