/*
Реализация среды исполнения языка программирования
Объектно-ориентированный продвинутый векторный транслятор
Copyright © 2021, 2024 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package avt.io.charset;
import avt.io.*;
import avt.lang.array.*;
public final class CharactersBuffer(Object, Closeable, CharWriter, Cloneable, Measureable, CharArray, Extendable)
{
private int fldLength;
private char[] fldContent;
public () { }
public String toString() { return new String(fldContent, 0, fldLength); }
public void close() { }
public void write(int charData) {
int curLength = fldLength;
int newLength = curLength + 1;
char[] content = madeLarger(curLength, newLength);
content[curLength] = (char) charData;
fldLength = newLength;
}
public void write(char[] src) { write(src, 0, src == null ? 0 : src.length); }
public void write(char[] src, int offset, int length) {
if(src == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "src" }));
}
Array.checkBounds(src, offset, length);
if(length > 0)
{
int curLength = fldLength;
int newLength = curLength + length;
char[] content = madeLarger(curLength, newLength);
Array.copy(src, offset, content, curLength, length);
fldLength = newLength;
}
}
public void flush() { }
public CharactersBuffer clone() {
CharactersBuffer result = new CharactersBuffer();
result.fldContent = fldContent.clone();
result.fldLength = fldLength;
return result;
}
public void getChars(int beginIndex, int endIndex, MutableCharArray dst, int offset) {
checkBounds(beginIndex, endIndex);
if(dst == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "dst" }));
}
int length = endIndex - beginIndex;
Array.checkBounds(dst, offset, length);
if(dst instanceof char[])
{
Array.copy(fldContent, beginIndex, (char[]) dst, offset, length);
return;
}
for(char[] content = fldContent, int index = beginIndex; length-- > 0; ) dst[offset++] = content[index++];
}
public void copyInto(MutableCharArray dst, int offset) {
if(dst == null)
{
throw new NullPointerException(String.format(avt.lang.package.getResourceString("null-pointer.argument"), new Object[] { "dst" }));
}
int length = fldLength;
Array.checkBounds(dst, offset, length);
if(dst instanceof char[])
{
Array.copy(fldContent, 0, (char[]) dst, offset, length);
return;
}
for(char[] content = fldContent, int index = 0; length-- > 0; ) dst[offset++] = content[index++];
}
public void discard() { fldLength = 0; }
public void discard(int charsQuantity) {
if(charsQuantity > 0)
{
int length = fldLength;
if(charsQuantity >= length)
{
fldLength = 0;
return;
}
char[] content = fldContent;
Array.copy(content, charsQuantity, content, 0, fldLength = length - charsQuantity);
}
}
public char[] toCharArray() {
int length = fldLength;
char[] result = new char[length];
Array.copy(fldContent, 0, result, 0, length);
return result;
}
public int length { read = fldLength }
public char operator [](int index) {
if(index < 0 || index >= fldLength)
{
throw new IndexOutOfBoundsException(avt.lang.package.getResourceString("out-of-bounds.index"));
}
return fldContent[index];
}
private void checkBounds(int beginIndex, int endIndex) {
int length = fldLength;
if((beginIndex | endIndex) < 0 || beginIndex > length || endIndex > length || beginIndex > endIndex)
{
throw new IndexOutOfBoundsException(avt.lang.package.getResourceString("out-of-bounds.index"));
}
}
private char[] madeLarger(int curLength, int newLength) {
if(newLength < 0)
{
throw new BufferTooLargeError(avt.lang.package.getResourceString("!error.buffer-too-large"));
}
char[] content = fldContent;
if(content == null)
{
fldContent = content = new char[newLength >= Int.MAX_VALUE - 0x3f ? Int.MAX_VALUE : newLength + 0x3f];
} else
{
int curCapacity = content.length;
if(newLength > curCapacity)
{
int newCapacity = curCapacity << 1 | 1;
if(newCapacity < 0) newCapacity = Int.MAX_VALUE;
if(newCapacity < newLength) newCapacity = newLength >= Int.MAX_VALUE - 0x3f ? Int.MAX_VALUE : newLength + 0x3f;
Array.copy(content, 0, fldContent = content = new char[newCapacity], 0, curLength);
}
}
fldLength = newLength;
return content;
}
}