"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BlobReader = exports.Uint8Chunks = void 0;
const ConcurrentQuery_1 = require("./ConcurrentQuery");
/** @beta */
class Uint8Chunks {
    constructor() {
        this._chunks = [];
    }
    append(chunk) {
        this._chunks.push(chunk);
    }
    at(idx) { return this._chunks[idx]; }
    get length() { return this._chunks.length; }
    [Symbol.iterator]() {
        return this._chunks[Symbol.iterator];
    }
    combine() {
        const totalChunkLength = this._chunks.reduce((acc, v) => acc + v.length, 0);
        const combineChunk = new Uint8Array(totalChunkLength);
        let offset = 0;
        for (const array of this._chunks) {
            combineChunk.set(array, offset);
            offset += array.length;
        }
        return combineChunk;
    }
}
exports.Uint8Chunks = Uint8Chunks;
/** @beta */
class BlobReader {
    constructor(_executor, className, accessString, instanceId, options) {
        this._executor = _executor;
        this.className = className;
        this.accessString = accessString;
        this.instanceId = instanceId;
        this._chunks = new Uint8Chunks();
        this._lengthToRead = -1;
        this._options = new ConcurrentQuery_1.BlobOptionsBuilder().getOptions();
        this.reset(options);
    }
    reset(options) {
        if (options) {
            this._options = options;
        }
        this._chunks = new Uint8Chunks();
        this._lengthToRead = this.range.count;
    }
    get range() { return this._options.range; }
    async step() {
        if (this._lengthToRead === this._chunks.length) {
            return false;
        }
        const request = {
            kind: ConcurrentQuery_1.DbRequestKind.BlobIO,
            className: this.className,
            accessString: this.accessString,
            instanceId: this.instanceId,
            ...this._options,
        };
        request.range = { offset: this._chunks.length, count: this.range ? this._lengthToRead - this._chunks.length : 0 };
        const resp = await this._executor.execute(request);
        ConcurrentQuery_1.DbQueryError.throwIfError(resp, request);
        if (this._lengthToRead === -1) {
            this._lengthToRead = resp.rawBlobSize;
        }
        if (resp.data && resp.data.length > 0) {
            this._chunks.append(resp.data);
        }
        return true;
    }
    async readToEnd() {
        while (await this.step()) { }
        return this._chunks.combine();
    }
    get current() {
        if (this._chunks.length === 0) {
            throw new Error("there is no current buffer");
        }
        return this._chunks.at(this._chunks.length);
    }
    get chunks() { return this._chunks; }
}
exports.BlobReader = BlobReader;
//# sourceMappingURL=BlobReader.js.map