"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.writeIntBE = exports.readIntBE = exports.writeUIntBE = exports.readUIntBE = exports.writeIntLE = exports.AnsiStringType = exports.StringType = exports.BufferType = exports.IgnoreType = exports.Float80_LE = exports.Float80_BE = exports.Float64_LE = exports.Float64_BE = exports.Float32_LE = exports.Float32_BE = exports.Float16_LE = exports.Float16_BE = exports.INT64_BE = exports.UINT64_BE = exports.INT64_LE = exports.UINT64_LE = exports.INT32_LE = exports.INT32_BE = exports.INT24_BE = exports.INT24_LE = exports.INT16_LE = exports.INT16_BE = exports.INT8 = exports.UINT32_BE = exports.UINT32_LE = exports.UINT24_BE = exports.UINT24_LE = exports.UINT16_BE = exports.UINT16_LE = exports.UINT8 = void 0;
const ieee754 = require("ieee754");
// Primitive types
/**
 * 8-bit unsigned integer
 */
exports.UINT8 = {
    len: 1,
    get(buf, off) {
        return buf.readUInt8(off);
    },
    put(buf, off, v) {
        return buf.writeUInt8(v, off);
    }
};
/**
 * 16-bit unsigned integer, Little Endian byte order
 */
exports.UINT16_LE = {
    len: 2,
    get(buf, off) {
        return buf.readUInt16LE(off);
    },
    put(buf, off, v) {
        return buf.writeUInt16LE(v, off);
    }
};
/**
 * 16-bit unsigned integer, Big Endian byte order
 */
exports.UINT16_BE = {
    len: 2,
    get(buf, off) {
        return buf.readUInt16BE(off);
    },
    put(buf, off, v) {
        return buf.writeUInt16BE(v, off);
    }
};
/**
 * 24-bit unsigned integer, Little Endian byte order
 */
exports.UINT24_LE = {
    len: 3,
    get(buf, off) {
        return buf.readUIntLE(off, 3);
    },
    put(buf, off, v) {
        return buf.writeUIntLE(v, off, 3);
    }
};
/**
 * 24-bit unsigned integer, Big Endian byte order
 */
exports.UINT24_BE = {
    len: 3,
    get(buf, off) {
        return buf.readUIntBE(off, 3);
    },
    put(buf, off, v) {
        return buf.writeUIntBE(v, off, 3);
    }
};
/**
 * 32-bit unsigned integer, Little Endian byte order
 */
exports.UINT32_LE = {
    len: 4,
    get(buf, off) {
        return buf.readUInt32LE(off);
    },
    put(b, o, v) {
        return b.writeUInt32LE(v, o);
    }
};
/**
 * 32-bit unsigned integer, Big Endian byte order
 */
exports.UINT32_BE = {
    len: 4,
    get(buf, off) {
        return buf.readUInt32BE(off);
    },
    put(buf, off, v) {
        return buf.writeUInt32BE(v, off);
    }
};
/**
 * 8-bit signed integer
 */
exports.INT8 = {
    len: 1,
    get(buf, off) {
        return buf.readInt8(off);
    },
    put(buf, off, v) {
        return buf.writeInt8(v, off);
    }
};
/**
 * 16-bit signed integer, Big Endian byte order
 */
exports.INT16_BE = {
    len: 2,
    get(buf, off) {
        return buf.readInt16BE(off);
    },
    put(b, o, v) {
        return b.writeInt16BE(v, o);
    }
};
/**
 * 16-bit signed integer, Little Endian byte order
 */
exports.INT16_LE = {
    len: 2,
    get(buf, off) {
        return buf.readInt16LE(off);
    },
    put(b, o, v) {
        return b.writeInt16LE(v, o);
    }
};
/**
 * 24-bit signed integer, Little Endian byte order
 */
