StringBuilder.avt

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

/*
    Исходный код среды исполнения ПВТ-ОО.

    Этот исходный код является частью проекта ПВТ-ОО.

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

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

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

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

package avt.lang;

import avt.lang.array.*;
import platform.independent.streamformat.*;

public class StringBuilder(Object, MutableDataHolder, CharSequence, Cloneable, DataHolder, Measureable, MutableCharArray, CharArray)
{
    protected int fldLength;
    protected char[] fldChars;

    public () { fldChars = new char[63]; }

    public (int initialCapacity) { fldChars = new char[initialCapacity <= 1 ? 1 : initialCapacity]; }

    protected (char[] chars, int length) {
        fldLength = length;
        fldChars = chars;
    }

    public String toString() { return new String(fldChars, 0, fldLength); }

    public void clear() { fldLength = 0; }

    public void getChars(int beginIndex, int endIndex, MutableCharArray dst, int offset) {
        checkBounds(beginIndex, endIndex);
        if(dst == null)
        {
            throw new NullPointerException("аргумент dst равен нулевой ссылке");
        }
        int length = endIndex - beginIndex;
        Array.checkBounds(dst, offset, length);
        copyChars(beginIndex, dst, offset, length);
    }

    public StringBuilder subsequence(int beginIndex, int endIndex) {
        checkBounds(beginIndex, endIndex);
        int length = endIndex - beginIndex;
        char[] chars = new char[length];
        copyChars(beginIndex, chars, 0, length);
        return new StringBuilder(chars, length);
    }

    public StringBuilder subsequence(int beginIndex) { return subsequence(beginIndex, fldLength); }

    public StringBuilder clone() { return subsequence(0, fldLength); }

    public boolean isEmpty() { return fldLength <= 0; }

    public int indexOf(int character) { return findForward(character, 0); }

    public int indexOf(int character, int startFromIndex) { return findForward(character, startFromIndex); }

    public int indexOf(String string) { return findForward(string, 0); }

    public int indexOf(String string, int startFromIndex) { return findForward(string, startFromIndex); }

    public int lastIndexOf(int character) { return findBackward(character, Int.MAX_VALUE); }

    public int lastIndexOf(int character, int startFromIndex) { return findBackward(character, startFromIndex); }

    public int lastIndexOf(String string) { return findBackward(string, Int.MAX_VALUE); }

    public int lastIndexOf(String string, int startFromIndex) { return findBackward(string, startFromIndex); }

    public StringBuilder trimToLength() {
        trim();
        return this;
    }

    public StringBuilder insert(int index, boolean src) {
        String array = String.valueOf(src);
        insertArray(index, array, 0, array.length);
        return this;
    }

    public StringBuilder insert(int index, char src) {
        insertChar(index, src);
        return this;
    }

    public StringBuilder insert(int index, byte src) {
        String array = String.valueOf(src);
        insertArray(index, array, 0, array.length);
        return this;
    }

    public StringBuilder insert(int index, short src) {
        String array = String.valueOf(src);
        insertArray(index, array, 0, array.length);
        return this;
    }

    public StringBuilder insert(int index, int src) {
        String array = String.valueOf(src);
        insertArray(index, array, 0, array.length);
        return this;
    }

    public StringBuilder insert(int index, long src) {
        String array = String.valueOf(src);
        insertArray(index, array, 0, array.length);
        return this;
    }

    public StringBuilder insert(int index, float src) {
        String array = String.valueOf(src);
        insertArray(index, array, 0, array.length);
        return this;
    }

    public StringBuilder insert(int index, double src) {
        String array = String.valueOf(src);
        insertArray(index, array, 0, array.length);
        return this;
    }

    public StringBuilder insert(int index, real src) {
        String array = String.valueOf(src);
        insertArray(index, array, 0, array.length);
        return this;
    }

    public StringBuilder insert(int index, Object src) {
        String array = String.valueOf(src);
        insertArray(index, array, 0, array.length);
        return this;
    }

    public StringBuilder insert(int index, CharArray src, int offset, int length) {
        Array.checkBounds(src, offset, length);
        insertArray(index, src, offset, length);
        return this;
    }

    public StringBuilder insertf(int index, String form, ObjectArray data) {
        String array = String.format(form, data);
        insertArray(index, array, 0, array.length);
        return this;
    }

    public StringBuilder delete(int beginIndex, int endIndex) {
        checkBounds(beginIndex, endIndex);
        deletePortion(beginIndex, endIndex);
        return this;
    }

    public StringBuilder delete(int index) {
        checkIndex(index);
        deletePortion(index, index + 1);
        return this;
    }

    public StringBuilder append(boolean src) {
        String array = String.valueOf(src);
        appendArray(array, 0, array.length);
        return this;
    }

    public StringBuilder append(char src) {
        appendChar(src);
        return this;
    }

    public StringBuilder append(byte src) {
        String array = String.valueOf(src);
        appendArray(array, 0, array.length);
        return this;
    }

    public StringBuilder append(short src) {
        String array = String.valueOf(src);
        appendArray(array, 0, array.length);
        return this;
    }

    public StringBuilder append(int src) {
        String array = String.valueOf(src);
        appendArray(array, 0, array.length);
        return this;
    }

    public StringBuilder append(long src) {
        String array = String.valueOf(src);
        appendArray(array, 0, array.length);
        return this;
    }

    public StringBuilder append(float src) {
        String array = String.valueOf(src);
        appendArray(array, 0, array.length);
        return this;
    }

    public StringBuilder append(double src) {
        String array = String.valueOf(src);
        appendArray(array, 0, array.length);
        return this;
    }

    public StringBuilder append(real src) {
        String array = String.valueOf(src);
        appendArray(array, 0, array.length);
        return this;
    }

    public StringBuilder append(Object src) {
        String array = String.valueOf(src);
        appendArray(array, 0, array.length);
        return this;
    }

    public StringBuilder append(CharArray src, int offset, int length) {
        Array.checkBounds(src, offset, length);
        appendArray(src, offset, length);
        return this;
    }

    public StringBuilder appendf(String form, ObjectArray data) {
        String array = String.format(form, data);
        appendArray(array, 0, array.length);
        return this;
    }

    public String displayString() { return toString(); }

    public int length { read = fldLength, write = setLength }

    public final int capacity { read = getCapacity }

    public void operator []=(int index, char character) {
        checkIndex(index);
        fldChars[index] = character;
    }

    public char operator [](int index) {
        checkIndex(index);
        return fldChars[index];
    }

    public final StringBuilder operator +(boolean src) { return append(src); }

    public final StringBuilder operator +(char src) { return append(src); }

    public final StringBuilder operator +(byte src) { return append(src); }

    public final StringBuilder operator +(short src) { return append(src); }

    public final StringBuilder operator +(int src) { return append(src); }

    public final StringBuilder operator +(long src) { return append(src); }

    public final StringBuilder operator +(float src) { return append(src); }

    public final StringBuilder operator +(double src) { return append(src); }

    public final StringBuilder operator +(real src) { return append(src); }

    public final StringBuilder operator +(Object src) { return append(src); }

    protected void trim() {
        int length = fldLength;
        char[] chars = fldChars;
        if(length < chars.length)
        {
            Array.copy(chars, 0, fldChars = new char[length], 0, length);
        }
    }

    protected void setLength(int newLength) {
        if(newLength < 0)
        {
            throw new NegativeArrayLengthException("длина не может быть отрицательной");
        }
        int curLength = fldLength;
        char[] chars = fldChars;
        if(newLength > chars.length) chars = madeLarger(newLength);
        if(newLength > curLength) Array.fill(chars, curLength, newLength - curLength, '\0');
        fldLength = newLength;
    }

    protected void copyChars(int index, MutableCharArray dst, int offset, int length) {
        if(dst instanceof char[])
        {
            Array.copy(fldChars, index, (char[]) dst, offset, length);
            return;
        }
        for(char[] chars = fldChars; length-- > 0; ) dst[offset++] = chars[index++];
    }

    protected void insertChar(int index, char src) {
        int thisLength = fldLength;
        char[] thisChars = madeLarger(thisLength + 1);
        if(index < 0) index = 0;
        if(index > thisLength) index = thisLength;
        Array.copy(thisChars, index, thisChars, index + 1, thisLength++ - index);
        thisChars[index] = src;
        fldLength = thisLength;
    }

    protected void insertArray(int index, CharArray src, int offset, int length) {
        int thisLength = fldLength;
        int newLength = thisLength + length;
        char[] thisChars = madeLarger(newLength);
        if(index < 0) index = 0;
        if(index > thisLength) index = thisLength;
        Array.copy(thisChars, index, thisChars, index + length, thisLength - index);
        if(src instanceof char[])
        {
            Array.copy((char[]) src, offset, thisChars, index, length);
        }
        else if(src instanceof CharSequence)
        {
            ((CharSequence) src).getChars(offset, offset + length, thisChars, index);
        }
        else
        {
            while(length-- > 0) thisChars[index++] = src[offset++];
        }
        fldLength = newLength;
    }

    protected void appendChar(char src) {
        int length = fldLength;
        char[] chars = madeLarger(length + 1);
        chars[length++] = src;
        fldLength = length;
    }

    protected void appendArray(CharArray src, int offset, int length) {
        int thisLength = fldLength;
        int newLength = thisLength + length;
        char[] thisChars = madeLarger(newLength);
        if(src instanceof char[])
        {
            Array.copy((char[]) src, offset, thisChars, thisLength, length);
        }
        else if(src instanceof CharSequence)
        {
            ((CharSequence) src).getChars(offset, offset + length, thisChars, thisLength);
        }
        else
        {
            while(length-- > 0) thisChars[thisLength++] = src[offset++];
        }
        fldLength = newLength;
    }

    protected void deletePortion(int beginIndex, int endIndex) {
        int count = endIndex - beginIndex;
        int thisLength = fldLength;
        char[] thisChars = fldChars;
        Array.copy(thisChars, endIndex, thisChars, beginIndex, thisLength - endIndex);
        fldLength = thisLength - count;
    }

    protected int findForward(int character, int startFromIndex) {
        int thisLength = fldLength;
        if(startFromIndex < 0) startFromIndex = 0;
        return startFromIndex >= thisLength ? -1 : Array.indexOf(character, fldChars, startFromIndex, thisLength - startFromIndex);
    }

    protected int findForward(String string, int startFromIndex) {
        int anotLength;
        if(string == null || (anotLength = string.length) <= 0) return startFromIndex;
        if(startFromIndex < 0) startFromIndex = 0;
        int thisLength = fldLength;
        int limit = thisLength - anotLength + 1;
        if(startFromIndex < limit)
        {
            int character = string[0];
            char[] thisChars = fldChars;
            do
            {
                if((startFromIndex = Array.indexOf(character, thisChars, startFromIndex, limit - startFromIndex)) < 0) break;
                if(string.contentEquals(thisChars, startFromIndex)) return startFromIndex;
            } while(++startFromIndex < limit);
        }
        return -1;
    }

    protected int findBackward(int character, int startFromIndex) {
        int thisLength = fldLength;
        if(startFromIndex >= thisLength) startFromIndex = thisLength - 1;
        return startFromIndex < 0 ? -1 : Array.lastIndexOf(character, fldChars, startFromIndex, startFromIndex + 1);
    }

    protected int findBackward(String string, int startFromIndex) {
        int anotLength;
        if(string == null || (anotLength = string.length) <= 0) return startFromIndex;
        int thisLength = fldLength;
        int limit = thisLength - anotLength;
        if(startFromIndex > limit) startFromIndex = limit;
        if(startFromIndex >= 0)
        {
            int character = string[0];
            char[] thisChars = fldChars;
            do
            {
                if((startFromIndex = Array.lastIndexOf(character, thisChars, startFromIndex, startFromIndex + 1)) < 0) break;
                if(string.contentEquals(thisChars, startFromIndex)) return startFromIndex;
            } while(--startFromIndex >= 0);
        }
        return -1;
    }

    protected final void checkBounds(int beginIndex, int endIndex) {
        int thisLength = length;
        if((beginIndex | endIndex) < 0 || beginIndex > thisLength || endIndex > thisLength || beginIndex > endIndex)
        {
            throw new StringIndexOutOfBoundsException("индекс символа строки выходит из диапазона");
        }
    }

    protected final void checkIndex(int index) {
        if(index < 0 || index >= length)
        {
            throw new StringIndexOutOfBoundsException("индекс символа строки выходит из диапазона");
        }
    }

    private int getCapacity() { return fldChars.length; }

    private char[] madeLarger(int minimumCapacity) {
        if(minimumCapacity < 0)
        {
            throw new BufferTooLargeError("объём буфера очень велик");
        }
        char[] chars = fldChars;
        int currentCapacity = chars.length;
        if(minimumCapacity > currentCapacity)
        {
            int newCapacity = currentCapacity >= (Int.MAX_VALUE >> 1) ? Int.MAX_VALUE : (currentCapacity << 1) + 1;
            if(newCapacity < minimumCapacity) newCapacity = minimumCapacity;
            Array.copy(chars, 0, fldChars = chars = new char[newCapacity], 0, currentCapacity);
        }
        return chars;
    }
}