"use strict";
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
// This module is browser compatible.
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
    return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
    if (kind === "m") throw new TypeError("Private method is not writable");
    if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
    if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
    return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var _BufReader_buf, _BufReader_rd, _BufReader_r, _BufReader_w, _BufReader_eof, _BufReader_fill, _BufReader_reset;
Object.defineProperty(exports, "__esModule", { value: true });
exports.BufReader = exports.PartialReadError = exports.BufferFullError = void 0;
const assert_js_1 = require("../../assert/0.218.2/assert.js");
const copy_js_1 = require("../../bytes/0.218.2/copy.js");
const DEFAULT_BUF_SIZE = 4096;
const MIN_BUF_SIZE = 16;
const MAX_CONSECUTIVE_EMPTY_READS = 100;
const CR = "\r".charCodeAt(0);
const LF = "\n".charCodeAt(0);
/**
 * @deprecated (will be removed after 1.0.0) Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
 */
class BufferFullError extends Error {
    constructor(partial) {
        super("Buffer full");
        Object.defineProperty(this, "partial", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: partial
        });
        Object.defineProperty(this, "name", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: "BufferFullError"
        });
    }
}
exports.BufferFullError = BufferFullError;
/**
 * @deprecated (will be removed after 1.0.0) Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
 */
class PartialReadError extends Error {
    constructor() {
        super("Encountered UnexpectedEof, data only partially read");
        Object.defineProperty(this, "name", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: "PartialReadError"
        });
        Object.defineProperty(this, "partial", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
    }
}
exports.PartialReadError = PartialReadError;
/**
 * @deprecated (will be removed after 1.0.0) Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
 */