exports.INT24_LE = {
    len: 3,
    get(buf, off) {
        return buf.readIntLE(off, 3);
    },
    put(b, o, v) {
        return b.writeIntLE(v, o, 3);
    }
};
/**
 * 24-bit signed integer, Big Endian byte order
 */
exports.INT24_BE = {
    len: 3,
    get(buf, off) {
        return buf.readIntBE(off, 3);
    },
    put(b, o, v) {
        return b.writeIntBE(v, o, 3);
    }
};
/**
 * 32-bit signed integer, Big Endian byte order
 */
exports.INT32_BE = {
    len: 4,
    get(buf, off) {
        return buf.readInt32BE(off);
    },
    put(b, o, v) {
        return b.writeInt32BE(v, o);
    }
};
/**
 * 32-bit signed integer, Big Endian byte order
 */
exports.INT32_LE = {
    len: 4,
    get(buf, off) {
        return buf.readInt32LE(off);
    },
    put(b, o, v) {
        return b.writeInt32LE(v, o);
    }
};
/**
 * 64-bit unsigned integer, Little Endian byte order
 */
exports.UINT64_LE = {
    len: 8,
    get(buf, off) {
        return readUIntLE(buf, off, this.len);
    },
    put(b, o, v) {
        return writeUIntLE(b, v, o, this.len);
    }
};
/**
 * 64-bit signed integer, Little Endian byte order
 */
exports.INT64_LE = {
    len: 8,
    get(buf, off) {
        return readIntLE(buf, off, this.len);
    },
    put(b, off, v) {
        return writeIntLE(b, v, off, this.len);
    }
};
/**
 * 64-bit unsigned integer, Big Endian byte order
 */
exports.UINT64_BE = {
    len: 8,
    get(b, off) {
        return readUIntBE(b, off, this.len);
    },
    put(b, o, v) {
        return writeUIntBE(b, v, o, this.len);
    }
};
/**
 * 64-bit signed integer, Big Endian byte order
 */
exports.INT64_BE = {
    len: 8,
    get(b, off) {
        return readIntBE(b, off, this.len);
    },
    put(b, off, v) {
        return writeIntBE(b, v, off, this.len);
    }
};
/**
 * IEEE 754 16-bit (half precision) float, big endian
 */
exports.Float16_BE = {
    len: 2,
    get(b, off) {
        return ieee754.read(b, off, false, 10, this.len);
    },
    put(b, off, v) {
        ieee754.write(b, v, off, false, 10, this.len);
        return off + this.len;
    }
};
/**
 * IEEE 754 16-bit (half precision) float, little endian
 */
exports.Float16_LE = {
    len: 2,
    get(b, off) {
        return ieee754.read(b, off, true, 10, this.len);
    },
    put(b, off, v) {
        ieee754.write(b, v, off, true, 10, this.len);
        return off + this.len;
    }
};
/**
 * IEEE 754 32-bit (single precision) float, big endian
 */
exports.Float32_BE = {
    len: 4,
    get(b, off) {
        return b.readFloatBE(off);
    },
    put(b, off, v) {
        return b.writeFloatBE(v, off);
    }
};
/**
 * IEEE 754 32-bit (single precision) float, little endian
 */
exports.Float32_LE = {
    len: 4,
    get(b, off) {
        return b.readFloatLE(off);
    },
    put(b, off, v) {
        return b.writeFloatLE(v, off);
    }
};
/**
 * IEEE 754 64-bit (double precision) float, big endian
 */
exports.Float64_BE = {
    len: 8,
    get(b, off) {
        return b.readDoubleBE(off);
    },
    put(b, off, v) {
        return b.writeDoubleBE(v, off);
    }
};
/**
 * IEEE 754 64-bit (double precision) float, little endian
 */
exports.Float64_LE = {
    len: 8,
    get(b, off) {
        return b.readDoubleLE(off);
    },
    put(b, off, v) {
        return b.writeDoubleLE(v, off);
    }
};
/**
 * IEEE 754 80-bit (extended precision) float, big endian
 */
