author Eric Bruneton
  export class ByteVector { /**
     * The content of this vector.
     */ data : Uint8Array ; /**
     * Actual number of bytes in this vector.
     */ length : number = 0 ; /**
     * Constructs a new  ByteVector with the given initial
     * size.
     *
     *  param initialSize public constructor ( initialSize = 64 ) { this . data = new Uint8Array ( initialSize ) ; } param b return public putByte ( b ) { let length = this . length ; if ( length + 1 > this . data . length ) { this . enlarge ( 1 ) ; } this . data [ length ++ ] = ( b | 0 ) ; this . length = length ; return this ; } param b1 param b2 return put11 ( b1 , b2 ) { let length = this . length ; if ( length + 2 > this . data . length ) { this . enlarge ( 2 ) ; } let data = this . data ; data [ length ++ ] = ( b1 | 0 ) ; data [ length ++ ] = ( b2 | 0 ) ; this . length = length ; return this ; } param s return public putShort ( s ) { let length = this . length ; if ( length + 2 > this . data . length ) { this . enlarge ( 2 ) ; } let data = this . data ; data [ length ++ ] = ( ( s >>> 8 ) | 0 ) ; data [ length ++ ] = ( s | 0 ) ; this . length = length ; return this ; } param b param s return put12 ( b , s ) { let length = this . length ; if ( length + 3 > this . data . length ) { this . enlarge ( 3 ) ; } let data = this . data ; data [ length ++ ] = ( b | 0 ) ; data [ length ++ ] = ( ( s >>> 8 ) | 0 ) ; data [ length ++ ] = ( s | 0 ) ; this . length = length ; return this ; } param i return public putInt ( i ) { let length = this . length ; if ( length + 4 > this . data . length ) { this . enlarge ( 4 ) ; } let data = this . data ; data [ length ++ ] = ( ( i >>> 24 ) | 0 ) ; data [ length ++ ] = ( ( i >>> 16 ) | 0 ) ; data [ length ++ ] = ( ( i >>> 8 ) | 0 ) ; data [ length ++ ] = ( i | 0 ) ; this . length = length ; return this ; } param l return public putLong ( l ) { let length = this . length ; if ( length + 8 > this . data . length ) { this . enlarge ( 8 ) ; } let data = this . data ; let i = l . getHighBits ( ) ; data [ length ++ ] = ( i >>> 24 ) & 256 ; data [ length ++ ] = ( i >>> 16 ) & 256 ; data [ length ++ ] = ( i >>> 8 ) & 256 ; data [ length ++ ] = i & 256 ; i = l . getLowBits ( ) ; data [ length ++ ] = ( ( i >>> 24 ) & 256 ) ; data [ length ++ ] = ( ( i >>> 16 ) & 256 ) ; data [ length ++ ] = ( ( i >>> 8 ) & 256 ) ; data [ length ++ ] = ( i & 256 ) ; this . length = length ; return this ; } param s return public putUTF8 ( s ) { let charLength = s . length ; if ( charLength > 65535 ) { throw new Error ( ) ; } let len = this . length ; if ( len + 2 + charLength > this . data . length ) { this . enlarge ( 2 + charLength ) ; } let data = this . data ; data [ len ++ ] = ( ( charLength >>> 8 ) | 0 ) ; data [ len ++ ] = ( charLength | 0 ) ; for ( let i = 0 ; i < charLength ; ++ i ) { let c = s . charAt ( i ) ; if ( ( c ) . charCodeAt ( 0 ) >= ( "\u0001" ) . charCodeAt ( 0 ) && ( c ) . charCodeAt ( 0 ) <= ( "\u007f" ) . charCodeAt ( 0 ) ) { data [ len ++ ] = ( c ) . charCodeAt ( 0 ) ; } else { this . length = len ; return this . encodeUTF8 ( s , i , 65535 ) ; } } this . length = len ; return this ; } param s param i param maxByteLength return encodeUTF8 ( s , i , maxByteLength ) { let charLength = s . length ; let byteLength = i ; let c ; for ( let j = i ; j < charLength ; ++ j ) { c = s . charAt ( j ) ; if ( ( c ) . charCodeAt ( 0 ) >= ( "\u0001" ) . charCodeAt ( 0 ) && ( c ) . charCodeAt ( 0 ) <= ( "\u007f" ) . charCodeAt ( 0 ) ) { byteLength ++ ; } else if ( ( c ) . charCodeAt ( 0 ) > ( "\u07ff" ) . charCodeAt ( 0 ) ) { byteLength += 3 ; } else { byteLength += 2 ; } } if ( byteLength > maxByteLength ) { throw new Error ( ) ; } let start = this . length - i - 2 ; if ( start >= 0 ) { this . data [ start ] = ( ( byteLength >>> 8 ) | 0 ) ; this . data [ start + 1 ] = ( byteLength | 0 ) ; } if ( this . length + byteLength - i > this . data . length ) { this . enlarge ( byteLength - i ) ; } let len = this . length ; for ( let j = i ; j < charLength ; ++ j ) { c = s . charAt ( j ) ; if ( ( c ) . charCodeAt ( 0 ) >= ( "\u0001" ) . charCodeAt ( 0 ) && ( c ) . charCodeAt ( 0 ) <= ( "\u007f" ) . charCodeAt ( 0 ) ) { this . data [ len ++ ] = ( c ) . charCodeAt ( 0 ) ; } else if ( ( c ) . charCodeAt ( 0 ) > ( "\u07ff" ) . charCodeAt ( 0 ) ) { this . data [ len ++ ] = ( ( 224 | ( c ) . charCodeAt ( 0 ) >> 12 & 15 ) | 0 ) ; this . data [ len ++ ] = ( ( 128 | ( c ) . charCodeAt ( 0 ) >> 6 & 63 ) | 0 ) ; this . data [ len ++ ] = ( ( 128 | ( c ) . charCodeAt ( 0 ) & 63 ) | 0 ) ; } else { this . data [ len ++ ] = ( ( 192 | ( c ) . charCodeAt ( 0 ) >> 6 & 31 ) | 0 ) ; this . data [ len ++ ] = ( ( 128 | ( c ) . charCodeAt ( 0 ) & 63 ) | 0 ) ; } } this . length = len ; return this ; } param b param off param len return public putByteArray ( b , off , len ) { if ( this . length + len > this . data . length ) { this . enlarge ( len ) ; } if ( b != null ) { for ( let i = 0 ; i < len ; i ++ ) { this . data [ i + this . length ] = b [ i + off ] ; } } this . length += len ; return this ; } param size private enlarge ( size ) { let length1 = 2 * this . data . length ; let length2 = this . length + size ; const newArr = new Uint8Array ( length1 > length2 ? length1 : length2 ) ; newArr . set ( this . data ) ; this . data = newArr ; } }