class BufReader {
    // private lastByte: number;
    // private lastCharSize: number;
    /** return new BufReader unless r is BufReader */
    static create(r, size = DEFAULT_BUF_SIZE) {
        return r instanceof BufReader ? r : new BufReader(r, size);
    }
    constructor(rd, size = DEFAULT_BUF_SIZE) {
        _BufReader_buf.set(this, void 0);
        _BufReader_rd.set(this, void 0); // Reader provided by caller.
        _BufReader_r.set(this, 0); // buf read position.
        _BufReader_w.set(this, 0); // buf write position.
        _BufReader_eof.set(this, false);
        // Reads a new chunk into the buffer.
        _BufReader_fill.set(this, async () => {
            // Slide existing data to beginning.
            if (__classPrivateFieldGet(this, _BufReader_r, "f") > 0) {
                __classPrivateFieldGet(this, _BufReader_buf, "f").copyWithin(0, __classPrivateFieldGet(this, _BufReader_r, "f"), __classPrivateFieldGet(this, _BufReader_w, "f"));
                __classPrivateFieldSet(this, _BufReader_w, __classPrivateFieldGet(this, _BufReader_w, "f") - __classPrivateFieldGet(this, _BufReader_r, "f"), "f");
                __classPrivateFieldSet(this, _BufReader_r, 0, "f");
            }
            if (__classPrivateFieldGet(this, _BufReader_w, "f") >= __classPrivateFieldGet(this, _BufReader_buf, "f").byteLength) {
                throw Error("bufio: tried to fill full buffer");
            }
            // Read new data: try a limited number of times.
            for (let i = MAX_CONSECUTIVE_EMPTY_READS; i > 0; i--) {
                const rr = await __classPrivateFieldGet(this, _BufReader_rd, "f").read(__classPrivateFieldGet(this, _BufReader_buf, "f").subarray(__classPrivateFieldGet(this, _BufReader_w, "f")));
                if (rr === null) {
                    __classPrivateFieldSet(this, _BufReader_eof, true, "f");
                    return;
                }
                (0, assert_js_1.assert)(rr >= 0, "negative read");
                __classPrivateFieldSet(this, _BufReader_w, __classPrivateFieldGet(this, _BufReader_w, "f") + rr, "f");
                if (rr > 0) {
                    return;
                }
            }
            throw new Error(`No progress after ${MAX_CONSECUTIVE_EMPTY_READS} read() calls`);
        });
        _BufReader_reset.set(this, (buf, rd) => {
            __classPrivateFieldSet(this, _BufReader_buf, buf, "f");
            __classPrivateFieldSet(this, _BufReader_rd, rd, "f");
            __classPrivateFieldSet(this, _BufReader_eof, false, "f");
            // this.lastByte = -1;
            // this.lastCharSize = -1;
        });
        if (size < MIN_BUF_SIZE) {
            size = MIN_BUF_SIZE;
        }
        __classPrivateFieldGet(this, _BufReader_reset, "f").call(this, new Uint8Array(size), rd);
    }
    /** Returns the size of the underlying buffer in bytes. */
    size() {
        return __classPrivateFieldGet(this, _BufReader_buf, "f").byteLength;
    }
    buffered() {
        return __classPrivateFieldGet(this, _BufReader_w, "f") - __classPrivateFieldGet(this, _BufReader_r, "f");
    }
    /** Discards any buffered data, resets all state, and switches
     * the buffered reader to read from r.
     */
    reset(r) {
        __classPrivateFieldGet(this, _BufReader_reset, "f").call(this, __classPrivateFieldGet(this, _BufReader_buf, "f"), r);
    }
    /** reads data into p.
     * It returns the number of bytes read into p.
     * The bytes are taken from at most one Read on the underlying Reader,
     * hence n may be less than len(p).
     * To read exactly len(p) bytes, use io.ReadFull(b, p).
     */
    async read(p) {
        let rr = p.byteLength;
        if (p.byteLength === 0)
            return rr;
        if (__classPrivateFieldGet(this, _BufReader_r, "f") === __classPrivateFieldGet(this, _BufReader_w, "f")) {
            if (p.byteLength >= __classPrivateFieldGet(this, _BufReader_buf, "f").byteLength) {
                // Large read, empty buffer.
                // Read directly into p to avoid copy.
                const rr = await __classPrivateFieldGet(this, _BufReader_rd, "f").read(p);
                const nread = rr ?? 0;
                (0, assert_js_1.assert)(nread >= 0, "negative read");
                // if (rr.nread > 0) {
                //   this.lastByte = p[rr.nread - 1];
                //   this.lastCharSize = -1;
                // }
                return rr;
            }
            // One read.
            // Do not use this.fill, which will loop.
            __classPrivateFieldSet(this, _BufReader_r, 0, "f");
            __classPrivateFieldSet(this, _BufReader_w, 0, "f");
            rr = await __classPrivateFieldGet(this, _BufReader_rd, "f").read(__classPrivateFieldGet(this, _BufReader_buf, "f"));
            if (rr === 0 || rr === null)
                return rr;
            (0, assert_js_1.assert)(rr >= 0, "negative read");
            __classPrivateFieldSet(this, _BufReader_w, __classPrivateFieldGet(this, _BufReader_w, "f") + rr, "f");
        }
        // copy as much as we can
        const copied = (0, copy_js_1.copy)(__classPrivateFieldGet(this, _BufReader_buf, "f").subarray(__classPrivateFieldGet(this, _BufReader_r, "f"), __classPrivateFieldGet(this, _BufReader_w, "f")), p, 0);
        __classPrivateFieldSet(this, _BufReader_r, __classPrivateFieldGet(this, _BufReader_r, "f") + copied, "f");
        // this.lastByte = this.buf[this.r - 1];
        // this.lastCharSize = -1;
        return copied;
    }
    /** reads exactly `p.length` bytes into `p`.
     *
     * If successful, `p` is returned.
     *
     * If the end of the underlying stream has been reached, and there are no more
     * bytes available in the buffer, `readFull()` returns `null` instead.
     *
     * An error is thrown if some bytes could be read, but not enough to fill `p`
     * entirely before the underlying stream reported an error or EOF. Any error
     * thrown will have a `partial` property that indicates the slice of the
     * buffer that has been successfully filled with data.
     *
     * Ported from https://golang.org/pkg/io/#ReadFull
     */
    async readFull(p) {
        let bytesRead = 0;
        while (bytesRead < p.length) {
            try {
                const rr = await this.read(p.subarray(bytesRead));
                if (rr === null) {
                    if (bytesRead === 0) {
                        return null;
                    }
                    else {
                        throw new PartialReadError();
                    }
                }
                bytesRead += rr;
            }
            catch (err) {
                if (err instanceof PartialReadError) {
                    err.partial = p.subarray(0, bytesRead);
                }
                throw err;
            }
        }
        return p;
    }
    /** Returns the next byte [0, 255] or `null`. */
    async readByte() {
        var _a;
        while (__classPrivateFieldGet(this, _BufReader_r, "f") === __classPrivateFieldGet(this, _BufReader_w, "f")) {
            if (__classPrivateFieldGet(this, _BufReader_eof, "f"))
                return null;
            await __classPrivateFieldGet(this, _BufReader_fill, "f").call(this); // buffer is empty.
        }
        const c = __classPrivateFieldGet(this, _BufReader_buf, "f")[__classPrivateFieldGet(this, _BufReader_r, "f")];
        __classPrivateFieldSet(this, _BufReader_r, (_a = __classPrivateFieldGet(this, _BufReader_r, "f"), _a++, _a), "f");
        // this.lastByte = c;
        return c;
    }
    /** readString() reads until the first occurrence of delim in the input,
     * returning a string containing the data up to and including the delimiter.
     * If ReadString encounters an error before finding a delimiter,
     * it returns the data read before the error and the error itself
     * (often `null`).
     * ReadString returns err !== null if and only if the returned data does not end
     * in delim.
     * For simple uses, a Scanner may be more convenient.
     */
    async readString(delim) {
        if (delim.length !== 1) {
            throw new Error("Delimiter should be a single character");
        }
        const buffer = await this.readSlice(delim.charCodeAt(0));
        if (buffer === null)
            return null;
        return new TextDecoder().decode(buffer);
    }
    /** `readLine()` is a low-level line-reading primitive. Most callers should
     * use `readString('\n')` instead or use a Scanner.
     *
     * `readLine()` tries to return a single line, not including the end-of-line
     * bytes. If the line was too long for the buffer then `more` is set and the
     * beginning of the line is returned. The rest of the line will be returned
     * from future calls. `more` will be false when returning the last fragment
     * of the line. The returned buffer is only valid until the next call to
     * `readLine()`.
     *
     * The text returned from ReadLine does not include the line end ("\r\n" or
     * "\n").
     *
     * When the end of the underlying stream is reached, the final bytes in the
     * stream are returned. No indication or error is given if the input ends
     * without a final line end. When there are no more trailing bytes to read,
     * `readLine()` returns `null`.
     *
     * Calling `unreadByte()` after `readLine()` will always unread the last byte
     * read (possibly a character belonging to the line end) even if that byte is
     * not part of the line returned by `readLine()`.
     */
    async readLine() {
        var _a;
        let line = null;
        try {
            line = await this.readSlice(LF);
        }
        catch (err) {
            let partial;
            if (err instanceof PartialReadError) {
                partial = err.partial;
                (0, assert_js_1.assert)(partial instanceof Uint8Array, "bufio: caught error from `readSlice()` without `partial` property");
            }
            // Don't throw if `readSlice()` failed with `BufferFullError`, instead we
            // just return whatever is available and set the `more` flag.
            if (!(err instanceof BufferFullError)) {
                throw err;
            }
            partial = err.partial;
            // Handle the case where "\r\n" straddles the buffer.
            if (!__classPrivateFieldGet(this, _BufReader_eof, "f") && partial &&
                partial.byteLength > 0 &&
                partial[partial.byteLength - 1] === CR) {
                // Put the '\r' back on buf and drop it from line.
                // Let the next call to ReadLine check for "\r\n".
                (0, assert_js_1.assert)(__classPrivateFieldGet(this, _BufReader_r, "f") > 0, "bufio: tried to rewind past start of buffer");
                __classPrivateFieldSet(this, _BufReader_r, (_a = __classPrivateFieldGet(this, _BufReader_r, "f"), _a--, _a), "f");
                partial = partial.subarray(0, partial.byteLength - 1);
            }
            if (partial) {
                return { line: partial, more: !__classPrivateFieldGet(this, _BufReader_eof, "f") };
            }
        }
        if (line === null) {
            return null;
        }
        if (line.byteLength === 0) {
            return { line, more: false };
        }
        if (line[line.byteLength - 1] === LF) {
            let drop = 1;
            if (line.byteLength > 1 && line[line.byteLength - 2] === CR) {
                drop = 2;
            }
            line = line.subarray(0, line.byteLength - drop);
        }
        return { line, more: false };
    }
    /** `readSlice()` reads until the first occurrence of `delim` in the input,
     * returning a slice pointing at the bytes in the buffer. The bytes stop
     * being valid at the next read.
     *
     * If `readSlice()` encounters an error before finding a delimiter, or the
     * buffer fills without finding a delimiter, it throws an error with a
     * `partial` property that contains the entire buffer.
     *
     * If `readSlice()` encounters the end of the underlying stream and there are
     * any bytes left in the buffer, the rest of the buffer is returned. In other
     * words, EOF is always treated as a delimiter. Once the buffer is empty,
     * it returns `null`.
     *
     * Because the data returned from `readSlice()` will be overwritten by the
     * next I/O operation, most clients should use `readString()` instead.
     */
    async readSlice(delim) {
        let s = 0; // search start index
        let slice;
        while (true) {
            // Search buffer.
            let i = __classPrivateFieldGet(this, _BufReader_buf, "f").subarray(__classPrivateFieldGet(this, _BufReader_r, "f") + s, __classPrivateFieldGet(this, _BufReader_w, "f")).indexOf(delim);
            if (i >= 0) {
                i += s;
                slice = __classPrivateFieldGet(this, _BufReader_buf, "f").subarray(__classPrivateFieldGet(this, _BufReader_r, "f"), __classPrivateFieldGet(this, _BufReader_r, "f") + i + 1);
                __classPrivateFieldSet(this, _BufReader_r, __classPrivateFieldGet(this, _BufReader_r, "f") + (i + 1), "f");
                break;
            }
            // EOF?
            if (__classPrivateFieldGet(this, _BufReader_eof, "f")) {
                if (__classPrivateFieldGet(this, _BufReader_r, "f") === __classPrivateFieldGet(this, _BufReader_w, "f")) {
                    return null;
                }
                slice = __classPrivateFieldGet(this, _BufReader_buf, "f").subarray(__classPrivateFieldGet(this, _BufReader_r, "f"), __classPrivateFieldGet(this, _BufReader_w, "f"));
                __classPrivateFieldSet(this, _BufReader_r, __classPrivateFieldGet(this, _BufReader_w, "f"), "f");
                break;
            }
            // Buffer full?
            if (this.buffered() >= __classPrivateFieldGet(this, _BufReader_buf, "f").byteLength) {
                __classPrivateFieldSet(this, _BufReader_r, __classPrivateFieldGet(this, _BufReader_w, "f"), "f");
                // #4521 The internal buffer should not be reused across reads because it causes corruption of data.
                const oldbuf = __classPrivateFieldGet(this, _BufReader_buf, "f");
                const newbuf = __classPrivateFieldGet(this, _BufReader_buf, "f").slice(0);
                __classPrivateFieldSet(this, _BufReader_buf, newbuf, "f");
                throw new BufferFullError(oldbuf);
            }
            s = __classPrivateFieldGet(this, _BufReader_w, "f") - __classPrivateFieldGet(this, _BufReader_r, "f"); // do not rescan area we scanned before
            // Buffer is not full.
            try {
                await __classPrivateFieldGet(this, _BufReader_fill, "f").call(this);
            }
            catch (err) {
                if (err instanceof PartialReadError) {
                    err.partial = slice;
                }
                throw err;
            }
        }
        // Handle last byte, if any.
        // const i = slice.byteLength - 1;
        // if (i >= 0) {
        //   this.lastByte = slice[i];
        //   this.lastCharSize = -1
        // }
        return slice;
    }
    /** `peek()` returns the next `n` bytes without advancing the reader. The
     * bytes stop being valid at the next read call.
     *
     * When the end of the underlying stream is reached, but there are unread
     * bytes left in the buffer, those bytes are returned. If there are no bytes
     * left in the buffer, it returns `null`.
     *
     * If an error is encountered before `n` bytes are available, `peek()` throws
     * an error with the `partial` property set to a slice of the buffer that
     * contains the bytes that were available before the error occurred.
     */
    async peek(n) {
        if (n < 0) {
            throw Error("negative count");
        }
        let avail = __classPrivateFieldGet(this, _BufReader_w, "f") - __classPrivateFieldGet(this, _BufReader_r, "f");
        while (avail < n && avail < __classPrivateFieldGet(this, _BufReader_buf, "f").byteLength && !__classPrivateFieldGet(this, _BufReader_eof, "f")) {
            try {
                await __classPrivateFieldGet(this, _BufReader_fill, "f").call(this);
            }
            catch (err) {
                if (err instanceof PartialReadError) {
                    err.partial = __classPrivateFieldGet(this, _BufReader_buf, "f").subarray(__classPrivateFieldGet(this, _BufReader_r, "f"), __classPrivateFieldGet(this, _BufReader_w, "f"));
                }
                throw err;
            }
            avail = __classPrivateFieldGet(this, _BufReader_w, "f") - __classPrivateFieldGet(this, _BufReader_r, "f");
        }
        if (avail === 0 && __classPrivateFieldGet(this, _BufReader_eof, "f")) {
            return null;
        }
        else if (avail < n && __classPrivateFieldGet(this, _BufReader_eof, "f")) {
            return __classPrivateFieldGet(this, _BufReader_buf, "f").subarray(__classPrivateFieldGet(this, _BufReader_r, "f"), __classPrivateFieldGet(this, _BufReader_r, "f") + avail);
        }
        else if (avail < n) {
            throw new BufferFullError(__classPrivateFieldGet(this, _BufReader_buf, "f").subarray(__classPrivateFieldGet(this, _BufReader_r, "f"), __classPrivateFieldGet(this, _BufReader_w, "f")));
        }
        return __classPrivateFieldGet(this, _BufReader_buf, "f").subarray(__classPrivateFieldGet(this, _BufReader_r, "f"), __classPrivateFieldGet(this, _BufReader_r, "f") + n);
    }
}
exports.BufReader = BufReader;
_BufReader_buf = new WeakMap(), _BufReader_rd = new WeakMap(), _BufReader_r = new WeakMap(), _BufReader_w = new WeakMap(), _BufReader_eof = new WeakMap(), _BufReader_fill = new WeakMap(), _BufReader_reset = new WeakMap();
