ByteArrayBidirectStream.avt

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

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

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

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

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

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

package avt.io;

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

public class ByteArrayBidirectStream(Object, Closeable, Extension, MarkExtension, RawData, Extendable, Measureable, ByteStream, MutableByteArray, ByteArray)
{
    protected int fldMarkedRead;
    protected int fldMarkedWrite;
    protected final ByteArrayBidirectStreamReader fldReader;
    protected final ByteArrayBidirectStreamWriter fldWriter;

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

    public (byte[] array): this(array, array == null ? 0 : array.length, 0, 0) {  }

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

    public (byte[] array, int length, int readPosition, int writePosition) {
        ByteArrayBidirectStreamWriter writer = createWriter(array, length, writePosition);
        if(writer == null) writer = new ByteArrayBidirectStreamWriter(array, length, writePosition);
        ByteArrayBidirectStreamReader reader = createReader(array = writer.fldArray, length, readPosition);
        if(reader == null) reader = new ByteArrayBidirectStreamReader(array, length, readPosition);
        writer.fldSource = reader;
        fldReader = reader;
        fldWriter = writer;
    }

    public void close() {  }

    public void mark() {
        fldMarkedRead = fldReader.fldPosition;
        fldMarkedWrite = fldWriter.fldPosition;
    }

    public void reset() {
        fldReader.seek(fldMarkedRead, SeekExtension.BEGIN);
        fldWriter.seek(fldMarkedWrite, SeekExtension.BEGIN);
    }

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

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

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

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

    public final int length { read = fldWriter.fldLength }

    public final ByteArrayInputStream reader { read = fldReader }

    public final ByteArrayOutputStream writer { read = fldWriter }

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

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

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

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

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

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

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

    protected ByteArrayBidirectStreamReader createReader(byte[] array, int length, int position) { return null; }

    protected ByteArrayBidirectStreamWriter createWriter(byte[] array, int length, int position) { return null; }
}

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

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

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

public class ByteArrayBidirectStreamWriter(ByteArrayOutputStream)
{
    ByteArrayBidirectStreamReader fldSource;

    protected (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[] result = super.madeLarger(curLength, newLength);
        ByteArrayBidirectStreamReader source = fldSource;
        source.fldArray = result;
        source.fldLength = newLength;
        return result;
    }

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

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