/*
 * SDK Pullenti Unitext, version 4.33, fabruary 2026. Copyright (c) 2013-2026, Pullenti. All rights reserved. 
 * Non-Commercial Freeware and Commercial Software. 
 * This class is generated using the converter UniSharping (www.unisharping.ru) from Pullenti C# project. 
 * The latest version of the code is available on the site www.pullenti.ru
 */

const Stream = require("./../../../unisharp/Stream");

// An input buffer customised for use by <see cref="InflaterInputStream"/>
class InflaterInputBuffer {
    
    constructor(stream, bufferSize = 4096) {
        this.m_RawLength = 0;
        this.m_RawData = null;
        this.m_ClearTextLength = 0;
        this.m_ClearText = null;
        this.m_Available = 0;
        this.inputStream = null;
        this.inputStream = stream;
        if (bufferSize < 1024) 
            bufferSize = 1024;
        this.m_RawData = new Uint8Array(bufferSize);
        this.m_ClearText = this.m_RawData;
    }
    
    get rawLength() {
        return this.m_RawLength;
    }
    
    get rawData() {
        return this.m_RawData;
    }
    
    get clearTextLength() {
        return this.m_ClearTextLength;
    }
    
    get clearText() {
        return this.m_ClearText;
    }
    
    get available() {
        return this.m_Available;
    }
    set available(value) {
        this.m_Available = value;
        return value;
    }
    
    setInflaterInput(inflater) {
        if (this.m_Available > 0) {
            inflater.setInputEx(this.m_ClearText, this.m_ClearTextLength - this.m_Available, this.m_Available);
            this.m_Available = 0;
        }
    }
    
    fill() {
        this.m_RawLength = 0;
        let toRead = this.m_RawData.length;
        while (toRead > 0) {
            let count = this.inputStream.read(this.m_RawData, this.m_RawLength, toRead);
            if (count <= 0) 
                break;
            this.m_RawLength += count;
            toRead -= count;
        }{
                this.m_ClearTextLength = this.m_RawLength;
            }
        this.m_Available = this.m_ClearTextLength;
    }
    
    readRawBuffer(buffer) {
        return this.readRawBufferEx(buffer, 0, buffer.length);
    }
    
    readRawBufferEx(outBuffer, offset, length) {
        if (length < 0) 
            throw new Error("length");
        let currentOffset = offset;
        let currentLength = length;
        while (currentLength > 0) {
            if (this.m_Available <= 0) {
                this.fill();
                if (this.m_Available <= 0) 
                    return 0;
            }
            let toCopy = Math.min(currentLength, this.m_Available);
            for(let iii = 0; iii < (toCopy); iii++) outBuffer[(currentOffset) + iii] = this.m_RawData[(this.m_RawLength - (this.m_Available)) + iii];
            currentOffset += toCopy;
            currentLength -= toCopy;
            this.m_Available -= toCopy;
        }
        return length;
    }
    
    readClearTextBuffer(outBuffer, offset, length) {
        if (length < 0) 
            throw new Error("length");
        let currentOffset = offset;
        let currentLength = length;
        while (currentLength > 0) {
            if (this.m_Available <= 0) {
                this.fill();
                if (this.m_Available <= 0) 
                    return 0;
            }
            let toCopy = Math.min(currentLength, this.m_Available);
            for(let iii = 0; iii < (toCopy); iii++) outBuffer[(currentOffset) + iii] = this.m_ClearText[(this.m_ClearTextLength - (this.m_Available)) + iii];
            currentOffset += toCopy;
            currentLength -= toCopy;
            this.m_Available -= toCopy;
        }
        return length;
    }
    
    readLeByte() {
        if (this.m_Available <= 0) {
            this.fill();
            if (this.m_Available <= 0) 
                throw new Error("EOF in header");
        }
        let result = this.m_RawData[this.m_RawLength - this.m_Available];
        this.m_Available -= 1;
        return result;
    }
    
    readLeShort() {
        return this.readLeByte() | (this.readLeByte() << 8);
    }
    
    readLeInt() {
        return this.readLeShort() | (this.readLeShort() << 16);
    }
}


module.exports = InflaterInputBuffer