import { type DecodeCursor, readData, readMarkerOrUndefined } from '../helper/decode.js';
import { toUint8Array } from '../helper/utils.js';
import { UnexpectedEofError } from '../helper/errors.js';
import type { DecodeOptions } from '../options.js';

/** decoder */
export class DecoderBase {
    constructor(
        data: BufferSource,
        readonly options?: DecodeOptions,
    ) {
        this.data = toUint8Array(data);
        this.view = new DataView(this.data.buffer, this.data.byteOffset, this.data.byteLength);
    }

    protected readonly view: DataView;
    protected readonly data: Uint8Array;
    /** 当前读指针位置 */
    protected offset = 0;
    /** EOF */
    protected eof(): never {
        throw new UnexpectedEofError();
    }

    /** 解码 */
    decode(): unknown {
        const marker = readMarkerOrUndefined(this as this & DecodeCursor);
        if (marker === undefined) return undefined;
        return readData(this as this & DecodeCursor, marker);
    }
}
