aboutsummaryrefslogblamecommitdiffstats
path: root/packages/utils/src/abi_encoder/abstract_data_types/types/pointer.ts
blob: 0f3c55280c2b968acd398824d90dce223950b402 (plain) (tree)
1
2
3
4
5
6
7
8
9



                                           


                                                                     
                                                  
                                                  
 

                                                
 
                                                                
                                     
                                
 
                                                                                                               
                                 
                                        
                              

     
                                                                                                 
                                         

                                                                                               
                                                                                             

                                              
                                                 
                                                                                                           




                                                                            
                                                                               
                                                                                             
                                                                                               
                                                   
                                                      
                                                                       



                                          

                                                                         
                                
                    
     
                                                   
 
import { DataItem } from 'ethereum-types';
import * as ethUtil from 'ethereumjs-util';
import * as _ from 'lodash';

import { PointerCalldataBlock } from '../../calldata/blocks/pointer';
import { CalldataBlock } from '../../calldata/calldata_block';
import { RawCalldata } from '../../calldata/raw_calldata';
import { constants } from '../../utils/constants';
import { DecodingRules } from '../../utils/rules';

import { DataType } from '../data_type';
import { DataTypeFactory } from '../interfaces';

export abstract class AbstractPointerDataType extends DataType {
    protected _destination: DataType;
    protected _parent: DataType;

    public constructor(dataItem: DataItem, factory: DataTypeFactory, destination: DataType, parent: DataType) {
        super(dataItem, factory);
        this._destination = destination;
        this._parent = parent;
    }

    public generateCalldataBlock(value: any, parentBlock?: CalldataBlock): PointerCalldataBlock {
        if (_.isUndefined(parentBlock)) {
            throw new Error(`DependentDataType requires a parent block to generate its block`);
        }
        const destinationBlock = this._destination.generateCalldataBlock(value, parentBlock);
        const name = this.getDataItem().name;
        const signature = this.getSignature();
        const parentName = parentBlock.getName();
        const block = new PointerCalldataBlock(name, signature, parentName, destinationBlock, parentBlock);
        return block;
    }

    public generateValue(calldata: RawCalldata, rules: DecodingRules): any {
        const destinationOffsetBuf = calldata.popWord();
        const destinationOffsetHex = ethUtil.bufferToHex(destinationOffsetBuf);
        const destinationOffsetRelative = parseInt(destinationOffsetHex, constants.HEX_BASE);
        const destinationOffsetAbsolute = calldata.toAbsoluteOffset(destinationOffsetRelative);
        const currentOffset = calldata.getOffset();
        calldata.setOffset(destinationOffsetAbsolute);
        const value = this._destination.generateValue(calldata, rules);
        calldata.setOffset(currentOffset);
        return value;
    }

    // Disable prefer-function-over-method for inherited abstract method.
    /* tslint:disable prefer-function-over-method */
    public isStatic(): boolean {
        return true;
    }
    /* tslint:enable prefer-function-over-method */
}