ChainedInputByteStream.java 4.62 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.adobe.internal.io.stream;

import com.adobe.internal.io.stream.InputByteStream;
import com.adobe.internal.io.stream.InputByteStreamImpl;
import java.io.IOException;
import java.util.ArrayList;

final class ChainedInputByteStream
extends InputByteStreamImpl {
    private InputByteStream[] mByteStreams;
    private long[] mLengths;
    private int mCurrentByteStreamIndex;
    private long mPosition;
    private long mTotalLength;

    ChainedInputByteStream(InputByteStream[] byteStreams) throws IOException {
        this.mByteStreams = byteStreams;
        this.mLengths = new long[this.mByteStreams.length];
        for (int i = 0; i < this.mLengths.length; ++i) {
            this.mByteStreams[i].seek(0);
            this.mLengths[i] = this.mByteStreams[i].length();
            this.mTotalLength += this.mLengths[i];
        }
    }

    @Override
    public long getPosition() throws IOException {
        return this.mPosition;
    }

    @Override
    public long length() throws IOException {
        return this.mTotalLength;
    }

    @Override
    public InputByteStream seek(long position) throws IOException {
        if (position < 0) {
            position = 0;
        }
        if (position >= this.mTotalLength) {
            position = this.mTotalLength - 1;
        }
        this.mPosition = position;
        this.mCurrentByteStreamIndex = 0;
        while (position >= this.mLengths[this.mCurrentByteStreamIndex]) {
            position -= this.mLengths[this.mCurrentByteStreamIndex];
            ++this.mCurrentByteStreamIndex;
        }
        this.mByteStreams[this.mCurrentByteStreamIndex].seek(position);
        return this;
    }

    @Override
    public InputByteStream slice(long begin, long length) throws IOException {
        int i;
        if (begin == 0 && this.mTotalLength == 0) {
            return new ChainedInputByteStream(new InputByteStream[0]);
        }
        if (begin < 0 || begin >= this.mTotalLength || length < 0 || begin + length > this.mTotalLength) {
            throw new IOException("Invalid Parameter");
        }
        ArrayList<InputByteStream> bufs = new ArrayList<InputByteStream>();
        long endPosition = begin + length;
        long beginPosition = begin;
        int begin_index = 0;
        while (beginPosition >= this.mLengths[begin_index]) {
            beginPosition -= this.mLengths[begin_index];
            ++begin_index;
        }
        int end_index = 0;
        while (endPosition > this.mLengths[end_index]) {
            endPosition -= this.mLengths[end_index];
            ++end_index;
        }
        for (i = begin_index; i < end_index; ++i) {
            bufs.add(this.mByteStreams[i].slice(beginPosition, this.mLengths[i] - beginPosition));
            beginPosition = 0;
        }
        bufs.add(this.mByteStreams[i].slice(beginPosition, endPosition - beginPosition));
        InputByteStream[] streams = new InputByteStream[bufs.size()];
        System.arraycopy(bufs.toArray(), 0, streams, 0, bufs.size());
        return new ChainedInputByteStream(streams);
    }

    @Override
    public void close() throws IOException {
        for (int i = 0; i < this.mByteStreams.length; ++i) {
            this.mByteStreams[i].close();
        }
        this.mByteStreams = null;
    }

    @Override
    public int read() throws IOException {
        if (this.mCurrentByteStreamIndex >= this.mLengths.length) {
            return -1;
        }
        int byteRead = this.mByteStreams[this.mCurrentByteStreamIndex].read();
        if (byteRead == -1) {
            ++this.mCurrentByteStreamIndex;
            if (this.mCurrentByteStreamIndex == this.mLengths.length) {
                return -1;
            }
            this.mByteStreams[this.mCurrentByteStreamIndex].seek(0);
            byteRead = this.read();
        } else {
            ++this.mPosition;
        }
        return byteRead;
    }

    @Override
    public int read(byte[] bytes, int position, int length) throws IOException {
        int bytesCopied = 0;
        if (this.mCurrentByteStreamIndex >= this.mLengths.length) {
            return -1;
        }
        while (bytesCopied < length) {
            int bytesRead = this.mByteStreams[this.mCurrentByteStreamIndex].read(bytes, position + bytesCopied, length - bytesCopied);
            if (bytesRead == -1) {
                ++this.mCurrentByteStreamIndex;
                if (this.mCurrentByteStreamIndex < this.mLengths.length) continue;
                if (bytesCopied != 0) break;
                return -1;
            }
            bytesCopied += bytesRead;
        }
        this.mPosition += (long)bytesCopied;
        return bytesCopied;
    }
}