UNPKG

@ton/core

Version:

Core TypeScript library that implements low level primitives for TON blockchain.

559 lines (498 loc) 12.1 kB
/** * Copyright (c) Whales Corp. * All Rights Reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ import inspectSymbol from 'symbol.inspect'; import { Dictionary, DictionaryKey, DictionaryKeyTypes, DictionaryValue } from '../dict/Dictionary'; import { BitReader } from "./BitReader"; import { beginCell } from "./Builder"; import { Cell } from "./Cell"; import { readString } from "./utils/strings"; /** * Slice is a class that allows to read cell data */ export class Slice { private _reader: BitReader; private _refs: Cell[]; private _refsOffset: number; constructor(reader: BitReader, refs: Cell[]) { this._reader = reader.clone(); this._refs = [...refs]; this._refsOffset = 0; } /** * Get remaining bits */ get remainingBits() { return this._reader.remaining; } /** * Get offset bits */ get offsetBits() { return this._reader.offset; } /** * Get remaining refs */ get remainingRefs() { return this._refs.length - this._refsOffset; } /** * Get offset refs */ get offsetRefs() { return this._refsOffset; } /** * Skip bits * @param bits */ skip(bits: number) { this._reader.skip(bits); return this; } /** * Load a single bit * @returns true or false depending on the bit value */ loadBit() { return this._reader.loadBit(); } /** * Preload a signle bit * @returns true or false depending on the bit value */ preloadBit() { return this._reader.preloadBit(); } /** * Load a boolean * @returns true or false depending on the bit value */ loadBoolean() { return this.loadBit(); } /** * Load maybe boolean * @returns true or false depending on the bit value or null */ loadMaybeBoolean() { if (this.loadBit()) { return this.loadBoolean(); } else { return null; } } /** * Load bits as a new BitString * @param bits number of bits to read * @returns new BitString */ loadBits(bits: number) { return this._reader.loadBits(bits); } /** * Preload bits as a new BitString * @param bits number of bits to read * @returns new BitString */ preloadBits(bits: number) { return this._reader.preloadBits(bits); } /** * Load uint * @param bits number of bits to read * @returns uint value */ loadUint(bits: number) { return this._reader.loadUint(bits); } /** * Load uint * @param bits number of bits to read * @returns uint value */ loadUintBig(bits: number) { return this._reader.loadUintBig(bits); } /** * Preload uint * @param bits number of bits to read * @returns uint value */ preloadUint(bits: number) { return this._reader.preloadUint(bits); } /** * Preload uint * @param bits number of bits to read * @returns uint value */ preloadUintBig(bits: number) { return this._reader.preloadUintBig(bits); } /** * Load maybe uint * @param bits number of bits to read * @returns uint value or null */ loadMaybeUint(bits: number) { if (this.loadBit()) { return this.loadUint(bits); } else { return null; } } /** * Load maybe uint * @param bits number of bits to read * @returns uint value or null */ loadMaybeUintBig(bits: number) { if (this.loadBit()) { return this.loadUintBig(bits); } else { return null; } } /** * Load int * @param bits number of bits to read * @returns int value */ loadInt(bits: number) { return this._reader.loadInt(bits); } /** * Load int * @param bits number of bits to read * @returns int value */ loadIntBig(bits: number) { return this._reader.loadIntBig(bits); } /** * Preload int * @param bits number of bits to read * @returns int value */ preloadInt(bits: number) { return this._reader.preloadInt(bits); } /** * Preload int * @param bits number of bits to read * @returns int value */ preloadIntBig(bits: number) { return this._reader.preloadIntBig(bits); } /** * Load maybe uint * @param bits number of bits to read * @returns uint value or null */ loadMaybeInt(bits: number) { if (this.loadBit()) { return this.loadInt(bits); } else { return null; } } /** * Load maybe uint * @param bits number of bits to read * @returns uint value or null */ loadMaybeIntBig(bits: number) { if (this.loadBit()) { return this.loadIntBig(bits); } else { return null; } } /** * Load varuint * @param bits number of bits to read in header * @returns varuint value */ loadVarUint(bits: number) { return this._reader.loadVarUint(bits); } /** * Load varuint * @param bits number of bits to read in header * @returns varuint value */ loadVarUintBig(bits: number) { return this._reader.loadVarUintBig(bits); } /** * Preload varuint * @param bits number of bits to read in header * @returns varuint value */ preloadVarUint(bits: number) { return this._reader.preloadVarUint(bits); } /** * Preload varuint * @param bits number of bits to read in header * @returns varuint value */ preloadVarUintBig(bits: number) { return this._reader.preloadVarUintBig(bits); } /** * Load varint * @param bits number of bits to read in header * @returns varint value */ loadVarInt(bits: number) { return this._reader.loadVarInt(bits); } /** * Load varint * @param bits number of bits to read in header * @returns varint value */ loadVarIntBig(bits: number) { return this._reader.loadVarIntBig(bits); } /** * Preload varint * @param bits number of bits to read in header * @returns varint value */ preloadVarInt(bits: number) { return this._reader.preloadVarInt(bits); } /** * Preload varint * @param bits number of bits to read in header * @returns varint value */ preloadVarIntBig(bits: number) { return this._reader.preloadVarIntBig(bits); } /** * Load coins * @returns coins value */ loadCoins() { return this._reader.loadCoins(); } /** * Preload coins * @returns coins value */ preloadCoins() { return this._reader.preloadCoins(); } /** * Load maybe coins * @returns coins value or null */ loadMaybeCoins() { if (this._reader.loadBit()) { return this._reader.loadCoins(); } else { return null; } } /** * Load internal Address * @returns Address */ loadAddress() { return this._reader.loadAddress(); } /** * Load optional internal Address * @returns Address or null */ loadMaybeAddress() { return this._reader.loadMaybeAddress(); } /** * Load external address * @returns ExternalAddress */ loadExternalAddress() { return this._reader.loadExternalAddress(); } /** * Load optional external address * @returns ExternalAddress or null */ loadMaybeExternalAddress() { return this._reader.loadMaybeExternalAddress(); } /** * Load address * @returns Address, ExternalAddress or null */ loadAddressAny() { return this._reader.loadAddressAny(); } /** * Load reference * @returns Cell */ loadRef() { if (this._refsOffset >= this._refs.length) { throw new Error("No more references"); } return this._refs[this._refsOffset++]; } /** * Preload reference * @returns Cell */ preloadRef() { if (this._refsOffset >= this._refs.length) { throw new Error("No more references"); } return this._refs[this._refsOffset]; } /** * Load optional reference * @returns Cell or null */ loadMaybeRef() { if (this.loadBit()) { return this.loadRef(); } else { return null; } } /** * Preload optional reference * @returns Cell or null */ preloadMaybeRef() { if (this.preloadBit()) { return this.preloadRef(); } else { return null; } } /** * Load byte buffer * @param bytes number of bytes to load * @returns Buffer */ loadBuffer(bytes: number) { return this._reader.loadBuffer(bytes); } /** * Load byte buffer * @param bytes number of bytes to load * @returns Buffer */ preloadBuffer(bytes: number) { return this._reader.preloadBuffer(bytes); } /** * Load string tail */ loadStringTail() { return readString(this); } /** * Load maybe string tail * @returns string or null */ loadMaybeStringTail() { if (this.loadBit()) { return readString(this); } else { return null; } } /** * Load string tail from ref * @returns string */ loadStringRefTail() { return readString(this.loadRef().beginParse()); } /** * Load maybe string tail from ref * @returns string or null */ loadMaybeStringRefTail() { const ref = this.loadMaybeRef(); if (ref) { return readString(ref.beginParse()); } else { return null; } } /** * Loads dictionary * @param key key description * @param value value description * @returns Dictionary<K, V> */ loadDict<K extends DictionaryKeyTypes, V>(key: DictionaryKey<K>, value: DictionaryValue<V>): Dictionary<K, V> { return Dictionary.load(key, value, this); } /** * Loads dictionary directly from current slice * @param key key description * @param value value description * @returns Dictionary<K, V> */ loadDictDirect<K extends DictionaryKeyTypes, V>(key: DictionaryKey<K>, value: DictionaryValue<V>): Dictionary<K, V> { return Dictionary.loadDirect(key, value, this); } /** * Checks if slice is empty */ endParse() { if (this.remainingBits > 0 || this.remainingRefs > 0) { throw new Error("Slice is not empty"); } } /** * Convert slice to cell */ asCell() { return beginCell().storeSlice(this).endCell(); } /** * * @returns */ asBuilder() { return beginCell().storeSlice(this); } /** * Clone slice * @returns cloned slice */ clone(fromStart: boolean = false): Slice { if (fromStart) { let reader = this._reader.clone(); reader.reset(); return new Slice(reader, this._refs); } else { let res = new Slice(this._reader, this._refs); res._refsOffset = this._refsOffset; return res; } } /** * Print slice as string by converting it to cell * @returns string */ toString(): string { return this.asCell().toString(); } [inspectSymbol] = () => this.toString(); }