import { Variable , DecodedVariable , VariableLocation } from "../variable" ; import { ValueDetail } from "./value" ; import { BN } from "bn.js" ; import { LibSdbInterface } from "../../../interface" ; import { LibSdbTypes } from "../../types" ; import { VariableProcessor } from "../definition/processor" ; export class StructDetail { variable : Variable ; position : BN ; location : VariableLocation ; isPointer : boolean ; offset : number | null ; id : number ; name : string ; members : { name : string ; detail : ( LibSdbTypes . VariableDetailType | null ) ; } [ ] ; memoryLength : number ; constructor ( variable ) { this . variable = variable ; this . position = new BN ( 0 ) ; this . id = Variable . nextId ++ ; this . members = [ ] ; } getStorageUsed ( ) { let storageUsed = 0 ; for ( let i = 0 ; i < this . members . length ; i ++ ) { const detail = this . members [ i ] . detail ; if ( detail !== null ) { storageUsed += detail . getStorageUsed ( ) ; } } return Math . ceil ( storageUsed / 32 ) * 32 ; } childIds ( ) { let ids = [ ] ; for ( let i = 0 ; i < this . members . length ; i ++ ) { const type = this . members [ i ] . detail ; if ( ! ( type instanceof ValueDetail ) && type !== null ) { ids . push ( type . id ) ; ids = ids . concat ( type . childIds ( ) ) ; } } return ids ; } clone ( variable = this . variable ) { let clone = new StructDetail ( variable ) ; clone . position = this . position ; clone . location = this . location ; clone . isPointer = this . isPointer ; clone . offset = this . offset ; clone . name = this . name ; for ( let i = 0 ; i < this . members . length ; i ++ ) { clone . members . push ( { name : this . members [ i ] . name , detail : this . members [ i ] . detail === null ? null : this . members [ i ] . detail ! . clone ( variable ) } ) ; } clone . memoryLength = this . memoryLength ; return clone ; } assignMemberPositions ( ) { const processor = new VariableProcessor ( this . variable , this . position , 0 ) ; for ( let i = 0 ; i < this . members . length ; i ++ ) { if ( this . members [ i ] . detail !== null ) { processor . applyStoragePositions ( this . members [ i ] . detail ! ) ; } } } async decodeChildren ( stack , memory , _interface , address ) { let decodedVariables = [ ] ; if ( this . isPointer && this . variable . position && this . variable . position < stack . length ) { this . position = stack [ this . variable . position ] . clone ( ) ; this . assignMemberPositions ( ) ; } for ( let i = 0 ; i < this . members . length ; i ++ ) { let decodedVariable ; if ( this . members [ i ] . detail === null ) { decodedVariable = < DecodedVariable > { type : "" , variablesReference : 0 , value : "(unsupported type)" , result : "" } ; } else { decodedVariable = await this . members [ i ] . detail ! . decode ( stack , memory , _interface , address ) ; } decodedVariable . name = this . members [ i ] . name ; decodedVariables . push ( decodedVariable ) ; } return decodedVariables ; } async decode ( stack , memory , _interface , address ) { let decodedVariable = < DecodedVariable > { name : this . variable . name , type : this . name , variablesReference : this . id , value : "Struct" , result : "" } ; return decodedVariable ; } }