exports.Float80_BE = {
    len: 10,
    get(b, off) {
        return ieee754.read(b, off, false, 63, this.len);
    },
    put(b, off, v) {
        ieee754.write(b, v, off, false, 63, this.len);
        return off + this.len;
    }
};
/**
 * IEEE 754 80-bit (extended precision) float, little endian
 */
exports.Float80_LE = {
    len: 10,
    get(b, off) {
        return ieee754.read(b, off, true, 63, this.len);
    },
    put(b, off, v) {
        ieee754.write(b, v, off, true, 63, this.len);
        return off + this.len;
    }
};
/**
 * Ignore a given number of bytes
 */
class IgnoreType {
    /**
     * @param len number of bytes to ignore
     */
    constructor(len) {
        this.len = len;
    }
    // ToDo: don't read, but skip data
    get(buf, off) {
    }
}
exports.IgnoreType = IgnoreType;
class BufferType {
    constructor(len) {
        this.len = len;
    }
    get(buf, off) {
        return buf.slice(off, off + this.len);
    }
}
exports.BufferType = BufferType;
/**
 * Consume a fixed number of bytes from the stream and return a string with a specified encoding.
 */
class StringType {
    constructor(len, encoding) {
        this.len = len;
        this.encoding = encoding;
    }
    get(buf, off) {
        return buf.toString(this.encoding, off, off + this.len);
    }
}
exports.StringType = StringType;
/**
 * ANSI Latin 1 String
 * Using windows-1252 / ISO 8859-1 decoding
 */
class AnsiStringType {
    constructor(len) {
        this.len = len;
    }
    static decode(buffer, off, until) {
        let str = '';
        for (let i = off; i < until; ++i) {
            str += AnsiStringType.codePointToString(AnsiStringType.singleByteDecoder(buffer[i]));
        }
        return str;
    }
    static inRange(a, min, max) {
        return min <= a && a <= max;
    }
    static codePointToString(cp) {
        if (cp <= 0xFFFF) {
            return String.fromCharCode(cp);
        }
        else {
            cp -= 0x10000;
            return String.fromCharCode((cp >> 10) + 0xD800, (cp & 0x3FF) + 0xDC00);
        }
    }
    static singleByteDecoder(bite) {
        if (AnsiStringType.inRange(bite, 0x00, 0x7F)) {
            return bite;
        }
        const codePoint = AnsiStringType.windows1252[bite - 0x80];
        if (codePoint === null) {
            throw Error('invaliding encoding');
        }
        return codePoint;
    }
    get(buf, off = 0) {
        return AnsiStringType.decode(buf, off, off + this.len);
    }
}
exports.AnsiStringType = AnsiStringType;
AnsiStringType.windows1252 = [8364, 129, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352,
    8249, 338, 141, 381, 143, 144, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732,
    8482, 353, 8250, 339, 157, 382, 376, 160, 161, 162, 163, 164, 165, 166, 167, 168,
    169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184,
    185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200,
    201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216,
    217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232,
    233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247,
    248, 249, 250, 251, 252, 253, 254, 255];
/**
 * Best effort approach to read up to 64 bit unsigned integer, little endian.
 * Note that JavasScript is limited to 2^53 - 1 bit.
 */
function readUIntLE(buf, offset, byteLength) {
    offset = offset >>> 0;
    byteLength = byteLength >>> 0;
    let val = buf[offset];
    let mul = 1;
    let i = 0;
    while (++i < byteLength && (mul *= 0x100)) {
        val += buf[offset + i] * mul;
    }
    return val;
}
/**
 * Best effort approach to write up to 64 bit unsigned integer, little endian.
 * Note that JavasScript is limited to 2^53 - 1 bit.
 */
