ByteArrayStream.avt

Переключить прокрутку окна
Загрузить этот исходный код

/*
    Реализация среды исполнения языка программирования
    Объектно-ориентированный продвинутый векторный транслятор

    Copyright © 2021, 2024 Малик Разработчик

    Это свободная программа: вы можете перераспространять ее и/или изменять
    ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
    в каком она была опубликована Фондом свободного программного обеспечения;
    либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

    Эта программа распространяется в надежде, что она будет полезной,
    но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
    или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
    общественной лицензии GNU.

    Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
    вместе с этой программой. Если это не так, см.
    <https://www.gnu.org/licenses/>.
*/

package avt.io;

import avt.io.extension.*;
import avt.lang.array.*;

public class ByteArrayStream(Object, Closeable, Extension, MarkExtension, Extendable, Cloneable, RawData, ByteStream, Measureable, MutableByteArray, ByteArray)
{
    protected int fldMarkedReader;
    protected int fldMarkedWriter;
    private final ByteArrayStreamReader fldReader;
    private final ByteArrayStreamWriter fldWriter;

    public (): this(null, 0, 0, 0) {  }

    public (byte[] array): this(array, 0, 0, 0) {  }

    public (byte[] array, int length): this(array, length, 0, 0) {  }

    public (byte[] array, int length, int readPosition, int writePosition) {
        ByteArrayStreamWriter writer = new ByteArrayStreamWriter(array, length, writePosition);
        ByteArrayStreamReader reader = new ByteArrayStreamReader(writer.array, length, readPosition);
        writer.source = reader;
        fldReader = reader;
        fldWriter = writer;
    }

    public void close() {  }

    public void reset() {
        fldReader.seek(fldMarkedReader, SeekExtension.BEGIN);
        fldWriter.seek(fldMarkedWriter, SeekExtension.BEGIN);
    }

    public void mark(int transferLimit) {
        fldMarkedReader = fldReader.position;
        fldMarkedWriter = fldWriter.position;
    }

    public Extension[] getExtensions() { return new Extension[] { this }; }

    public ByteArrayStream clone() {
        ByteArrayStreamWriter writer = fldWriter;
        ByteArrayStream result = new ByteArrayStream(writer.array, writer.length, fldReader.position, writer.position);
        result.fldMarkedReader = fldMarkedReader;
        result.fldMarkedWriter = fldMarkedWriter;
        return result;
    }

    public void setData(byte[] array, int length) {
        int alength = array == null ? 0 : array.length;
        if(length < 0) length = 0;
        if(length > alength) length = alength;
        fldReader.setData(array, length);
        fldWriter.setData(array, length);
    }

    public final long getPointer() { return fldWriter.array.getPointer(); }

    public final long getLength() { return fldWriter.array.getLength(); }

    public ByteArrayInputStream reader { read = fldReader }

    public ByteArrayOutputStream writer { read = fldWriter }

    public int readPosition { read = fldReader.position, write = setReadPosition }

    public int writePosition { read = fldWriter.position, write = setWritePosition }

    public final int length { read = fldWriter.length }

    public final byte[] array { read = fldWriter.array }

    public final void operator []=(int index, byte component) { fldWriter.array[index] = component; }

    public final byte operator [](int index) { return fldWriter.array[index]; }

    private void setReadPosition(int newReadPosition) { fldReader.seek(newReadPosition, SeekExtension.BEGIN); }

    private void setWritePosition(int newWritePosition) { fldWriter.seek(newWritePosition, SeekExtension.BEGIN); }
}

class ByteArrayStreamReader(ByteArrayInputStream)
{
    (byte[] array, int length, int position): super(array, length, position) {  }

    void setData(byte[] array, int length) {
        fldArray = array;
        fldLength = length;
        notifyLengthChanged(length);
    }

    void notifyLengthChanged(int newLength) {
        if(fldPosition > newLength) fldPosition = newLength;
        if(fldMarked > newLength) fldMarked = newLength;
    }

    int position { read = fldPosition }
}

class ByteArrayStreamWriter(ByteArrayOutputStream)
{
    private ByteArrayStreamReader fldSource;

    (byte[] array, int length, int position): super(array, length, position) {  }

    public void truncate() {
        super.truncate();
        fldSource.notifyLengthChanged(fldLength);
    }

    protected byte[] madeLarger(int curLength, int newLength) {
        byte[] array = fldArray;
        byte[] result = super.madeLarger(curLength, newLength);
        ByteArrayStreamReader source = fldSource;
        if(array != result) source.fldArray = result;
        source.fldLength = newLength;
        return result;
    }

    void setData(byte[] array, int length) {
        fldArray = array;
        fldLength = length;
        notifyLengthChanged(length);
    }

    void notifyLengthChanged(int newLength) {
        if(fldPosition > newLength) fldPosition = newLength;
        if(fldMarked > newLength) fldMarked = newLength;
    }

    int position { read = fldPosition }

    int length { read = fldLength }

    byte[] array { read = fldArray }

    ByteArrayStreamReader source { write = fldSource }
}