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