"use strict"; var _LineDecoder_buffer, _LineDecoder_carriageReturnIndex; Object.defineProperty(exports, "__esModule", { value: true }); exports.LineDecoder = void 0; exports.findDoubleNewlineIndex = findDoubleNewlineIndex; const tslib_1 = require("../tslib.js"); const bytes_1 = require("../utils/bytes.js"); /** * A re-implementation of httpx's `LineDecoder` in Python that handles incrementally * reading lines from text. * * https://github.com/encode/httpx/blob/920333ea98118e9cf617f246905d7b202510941c/httpx/_decoders.py#L258 */ class LineDecoder { constructor() { _LineDecoder_buffer.set(this, void 0); _LineDecoder_carriageReturnIndex.set(this, void 0); tslib_1.__classPrivateFieldSet(this, _LineDecoder_buffer, new Uint8Array(), "f"); tslib_1.__classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, null, "f"); } decode(chunk) { if (chunk == null) { return []; } const binaryChunk = chunk instanceof ArrayBuffer ? new Uint8Array(chunk) : typeof chunk === 'string' ? (0, bytes_1.encodeUTF8)(chunk) : chunk; tslib_1.__classPrivateFieldSet(this, _LineDecoder_buffer, (0, bytes_1.concatBytes)([tslib_1.__classPrivateFieldGet(this, _LineDecoder_buffer, "f"), binaryChunk]), "f"); const lines = []; let patternIndex; while ((patternIndex = findNewlineIndex(tslib_1.__classPrivateFieldGet(this, _LineDecoder_buffer, "f"), tslib_1.__classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f"))) != null) { if (patternIndex.carriage && tslib_1.__classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") == null) { // skip until we either get a corresponding `\n`, a new `\r` or nothing tslib_1.__classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, patternIndex.index, "f"); continue; } // we got double \r or \rtext\n if (tslib_1.__classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") != null && (patternIndex.index !== tslib_1.__classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") + 1 || patternIndex.carriage)) { lines.push((0, bytes_1.decodeUTF8)(tslib_1.__classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(0, tslib_1.__classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") - 1))); tslib_1.__classPrivateFieldSet(this, _LineDecoder_buffer, tslib_1.__classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(tslib_1.__classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f")), "f"); tslib_1.__classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, null, "f"); continue; } const endIndex = tslib_1.__classPrivateFieldGet(this, _LineDecoder_carriageReturnIndex, "f") !== null ? patternIndex.preceding - 1 : patternIndex.preceding; const line = (0, bytes_1.decodeUTF8)(tslib_1.__classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(0, endIndex)); lines.push(line); tslib_1.__classPrivateFieldSet(this, _LineDecoder_buffer, tslib_1.__classPrivateFieldGet(this, _LineDecoder_buffer, "f").subarray(patternIndex.index), "f"); tslib_1.__classPrivateFieldSet(this, _LineDecoder_carriageReturnIndex, null, "f"); } return lines; } flush() { if (!tslib_1.__classPrivateFieldGet(this, _LineDecoder_buffer, "f").length) { return []; } return this.decode('\n'); } } exports.LineDecoder = LineDecoder; _LineDecoder_buffer = new WeakMap(), _LineDecoder_carriageReturnIndex = new WeakMap(); // prettier-ignore LineDecoder.NEWLINE_CHARS = new Set(['\n', '\r']); LineDecoder.NEWLINE_REGEXP = /\r\n|[\n\r]/g; /** * This function searches the buffer for the end patterns, (\r or \n) * and returns an object with the index preceding the matched newline and the * index after the newline char. `null` is returned if no new line is found. * * ```ts * findNewLineIndex('abc\ndef') -> { preceding: 2, index: 3 } * ``` */ function findNewlineIndex(buffer, startIndex) { const newline = 0x0a; // \n const carriage = 0x0d; // \r for (let i = startIndex ?? 0; i < buffer.length; i++) { if (buffer[i] === newline) { return { preceding: i, index: i + 1, carriage: false }; } if (buffer[i] === carriage) { return { preceding: i, index: i + 1, carriage: true }; } } return null; } function findDoubleNewlineIndex(buffer) { // This function searches the buffer for the end patterns (\r\r, \n\n, \r\n\r\n) // and returns the index right after the first occurrence of any pattern, // or -1 if none of the patterns are found. const newline = 0x0a; // \n const carriage = 0x0d; // \r for (let i = 0; i < buffer.length - 1; i++) { if (buffer[i] === newline && buffer[i + 1] === newline) { // \n\n return i + 2; } if (buffer[i] === carriage && buffer[i + 1] === carriage) { // \r\r return i + 2; } if (buffer[i] === carriage && buffer[i + 1] === newline && i + 3 < buffer.length && buffer[i + 2] === carriage && buffer[i + 3] === newline) { // \r\n\r\n return i + 4; } } return -1; } //# sourceMappingURL=line.js.map