2430eacc创建于 2024年11月20日历史提交
/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2024. All rights reserved.
 */
package zip4cj.io.inputstream

class PushbackInputStream <: InputStream {
    protected var buf: Array<Byte>

    protected var pos: Int64

    protected var input: InputStream

    private func ensureOpen(): Unit {
    }

    public init(input: InputStream, size: Int64) {
        this.input = input
        if (size <= 0) {
            throw IllegalArgumentException("size <= 0")
        }
        this.buf = Array<Byte>(size, repeat: 0)
        this.pos = size
    }

    public init(input: InputStream) {
        this(input, 1)
    }

    public func read(b: Array<Byte>): Int64 {
        return this.read(b, 0, b.size)
    }

    func read(b: Array<Byte>, off: Int64, len: Int64): Int64 {
        ensureOpen()
        var off_p = off
        var len_p = len
        if (off_p < 0 || len_p < 0 || len_p > b.size - off_p) {
            throw IndexOutOfBoundsException()
        } else if (len_p == 0) {
            return 0
        }

        var avail = buf.size - pos
        if (avail > 0) {
            if (len < avail) {
                avail = len
            }
            buf.copyTo(b, pos, off, avail)
            pos += avail
            off_p += avail
            len_p -= avail
        }
        if (len > 0) {
            len_p = input.read(b[off_p..off_p + len_p]) //read(b, off_p, len_p)
            if (len_p == 0) {
                if (avail == 0) {
                    return -1
                }
                return avail
            }
            return avail + len_p
        }
        return avail
    }

    public func unread(b: Int64) {
        ensureOpen()
        if (pos == 0) {
            throw ZipIOException("Push back buffer is full")
        }
        buf[pos - 1] = UInt8(b)
    }

    public func unread(b: Array<Byte>, off: Int64, len: Int64) {
        ensureOpen()
        if (len > pos) {
            throw ZipIOException("Push back buffer is full")
        }
        pos -= len
        b.copyTo(buf, off, pos, len)
    }

    public func unread(b: Array<Byte>) {
        unread(b, 0, b.size)
    }

    public func skip(n: Int64): Int64 {
        ensureOpen()
        var singleByteBuffer = Array<Byte>(1, repeat: 0)
        for (i in 0..n) {
            var flag = input.read(singleByteBuffer)
            if (flag <= 0) {
                return i
            }
        }
        return n
    }

    public func markSupported(): Bool {
        return false
    }

    public func mark(readlimit: Int64) {
        readlimit
        return
    }

    public func reset() {
        throw ZipIOException("mark/reset not supported")
    }

    public func close() {
        match ((input as Resource)) {
            case Some(v) => v.close()
            case _ => ()
        }
    }
}