author jdiaz5513
  import initTrace from "debug" ; import { MAX_DEPTH , NATIVE_LITTLE_ENDIAN } from "../../constants" ; import { format , padToWord } from "../../util" ; import { ListElementSize } from "../list-element-size" ; import { ObjectSize , getByteLength , getDataWordLength , getWordLength } from "../object-size" ; import { Segment } from "../segment" ; import { Data } from "./data" ; import { List , ListCtor } from "./list" ; import { Orphan } from "./orphan" ; import { _Pointer , _PointerCtor , Pointer , PointerCtor , getContent , getStructSize , initPointer , erase , setStructPointer , followFars , getTargetListElementSize , getTargetPointerType , isNull , getTargetCompositeListSize , getTargetListLength , setListPointer , getTargetStructSize , validate , copyFrom , } from "./pointer" ; import { PointerType } from "./pointer-type" ; import { Text } from "./text" ; import { PTR_INIT_COMPOSITE_STRUCT , PTR_ADOPT_COMPOSITE_STRUCT , PTR_DISOWN_COMPOSITE_STRUCT , PTR_INVALID_UNION_ACCESS , PTR_STRUCT_DATA_OUT_OF_BOUNDS , PTR_STRUCT_POINTER_OUT_OF_BOUNDS , INVARIANT_UNREACHABLE_CODE , } from "../../errors" ; const trace = initTrace ( "capnp:struct" ) ; trace ( "load" ) ; const TMP_WORD = new DataView ( new ArrayBuffer ( 8 ) ) ; export interface _StructCtor extends _PointerCtor { readonly id : string ; readonly size : ObjectSize ; } export interface StructCtor < T extends Struct > { readonly _capnp : _StructCtor ; new ( segment , byteOffset , depthLimit ? , compositeIndex ? ) : T ; } export interface _Struct extends _Pointer { compositeIndex ? : number ; } export class Struct extends Pointer { static readonly _capnp = { displayName : "Struct" as string , } ; static readonly getAs = getAs ; static readonly getBit = getBit ; static readonly getData = getData ; static readonly getFloat32 = getFloat32 ; static readonly getFloat64 = getFloat64 ; static readonly getUint8 = getUint8 ; static readonly getUint16 = getUint16 ; static readonly getUint32 = getUint32 ; static readonly getUint64 = getUint64 ; static readonly getInt8 = getInt8 ; static readonly getInt16 = getInt16 ; static readonly getInt32 = getInt32 ; static readonly getInt64 = getInt64 ; static readonly getList = getList ; static readonly getPointer = getPointer ; static readonly getPointerAs = getPointerAs ; static readonly getStruct = getStruct ; static readonly getText = getText ; static readonly initData = initData ; static readonly initList = initList ; static readonly initStruct = initStruct ; static readonly initStructAt = initStructAt ; static readonly setBit = setBit ; static readonly setFloat32 = setFloat32 ; static readonly setFloat64 = setFloat64 ; static readonly setUint8 = setUint8 ; static readonly setUint16 = setUint16 ; static readonly setUint32 = setUint32 ; static readonly setUint64 = setUint64 ; static readonly setInt8 = setInt8 ; static readonly setInt16 = setInt16 ; static readonly setInt32 = setInt32 ; static readonly setInt64 = setInt64 ; static readonly setText = setText ; static readonly testWhich = testWhich ; readonly _capnp ! : _Struct ; constructor param { Segment } segment param { number } byteOffset param { any } depthLimit param { number } compositeIndex constructor ( segment , byteOffset , depthLimit = MAX_DEPTH , compositeIndex ? ) { super ( segment , byteOffset , depthLimit ) ; this . _capnp . compositeIndex = compositeIndex ; this . _capnp . compositeList = compositeIndex !== undefined ; } static toString ( ) { return this . _capnp . displayName ; } toString ( ) { return ( `Struct_${ super . toString ( ) }` + `${ this . _capnp . compositeIndex === undefined ? "" : `,ci:${ this . _capnp . compositeIndex }` }` + ` > ${ getContent ( this ) . toString ( ) }` ) ; } } param { ObjectSize } size param { Struct } s returns { void } export function initStruct ( size , s ) { if ( s . _capnp . compositeIndex !== undefined ) { throw new Error ( format ( PTR_INIT_COMPOSITE_STRUCT , s ) ) ; } erase ( s ) ; const c = s . segment . allocate ( getByteLength ( size ) ) ; const res = initPointer ( c . segment , c . byteOffset , s ) ; setStructPointer ( res . offsetWords , size , res . pointer ) ; } export function initStructAt < T extends Struct > ( index , StructClass , p ) { const s = getPointerAs ( index , StructClass , p ) ; initStruct ( StructClass . _capnp . size , s ) ; return s ; } param { ObjectSize } dstSize param { Struct } s returns { void } export function resize ( dstSize , s ) { const srcSize = getSize ( s ) ; const srcContent = getContent ( s ) ; const dstContent = s . segment . allocate ( getByteLength ( dstSize ) ) ; dstContent . segment . copyWords ( dstContent . byteOffset , srcContent . segment , srcContent . byteOffset , Math . min ( getDataWordLength ( srcSize ) , getDataWordLength ( dstSize ) ) ) ; const res = initPointer ( dstContent . segment , dstContent . byteOffset , s ) ; setStructPointer ( res . offsetWords , dstSize , res . pointer ) ; for ( let i = 0 ; i < Math . min ( srcSize . pointerLength , dstSize . pointerLength ) ; i ++ ) { const srcPtr = new Pointer ( srcContent . segment , srcContent . byteOffset + srcSize . dataByteLength + i * 8 ) ; if ( isNull ( srcPtr ) ) { continue ; } const srcPtrTarget = followFars ( srcPtr ) ; const srcPtrContent = getContent ( srcPtr ) ; const dstPtr = new Pointer ( dstContent . segment , dstContent . byteOffset + dstSize . dataByteLength + i * 8 ) ; if ( getTargetPointerType ( srcPtr ) === PointerType . LIST && getTargetListElementSize ( srcPtr ) === ListElementSize . COMPOSITE ) { srcPtrContent . byteOffset -= 8 ; } const r = initPointer ( srcPtrContent . segment , srcPtrContent . byteOffset , dstPtr ) ; const a = srcPtrTarget . segment . getUint8 ( srcPtrTarget . byteOffset ) & 0x03 ; const b = srcPtrTarget . segment . getUint32 ( srcPtrTarget . byteOffset + 4 ) ; r . pointer . segment . setUint32 ( r . pointer . byteOffset , a | ( r . offsetWords << 2 ) ) ; r . pointer . segment . setUint32 ( r . pointer . byteOffset + 4 , b ) ; } srcContent . segment . fillZeroWords ( srcContent . byteOffset , getWordLength ( srcSize ) ) ; } export function adopt < T extends Struct > ( src , s ) { if ( s . _capnp . compositeIndex !== undefined ) { throw new Error ( format ( PTR_ADOPT_COMPOSITE_STRUCT , s ) ) ; } Pointer . adopt ( src , s ) ; } export function disown < T extends Struct > ( s ) { if ( s . _capnp . compositeIndex !== undefined ) { throw new Error ( format ( PTR_DISOWN_COMPOSITE_STRUCT , s ) ) ; } return Pointer . disown ( s ) ; } protected template T param { StructCtor < T > } StructClass param { Struct } s returns { T } export function getAs < T extends Struct > ( StructClass , s ) { return new StructClass ( s . segment , s . byteOffset , s . _capnp . depthLimit , s . _capnp . compositeIndex ) ; } protected param { number } bitOffset param { Struct } s param { DataView } defaultMask returns { boolean } export function getBit ( bitOffset , s , defaultMask ? ) { const byteOffset = Math . floor ( bitOffset / 8 ) ; const bitMask = 1 << bitOffset % 8 ; checkDataBounds ( byteOffset , 1 , s ) ; const ds = getDataSection ( s ) ; const v = ds . segment . getUint8 ( ds . byteOffset + byteOffset ) ; if ( defaultMask === undefined ) return ( v & bitMask ) !== 0 ; const defaultValue = defaultMask . getUint8 ( 0 ) ; return ( ( v ^ defaultValue ) & bitMask ) !== 0 ; } export function getData ( index , s , defaultValue ? ) { checkPointerBounds ( index , s ) ; const ps = getPointerSection ( s ) ; ps . byteOffset += index * 8 ; const l = new Data ( ps . segment , ps . byteOffset , s . _capnp . depthLimit - 1 ) ; if ( isNull ( l ) ) { if ( defaultValue ) { Pointer . copyFrom ( defaultValue , l ) ; } else { List . initList ( ListElementSize . BYTE , 0 , l ) ; } } return l ; } export function getDataSection ( s ) { return getContent ( s ) ; } param { number } byteOffset param { Struct } s param { DataView } defaultMask returns { number } export function getFloat32 ( byteOffset , s , defaultMask ? ) { checkDataBounds ( byteOffset , 4 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask === undefined ) { return ds . segment . getFloat32 ( ds . byteOffset + byteOffset ) ; } const v = ds . segment . getUint32 ( ds . byteOffset + byteOffset ) ^ defaultMask . getUint32 ( 0 , true ) ; TMP_WORD . setUint32 ( 0 , v , NATIVE_LITTLE_ENDIAN ) ; return TMP_WORD . getFloat32 ( 0 , NATIVE_LITTLE_ENDIAN ) ; } param { number } byteOffset param { Struct } s param { DataView } defaultMask returns { number } export function getFloat64 ( byteOffset , s , defaultMask ? ) { checkDataBounds ( byteOffset , 8 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask !== undefined ) { const lo = ds . segment . getUint32 ( ds . byteOffset + byteOffset ) ^ defaultMask . getUint32 ( 0 , true ) ; const hi = ds . segment . getUint32 ( ds . byteOffset + byteOffset + 4 ) ^ defaultMask . getUint32 ( 4 , true ) ; TMP_WORD . setUint32 ( 0 , lo , NATIVE_LITTLE_ENDIAN ) ; TMP_WORD . setUint32 ( 4 , hi , NATIVE_LITTLE_ENDIAN ) ; return TMP_WORD . getFloat64 ( 0 , NATIVE_LITTLE_ENDIAN ) ; } return ds . segment . getFloat64 ( ds . byteOffset + byteOffset ) ; } param { number } byteOffset param { Struct } s param { DataView } defaultMask returns { number } export function getInt16 ( byteOffset , s , defaultMask ? ) { checkDataBounds ( byteOffset , 2 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask === undefined ) { return ds . segment . getInt16 ( ds . byteOffset + byteOffset ) ; } const v = ds . segment . getUint16 ( ds . byteOffset + byteOffset ) ^ defaultMask . getUint16 ( 0 , true ) ; TMP_WORD . setUint16 ( 0 , v , NATIVE_LITTLE_ENDIAN ) ; return TMP_WORD . getInt16 ( 0 , NATIVE_LITTLE_ENDIAN ) ; } param { number } byteOffset param { Struct } s param { DataView } defaultMask returns { number } export function getInt32 ( byteOffset , s , defaultMask ? ) { checkDataBounds ( byteOffset , 4 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask === undefined ) { return ds . segment . getInt32 ( ds . byteOffset + byteOffset ) ; } const v = ds . segment . getUint32 ( ds . byteOffset + byteOffset ) ^ defaultMask . getUint16 ( 0 , true ) ; TMP_WORD . setUint32 ( 0 , v , NATIVE_LITTLE_ENDIAN ) ; return TMP_WORD . getInt32 ( 0 , NATIVE_LITTLE_ENDIAN ) ; } param { number } byteOffset param { Struct } s param { DataView } defaultMask returns { bigint } export function getInt64 ( byteOffset , s , defaultMask ? ) { checkDataBounds ( byteOffset , 8 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask !== undefined ) { const lo = ds . segment . getUint32 ( ds . byteOffset + byteOffset ) ^ defaultMask . getUint32 ( 0 , true ) ; const hi = ds . segment . getUint32 ( ds . byteOffset + byteOffset + 4 ) ^ defaultMask . getUint32 ( 4 , true ) ; TMP_WORD . setUint32 ( NATIVE_LITTLE_ENDIAN ? 0 : 4 , lo , NATIVE_LITTLE_ENDIAN ) ; TMP_WORD . setUint32 ( NATIVE_LITTLE_ENDIAN ? 4 : 0 , hi , NATIVE_LITTLE_ENDIAN ) ; return TMP_WORD . getBigInt64 ( 0 , NATIVE_LITTLE_ENDIAN ) ; } return ds . segment . getInt64 ( ds . byteOffset + byteOffset ) ; } param { number } byteOffset param { Struct } s param { DataView } defaultMask returns { number } export function getInt8 ( byteOffset , s , defaultMask ? ) { checkDataBounds ( byteOffset , 1 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask === undefined ) { return ds . segment . getInt8 ( ds . byteOffset + byteOffset ) ; } const v = ds . segment . getUint8 ( ds . byteOffset + byteOffset ) ^ defaultMask . getUint8 ( 0 ) ; TMP_WORD . setUint8 ( 0 , v ) ; return TMP_WORD . getInt8 ( 0 ) ; } export function getList < T > ( index , ListClass , s , defaultValue ? ) { checkPointerBounds ( index , s ) ; const ps = getPointerSection ( s ) ; ps . byteOffset += index * 8 ; const l = new ListClass ( ps . segment , ps . byteOffset , s . _capnp . depthLimit - 1 ) ; if ( isNull ( l ) ) { if ( defaultValue ) { Pointer . copyFrom ( defaultValue , l ) ; } else { List . initList ( ListClass . _capnp . size , 0 , l , ListClass . _capnp . compositeSize ) ; } } else if ( ListClass . _capnp . compositeSize !== undefined ) { const srcSize = getTargetCompositeListSize ( l ) ; const dstSize = ListClass . _capnp . compositeSize ; if ( dstSize . dataByteLength > srcSize . dataByteLength || dstSize . pointerLength > srcSize . pointerLength ) { const srcContent = getContent ( l ) ; const srcLength = getTargetListLength ( l ) ; trace ( "resizing composite list %s due to protocol upgrade, new size: %d" , l , getByteLength ( dstSize ) * srcLength ) ; const dstContent = l . segment . allocate ( getByteLength ( dstSize ) * srcLength + 8 ) ; const res = initPointer ( dstContent . segment , dstContent . byteOffset , l ) ; setListPointer ( res . offsetWords , ListClass . _capnp . size , srcLength , res . pointer , dstSize ) ; setStructPointer ( srcLength , dstSize , dstContent ) ; dstContent . byteOffset += 8 ; for ( let i = 0 ; i < srcLength ; i ++ ) { const srcElementOffset = srcContent . byteOffset + i * getByteLength ( srcSize ) ; const dstElementOffset = dstContent . byteOffset + i * getByteLength ( dstSize ) ; dstContent . segment . copyWords ( dstElementOffset , srcContent . segment , srcElementOffset , getWordLength ( srcSize ) ) ; for ( let j = 0 ; j < srcSize . pointerLength ; j ++ ) { const srcPtr = new Pointer ( srcContent . segment , srcElementOffset + srcSize . dataByteLength + j * 8 ) ; const dstPtr = new Pointer ( dstContent . segment , dstElementOffset + dstSize . dataByteLength + j * 8 ) ; const srcPtrTarget = followFars ( srcPtr ) ; const srcPtrContent = getContent ( srcPtr ) ; if ( getTargetPointerType ( srcPtr ) === PointerType . LIST && getTargetListElementSize ( srcPtr ) === ListElementSize . COMPOSITE ) { srcPtrContent . byteOffset -= 8 ; } const r = initPointer ( srcPtrContent . segment , srcPtrContent . byteOffset , dstPtr ) ; const a = srcPtrTarget . segment . getUint8 ( srcPtrTarget . byteOffset ) & 0x03 ; const b = srcPtrTarget . segment . getUint32 ( srcPtrTarget . byteOffset + 4 ) ; r . pointer . segment . setUint32 ( r . pointer . byteOffset , a | ( r . offsetWords << 2 ) ) ; r . pointer . segment . setUint32 ( r . pointer . byteOffset + 4 , b ) ; } } srcContent . segment . fillZeroWords ( srcContent . byteOffset , getWordLength ( srcSize ) * srcLength ) ; } } return l ; } export function getPointer ( index , s ) { checkPointerBounds ( index , s ) ; const ps = getPointerSection ( s ) ; ps . byteOffset += index * 8 ; return new Pointer ( ps . segment , ps . byteOffset , s . _capnp . depthLimit - 1 ) ; } export function getPointerAs < T extends Pointer > ( index , PointerClass , s ) { checkPointerBounds ( index , s ) ; const ps = getPointerSection ( s ) ; ps . byteOffset += index * 8 ; return new PointerClass ( ps . segment , ps . byteOffset , s . _capnp . depthLimit - 1 ) ; } export function getPointerSection ( s ) { const ps = getContent ( s ) ; ps . byteOffset += padToWord ( getSize ( s ) . dataByteLength ) ; return ps ; } export function getSize ( s ) { if ( s . _capnp . compositeIndex !== undefined ) { const c = getContent ( s , true ) ; c . byteOffset -= 8 ; return getStructSize ( c ) ; } return getTargetStructSize ( s ) ; } export function getStruct < T extends Struct > ( index , StructClass , s , defaultValue ? ) { const t = getPointerAs ( index , StructClass , s ) ; if ( isNull ( t ) ) { if ( defaultValue ) { Pointer . copyFrom ( defaultValue , t ) ; } else { initStruct ( StructClass . _capnp . size , t ) ; } } else { validate ( PointerType . STRUCT , t ) ; const ts = getTargetStructSize ( t ) ; if ( ts . dataByteLength < StructClass . _capnp . size . dataByteLength || ts . pointerLength < StructClass . _capnp . size . pointerLength ) { trace ( "need to resize child struct %s" , t ) ; resize ( StructClass . _capnp . size , t ) ; } } return t ; } export function getText ( index , s , defaultValue ? ) { const t = Text . fromPointer ( getPointer ( index , s ) ) ; if ( isNull ( t ) && defaultValue ) t . set ( 0 , defaultValue ) ; return t . get ( 0 ) ; } param { number } byteOffset param { Struct } s param { DataView } defaultMask returns { number } export function getUint16 ( byteOffset , s , defaultMask ? ) { checkDataBounds ( byteOffset , 2 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask === undefined ) { return ds . segment . getUint16 ( ds . byteOffset + byteOffset ) ; } return ds . segment . getUint16 ( ds . byteOffset + byteOffset ) ^ defaultMask . getUint16 ( 0 , true ) ; } param { number } byteOffset param { Struct } s param { DataView } defaultMask returns { number } export function getUint32 ( byteOffset , s , defaultMask ? ) { checkDataBounds ( byteOffset , 4 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask === undefined ) { return ds . segment . getUint32 ( ds . byteOffset + byteOffset ) ; } return ds . segment . getUint32 ( ds . byteOffset + byteOffset ) ^ defaultMask . getUint32 ( 0 , true ) ; } param { number } byteOffset param { Struct } s param { DataView } defaultMask returns { bigint } export function getUint64 ( byteOffset , s , defaultMask ? ) { checkDataBounds ( byteOffset , 8 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask !== undefined ) { const lo = ds . segment . getUint32 ( ds . byteOffset + byteOffset ) ^ defaultMask . getUint32 ( 0 , true ) ; const hi = ds . segment . getUint32 ( ds . byteOffset + byteOffset + 4 ) ^ defaultMask . getUint32 ( 4 , true ) ; TMP_WORD . setUint32 ( NATIVE_LITTLE_ENDIAN ? 0 : 4 , lo , NATIVE_LITTLE_ENDIAN ) ; TMP_WORD . setUint32 ( NATIVE_LITTLE_ENDIAN ? 4 : 0 , hi , NATIVE_LITTLE_ENDIAN ) ; return TMP_WORD . getBigUint64 ( 0 , NATIVE_LITTLE_ENDIAN ) ; } return ds . segment . getUint64 ( ds . byteOffset + byteOffset ) ; } param { number } byteOffset param { Struct } s param { DataView } defaultMask returns { number } export function getUint8 ( byteOffset , s , defaultMask ? ) { checkDataBounds ( byteOffset , 1 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask === undefined ) { return ds . segment . getUint8 ( ds . byteOffset + byteOffset ) ; } return ds . segment . getUint8 ( ds . byteOffset + byteOffset ) ^ defaultMask . getUint8 ( 0 ) ; } export function getVoid ( ) { throw new Error ( INVARIANT_UNREACHABLE_CODE ) ; } export function initData ( index , length , s ) { checkPointerBounds ( index , s ) ; const ps = getPointerSection ( s ) ; ps . byteOffset += index * 8 ; const l = new Data ( ps . segment , ps . byteOffset , s . _capnp . depthLimit - 1 ) ; erase ( l ) ; List . initList ( ListElementSize . BYTE , length , l ) ; return l ; } export function initList < T > ( index , ListClass , length , s ) { checkPointerBounds ( index , s ) ; const ps = getPointerSection ( s ) ; ps . byteOffset += index * 8 ; const l = new ListClass ( ps . segment , ps . byteOffset , s . _capnp . depthLimit - 1 ) ; erase ( l ) ; List . initList ( ListClass . _capnp . size , length , l , ListClass . _capnp . compositeSize ) ; return l ; } protected param { number } bitOffset param { boolean } value param { Struct } s param { DataView } defaultMask returns { void } export function setBit ( bitOffset , value , s , defaultMask ? ) { const byteOffset = Math . floor ( bitOffset / 8 ) ; const bitMask = 1 << bitOffset % 8 ; checkDataBounds ( byteOffset , 1 , s ) ; const ds = getDataSection ( s ) ; const b = ds . segment . getUint8 ( ds . byteOffset + byteOffset ) ; if ( defaultMask !== undefined ) { value = ( defaultMask . getUint8 ( 0 ) & bitMask ) !== 0 ? ! value : value ; } ds . segment . setUint8 ( ds . byteOffset + byteOffset , value ? b | bitMask : b & ~ bitMask ) ; } protected param { number } byteOffset param { number } value param { Struct } s param { DataView } defaultMask returns { void } export function setFloat32 ( byteOffset , value , s , defaultMask ? ) { checkDataBounds ( byteOffset , 4 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask !== undefined ) { TMP_WORD . setFloat32 ( 0 , value , NATIVE_LITTLE_ENDIAN ) ; const v = TMP_WORD . getUint32 ( 0 , NATIVE_LITTLE_ENDIAN ) ^ defaultMask . getUint32 ( 0 , true ) ; ds . segment . setUint32 ( ds . byteOffset + byteOffset , v ) ; return ; } ds . segment . setFloat32 ( ds . byteOffset + byteOffset , value ) ; } protected param { number } byteOffset param { number } value param { Struct } s param { DataView } defaultMask returns { void } export function setFloat64 ( byteOffset , value , s , defaultMask ? ) { checkDataBounds ( byteOffset , 8 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask !== undefined ) { TMP_WORD . setFloat64 ( 0 , value , NATIVE_LITTLE_ENDIAN ) ; const lo = TMP_WORD . getUint32 ( 0 , NATIVE_LITTLE_ENDIAN ) ^ defaultMask . getUint32 ( 0 , true ) ; const hi = TMP_WORD . getUint32 ( 4 , NATIVE_LITTLE_ENDIAN ) ^ defaultMask . getUint32 ( 4 , true ) ; ds . segment . setUint32 ( ds . byteOffset + byteOffset , lo ) ; ds . segment . setUint32 ( ds . byteOffset + byteOffset + 4 , hi ) ; return ; } ds . segment . setFloat64 ( ds . byteOffset + byteOffset , value ) ; } protected param { number } byteOffset param { number } value param { Struct } s param { DataView } defaultMask returns { void } export function setInt16 ( byteOffset , value , s , defaultMask ? ) { checkDataBounds ( byteOffset , 2 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask !== undefined ) { TMP_WORD . setInt16 ( 0 , value , NATIVE_LITTLE_ENDIAN ) ; const v = TMP_WORD . getUint16 ( 0 , NATIVE_LITTLE_ENDIAN ) ^ defaultMask . getUint16 ( 0 , true ) ; ds . segment . setUint16 ( ds . byteOffset + byteOffset , v ) ; return ; } ds . segment . setInt16 ( ds . byteOffset + byteOffset , value ) ; } protected param { number } byteOffset param { number } value param { Struct } s param { DataView } defaultMask returns { void } export function setInt32 ( byteOffset , value , s , defaultMask ? ) { checkDataBounds ( byteOffset , 4 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask !== undefined ) { TMP_WORD . setInt32 ( 0 , value , NATIVE_LITTLE_ENDIAN ) ; const v = TMP_WORD . getUint32 ( 0 , NATIVE_LITTLE_ENDIAN ) ^ defaultMask . getUint32 ( 0 , true ) ; ds . segment . setUint32 ( ds . byteOffset + byteOffset , v ) ; return ; } ds . segment . setInt32 ( ds . byteOffset + byteOffset , value ) ; } protected param { number } byteOffset param { bigint } value param { Struct } s param { DataView } defaultMask returns { void } export function setInt64 ( byteOffset , value , s , defaultMask ? ) { checkDataBounds ( byteOffset , 8 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask !== undefined ) { TMP_WORD . setBigInt64 ( 0 , value , NATIVE_LITTLE_ENDIAN ) ; const lo = TMP_WORD . getUint32 ( NATIVE_LITTLE_ENDIAN ? 0 : 4 , NATIVE_LITTLE_ENDIAN ) ^ defaultMask . getUint32 ( 0 , true ) ; const hi = TMP_WORD . getUint32 ( NATIVE_LITTLE_ENDIAN ? 4 : 0 , NATIVE_LITTLE_ENDIAN ) ^ defaultMask . getUint32 ( 4 , true ) ; ds . segment . setUint32 ( ds . byteOffset + byteOffset , lo ) ; ds . segment . setUint32 ( ds . byteOffset + byteOffset + 4 , hi ) ; return ; } ds . segment . setInt64 ( ds . byteOffset + byteOffset , value ) ; } protected param { number } byteOffset param { number } value param { Struct } s param { DataView } defaultMask returns { void } export function setInt8 ( byteOffset , value , s , defaultMask ? ) { checkDataBounds ( byteOffset , 1 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask !== undefined ) { TMP_WORD . setInt8 ( 0 , value ) ; const v = TMP_WORD . getUint8 ( 0 ) ^ defaultMask . getUint8 ( 0 ) ; ds . segment . setUint8 ( ds . byteOffset + byteOffset , v ) ; return ; } ds . segment . setInt8 ( ds . byteOffset + byteOffset , value ) ; } export function setPointer ( index , value , s ) { copyFrom ( value , getPointer ( index , s ) ) ; } export function setText ( index , value , s ) { Text . fromPointer ( getPointer ( index , s ) ) . set ( 0 , value ) ; } protected param { number } byteOffset param { number } value param { Struct } s param { DataView } defaultMask returns { void } export function setUint16 ( byteOffset , value , s , defaultMask ? ) { checkDataBounds ( byteOffset , 2 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask !== undefined ) value ^= defaultMask . getUint16 ( 0 , true ) ; ds . segment . setUint16 ( ds . byteOffset + byteOffset , value ) ; } protected param { number } byteOffset param { number } value param { Struct } s param { DataView } defaultMask returns { void } export function setUint32 ( byteOffset , value , s , defaultMask ? ) { checkDataBounds ( byteOffset , 4 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask !== undefined ) value ^= defaultMask . getUint32 ( 0 , true ) ; ds . segment . setUint32 ( ds . byteOffset + byteOffset , value ) ; } protected param { number } byteOffset param { bigint } value param { Struct } s param { DataView } defaultMask returns { void } export function setUint64 ( byteOffset , value , s , defaultMask ? ) { checkDataBounds ( byteOffset , 8 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask !== undefined ) { TMP_WORD . setBigUint64 ( 0 , value , NATIVE_LITTLE_ENDIAN ) ; const lo = TMP_WORD . getUint32 ( NATIVE_LITTLE_ENDIAN ? 0 : 4 , NATIVE_LITTLE_ENDIAN ) ^ defaultMask . getUint32 ( 0 , true ) ; const hi = TMP_WORD . getUint32 ( NATIVE_LITTLE_ENDIAN ? 4 : 0 , NATIVE_LITTLE_ENDIAN ) ^ defaultMask . getUint32 ( 4 , true ) ; ds . segment . setUint32 ( ds . byteOffset + byteOffset , lo ) ; ds . segment . setUint32 ( ds . byteOffset + byteOffset + 4 , hi ) ; return ; } ds . segment . setUint64 ( ds . byteOffset + byteOffset , value ) ; } protected param { number } byteOffset param { number } value param { Struct } s param { DataView } defaultMask returns { void } export function setUint8 ( byteOffset , value , s , defaultMask ? ) { checkDataBounds ( byteOffset , 1 , s ) ; const ds = getDataSection ( s ) ; if ( defaultMask !== undefined ) value ^= defaultMask . getUint8 ( 0 ) ; ds . segment . setUint8 ( ds . byteOffset + byteOffset , value ) ; } export function setVoid ( ) { throw new Error ( INVARIANT_UNREACHABLE_CODE ) ; } export function testWhich ( name , found , wanted , s ) { if ( found !== wanted ) { throw new Error ( format ( PTR_INVALID_UNION_ACCESS , s , name , found , wanted ) ) ; } } export function checkDataBounds ( byteOffset , byteLength , s ) { const dataByteLength = getSize ( s ) . dataByteLength ; if ( byteOffset < 0 || byteLength < 0 || byteOffset + byteLength > dataByteLength ) { throw new Error ( format ( PTR_STRUCT_DATA_OUT_OF_BOUNDS , s , byteLength , byteOffset , dataByteLength ) ) ; } } export function checkPointerBounds ( index , s ) { const pointerLength = getSize ( s ) . pointerLength ; if ( index < 0 || index >= pointerLength ) { throw new Error ( format ( PTR_STRUCT_POINTER_OUT_OF_BOUNDS , s , index , pointerLength ) ) ; } }