var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
import { typedArrayToBuffer } from '@iotize/common/byte-converter';
import { KaitaiStreamReader, KaitaiStreamWriter } from '@iotize/common/byte-stream';
import { debug } from '../debug';
import { CRC } from '../error-detection/crc';
export function enumKeyOrValueToNumber(key, mapping) {
    if (typeof key === 'string') {
        // if (!(key in mapping)) {
        //     throw new Error(``)
        // }
        return mapping[key];
    }
    else {
        return key;
    }
}
var TapStreamReader = /** @class */ (function (_super) {
    __extends(TapStreamReader, _super);
    function TapStreamReader() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    TapStreamReader.fromArray = function (array) {
        var buffer = typedArrayToBuffer(array);
        return new TapStreamReader(buffer);
    };
    TapStreamReader.create = function (packet) {
        return packet instanceof Uint8Array
            ? TapStreamReader.fromArray(packet)
            : packet;
    };
    TapStreamReader.prototype.readStr = function (n) {
        return String.fromCharCode.apply(null, this.readBytes(n));
    };
    /**
     * Read given byte size as string
     * @param n number of byte to read
     */
    TapStreamReader.prototype.readString = function (n) {
        if (n === void 0) { n = this.byteLeft; }
        return this.readStr(n);
    };
    /**
     * Read string until terminator character is reached
     */
    TapStreamReader.prototype.readStringTerminator = function (terminator) {
        var result = '';
        while (true) {
            var lastByte = this.readU1();
            var lastChar = String.fromCharCode(lastByte);
            if (lastChar !== terminator) {
                result += lastChar;
            }
            else {
                break;
            }
        }
        return result;
    };
    TapStreamReader.prototype.readU2 = function () {
        return this._isBigEndian ? this.readU2be() : this.readU2le();
    };
    TapStreamReader.prototype.readU4 = function () {
        return this._isBigEndian ? this.readU4be() : this.readU4le();
    };
    TapStreamReader.prototype.readF4 = function () {
        return this._isBigEndian ? this.readF4be() : this.readF4le();
    };
    TapStreamReader.prototype.subStream = function (length) {
        return TapStreamReader.fromArray(this.readBytes(length));
    };
    return TapStreamReader;
}(KaitaiStreamReader));
export { TapStreamReader };
var TapStreamWriter = /** @class */ (function (_super) {
    __extends(TapStreamWriter, _super);
    function TapStreamWriter(lengthOrBuffer, byteOffset, isBigEndian) {
        if (lengthOrBuffer === void 0) { lengthOrBuffer = 512; }
        if (isBigEndian === void 0) { isBigEndian = true; }
        var _this = this;
        if (typeof lengthOrBuffer === 'number') {
            lengthOrBuffer = new ArrayBuffer(lengthOrBuffer);
        }
        _this = _super.call(this, lengthOrBuffer, byteOffset, isBigEndian) || this;
        return _this;
    }
    TapStreamWriter.create = function (size) {
        return new TapStreamWriter(new ArrayBuffer(size));
    };
    TapStreamWriter.prototype.writeFunction = function (type, options, fieldValue, fieldSize) {
        switch (type) {
            case 'crc32':
                return this.addCRC(options);
            case 'padding':
                if (fieldValue) {
                    debug('Padding is already set');
                    return this.writeBytes(fieldValue);
                }
                else {
                    if (typeof fieldSize == undefined) {
                        throw new Error("Padding function expect padding size as a second argument. Args: " + JSON.stringify(arguments));
                    }
                    return this.addPadding(fieldSize);
                }
            default:
                throw new Error("Invalid writer function type: " + type);
        }
    };
    TapStreamWriter.prototype.addPadding = function (padSize) {
        this.writeBytes(new Uint8Array(padSize));
        return this;
    };
    TapStreamWriter.prototype.addCRC = function (options) {
        var buffer = this.toBytes;
        if (options && options.offset) {
            buffer = buffer.slice(options.offset);
        }
        var crc = CRC.fromBytes(buffer);
        this.writeU4(crc);
        // console.info(`TODO REMOVE Compute CRC from ${options ? options.offset : 0}:${buffer.length} 0x${bufferToHexString(buffer)} => 0x${crc.toString(16)}`)
        return this;
    };
    TapStreamWriter.prototype.writeUnsigned = function (value, length) {
        this.writeU(value, length);
        return this;
    };
    TapStreamWriter.prototype.writeU4 = function (value) {
        this.writeU(value, 4);
        return this;
    };
    TapStreamWriter.prototype.writeU2 = function (value) {
        this.writeU(value, 2);
        return this;
    };
    TapStreamWriter.prototype.writeU1 = function (value) {
        this.writeU(value, 1);
        return this;
    };
    TapStreamWriter.prototype.writeF4 = function (value) {
        this.writeF(value, 4);
        return this;
    };
    TapStreamWriter.prototype.writeFloat = function (value, length) {
        this.writeF(value, length);
        return this;
    };
    TapStreamWriter.prototype.writeSigned = function (value, length) {
        this.writeSigned(value, length);
        return this;
    };
    TapStreamWriter.prototype.writeString = function (value, length) {
        if (length === void 0) { length = (value === null || value === void 0 ? void 0 : value.length) || 0; }
        return this.writeStr(value || '', length);
    };
    TapStreamWriter.prototype.writeStr = function (value, length) {
        if (length === void 0) { length = value.length; }
        var i = 1;
        var stringWriteLength = Math.min(value.length, length);
        for (; i <= stringWriteLength; i++) {
            this.writeByte(value.charCodeAt(i - 1));
        }
        var remaining = length - stringWriteLength;
        if (remaining > 0) {
            this.writeBytes(new Uint8Array(remaining));
        }
        return this;
    };
    TapStreamWriter.prototype.writeBitsInt = function (value, n) {
        this.writeB(value, n);
        return this;
    };
    TapStreamWriter.prototype.writeBits = function (value, n) {
        this.writeB(value, n);
        return this;
    };
    TapStreamWriter.prototype.writeBoolean = function (value, n) {
        this.writeBits(value ? 1 : 0, n);
        return this;
    };
    return TapStreamWriter;
}(KaitaiStreamWriter));
export { TapStreamWriter };
//# sourceMappingURL=data:application/json;base64, 