ByteArrayByteWriter.java 9 KB
/*
 * Decompiled with CFR 0_118.
 */
package com.adobe.internal.io;

import com.adobe.internal.io.ByteWriter;
import java.io.IOException;
import java.util.ArrayList;

public final class ByteArrayByteWriter
implements ByteWriter {
    private byte[] mCurBuffer;
    private ArrayList mBufferArray;
    private int mCurIndex;
    private int mCurBase;
    private int mCurTop;
    private int mLength;
    private static final int mMinBufSize = 32;
    private int mMinBufBit;
    private static final int mMaxBufSize = 262144;
    private int mMaxBufBit;
    private int mTotalSize;

    public ByteArrayByteWriter() {
        this(0);
    }

    public ByteArrayByteWriter(byte[] buffer) {
        this(buffer, 0, buffer.length);
    }

    public ByteArrayByteWriter(int size) {
        if (size < 0) {
            throw new IllegalArgumentException("Negative initial size: " + size);
        }
        this.mCurBuffer = new byte[32];
        this.mBufferArray = new ArrayList();
        this.mBufferArray.add(this.mCurBuffer);
        this.mCurIndex = 0;
        this.mCurBase = 0;
        this.mCurTop = 32;
        this.mLength = 0;
        int bits = 32;
        int counter = 0;
        while (bits != 0) {
            bits >>= 1;
            ++counter;
        }
        this.mMinBufBit = counter - 1;
        bits = 262144;
        counter = 0;
        while (bits != 0) {
            bits >>= 1;
            ++counter;
        }
        this.mMaxBufBit = counter - 1;
        this.mTotalSize = 32;
    }

    public ByteArrayByteWriter(byte[] buffer, int offset, int length) {
        if (offset < 0 || length < 0 || offset + length > buffer.length) {
            throw new IllegalArgumentException("Bad array parameters - offset = " + offset + ", length = " + length);
        }
        this.mCurBuffer = buffer;
        this.mCurBase = - offset;
        this.mCurTop = length;
        this.mLength = length;
    }

    public ByteArrayByteWriter(ArrayList bufferArray, int length) {
        this.mCurIndex = 0;
        this.mCurBuffer = (byte[])bufferArray.get(this.mCurIndex);
        this.mBufferArray = bufferArray;
        this.mCurBase = 0;
        this.mCurTop = Math.min(length, this.mCurBuffer.length);
        this.mLength = length;
        int bits = 32;
        int counter = 0;
        while (bits != 0) {
            bits >>= 1;
            ++counter;
        }
        this.mMinBufBit = counter - 1;
        bits = 262144;
        counter = 0;
        while (bits != 0) {
            bits >>= 1;
            ++counter;
        }
        this.mMaxBufBit = counter - 1;
    }

    public byte[] toByteArray() {
        byte[] bufferCopy = new byte[this.mLength];
        int index = 0;
        int totalCount = 0;
        while (totalCount < this.mLength) {
            byte[] thisBuffer = (byte[])this.mBufferArray.get(index);
            int thisCount = Math.min(this.mLength - totalCount, thisBuffer.length);
            System.arraycopy(thisBuffer, 0, bufferCopy, totalCount, thisCount);
            totalCount += thisCount;
            ++index;
        }
        return bufferCopy;
    }

    @Override
    public void write(long position, int b) throws IOException {
        if (position < (long)this.mCurBase || position >= (long)this.mCurTop) {
            if (position < 0 || position >= Integer.MAX_VALUE) {
                throw new IOException("Attempt to position outside the buffer.");
            }
            if (position >= (long)this.mTotalSize) {
                this.resizeBuffer(position + 1);
            }
            this.reloadBuffer(position);
        }
        if (position >= (long)this.mLength) {
            this.mLength = (int)position + 1;
        }
        this.mCurBuffer[(int)position - this.mCurBase] = (byte)b;
    }

    @Override
    public void write(long position, byte[] b, int offset, int length) throws IOException {
        if (position < 0 || position + (long)length > Integer.MAX_VALUE) {
            throw new IOException("Attempt to position outside the buffer.");
        }
        if (offset < 0 || length < 0 || offset + length > b.length) {
            throw new IOException("Invalid offset/length on the array.");
        }
        if (length == 0) {
            return;
        }
        if (position + (long)length > (long)this.mLength) {
            this.mLength = (int)position + length;
        }
        if (position >= (long)this.mCurBase && position + (long)length <= (long)this.mCurTop) {
            System.arraycopy(b, offset, this.mCurBuffer, (int)position - this.mCurBase, length);
        } else {
            if (position + (long)length > (long)this.mTotalSize) {
                this.resizeBuffer(position + (long)length);
            }
            if (position < (long)this.mCurBase || position >= (long)this.mCurTop) {
                this.reloadBuffer(position);
            }
            int totalWritten = 0;
            while (totalWritten < length) {
                int thisWrite = Math.min(length - totalWritten, this.mCurTop - (int)position);
                System.arraycopy(b, offset, this.mCurBuffer, (int)position - this.mCurBase, thisWrite);
                position += (long)thisWrite;
                offset += thisWrite;
                if ((totalWritten += thisWrite) >= length) continue;
                ++this.mCurIndex;
                this.mCurBase = this.mCurTop;
                this.mCurBuffer = (byte[])this.mBufferArray.get(this.mCurIndex);
                this.mCurTop = this.mCurBase + this.mCurBuffer.length;
            }
        }
    }

    private void reloadBuffer(long position) {
        if (position < 32) {
            this.mCurIndex = 0;
            this.mCurBase = 0;
        } else if (position == (long)this.mCurTop) {
            ++this.mCurIndex;
            this.mCurBase = this.mCurTop;
        } else if (position >= 262144) {
            this.mCurIndex = (int)position / 262144 + this.mMaxBufBit - this.mMinBufBit;
            this.mCurBase = (int)position & -262144;
        } else {
            int index = this.mMaxBufBit - this.mMinBufBit + 1;
            int bits = (int)position << 31 - this.mMaxBufBit;
            while (--index != 0 && ((bits <<= 1) & Integer.MIN_VALUE) == 0) {
            }
            this.mCurIndex = index;
            this.mCurBase = 1 << index + this.mMinBufBit - 1 & -32;
        }
        this.mCurBuffer = (byte[])this.mBufferArray.get(this.mCurIndex);
        this.mCurTop = this.mCurBase + this.mCurBuffer.length;
    }

    private void resizeBuffer(long newSize) throws IOException {
        while ((long)this.mTotalSize < newSize) {
            int bufferSize = 0;
            int arraySize = this.mBufferArray.size();
            bufferSize = arraySize < 2 ? 32 : ((bufferSize = ((byte[])this.mBufferArray.get(arraySize - 1)).length) < 262144 ? (bufferSize *= 2) : 262144);
            this.mBufferArray.add(new byte[bufferSize]);
            this.mTotalSize += bufferSize;
        }
    }

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

    @Override
    public void flush() throws IOException {
    }

    @Override
    public void close() throws IOException {
    }

    public String toString() {
        return super.toString();
    }

    @Override
    public int read(long position) throws IOException {
        if (position < 0 || position >= (long)this.mLength) {
            return -1;
        }
        if (position < (long)this.mCurBase || position >= (long)this.mCurTop) {
            this.reloadBuffer(position);
        }
        return this.mCurBuffer[(int)position - this.mCurBase] & 255;
    }

    @Override
    public int read(long position, byte[] b, int offset, int length) throws IOException {
        if (position < 0 || position >= (long)this.mLength) {
            return -1;
        }
        if (offset < 0 || length < 0 || offset + length > b.length) {
            throw new IOException("Invalid offset/length on the array.");
        }
        if (length == 0) {
            return 0;
        }
        length = (int)Math.min((long)length, (long)this.mLength - position);
        if (position >= (long)this.mCurBase && position + (long)length <= (long)this.mCurTop) {
            System.arraycopy(this.mCurBuffer, (int)position - this.mCurBase, b, offset, length);
        } else {
            if (position < (long)this.mCurBase || position >= (long)this.mCurTop) {
                this.reloadBuffer(position);
            }
            int totalRead = 0;
            while (totalRead < length) {
                int thisRead = Math.min(length - totalRead, this.mCurTop - (int)position);
                System.arraycopy(this.mCurBuffer, (int)position - this.mCurBase, b, offset, thisRead);
                position += (long)thisRead;
                offset += thisRead;
                if ((totalRead += thisRead) >= length) continue;
                ++this.mCurIndex;
                this.mCurBase = this.mCurTop;
                this.mCurBuffer = (byte[])this.mBufferArray.get(this.mCurIndex);
                this.mCurTop = Math.min(this.mLength, this.mCurBase + this.mCurBuffer.length);
            }
        }
        return length;
    }
}