author jdiaz5513
  import initTrace from "debug" ; import { MAX_BUFFER_DUMP_BYTES , MAX_INT32 , MAX_UINT32 } from "./constants" ; import { RANGE_INT32_OVERFLOW , RANGE_INVALID_UTF8 , RANGE_UINT32_OVERFLOW } from "./errors" ; const trace = initTrace ( "capnp:util" ) ; trace ( "load" ) ; export param { ArrayBuffer } buffer returns { string } export function bufferToHex ( buffer ) { const a = new Uint8Array ( buffer ) ; const h = [ ] ; for ( let i = 0 ; i < a . byteLength ; i ++ ) h . push ( pad ( a [ i ] . toString ( 16 ) , 2 ) ) ; return `[${ h . join ( " " ) }]` ; } export param { number } value returns { number } export function checkInt32 ( value ) { if ( value > MAX_INT32 || value < - MAX_INT32 ) { throw new RangeError ( RANGE_INT32_OVERFLOW ) ; } return value ; } export function checkUint32 ( value ) { if ( value < 0 || value > MAX_UINT32 ) { throw new RangeError ( RANGE_UINT32_OVERFLOW ) ; } return value ; } export param { Uint8Array } src returns { string } export function decodeUtf8 ( src ) { const l = src . byteLength ; let dst = "" ; let i = 0 ; let cp = 0 ; let a = 0 ; let b = 0 ; let c = 0 ; let d = 0 ; while ( i < l ) { a = src [ i ++ ] ; if ( ( a & 0b10000000 ) === 0 ) { cp = a ; } else if ( ( a & 0b11100000 ) === 0b11000000 ) { if ( i >= l ) throw new RangeError ( RANGE_INVALID_UTF8 ) ; b = src [ i ++ ] ; cp = ( ( a & 0b00011111 ) << 6 ) | ( b & 0b00111111 ) ; } else if ( ( a & 0b11110000 ) === 0b11100000 ) { if ( i + 1 >= l ) throw new RangeError ( RANGE_INVALID_UTF8 ) ; b = src [ i ++ ] ; c = src [ i ++ ] ; cp = ( ( a & 0b00001111 ) << 12 ) | ( ( b & 0b00111111 ) << 6 ) | ( c & 0b00111111 ) ; } else if ( ( a & 0b11111000 ) === 0b11110000 ) { if ( i + 2 >= l ) throw new RangeError ( RANGE_INVALID_UTF8 ) ; b = src [ i ++ ] ; c = src [ i ++ ] ; d = src [ i ++ ] ; cp = ( ( a & 0b00000111 ) << 18 ) | ( ( b & 0b00111111 ) << 12 ) | ( ( c & 0b00111111 ) << 6 ) | ( d & 0b00111111 ) ; } else { throw new RangeError ( RANGE_INVALID_UTF8 ) ; } if ( cp <= 0xd7ff || ( cp >= 0xe000 && cp <= 0xffff ) ) { dst += String . fromCharCode ( cp ) ; } else { cp -= 0x00010000 ; const hi = ( cp >>> 10 ) + 0xd800 ; const lo = ( cp & 0x03ff ) + 0xdc00 ; if ( hi < 0xd800 || hi > 0xdbff ) throw new RangeError ( RANGE_INVALID_UTF8 ) ; dst += String . fromCharCode ( hi , lo ) ; } } return dst ; } export function dumpBuffer ( buffer ) { const b = buffer instanceof ArrayBuffer ? new Uint8Array ( buffer ) : new Uint8Array ( buffer . buffer , buffer . byteOffset , buffer . byteLength ) ; const byteLength = Math . min ( b . byteLength , MAX_BUFFER_DUMP_BYTES ) ; let r = format ( "\n=== buffer[%d] ===" , byteLength ) ; for ( let j = 0 ; j < byteLength ; j += 16 ) { r += `\n${ pad ( j . toString ( 16 ) , 8 ) }: ` ; let s = "" ; let k ; for ( k = 0 ; k < 16 && j + k < b . byteLength ; k ++ ) { const v = b [ j + k ] ; r += `${ pad ( v . toString ( 16 ) , 2 ) } ` ; s += v > 31 && v < 255 ? String . fromCharCode ( v ) : "·" ; if ( k === 7 ) r += " " ; } r += `${ repeat ( ( 17 - k ) * 3 , " " ) }${ s }` ; } r += "\n" ; if ( byteLength !== b . byteLength ) { r += format ( "=== (truncated %d bytes) ===\n" , b . byteLength - byteLength ) ; } return r ; } export param { string } src returns { Uint8Array } export function encodeUtf8 ( src ) { const l = src . length ; const dst = new Uint8Array ( new ArrayBuffer ( l * 4 ) ) ; let j = 0 ; for ( let i = 0 ; i < l ; i ++ ) { const c = src . charCodeAt ( i ) ; if ( c <= 0x7f ) { dst [ j ++ ] = c ; } else if ( c <= 0x07ff ) { dst [ j ++ ] = 0b11000000 | ( c >>> 6 ) ; dst [ j ++ ] = 0b10000000 | ( ( c >>> 0 ) & 0b00111111 ) ; } else if ( c <= 0xd7ff || c >= 0xe000 ) { dst [ j ++ ] = 0b11100000 | ( c >>> 12 ) ; dst [ j ++ ] = 0b10000000 | ( ( c >>> 6 ) & 0b00111111 ) ; dst [ j ++ ] = 0b10000000 | ( ( c >>> 0 ) & 0b00111111 ) ; } else { if ( i + 1 >= l ) throw new RangeError ( RANGE_INVALID_UTF8 ) ; const hi = c - 0xd800 ; const lo = src . charCodeAt ( ++ i ) - 0xdc00 ; const cp = ( ( hi << 10 ) | lo ) + 0x00010000 ; dst [ j ++ ] = 0b11110000 | ( cp >>> 18 ) ; dst [ j ++ ] = 0b10000000 | ( ( cp >>> 12 ) & 0b00111111 ) ; dst [ j ++ ] = 0b10000000 | ( ( cp >>> 6 ) & 0b00111111 ) ; dst [ j ++ ] = 0b10000000 | ( ( cp >>> 0 ) & 0b00111111 ) ; } } return dst . subarray ( 0 , j ) ; } param { string } s param { ... any } args returns { string } export function format ( s , ... args ) { const n = s . length ; let arg ; let argIndex = 0 ; let c ; let escaped = false ; let i = 0 ; let leadingZero = false ; let precision ; let result = "" ; function nextArg ( ) { return args [ argIndex ++ ] ; } function slurpNumber ( ) { let digits = "" ; while ( /\d/ . test ( s [ i ] ) ) { digits += s [ i ++ ] ; c = s [ i ] ; } return digits . length > 0 ? parseInt ( digits , 10 ) : null ; } for ( ; i < n ; ++ i ) { c = s [ i ] ; if ( escaped ) { escaped = false ; if ( c === "." ) { leadingZero = false ; c = s [ ++ i ] ; } else if ( c === "0" && s [ i + 1 ] === "." ) { leadingZero = true ; i += 2 ; c = s [ i ] ; } else { leadingZero = true ; } precision = slurpNumber ( ) ; switch ( c ) { case "a" : result += "0x" + pad ( parseInt ( String ( nextArg ( ) ) , 10 ) . toString ( 16 ) , 8 ) ; break ; case "b" : result += parseInt ( String ( nextArg ( ) ) , 10 ) . toString ( 2 ) ; break ; case "c" : arg = nextArg ( ) ; if ( typeof arg === "string" || arg instanceof String ) { result += arg ; } else { result += String . fromCharCode ( parseInt ( String ( arg ) , 10 ) ) ; } break ; case "d" : result += parseInt ( String ( nextArg ( ) ) , 10 ) ; break ; case "f" : { const tmp = parseFloat ( String ( nextArg ( ) ) ) . toFixed ( precision || 6 ) ; result += leadingZero ? tmp : tmp . replace ( /^0/ , "" ) ; break ; } case "j" : result += JSON . stringify ( nextArg ( ) ) ; break ; case "o" : result += "0" + parseInt ( String ( nextArg ( ) ) , 10 ) . toString ( 8 ) ; break ; case "s" : result += nextArg ( ) ; break ; case "x" : result += "0x" + parseInt ( String ( nextArg ( ) ) , 10 ) . toString ( 16 ) ; break ; case "X" : result += "0x" + parseInt ( String ( nextArg ( ) ) , 10 ) . toString ( 16 ) . toUpperCase ( ) ; break ; default : result += c ; break ; } } else if ( c === "%" ) { escaped = true ; } else { result += c ; } } return result ; } export template T param { T } x returns { T } export function identity < T > ( x ) { return x ; } export function pad ( v , width , pad = "0" ) { return v . length >= width ? v : new Array ( width - v . length + 1 ) . join ( pad ) + v ; } export param { number } size returns { number } export function padToWord ( size ) { return ( size + 7 ) & ~ 7 ; } param { number } times param { string } str returns { string } export function repeat ( times , str ) { let out = "" ; let n = times ; let s = str ; if ( n < 1 || n > Number . MAX_VALUE ) return out ; do { if ( n % 2 ) out += s ; n = Math . floor ( n / 2 ) ; if ( n ) s += s ; } while ( n ) ; return out ; } const hex = ( v ) => parseInt ( String ( v ) ) . toString ( 16 ) ; initTrace . formatters [ "h" ] = hex ; initTrace . formatters [ "x" ] = ( v ) => `0x${ hex ( v ) }` ; initTrace . formatters [ "a" ] = ( v ) => `0x${ pad ( hex ( v ) , 8 ) }` ; initTrace . formatters [ "X" ] = ( v ) => `0x${ hex ( v ) . toUpperCase ( ) }` ;