UNPKG

@0x/utils

Version:
105 lines 3.29 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.ReverseCalldataIterator = exports.CalldataIterator = void 0; /* tslint:disable max-classes-per-file */ const _ = require("lodash"); const queue_1 = require("../utils/queue"); const blob_1 = require("./blocks/blob"); const pointer_1 = require("./blocks/pointer"); const set_1 = require("./blocks/set"); /** * Iterator class for Calldata Blocks. Blocks follows the order * they should be put into calldata that is passed to he EVM. * * Example #1: * Let root = Set { * Blob{} A, * Pointer { * Blob{} a * } B, * Blob{} C * } * It will iterate as follows: [A, B, C, B.a] * * Example #2: * Let root = Set { * Blob{} A, * Pointer { * Blob{} a * Pointer { * Blob{} b * } * } B, * Pointer { * Blob{} c * } C * } * It will iterate as follows: [A, B, C, B.a, B.b, C.c] */ class BaseIterator { constructor(root) { this._root = root; this._queue = BaseIterator._createQueue(root); } static _createQueue(block) { const queue = new queue_1.Queue(); // Base case if (!(block instanceof set_1.SetCalldataBlock)) { queue.pushBack(block); return queue; } // This is a set; add members const set = block; _.eachRight(set.getMembers(), (member) => { queue.mergeFront(BaseIterator._createQueue(member)); }); // Add children _.each(set.getMembers(), (member) => { // Traverse child if it is a unique pointer. // A pointer that is an alias for another pointer is ignored. if (member instanceof pointer_1.PointerCalldataBlock && member.getAlias() === undefined) { const dependency = member.getDependency(); queue.mergeBack(BaseIterator._createQueue(dependency)); } }); // Put set block at the front of the queue queue.pushFront(set); return queue; } [Symbol.iterator]() { return { next: () => { const nextBlock = this.nextBlock(); if (nextBlock !== undefined) { return { value: nextBlock, done: false, }; } return { done: true, value: new blob_1.BlobCalldataBlock('', '', '', Buffer.from('')), }; }, }; } } class CalldataIterator extends BaseIterator { constructor(root) { super(root); } nextBlock() { return this._queue.popFront(); } } exports.CalldataIterator = CalldataIterator; class ReverseCalldataIterator extends BaseIterator { constructor(root) { super(root); } nextBlock() { return this._queue.popBack(); } } exports.ReverseCalldataIterator = ReverseCalldataIterator; //# sourceMappingURL=iterator.js.map