author jdiaz5513
  import initTrace from "debug" ; import { MAX_SEGMENT_LENGTH , NATIVE_LITTLE_ENDIAN } from "../constants" ; import { SEG_REPLACEMENT_BUFFER_TOO_SMALL , SEG_SIZE_OVERFLOW } from "../errors" ; import { format , padToWord } from "../util" ; import { Message } from "./message" ; import { Pointer } from "./pointers" ; const trace = initTrace ( "capnp:segment" ) ; trace ( "load" ) ; export class Segment implements DataView { buffer : ArrayBuffer ; /** The number of bytes currently allocated in the segment. */ byteLength : number ; /**
     * This value should always be zero. It's only here to satisfy the DataView interface.
     *
     * In the future the Segment implementation (or a child class) may allow accessing the buffer from a nonzero offset,
     * but that adds a lot of extra arithmetic.
     */ byteOffset : number ; readonly [ Symbol . toStringTag ] = "Segment" as "DataView" ; readonly id : number ; readonly message : Message ; private _dv : DataView ; constructor ( id , message , buffer , byteLength = 0 ) { this . id = id ; this . message = message ; this . buffer = buffer ; this . _dv = new DataView ( buffer ) ; this . byteOffset = 0 ; this . byteLength = byteLength ; } param { number } byteLength returns { Pointer } allocate ( byteLength ) { trace ( "allocate(%d)" , byteLength ) ; let segment = this ; byteLength = padToWord ( byteLength ) ; if ( byteLength > MAX_SEGMENT_LENGTH - 8 ) { throw new Error ( format ( SEG_SIZE_OVERFLOW , byteLength ) ) ; } if ( ! segment . hasCapacity ( byteLength ) ) { segment = segment . message . allocateSegment ( byteLength ) ; } const byteOffset = segment . byteLength ; segment . byteLength = segment . byteLength + byteLength ; trace ( "Allocated %x bytes in %s (requested segment: %s)." , byteLength , this , segment ) ; return new Pointer ( segment , byteOffset ) ; } param { number } byteOffset param { Segment } srcSegment param { number } srcByteOffset returns { void } copyWord ( byteOffset , srcSegment , srcByteOffset ) { const value = srcSegment . _dv . getFloat64 ( srcByteOffset , NATIVE_LITTLE_ENDIAN ) ; this . _dv . setFloat64 ( byteOffset , value , NATIVE_LITTLE_ENDIAN ) ; } param { number } byteOffset param { Segment } srcSegment param { number } srcByteOffset param { number } wordLength returns { void } copyWords ( byteOffset , srcSegment , srcByteOffset , wordLength ) { const dst = new Float64Array ( this . buffer , byteOffset , wordLength ) ; const src = new Float64Array ( srcSegment . buffer , srcByteOffset , wordLength ) ; dst . set ( src ) ; } param { number } byteOffset param { number } wordLength returns { void } fillZeroWords ( byteOffset , wordLength ) { new Float64Array ( this . buffer , byteOffset , wordLength ) . fill ( 0 ) ; } getBigInt64 ( byteOffset , littleEndian ? ) { return this . _dv . getBigInt64 ( byteOffset , littleEndian ) ; } getBigUint64 ( byteOffset , littleEndian ? ) { return this . _dv . getBigUint64 ( byteOffset , littleEndian ) ; } returns { number } getCapacity ( ) { return this . buffer . byteLength ; } param { number } byteOffset returns { number } getFloat32 ( byteOffset ) { return this . _dv . getFloat32 ( byteOffset , true ) ; } param { number } byteOffset returns { number } getFloat64 ( byteOffset ) { return this . _dv . getFloat64 ( byteOffset , true ) ; } param { number } byteOffset returns { number } getInt16 ( byteOffset ) { return this . _dv . getInt16 ( byteOffset , true ) ; } param { number } byteOffset returns { number } getInt32 ( byteOffset ) { return this . _dv . getInt32 ( byteOffset , true ) ; } param { number } byteOffset returns { number } getInt64 ( byteOffset ) { return this . _dv . getBigInt64 ( byteOffset , true ) ; } param { number } byteOffset returns { number } getInt8 ( byteOffset ) { return this . _dv . getInt8 ( byteOffset ) ; } param { number } byteOffset returns { number } getUint16 ( byteOffset ) { return this . _dv . getUint16 ( byteOffset , true ) ; } param { number } byteOffset returns { number } getUint32 ( byteOffset ) { return this . _dv . getUint32 ( byteOffset , true ) ; } param { number } byteOffset returns { number } getUint64 ( byteOffset ) { return this . _dv . getBigUint64 ( byteOffset , true ) ; } param { number } byteOffset returns { number } getUint8 ( byteOffset ) { return this . _dv . getUint8 ( byteOffset ) ; } hasCapacity ( byteLength ) { trace ( "hasCapacity(%d)" , byteLength ) ; return this . buffer . byteLength - this . byteLength >= byteLength ; } param { number } byteOffset returns { boolean } isWordZero ( byteOffset ) { return this . _dv . getFloat64 ( byteOffset , NATIVE_LITTLE_ENDIAN ) === 0 ; } param { ArrayBuffer } buffer returns { void } replaceBuffer ( buffer ) { trace ( "replaceBuffer(%p)" , buffer ) ; if ( this . buffer === buffer ) return ; if ( buffer . byteLength < this . byteLength ) { throw new Error ( SEG_REPLACEMENT_BUFFER_TOO_SMALL ) ; } this . _dv = new DataView ( buffer ) ; this . buffer = buffer ; } setBigInt64 ( byteOffset , value , littleEndian ? ) { this . _dv . setBigInt64 ( byteOffset , value , littleEndian ) ; } /** WARNING: This function is not yet implemented.  */ setBigUint64 ( byteOffset , value , littleEndian ? ) { this . _dv . setBigUint64 ( byteOffset , value , littleEndian ) ; } param { number } byteOffset param { number } val returns { void } setFloat32 ( byteOffset , val ) { this . _dv . setFloat32 ( byteOffset , val , true ) ; } param { number } byteOffset param { number } val returns { void } setFloat64 ( byteOffset , val ) { this . _dv . setFloat64 ( byteOffset , val , true ) ; } param { number } byteOffset param { number } val returns { void } setInt16 ( byteOffset , val ) { this . _dv . setInt16 ( byteOffset , val , true ) ; } param { number } byteOffset param { number } val returns { void } setInt32 ( byteOffset , val ) { this . _dv . setInt32 ( byteOffset , val , true ) ; } param { number } byteOffset param { number } val returns { void } setInt8 ( byteOffset , val ) { this . _dv . setInt8 ( byteOffset , val ) ; } param { number } byteOffset param { bigint } val returns { void } setInt64 ( byteOffset , val ) { this . _dv . setBigInt64 ( byteOffset , val , true ) ; } param { number } byteOffset param { number } val returns { void } setUint16 ( byteOffset , val ) { this . _dv . setUint16 ( byteOffset , val , true ) ; } param { number } byteOffset param { number } val returns { void } setUint32 ( byteOffset , val ) { this . _dv . setUint32 ( byteOffset , val , true ) ; } param { number } byteOffset param { bigint } val returns { void } setUint64 ( byteOffset , val ) { this . _dv . setBigUint64 ( byteOffset , val , true ) ; } param { number } byteOffset param { number } val returns { void } setUint8 ( byteOffset , val ) { this . _dv . setUint8 ( byteOffset , val ) ; } param { number } byteOffset returns { void } setWordZero ( byteOffset ) { this . _dv . setFloat64 ( byteOffset , 0 , NATIVE_LITTLE_ENDIAN ) ; } toString ( ) { return format ( "Segment_id:%d,off:%a,len:%a,cap:%a" , this . id , this . byteLength , this . byteOffset , this . buffer . byteLength ) ; } }