All files / ethers.js/src.ts/abi/coders number.ts

90.32% Statements 56/62
81.81% Branches 9/11
80% Functions 4/5
90.32% Lines 56/62

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 641x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 2046x 2046x 2046x 2046x 2046x 2046x 2046x 2046x 2046x 2046x 2046x     2046x 2046x 2346x 2346x 2346x 2346x 2346x 1210x 1210x     1210x 2346x     2346x 2346x 2346x 2046x 2046x 2298x 2298x 2298x 1146x 1146x 2298x 2298x 2298x 2046x    
import {
    defineProperties, fromTwos, getBigInt, mask, toTwos
} from "../../utils/index.js";
 
import { Typed } from "../typed.js";
import { Coder, WordSize } from "./abstract-coder.js";
 
import type { BigNumberish } from "../../utils/index.js";
 
import type { Reader, Writer } from "./abstract-coder.js";
 
 
const BN_0 = BigInt(0);
const BN_1 = BigInt(1);
const BN_MAX_UINT256 = BigInt("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
 
/**
 *  @_ignore
 */
export class NumberCoder extends Coder {
    readonly size!: number;
    readonly signed!: boolean;
 
    constructor(size: number, signed: boolean, localName: string) {
        const name = ((signed ? "int": "uint") + (size * 8));
        super(name, name, localName, false);
 
        defineProperties<NumberCoder>(this, { size, signed }, { size: "number", signed: "boolean" });
    }
 
    defaultValue(): number {
        return 0;
    }
 
    encode(writer: Writer, _value: BigNumberish | Typed): number {
        let value = getBigInt(Typed.dereference(_value, this.type));
 
        // Check bounds are safe for encoding
        let maxUintValue = mask(BN_MAX_UINT256, WordSize * 8);
        if (this.signed) {
            let bounds = mask(maxUintValue, (this.size * 8) - 1);
            if (value > bounds || value < -(bounds + BN_1)) {
                this._throwError("value out-of-bounds", _value);
            }
            value = toTwos(value, 8 * WordSize);
        } else if (value < BN_0 || value > mask(maxUintValue, this.size * 8)) {
            this._throwError("value out-of-bounds", _value);
        }
 
        return writer.writeValue(value);
    }
 
    decode(reader: Reader): any {
        let value = mask(reader.readValue(), this.size * 8);
 
        if (this.signed) {
            value = fromTwos(value, this.size * 8);
        }
 
        return value;
    }
}