"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Hasher = exports.HashRep = void 0;
const TY_BEGIN = 0x01;
const TY_END = 0x02;
const TY_STRING = 0x10;
const TY_NUMBER = 0x11;
const TY_INTEGER = 0x12;
const TY_FLAGS = 0x13;
const TY_BUFFER = 0x14;
const g_bufSize1 = Buffer.allocUnsafe(1);
const g_bufSize4 = Buffer.allocUnsafe(4);
const g_bufSize8 = Buffer.allocUnsafe(8);
function transferUInt8(h, x) {
    g_bufSize1.writeUInt8(x, 0);
    h.update(g_bufSize1);
}
function transferInt32(h, x) {
    g_bufSize4.writeInt32LE(x, 0);
    h.update(g_bufSize4);
}
function transferUInt32(h, x) {
    g_bufSize4.writeUInt32LE(x, 0);
    h.update(g_bufSize4);
}
function transferFloat64(h, x) {
    g_bufSize8.writeDoubleLE(x, 0);
    h.update(g_bufSize8);
}
class HashRep {
}
exports.HashRep = HashRep;
class HrString extends HashRep {
    constructor(s) {
        super();
        this.s = s;
    }
    transfer(h) {
        const bufRaw = Buffer.from(this.s, "utf-8");
        transferUInt32(h, TY_STRING);
        transferUInt32(h, bufRaw.byteLength);
        h.update(bufRaw);
    }
}
class HrIntegers extends HashRep {
    constructor(s) {
        super();
        this.s = s;
    }
    transfer(h) {
        transferUInt32(h, TY_INTEGER);
        transferUInt32(h, this.s.length);
        for (let index = 0; index < this.s.length; index++) {
            transferInt32(h, this.s[index] || 0);
        }
    }
}
class HrNumbers extends HashRep {
    constructor(s) {
        super();
        this.s = s;
    }
    transfer(h) {
        transferUInt32(h, TY_NUMBER);
        transferUInt32(h, this.s.length);
        for (let index = 0; index < this.s.length; index++) {
            transferFloat64(h, this.s[index] || 0);
        }
    }
}
class HrFlags extends HashRep {
    constructor(s) {
        super();
        this.s = s;
    }
    transfer(h) {
        transferUInt32(h, TY_FLAGS);
        transferUInt32(h, this.s.length);
        for (let index = 0; index < this.s.length; index++) {
            transferUInt8(h, this.s[index] ? 1 : 0);
        }
    }
}
class HrBuffer extends HashRep {
    constructor(s) {
        super();
        this.s = s;
    }
    transfer(h) {
        transferUInt32(h, TY_BUFFER);
        transferUInt32(h, this.s.byteLength);
        h.update(this.s);
    }
}
class HrIsolate extends HashRep {
    constructor(r) {
        super();
        this.r = r;
    }
    transfer(h) {
        transferUInt32(h, TY_BEGIN);
        this.r.transfer(h);
        transferUInt32(h, TY_END);
    }
}
class Hasher extends HashRep {
    constructor() {
        super(...arguments);
        this.parts = [];
    }
    transfer(h) {
        for (const part of this.parts)
            part.transfer(h);
    }
    string(s) {
        this.parts.push(new HrString(s));
        return this;
    }
    integer(...n) {
        this.parts.push(new HrIntegers(n));
        return this;
    }
    number(...n) {
        this.parts.push(new HrNumbers(n));
        return this;
    }
    flag(...n) {
        this.parts.push(new HrFlags(n));
        return this;
    }
    numbers(n) {
        this.parts.push(new HrNumbers(n));
        return this;
    }
    buffer(s) {
        this.parts.push(new HrBuffer(s));
        return this;
    }
    include(hr) {
        const wrap = new HrIsolate(hr);
        this.parts.push(wrap);
        return this;
    }
    begin() {
        const hasher = new Hasher();
        const wrap = new HrIsolate(hasher);
        this.parts.push(wrap);
        return hasher;
    }
    beginSubObj(s) {
        this.string(s);
        return this.begin();
    }
}
exports.Hasher = Hasher;
//# sourceMappingURL=index.js.map