/*
Реализация среды исполнения языка программирования
Объектно-ориентированный продвинутый векторный транслятор
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;
}
}