function writeUIntLE(buf, value, offset, byteLength) {
    value = +value;
    offset = offset >>> 0;
    byteLength = byteLength >>> 0;
    let mul = 1;
    let i = 0;
    buf[offset] = value & 0xFF;
    while (++i < byteLength && (mul *= 0x100)) {
        buf[offset + i] = (value / mul) & 0xFF;
    }
    return offset + byteLength;
}
/**
 * Best effort approach to read 64 but signed integer, little endian.
 * Note that JavasScript is limited to 2^53 - 1 bit.
 */
function readIntLE(buf, offset, byteLength) {
    offset = offset >>> 0;
    byteLength = byteLength >>> 0;
    let val = buf[offset];
    let mul = 1;
    let i = 0;
    while (++i < byteLength && (mul *= 0x100)) {
        val += buf[offset + i] * mul;
    }
    mul *= 0x80;
    if (val >= mul)
        val -= Math.pow(2, 8 * byteLength);
    return val;
}
/**
 * Best effort approach to write 64 but signed integer, little endian.
 * Note that JavasScript is limited to 2^53 - 1 bit.
 */
function writeIntLE(buf, value, offset, byteLength) {
    value = +value;
    offset = offset >>> 0;
    let i = 0;
    let mul = 1;
    let sub = 0;
    buf[offset] = value & 0xFF;
    while (++i < byteLength && (mul *= 0x100)) {
        if (value < 0 && sub === 0 && buf[offset + i - 1] !== 0) {
            sub = 1;
        }
        buf[offset + i] = ((value / mul) >> 0) - sub & 0xFF;
    }
    return offset + byteLength;
}
exports.writeIntLE = writeIntLE;
/**
 * Best effort approach to read up to 64 bit unsigned integer, big endian.
 * Note that JavasScript is limited to 2^53 - 1 bit.
 */
function readUIntBE(buf, offset, byteLength) {
    offset = offset >>> 0;
    byteLength = byteLength >>> 0;
    let val = buf[offset + --byteLength];
    let mul = 1;
    while (byteLength > 0 && (mul *= 0x100)) {
        val += buf[offset + --byteLength] * mul;
    }
    return val;
}
exports.readUIntBE = readUIntBE;
/**
 * Best effort approach to write up to 64 bit unsigned integer, big endian.
 * Note that JavasScript is limited to 2^53 - 1 bit.
 */
function writeUIntBE(buf, value, offset, byteLength) {
    value = +value;
    offset = offset >>> 0;
    byteLength = byteLength >>> 0;
    let i = byteLength - 1;
    let mul = 1;
    buf[offset + i] = value & 0xFF;
    while (--i >= 0 && (mul *= 0x100)) {
        buf[offset + i] = (value / mul) & 0xFF;
    }
    return offset + byteLength;
}
exports.writeUIntBE = writeUIntBE;
/**
 * Best effort approach to read 64 but signed integer, big endian.
 * Note that JavasScript is limited to 2^53 - 1 bit.
 */
function readIntBE(buf, offset, byteLength) {
    offset = offset >>> 0;
    byteLength = byteLength >>> 0;
    let i = byteLength;
    let mul = 1;
    let val = buf[offset + --i];
    while (i > 0 && (mul *= 0x100)) {
        val += buf[offset + --i] * mul;
    }
    mul *= 0x80;
    if (val >= mul)
        val -= Math.pow(2, 8 * byteLength);
    return val;
}
exports.readIntBE = readIntBE;
/**
 * Best effort approach to write 64 but signed integer, big endian.
 * Note that JavasScript is limited to 2^53 - 1 bit.
 */
function writeIntBE(buf, value, offset, byteLength) {
    value = +value;
    offset = offset >>> 0;
    let i = byteLength - 1;
    let mul = 1;
    let sub = 0;
    buf[offset + i] = value & 0xFF;
    while (--i >= 0 && (mul *= 0x100)) {
        if (value < 0 && sub === 0 && buf[offset + i + 1] !== 0) {
            sub = 1;
        }
        buf[offset + i] = ((value / mul) >> 0) - sub & 0xFF;
    }
    return offset + byteLength;
}
exports.writeIntBE = writeIntBE;
