ton3-core
Version:
TON low-level API tools
266 lines • 9.23 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Slice = void 0;
const coins_1 = require("../coins");
const address_1 = require("../address");
const hashmap_1 = require("./hashmap");
const helpers_1 = require("../utils/helpers");
const numbers_1 = require("../utils/numbers");
class Slice {
constructor(bits, refs) {
this._bits = bits;
this._refs = refs;
}
get bits() {
return Array.from(this._bits);
}
get refs() {
return Array.from(this._refs);
}
skip(size) {
return this.skipBits(size);
}
skipBits(size) {
if (this._bits.length < size) {
throw new Error('Slice: bits overflow.');
}
this._bits.splice(0, size);
return this;
}
skipRefs(size) {
if (this._refs.length < size) {
throw new Error('Slice: refs overflow.');
}
this._refs.splice(0, size);
return this;
}
skipDict() {
const isEmpty = this.loadBit() === 0;
return !isEmpty
? this.skipRefs(1)
: this;
}
loadRef() {
if (!this._refs.length) {
throw new Error('Slice: refs overflow.');
}
return this._refs.shift();
}
preloadRef() {
if (!this._refs.length) {
throw new Error('Slice: refs overflow.');
}
return this._refs[0];
}
loadMaybeRef() {
return this.loadBit() === 1
? this.loadRef()
: null;
}
preloadMaybeRef() {
return this.preloadBit() === 1
? this.preloadRef()
: null;
}
loadBit() {
if (!this._bits.length) {
throw new Error('Slice: bits overflow.');
}
return this._bits.shift();
}
preloadBit() {
if (!this._bits.length) {
throw new Error('Slice: bits overflow.');
}
return this._bits[0];
}
loadBits(size) {
if (size < 0 || this._bits.length < size) {
throw new Error('Slice: bits overflow.');
}
return this._bits.splice(0, size);
}
preloadBits(size) {
if (size < 0 || this._bits.length < size) {
throw new Error('Slice: bits overflow.');
}
return this._bits.slice(0, size);
}
loadInt(size) {
const bits = this.loadBits(size);
return (0, numbers_1.bitsToIntUint)(bits, { type: 'int' });
}
preloadInt(size) {
const bits = this.preloadBits(size);
return (0, numbers_1.bitsToIntUint)(bits, { type: 'int' });
}
loadBigInt(size) {
const bits = this.loadBits(size);
const { value } = (0, numbers_1.bitsToBigInt)(bits);
return value;
}
preloadBigInt(size) {
const bits = this.preloadBits(size);
const { value } = (0, numbers_1.bitsToBigInt)(bits);
return value;
}
loadUint(size) {
const bits = this.loadBits(size);
return (0, numbers_1.bitsToIntUint)(bits, { type: 'uint' });
}
preloadUint(size) {
const bits = this.preloadBits(size);
return (0, numbers_1.bitsToIntUint)(bits, { type: 'uint' });
}
loadBigUint(size) {
const bits = this.loadBits(size);
const { value } = (0, numbers_1.bitsToBigUint)(bits);
return value;
}
preloadBigUint(size) {
const bits = this.preloadBits(size);
const { value } = (0, numbers_1.bitsToBigUint)(bits);
return value;
}
loadVarInt(length) {
const size = Math.ceil(Math.log2(length));
const sizeBytes = this.loadUint(size);
const sizeBits = sizeBytes * 8;
return this.loadInt(sizeBits);
}
preloadVarInt(length) {
const size = Math.ceil(Math.log2(length));
const sizeBytes = this.preloadUint(size);
const sizeBits = sizeBytes * 8;
const bits = this.preloadBits(size + sizeBits).slice(size);
return (0, numbers_1.bitsToIntUint)(bits, { type: 'int' });
}
loadVarBigInt(length) {
const size = Math.ceil(Math.log2(length));
const sizeBytes = this.loadUint(size);
const sizeBits = sizeBytes * 8;
const bits = this.loadBits(sizeBits);
const { value } = (0, numbers_1.bitsToBigInt)(bits);
return value;
}
preloadVarBigInt(length) {
const size = Math.ceil(Math.log2(length));
const sizeBytes = this.preloadUint(size);
const sizeBits = sizeBytes * 8;
const bits = this.preloadBits(size + sizeBits).slice(size);
const { value } = (0, numbers_1.bitsToBigInt)(bits);
return value;
}
loadVarUint(length) {
const size = Math.ceil(Math.log2(length));
const sizeBytes = this.loadUint(size);
const sizeBits = sizeBytes * 8;
return this.loadUint(sizeBits);
}
preloadVarUint(length) {
const size = Math.ceil(Math.log2(length));
const sizeBytes = this.preloadUint(size);
const sizeBits = sizeBytes * 8;
const bits = this.preloadBits(size + sizeBits).slice(size);
return (0, numbers_1.bitsToIntUint)(bits, { type: 'uint' });
}
loadVarBigUint(length) {
const size = Math.ceil(Math.log2(length));
const sizeBytes = this.loadUint(size);
const sizeBits = sizeBytes * 8;
const bits = this.loadBits(sizeBits);
const { value } = (0, numbers_1.bitsToBigUint)(bits);
return value;
}
preloadVarBigUint(length) {
const size = Math.ceil(Math.log2(length));
const sizeBytes = this.preloadUint(size);
const sizeBits = sizeBytes * 8;
const bits = this.preloadBits(size + sizeBits).slice(size);
const { value } = (0, numbers_1.bitsToBigUint)(bits);
return value;
}
loadBytes(size) {
const bits = this.loadBits(size);
return (0, helpers_1.bitsToBytes)(bits);
}
preloadBytes(size) {
const bits = this.preloadBits(size);
return (0, helpers_1.bitsToBytes)(bits);
}
loadString(size = null) {
const bytes = size === null
? this.loadBytes(this._bits.length)
: this.loadBytes(size);
return (0, helpers_1.bytesToString)(bytes);
}
preloadString(size = null) {
const bytes = size === null
? this.preloadBytes(this._bits.length)
: this.preloadBytes(size);
return (0, helpers_1.bytesToString)(bytes);
}
loadAddress() {
const FLAG_ADDRESS_NO = [0, 0];
const FLAG_ADDRESS = [1, 0];
const flag = this.preloadBits(2);
if (flag.every((bit, i) => bit === FLAG_ADDRESS_NO[i])) {
return this.skip(2) && address_1.Address.NONE;
}
if (flag.every((bit, i) => bit === FLAG_ADDRESS[i])) {
const size = 2 + 1 + 8 + 256;
const bits = this.loadBits(size).slice(2);
const _anycast = bits.splice(0, 1);
const workchain = (0, numbers_1.bitsToIntUint)(bits.splice(0, 8), { type: 'int' });
const hash = (0, helpers_1.bitsToHex)(bits.splice(0, 256));
const raw = `${workchain}:${hash}`;
return new address_1.Address(raw);
}
throw new Error('Slice: bad address flag bits.');
}
preloadAddress() {
const FLAG_ADDRESS_NO = [0, 0];
const FLAG_ADDRESS = [1, 0];
const flag = this.preloadBits(2);
if (flag.every((bit, i) => bit === FLAG_ADDRESS_NO[i])) {
return address_1.Address.NONE;
}
if (flag.every((bit, i) => bit === FLAG_ADDRESS[i])) {
const size = 2 + 1 + 8 + 256;
const bits = this.preloadBits(size).slice(2);
const _anycast = bits.splice(0, 1);
const workchain = (0, numbers_1.bitsToIntUint)(bits.splice(0, 8), { type: 'int' });
const hash = (0, helpers_1.bitsToHex)(bits.splice(0, 256));
const raw = `${workchain}:${hash}`;
return new address_1.Address(raw);
}
throw new Error('Slice: bad address flag bits.');
}
loadCoins(decimals = 9) {
const coins = this.loadVarBigUint(16);
return new coins_1.Coins(coins, { isNano: true, decimals });
}
preloadCoins(decimals = 9) {
const coins = this.preloadVarBigUint(16);
return new coins_1.Coins(coins, { isNano: true, decimals });
}
loadDict(keySize, options) {
const dictConstructor = this.loadBit();
const isEmpty = dictConstructor === 0;
return !isEmpty
? hashmap_1.HashmapE.parse(keySize, new Slice([dictConstructor], [this.loadRef()]), options)
: new hashmap_1.HashmapE(keySize, options);
}
preloadDict(keySize, options) {
const dictConstructor = this.preloadBit();
const isEmpty = dictConstructor === 0;
return !isEmpty
? hashmap_1.HashmapE.parse(keySize, new Slice([dictConstructor], [this.preloadRef()]), options)
: new hashmap_1.HashmapE(keySize, options);
}
static parse(cell) {
return new Slice(cell.bits, cell.refs);
}
}
exports.Slice = Slice;
//# sourceMappingURL=slice.js.map