String.avt

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

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

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

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

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

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

package avt.lang;

import avt.io.charset.*;
import avt.lang.array.*;
import avt.lang.math.*;
import avt.lang.table.*;
import platform.dependent.*;
import platform.independent.streamformat.*;

public final class String(Object, CharSequence, DataHolder, Comparable, Cloneable, Measureable, CharArray)
{
    private static byte[] created;
    private static String[] constants;
    private static String empty;
    private static Mutex poolOperation;
    private static HashValueTable poolTable;

    public static String valueOf(boolean src) { return src ? "true" : "false"; }

    public static String valueOf(char src) { return new String(src); }

    public static native String valueOf(byte src);

    public static native String valueOf(short src);

    public static native String valueOf(int src);

    public static native String valueOf(long src);

    public static native String valueOf(float src);

    public static native String valueOf(double src);

    public static native String valueOf(real src);

    public static String valueOf(Object src) { return src == null ? "null" : src.toString(); }

    public static String valueOf(CharArray src, int offset, int length) { return new String(src, offset, length); }

    public static String format(String form, ObjectArray data) {
        if(form == null) return null;
        int beginIndex = 0;
        int formLength = form.length;
        StringBuilder result = new StringBuilder();
        label0: for(int endIndex = 0, int dataLength = data == null ? -1 : data.length; (endIndex = form.indexOf('%', beginIndex)) >= 0; beginIndex = endIndex)
        {
            result + form.substring(beginIndex, endIndex);
            int formIndex = (beginIndex = endIndex) + 1;
            if(formIndex >= formLength) break label0;
            char formChar = form[formIndex];
            if(formChar == '%')
            {
                endIndex = formIndex + 1;
                result + '%';
                continue label0;
            }
            if(formChar < '0' || formChar > '9')
            {
                result + form.substring(beginIndex, endIndex = formIndex + 1);
                continue label0;
            }
            int dataIndex = formChar - '0';
            do
            {
                if(++formIndex >= formLength) break label0;
                if((formChar = form[formIndex]) < '0' || formChar > '9') break;
                int digit = formChar - '0';
                if((dataIndex *= 10) > (Int.MAX_VALUE - digit))
                {
                    result + form.substring(beginIndex, endIndex = formIndex + 1);
                    continue label0;
                }
                dataIndex += digit;
            } while(true);
            boolean isReal = false;
            boolean isString = true;
            boolean isExpForm = false;
            boolean significandAll = false;
            boolean significandSign = false;
            boolean orderSign = true;
            boolean leadZeroOutput = false;
            int significandDigits = 1;
            int orderDigits = 0;
            int leadZeroWidth = 0;
            if(formChar == '#')
            {
                isString = false;
                if(++formIndex >= formLength) break label0;
                if((formChar = form[formIndex]) == '+')
                {
                    significandSign = true;
                    if(++formIndex >= formLength) break label0;
                    formChar = form[formIndex];
                }
                if(formChar == '0')
                {
                    leadZeroOutput = true;
                    if(++formIndex >= formLength) break label0;
                    if((formChar = form[formIndex]) < '0' || formChar > '9')
                    {
                        result + form.substring(beginIndex, endIndex = formIndex + 1);
                        continue label0;
                    }
                    leadZeroWidth = formChar - '0';
                    if(++formIndex >= formLength) break label0;
                    if((formChar = form[formIndex]) >= '0' && formChar <= '9')
                    {
                        leadZeroWidth = (leadZeroWidth * 10) + (formChar - '0');
                        if(++formIndex >= formLength) break label0;
                        formChar = form[formIndex];
                    }
                } else
                {
                    if(formChar != '1')
                    {
                        result + form.substring(beginIndex, endIndex = formIndex + 1);
                        continue label0;
                    }
                    if(++formIndex >= formLength) break label0;
                    if((formChar = form[formIndex]) == '.')
                    {
                        isReal = true;
                        if(++formIndex >= formLength) break label0;
                        if((formChar = form[formIndex]) < '0' || formChar > '9')
                        {
                            result + form.substring(beginIndex, endIndex = formIndex + 1);
                            continue label0;
                        }
                        significandDigits = formChar - '0';
                        if(++formIndex >= formLength) break label0;
                        if((formChar = form[formIndex]) >= '0' && formChar <= '9')
                        {
                            significandDigits = (significandDigits * 10) + (formChar - '0');
                            if(++formIndex >= formLength) break label0;
                            formChar = form[formIndex];
                        }
                        if(significandDigits++ < 1)
                        {
                            result + form.substring(beginIndex, endIndex = formIndex + 1);
                            continue label0;
                        }
                        if(formChar == 'A' || formChar == 'a')
                        {
                            significandAll = true;
                            if(++formIndex >= formLength) break label0;
                            formChar = form[formIndex];
                        }
                    }
                    if((isExpForm = formChar == 'E') || formChar == 'e')
                    {
                        isReal = true;
                        if(++formIndex >= formLength) break label0;
                        if((formChar = form[formIndex]) != '+')
                        {
                            orderSign = false;
                        } else
                        {
                            if(++formIndex >= formLength) break label0;
                            formChar = form[formIndex];
                        }
                        if(formChar < '0' || formChar > '4')
                        {
                            result + form.substring(beginIndex, endIndex = formIndex + 1);
                            continue label0;
                        }
                        orderDigits = formChar - '0';
                        if(++formIndex >= formLength) break label0;
                        formChar = form[formIndex];
                    }
                }
            }
            int fieldWidth = 0;
            if(formChar == ':')
            {
                if(++formIndex >= formLength) break label0;
                if((formChar = form[formIndex]) < '0' || formChar > '9')
                {
                    result + form.substring(beginIndex, endIndex = formIndex + 1);
                    continue label0;
                }
                fieldWidth = formChar - '0';
                do
                {
                    if(++formIndex >= formLength) break label0;
                    if((formChar = form[formIndex]) < '0' || formChar > '9') break;
                    int digit = formChar - '0';
                    if((fieldWidth *= 10) > (1024 - digit))
                    {
                        result + form.substring(beginIndex, endIndex = formIndex + 1);
                        continue label0;
                    }
                    fieldWidth += digit;
                } while(true);
            }
            if(formChar != '%')
            {
                result + form.substring(beginIndex, endIndex = formIndex + 1);
                continue label0;
            }
            if(dataLength < 0)
            {
                throw new NullPointerException(package.getResourceString("null-pointer.format-data"));
            }
            if(dataIndex < 0 || dataIndex >= dataLength)
            {
                throw new ArrayIndexOutOfBoundsException(package.getResourceString("out-of-bounds.array-index.format-data"));
            }
            Object dataComponent = data[dataIndex];
            if(dataComponent == null)
            {
                throw new NullPointerException(package.getResourceString("null-pointer.format-data.component"));
            }
            String formatted;
            if(isString)
            {
                formatted = dataComponent.toString();
            } else
            {
                if(!(dataComponent instanceof Numeric))
                {
                    throw new ClassCastException(package.getResourceString("class-cast.format-data")) { source = dataComponent.getClass(), destination = Numeric.class };
                }
                Numeric dataNumeric = (Numeric) dataComponent;
                if(isReal)
                {
                    formatted = Real.toString(
                        dataNumeric.asReal(), significandDigits <= 1 ? RealRepresenter.MAX_SIGNIFICAND_DIGITS : significandDigits, orderDigits,
                        significandAll, orderDigits > 0, isExpForm, significandSign, orderSign
                    );
                } else
                {
                    long number = dataNumeric.asLong();
                    formatted = leadZeroOutput ? Long.toLeadZeroString(number, leadZeroWidth) : Long.toString(number);
                    if(significandSign && number >= 0) formatted = "+" + formatted;
                }
            }
            int formattedWidth = formatted.length;
            if(fieldWidth > formattedWidth) for(int count = fieldWidth - formattedWidth; count-- > 0; ) result + ' ';
            endIndex = formIndex + 1;
            result + formatted;
        }
        return (result + form.substring(beginIndex)).toString();
    }

    public static String decode(ByteArray src, String charsetName) throws UnsupportedCharsetNameException {
        char[] chars = Charset.get(charsetName).decode(src);
        return new String(0, chars.length, chars);
    }

    public static String decode(ByteArray src, int offset, int length, String charsetName) throws UnsupportedCharsetNameException {
        char[] chars = Charset.get(charsetName).decode(src, offset, length);
        return new String(0, chars.length, chars);
    }

    package static void initialize() {
        int length = getConstantCount();
        created = new byte[length + 7 >> 3];
        constants = new String[length];
        empty = new String();
        poolOperation = Runtime.getInstance().newMutex();
        (poolTable = new HashValueTable()).append(empty.hashCodeAsLong2(), empty);
    }

    package static void clean() {
        if(poolTable != null)
        {
            boolean cleaning = true;
            Mutex operation = poolOperation;
            RemoveWeakValueState state = new RemoveWeakValueState();
            do
            {
                operation.lock();
                try
                {
                    for(int count = 0x0400; count-- > 0; ) if(!poolTable.removeWeakValue(state))
                    {
                        cleaning = false;
                        break;
                    }
                } finally
                {
                    operation.unlock();
                }
            } while(cleaning);
        }
    }

    package static String getConstant(int index) {
        if(index < 0 || index >= constants.length)
        {
            return null;
        }
        String result;
        if(isConstantCreated(index))
        {
            while((result = constants[index]) == null) Thread.yield();
        } else
        {
            int length = getConstantLength(index);
            try
            {
                result = length <= 0 ? empty : (new String(0, length, (char[]) char[].class.newArrayAt(getConstantPointer(index), length))).intern();
            }
            catch(Throwable exception)
            {
                result = empty;
            }
            constants[index] = result;
        }
        if(result.fldLength <= 0 && getConstantLength(index) > 0)
        {
            Runtime.getInstance().throwOutOfMemoryError();
        }
        return result;
    }

    private static native boolean isConstantCreated(int index);

    private static native int getConstantCount();

    private static native int getConstantLength(int index);

    private static native long getConstantPointer(int index);

    private boolean fldIsHashAsInt032Computed;
    private boolean fldIsHashAsInt064Computed;
    private boolean fldIsHashAsInt128Computed;
    private int fldHashAsInt032;
    private long fldHashAsInt064;
    private long2 fldHashAsInt128;
    private final int fldOffset;
    private final int fldLength;
    private final char[] fldChars;

    public () {  }

    public (char src) {
        fldLength = 1;
        fldChars = new char[] { src };
    }

    public (CharArray src) {
        if(src == null) return;
        int length = fldLength = src.length;
        if(length <= 0) return;
        if(src instanceof StringBuilder)
        {
            src = ((StringBuilder) src).fldContent;
        }
        if(src instanceof char[])
        {
            Array.copy((char[]) src, 0, fldChars = new char[length], 0, length);
        }
        else if(!(src instanceof String))
        {
            char[] chars = fldChars = new char[length];
            for(int chi = 0; chi < length; chi++) chars[chi] = src[chi];
        }
        else
        {
            String anot = (String) src;
            fldOffset = anot.fldOffset;
            fldChars = anot.fldChars;
        }
    }

    public (CharArray src, int offset, int length) {
        if(src == null) return;
        int2 bounds = Array.intersectBounds(src, offset, length);
        if((length = fldLength = bounds[1]) <= 0) return;
        if(src instanceof StringBuilder)
        {
            src = ((StringBuilder) src).fldContent;
        }
        if(src instanceof char[])
        {
            Array.copy((char[]) src, bounds[0], fldChars = new char[length], 0, length);
        }
        else if(!(src instanceof String))
        {
            char[] chars = fldChars = new char[length];
            for(int chi = 0, int chj = bounds[0]; chi < length; chi++, chj++) chars[chi] = src[chj];
        }
        else
        {
            String anot = (String) src;
            fldOffset = anot.fldOffset + bounds[0];
            fldChars = anot.fldChars;
        }
    }

    public (ByteArray src) {
        if(src == null) return;
        fldLength = (fldChars = Charset.getDefault().decode(src)).length;
    }

    public (ByteArray src, int offset, int length) {
        if(src == null) return;
        int2 bounds = Array.intersectBounds(src, offset, length);
        fldLength = (fldChars = Charset.getDefault().decode(src, bounds[0], bounds[1])).length;
    }

    public (ByteArray src, Charset charset) {
        if(src == null) return;
        fldLength = (fldChars = (charset != null ? charset : Charset.getDefault()).decode(src)).length;
    }

    public (ByteArray src, int offset, int length, Charset charset) {
        if(src == null) return;
        int2 bounds = Array.intersectBounds(src, offset, length);
        fldLength = (fldChars = (charset != null ? charset : Charset.getDefault()).decode(src, bounds[0], bounds[1])).length;
    }

    private (int offset, int length, char[] chars) {
        fldOffset = offset;
        fldLength = length;
        fldChars = chars;
    }

    public boolean equals(Object anot) {
        if(anot == this) return true;
        if(anot instanceof String)
        {
            int thisLength = fldLength;
            String astr = (String) anot;
            if(thisLength == astr.fldLength)
            {
                int thisOffset = this.fldOffset;
                int anotOffset = astr.fldOffset;
                char[] thisChars = this.fldChars;
                char[] anotChars = astr.fldChars;
                if(thisChars == anotChars && thisOffset == anotOffset || thisLength <= 0 || Array.offsetOfNonEqual(thisChars, thisOffset, anotChars, anotOffset, thisLength) == INDEFINITE) return true;
            }
        }
        return false;
    }

    public int hashCode() {
        if(fldIsHashAsInt032Computed) return fldHashAsInt032;
        int result = 0i;
        for(char[] chars = fldChars, int offset = fldOffset, int length = fldLength, int mult = 1; length-- > 0; mult *= 31)
        {
            result += mult * (int) chars[offset++];
        }
        fldHashAsInt032 = result;
        fldIsHashAsInt032Computed = true;
        return result;
    }

    public long hashCodeAsLong() {
        if(fldIsHashAsInt064Computed) return fldHashAsInt064;
        long result = 0L;
        for(char[] chars = fldChars, int offset = fldOffset, int length = fldLength, long mult = 1; length-- > 0; mult *= 31)
        {
            result += mult * (long) chars[offset++];
        }
        fldHashAsInt064 = result;
        fldIsHashAsInt064Computed = true;
        return result;
    }

    public long2 hashCodeAsLong2() {
        if(fldIsHashAsInt128Computed) return fldHashAsInt128;
        long2 result = 0L;
        for(char[] chars = fldChars, int offset = fldOffset, int length = fldLength, long2 mult = 1; length-- > 0; mult = Int128.mul(mult, 31))
        {
            result = Int128.add(result, Int128.mul(mult, (long2) chars[offset++]));
        }
        fldHashAsInt128 = result;
        fldIsHashAsInt128Computed = true;
        return result;
    }

    public String toString() { return this; }

    public void getChars(int beginIndex, int endIndex, MutableCharArray dst, int offset) {
        int length = fldLength;
        if((beginIndex | endIndex) < 0 || beginIndex > length || endIndex > length || beginIndex > endIndex)
        {
            throw new StringIndexOutOfBoundsException(package.getResourceString("out-of-bounds.string-index"));
        }
        if(dst == null)
        {
            throw new NullPointerException(String.format(package.getResourceString("null-pointer.argument"), new Object[] { "dst" }));
        }
        Array.checkBounds(dst, offset, length = endIndex - beginIndex);
        if(dst instanceof StringBuilder)
        {
            dst = ((StringBuilder) dst).fldContent;
        }
        if(dst instanceof char[])
        {
            Array.copy(fldChars, fldOffset + beginIndex, (char[]) dst, offset, length);
            return;
        }
        for(char[] chars = fldChars, beginIndex += fldOffset; length-- > 0; ) dst[offset++] = chars[beginIndex++];
    }

    public char[] toCharArray() {
        int length = fldLength;
        char[] result = new char[length];
        Array.copy(fldChars, fldOffset, result, 0, length);
        return result;
    }

    public String join(CharSequence anot) {
        if(anot == null) return this;
        int anotLength = anot.length;
        if(anotLength <= 0) return this;
        int thisLength = fldLength;
        int resultLength = anotLength + thisLength;
        if(resultLength < 0)
        {
            throw new BufferTooLargeError(package.getResourceString("!error.buffer-too-large"));
        }
        char[] resultChars = new char[resultLength];
        Array.copy(fldChars, fldOffset, resultChars, 0, thisLength);
        anot.getChars(0, anotLength, resultChars, thisLength);
        return new String(resultChars, 0, resultLength);
    }

    public String join(CharSequence[] seqs) {
        if(seqs == null) return this;
        int seqsLength = seqs.length;
        if(seqsLength <= 0) return this;
        int thisLength = fldLength;
        int resultLength = thisLength;
        int[] seqsLengths = new int[seqsLength];
        CharSequence[] seqsCopy = new CharSequence[seqsLength];
        for(int index = 0; index < seqsLength; index++)
        {
            Measureable seq = seqsCopy[index] = seqs[index];
            int anotLength = seq == null ? 0 : seq.length;
            if(anotLength < 0) anotLength = 0;
            if((resultLength += anotLength) < 0)
            {
                throw new BufferTooLargeError(package.getResourceString("!error.buffer-too-large"));
            }
            seqsLengths[index] = anotLength;
        }
        char[] resultChars = new char[resultLength];
        Array.copy(fldChars, fldOffset, resultChars, 0, thisLength);
        for(int resultPosition = thisLength, int index = 0; index < seqsLength; index++)
        {
            int anotLength = seqsLengths[index];
            if(anotLength > 0)
            {
                seqsCopy[index].getChars(0, anotLength, resultChars, resultPosition);
                resultPosition += anotLength;
            }
        }
        return new String(resultChars, 0, resultLength);
    }

    public String subsequence(int beginIndex) {
        int length = fldLength;
        if(beginIndex < 0 || beginIndex > length)
        {
            throw new StringIndexOutOfBoundsException(package.getResourceString("out-of-bounds.string-index"));
        }
        return beginIndex == length ? "" : beginIndex == 0 ? this : new String(fldOffset + beginIndex, length - beginIndex, fldChars);
    }

    public String subsequence(int beginIndex, int endIndex) {
        int length = fldLength;
        if((beginIndex | endIndex) < 0 || beginIndex > length || endIndex > length || beginIndex > endIndex)
        {
            throw new StringIndexOutOfBoundsException(package.getResourceString("out-of-bounds.string-index"));
        }
        return beginIndex == endIndex ? "" : beginIndex == endIndex - length ? this : new String(fldOffset + beginIndex, endIndex - beginIndex, fldChars);
    }

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

    public int compareTo(Comparable anot) {
        if(anot == this) return EQUALS;
        if(anot instanceof String)
        {
            String astr = (String) anot;
            int thisLength = fldLength;
            int anotLength = astr.fldLength;
            if(anotLength <= 0) return thisLength;
            if(thisLength <= 0) return -anotLength;
            int thisOffset = fldOffset;
            int anotOffset = astr.fldOffset;
            char[] thisChars = fldChars;
            char[] anotChars = astr.fldChars;
            int nonEqualOffset = Array.offsetOfNonEqual(thisChars, thisOffset, anotChars, anotOffset, thisLength < anotLength ? thisLength : anotLength);
            return nonEqualOffset < 0 ? thisLength - anotLength : thisChars[thisOffset + nonEqualOffset] - anotChars[anotOffset + nonEqualOffset];
        }
        return INDEFINITE;
    }

    public String clone() { return new String(fldOffset, fldLength, fldChars); }

    public boolean contentEquals(CharArray array) {
        int thisLength = fldLength;
        if(array == null || array.length < thisLength)
        {
            return false;
        }
        if(thisLength <= 0)
        {
            return true;
        }
        if(array instanceof StringBuilder)
        {
            array = ((StringBuilder) array).fldContent;
        }
        if(array instanceof char[])
        {
            return Array.offsetOfNonEqual(fldChars, fldOffset, (char[]) array, 0, thisLength) == INDEFINITE;
        }
        if(array instanceof String)
        {
            String anot = (String) array;
            return Array.offsetOfNonEqual(fldChars, fldOffset, anot.fldChars, anot.fldOffset, thisLength) == INDEFINITE;
        }
        for(char[] thisChars = fldChars, int thisOffset = fldOffset, int offset = 0; thisLength-- > 0; ) if(thisChars[thisOffset++] != array[offset++])
        {
            return false;
        }
        return true;
    }

    public boolean contentEquals(CharArray array, int offset) {
        int thisLength = fldLength;
        if(array == null || offset < 0 || offset > array.length - thisLength)
        {
            return false;
        }
        if(thisLength <= 0)
        {
            return true;
        }
        if(array instanceof StringBuilder)
        {
            array = ((StringBuilder) array).fldContent;
        }
        if(array instanceof char[])
        {
            return Array.offsetOfNonEqual(fldChars, fldOffset, (char[]) array, offset, thisLength) == INDEFINITE;
        }
        if(array instanceof String)
        {
            String anot = (String) array;
            return Array.offsetOfNonEqual(fldChars, fldOffset, anot.fldChars, anot.fldOffset + offset, thisLength) == INDEFINITE;
        }
        for(char[] thisChars = fldChars, int thisOffset = fldOffset; thisLength-- > 0; ) if(thisChars[thisOffset++] != array[offset++])
        {
            return false;
        }
        return true;
    }

    public boolean contains(CharArray array) {
        if(array == null) return false;
        int length = array.length;
        if(length <= 0) return true;
        int thisOffset = fldOffset;
        int thisLimit = thisOffset + fldLength - --length;
        if(thisOffset >= thisLimit) return false;
        char[] thisChars = fldChars;
        if(array instanceof StringBuilder)
        {
            array = ((StringBuilder) array).fldContent;
        }
        if(array instanceof char[])
        {
            char[] astr = (char[]) array;
            char first = astr[0];
            while((thisOffset = Array.indexOf(first, thisChars, thisOffset, thisLimit - thisOffset) + 1) > 0)
            {
                if(length <= 0 || Array.offsetOfNonEqual(thisChars, thisOffset, astr, 1, length) == INDEFINITE) return true;
                if(thisOffset >= thisLimit) break;
            }
        }
        else if(array instanceof String)
        {
            String astr = (String) array;
            int anotOffset = astr.fldOffset;
            char[] anotChars = astr.fldChars;
            char first = anotChars[anotOffset++];
            while((thisOffset = Array.indexOf(first, thisChars, thisOffset, thisLimit - thisOffset) + 1) > 0)
            {
                if(length <= 0 || Array.offsetOfNonEqual(thisChars, thisOffset, anotChars, anotOffset, length) == INDEFINITE) return true;
                if(thisOffset >= thisLimit) break;
            }
        }
        else
        {
            char first = array[0];
            while((thisOffset = Array.indexOf(first, thisChars, thisOffset, thisLimit - thisOffset) + 1) > 0)
            {
                label0:
                {
                    for(int chi = thisOffset, int chj = 0; chj < length; ) if(thisChars[chi++] != array[++chj]) break label0;
                    return true;
                }
                if(thisOffset >= thisLimit) break;
            }
        }
        return false;
    }

    public boolean contains(CharArray array, int offset, int length) {
        if(array == null) return false;
        int2 bounds = Array.intersectBounds(array, offset, length);
        if((length = bounds[1]) <= 0) return true;
        int thisOffset = fldOffset;
        int thisLimit = thisOffset + fldLength - --length;
        if(thisOffset >= thisLimit) return false;
        char[] thisChars = fldChars;
        offset = bounds[0];
        if(array instanceof StringBuilder)
        {
            array = ((StringBuilder) array).fldContent;
        }
        if(array instanceof char[])
        {
            char[] astr = (char[]) array;
            char first = astr[offset++];
            while((thisOffset = Array.indexOf(first, thisChars, thisOffset, thisLimit - thisOffset) + 1) > 0)
            {
                if(length <= 0 || Array.offsetOfNonEqual(thisChars, thisOffset, astr, offset, length) == INDEFINITE) return true;
                if(thisOffset >= thisLimit) break;
            }
        }
        else if(array instanceof String)
        {
            String astr = (String) array;
            int anotOffset = astr.fldOffset + offset;
            char[] anotChars = astr.fldChars;
            char first = anotChars[anotOffset++];
            while((thisOffset = Array.indexOf(first, thisChars, thisOffset, thisLimit - thisOffset) + 1) > 0)
            {
                if(length <= 0 || Array.offsetOfNonEqual(thisChars, thisOffset, anotChars, anotOffset, length) == INDEFINITE) return true;
                if(thisOffset >= thisLimit) break;
            }
        }
        else
        {
            char first = array[offset];
            while((thisOffset = Array.indexOf(first, thisChars, thisOffset, thisLimit - thisOffset) + 1) > 0)
            {
                label0:
                {
                    for(int chi = thisOffset, int chj = offset, int count = length; count-- > 0; ) if(thisChars[chi++] != array[++chj]) break label0;
                    return true;
                }
                if(thisOffset >= thisLimit) break;
            }
        }
        return false;
    }

    public boolean equalsIgnoreCase(String anot) {
        int thisLength = fldLength;
        return anot != null && thisLength == anot.fldLength && regionMatches(0, anot, 0, thisLength, true);
    }

    public boolean regionMatches(int thisOffset, String anot, int anotOffset, int length) {
        if(anot == null)
        {
            return false;
        }
        int lim = thisOffset + length;
        int len = fldLength;
        if(lim > len || lim < thisOffset || thisOffset > len || thisOffset < 0 || (lim = anotOffset + length) > (len = anot.fldLength) || lim < anotOffset || anotOffset > len || anotOffset < 0)
        {
            return false;
        }
        return length <= 0 || Array.offsetOfNonEqual(fldChars, fldOffset + thisOffset, anot.fldChars, anot.fldOffset + anotOffset, length) == INDEFINITE;
    }

    public boolean regionMatches(int thisOffset, String anot, int anotOffset, int length, boolean isIgnoreCase) {
        if(anot == null)
        {
            return false;
        }
        int lim = thisOffset + length;
        int len = fldLength;
        if(lim > len || lim < thisOffset || thisOffset > len || thisOffset < 0 || (lim = anotOffset + length) > (len = anot.fldLength) || lim < anotOffset || anotOffset > len || anotOffset < 0)
        {
            return false;
        }
        thisOffset += fldOffset;
        anotOffset += anot.fldOffset;
        char[] thisChars = fldChars;
        char[] anotChars = anot.fldChars;
        char thisChar;
        char anotChar;
        int nonEqualOffset;
        do
        {
            if(length <= 0 || (nonEqualOffset = Array.offsetOfNonEqual(thisChars, thisOffset, anotChars, anotOffset, length)) == INDEFINITE) return true;
            thisOffset += nonEqualOffset;
            anotOffset += nonEqualOffset;
            thisChar = thisChars[thisOffset++];
            anotChar = anotChars[anotOffset++];
            length -= 1 + nonEqualOffset;
        } while(isIgnoreCase && (Char.toUpperCase(thisChar) == Char.toUpperCase(anotChar) || Char.toLowerCase(thisChar) == Char.toLowerCase(anotChar)));
        return false;
    }

    public boolean endsWith(String suffix) {
        if(suffix == null)
        {
            throw new NullPointerException(String.format(package.getResourceString("null-pointer.argument"), new Object[] { "suffix" }));
        }
        int anotLength = suffix.fldLength;
        int offset = fldLength - anotLength;
        if(offset < 0) return false;
        return anotLength <= 0 || Array.offsetOfNonEqual(fldChars, fldOffset + offset, suffix.fldChars, suffix.fldOffset, anotLength) == INDEFINITE;
    }

    public boolean startsWith(String prefix) {
        if(prefix == null)
        {
            throw new NullPointerException(String.format(package.getResourceString("null-pointer.argument"), new Object[] { "prefix" }));
        }
        int anotLength = prefix.fldLength;
        if(fldLength < anotLength) return false;
        return anotLength <= 0 || Array.offsetOfNonEqual(fldChars, fldOffset, prefix.fldChars, prefix.fldOffset, anotLength) == INDEFINITE;
    }

    public boolean startsWith(String prefix, int offset) {
        if(prefix == null)
        {
            throw new NullPointerException(String.format(package.getResourceString("null-pointer.argument"), new Object[] { "prefix" }));
        }
        int anotLength = prefix.fldLength;
        if(offset < 0 || offset > fldLength - anotLength) return false;
        return anotLength <= 0 || Array.offsetOfNonEqual(fldChars, fldOffset + offset, prefix.fldChars, prefix.fldOffset, anotLength) == INDEFINITE;
    }

    public int indexOf(int character) {
        if(character < 0 || character > 0xffff) return -1;
        int length = fldLength;
        if(length <= 0) return -1;
        int offset = fldOffset;
        int index = Array.indexOf(character, fldChars, offset, length);
        return index < 0 ? -1 : index - offset;
    }

    public int indexOf(int character, int startFromIndex) {
        if(character < 0 || character > 0xffff) return -1;
        int length = fldLength;
        if(startFromIndex < 0) startFromIndex = 0;
        if(startFromIndex >= length) return -1;
        int offset = fldOffset;
        int index = Array.indexOf(character, fldChars, offset + startFromIndex, length - startFromIndex);
        return index < 0 ? -1 : index - offset;
    }

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

    public int indexOf(String string, int startFromIndex) {
        if(string == null)
        {
            throw new NullPointerException(String.format(package.getResourceString("null-pointer.argument"), new Object[] { "string" }));
        }
        int anotLength = string.fldLength;
        int thisLength = fldLength - anotLength;
        if(startFromIndex < 0) startFromIndex = 0;
        if(startFromIndex > thisLength++) return -1;
        if(anotLength-- <= 0) return startFromIndex;
        int anotOffset = string.fldOffset;
        int thisOffset = fldOffset;
        char[] anotChars = string.fldChars;
        char[] thisChars = fldChars;
        char first = anotChars[anotOffset++];
        do
        {
            int thisIndex = Array.indexOf(first, thisChars, thisOffset + startFromIndex, thisLength - startFromIndex);
            if(thisIndex < 0) break;
            startFromIndex = thisIndex++ - thisOffset;
            if(anotLength <= 0 || Array.offsetOfNonEqual(thisChars, thisIndex, anotChars, anotOffset, anotLength) == INDEFINITE) return startFromIndex;
        } while(++startFromIndex < thisLength);
        return -1;
    }

    public int indexOfNon(int character) {
        int length = fldLength;
        if(length <= 0) return -1;
        if(character < 0 || character > 0xffff) return 0;
        int offset = fldOffset;
        int index = Array.indexOfNon(character, fldChars, offset, length);
        return index < 0 ? -1 : index - offset;
    }

    public int indexOfNon(int character, int startFromIndex) {
        int length = fldLength;
        if(startFromIndex < 0) startFromIndex = 0;
        if(startFromIndex >= length) return -1;
        if(character < 0 || character > 0xffff) return startFromIndex;
        int offset = fldOffset;
        int index = Array.indexOfNon(character, fldChars, offset + startFromIndex, length - startFromIndex);
        return index < 0 ? -1 : index - offset;
    }

    public int lastIndexOf(int character) {
        if(character < 0 || character > 0xffff) return -1;
        int length = fldLength;
        if(length <= 0) return -1;
        int offset = fldOffset;
        int index = Array.lastIndexOf(character, fldChars, offset + length - 1, length);
        return index < 0 ? -1 : index - offset;
    }

    public int lastIndexOf(int character, int startFromIndex) {
        if(character < 0 || character > 0xffff) return -1;
        int length = fldLength;
        if(startFromIndex >= length) startFromIndex = length - 1;
        if(startFromIndex < 0) return -1;
        int offset = fldOffset;
        int index = Array.lastIndexOf(character, fldChars, offset + startFromIndex, startFromIndex + 1);
        return index < 0 ? -1 : index - offset;
    }

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

    public int lastIndexOf(String string, int startFromIndex) {
        if(string == null)
        {
            throw new NullPointerException(String.format(package.getResourceString("null-pointer.argument"), new Object[] { "string" }));
        }
        int anotLength = string.fldLength;
        int thisLength = fldLength - anotLength;
        if(startFromIndex > thisLength++) startFromIndex = thisLength - 1;
        if(startFromIndex < 0) return -1;
        if(anotLength-- <= 0) return startFromIndex;
        int anotOffset = string.fldOffset;
        int thisOffset = fldOffset;
        char[] anotChars = string.fldChars;
        char[] thisChars = fldChars;
        char first = anotChars[anotOffset++];
        do
        {
            int thisIndex = Array.lastIndexOf(first, thisChars, thisOffset + startFromIndex, startFromIndex + 1);
            if(thisIndex < 0) break;
            startFromIndex = thisIndex++ - thisOffset;
            if(anotLength <= 0 || Array.offsetOfNonEqual(thisChars, thisIndex, anotChars, anotOffset, anotLength) == INDEFINITE) return startFromIndex;
        } while(--startFromIndex >= 0);
        return -1;
    }

    public int lastIndexOfNon(int character) {
        int length = fldLength;
        if(length <= 0) return -1;
        if(character < 0 || character > 0xffff) return length - 1;
        int offset = fldOffset;
        int index = Array.lastIndexOfNon(character, fldChars, offset + length - 1, length);
        return index < 0 ? -1 : index - offset;
    }

    public int lastIndexOfNon(int character, int startFromIndex) {
        int length = fldLength;
        if(startFromIndex >= length) startFromIndex = length - 1;
        if(startFromIndex < 0) return -1;
        if(character < 0 || character > 0xffff) return -1;
        int offset = fldOffset;
        int index = Array.lastIndexOfNon(character, fldChars, offset + startFromIndex, startFromIndex + 1);
        return index < 0 ? -1 : index - offset;
    }

    public int compareToIgnoreCase(String anot) {
        if(anot == this) return EQUALS;
        if(anot != null)
        {
            int thisLength = fldLength;
            int anotLength = anot.fldLength;
            if(anotLength <= 0) return thisLength;
            if(thisLength <= 0) return -anotLength;
            int thisOffset = fldOffset;
            int anotOffset = anot.fldOffset;
            char[] thisChars = fldChars;
            char[] anotChars = anot.fldChars;
            int nonEqualOffset = Array.offsetOfNonEqual(thisChars, thisOffset, anotChars, anotOffset, thisLength < anotLength ? thisLength : anotLength);
            return nonEqualOffset < 0 ? thisLength - anotLength : Char.compareIgnoreCase(thisChars[thisOffset + nonEqualOffset], anotChars[anotOffset + nonEqualOffset]);
        }
        return INDEFINITE;
    }

    public int compareToLexicographically(String anot) {
        if(anot == this) return EQUALS;
        if(anot != null)
        {
            int thisLength = fldLength;
            int anotLength = anot.fldLength;
            if(anotLength <= 0) return thisLength;
            if(thisLength <= 0) return -anotLength;
            int thisOffset = fldOffset;
            int anotOffset = anot.fldOffset;
            char[] thisChars = fldChars;
            char[] anotChars = anot.fldChars;
            int nonEqualOffset = Array.offsetOfNonEqual(thisChars, thisOffset, anotChars, anotOffset, thisLength < anotLength ? thisLength : anotLength);
            return nonEqualOffset < 0 ? thisLength - anotLength : Char.compareLexicographically(thisChars[thisOffset + nonEqualOffset], anotChars[anotOffset + nonEqualOffset]);
        }
        return INDEFINITE;
    }

    public byte[] toByteArray() {
        int length = fldLength;
        return length <= 0 ? new byte[0] : Charset.getDefault().encode(fldChars, fldOffset, length);
    }

    public byte[] toByteArray(Charset charset) {
        int length = fldLength;
        return length <= 0 ? new byte[0] : (charset != null ? charset : Charset.getDefault()).encode(fldChars, fldOffset, length);
    }

    public byte[] toByteArray(String charsetName) throws UnsupportedCharsetNameException {
        Charset charset = Charset.get(charsetName);
        int length = fldLength;
        return length <= 0 ? new byte[0] : charset.encode(fldChars, fldOffset, length);
    }

    public String[] split() {
        int boundsLength = 0;
        int2[] boundsData = new int2[0x0fi];
        int thisLength = fldLength;
        char[] thisChars = fldChars;
        for(int beginIndex = fldOffset, int thisLimit = beginIndex + thisLength; beginIndex <= thisLimit; )
        {
            int endIndex0 = beginIndex >= thisLimit ? beginIndex : Array.indexOf('\n', thisChars, beginIndex, thisLimit - beginIndex);
            int endIndex1 = beginIndex >= thisLimit ? beginIndex : Array.indexOf('\r', thisChars, beginIndex, thisLimit - beginIndex);
            if(endIndex0 < 0) endIndex0 = thisLimit;
            if(endIndex1 < 0) endIndex1 = thisLimit;
            int endIndex = endIndex0 < endIndex1 ? endIndex0 : endIndex1;
            if(boundsLength == boundsData.length)
            {
                Array.copy(boundsData, 0, boundsData = new int2[boundsLength << 1 | 1], 0, boundsLength);
            }
            boundsData[boundsLength++] = new int2 { beginIndex, endIndex - beginIndex };
            beginIndex = endIndex + 1;
            if(beginIndex < thisLimit && thisChars[endIndex] == '\r' && thisChars[beginIndex] == '\n') beginIndex++;
        }
        String[] result = new String[boundsLength];
        while(boundsLength-- > 0)
        {
            int2 substringBounds = boundsData[boundsLength];
            int substringLength = substringBounds[1];
            result[boundsLength] = substringLength <= 0 ? "" : substringLength == thisLength ? this : new String(substringBounds[0], substringLength, thisChars);
        }
        return result;
    }

    public String trim() {
        int beginIndex = fldOffset;
        int endIndex = beginIndex + fldLength - 1;
        int chi = beginIndex;
        int chj = endIndex;
        char[] chars = fldChars;
        while(chi <= chj && chars[chi] <= '\u0020') chi++;
        while(chi <= chj && chars[chj] <= '\u0020') chj--;
        return chi > chj ? "" : chi == beginIndex && chj == endIndex ? this : new String(chi, chj - chi + 1, chars);
    }

    public String intern() {
        boolean multiThreaded = Runtime.getInstance().multiThreaded;
        long2 hash = hashCodeAsLong2();
        Mutex operation = poolOperation;
        if(multiThreaded) operation.lock();
        try
        {
            String canonical = (String) poolTable.get(hash, this);
            if(canonical != null) return canonical;
            poolTable.append(hash, this);
        } finally
        {
            if(multiThreaded) operation.unlock();
        }
        return this;
    }

    public String toLowerCase() {
        int thisOffset = fldOffset;
        int thisLength = fldLength;
        char[] thisChars = fldChars;
        int chi = thisOffset;
        label0:
        {
            for(int thisLimit = thisOffset + thisLength; chi < thisLimit; chi++)
            {
                char character = thisChars[chi];
                if(character != Char.toLowerCase(character)) break label0;
            }
            return this;
        }
        char[] resultChars = new char[thisLength];
        for(int chj = chi - thisOffset, Array.copy(thisChars, thisOffset, resultChars, 0, chj); chj < thisLength; chi++, chj++)
        {
            resultChars[chj] = Char.toLowerCase(thisChars[chi]);
        }
        return new String(0, thisLength, resultChars);
    }

    public String toUpperCase() {
        int thisOffset = fldOffset;
        int thisLength = fldLength;
        char[] thisChars = fldChars;
        int chi = thisOffset;
        label0:
        {
            for(int thisLimit = thisOffset + thisLength; chi < thisLimit; chi++)
            {
                char character = thisChars[chi];
                if(character != Char.toUpperCase(character)) break label0;
            }
            return this;
        }
        char[] resultChars = new char[thisLength];
        for(int chj = chi - thisOffset, Array.copy(thisChars, thisOffset, resultChars, 0, chj); chj < thisLength; chi++, chj++)
        {
            resultChars[chj] = Char.toUpperCase(thisChars[chi]);
        }
        return new String(0, thisLength, resultChars);
    }

    public native String substring(int beginIndex);

    public native String substring(int beginIndex, int endIndex);

    public String replaceAll(char oldCharacter, char newCharacter) {
        int thisLength = fldLength;
        if(thisLength <= 0 || oldCharacter == newCharacter) return this;
        int thisOffset = fldOffset;
        char[] thisChars = fldChars;
        int chi = Array.indexOf(oldCharacter, thisChars, thisOffset, thisLength);
        if(chi < 0) return this;
        char[] resultChars = new char[thisLength];
        for(int chj = chi - thisOffset, Array.copy(thisChars, thisOffset, resultChars, 0, chj); chj < thisLength; chi++, chj++)
        {
            char character = thisChars[chi];
            resultChars[chj] = character != oldCharacter ? character : newCharacter;
        }
        return new String(0, thisLength, resultChars);
    }

    public String replaceAll(String oldString, String newString) {
        if(oldString == null)
        {
            throw new NullPointerException(String.format(package.getResourceString("null-pointer.argument"), new Object[] { "oldString" }));
        }
        if(newString == null)
        {
            throw new NullPointerException(String.format(package.getResourceString("null-pointer.argument"), new Object[] { "newString" }));
        }
        int thisLength = fldLength;
        int oldLength = oldString.fldLength;
        if(thisLength <= 0 || oldLength <= 0 || oldString.equals(newString)) return this;
        int indexLength = 0;
        int[] indexData = new int[0x1fi];
        for(int thisIndex = 0; (thisIndex = indexOf(oldString, thisIndex)) >= 0; thisIndex += oldLength)
        {
            if(indexLength == indexData.length)
            {
                Array.copy(indexData, 0, indexData = new int[indexLength << 1 | 1], 0, indexLength);
            }
            indexData[indexLength++] = thisIndex;
        }
        if(indexLength <= 0) return this;
        int newLength = newString.fldLength;
        long longResultLength = (long) thisLength + (long) indexLength * (long) (newLength - oldLength);
        if(longResultLength > (long) Int.MAX_VALUE || longResultLength < 0L)
        {
            throw new BufferTooLargeError(package.getResourceString("!error.buffer-too-large"));
        }
        int newOffset = newString.fldOffset;
        char[] newChars = newString.fldChars;
        int thisEnd = thisLength;
        int thisOffset = fldOffset;
        char[] thisChars = fldChars;
        int resultEnd = (int) longResultLength;
        int resultLength = resultEnd;
        char[] resultChars = new char[resultLength];
        while(indexLength-- > 0)
        {
            int thisBegin = indexData[indexLength] + oldLength;
            int copyLength = thisEnd - thisBegin;
            int resultBegin = resultEnd - copyLength;
            thisEnd = thisBegin - oldLength;
            Array.copy(thisChars, thisOffset + thisBegin, resultChars, resultBegin, copyLength);
            Array.copy(newChars, newOffset, resultChars, resultEnd = resultBegin - newLength, newLength);
        }
        Array.copy(thisChars, thisOffset, resultChars, 0, thisEnd);
        return new String(0, resultLength, resultChars);
    }

    public String replaceFirst(char oldCharacter, char newCharacter) { return replaceFirst(oldCharacter, newCharacter, 0); }

    public String replaceFirst(char oldCharacter, char newCharacter, int startFromIndex) {
        int thisLength = fldLength;
        if(thisLength <= 0 || oldCharacter == newCharacter) return this;
        if(startFromIndex < 0) startFromIndex = 0;
        if(startFromIndex >= thisLength) return this;
        int thisOffset = fldOffset;
        char[] thisChars = fldChars;
        int thisIndex = Array.indexOf(oldCharacter, thisChars, thisOffset + startFromIndex, thisLength - startFromIndex);
        if(thisIndex < 0) return this;
        char[] resultChars = new char[thisLength];
        Array.copy(thisChars, thisOffset, resultChars, 0, thisLength);
        resultChars[thisIndex - thisOffset] = newCharacter;
        return new String(0, thisLength, resultChars);
    }

    public String replaceFirst(String oldString, String newString) { return replaceFirst(oldString, newString, 0); }

    public String replaceFirst(String oldString, String newString, int startFromIndex) {
        if(oldString == null)
        {
            throw new NullPointerException(String.format(package.getResourceString("null-pointer.argument"), new Object[] { "oldString" }));
        }
        if(newString == null)
        {
            throw new NullPointerException(String.format(package.getResourceString("null-pointer.argument"), new Object[] { "newString" }));
        }
        int thisLength = fldLength;
        int oldLength = oldString.fldLength;
        if(thisLength <= 0 || oldLength <= 0 || oldString.equals(newString)) return this;
        int thisIndex = indexOf(oldString, startFromIndex);
        if(thisIndex < 0) return this;
        int newLength = newString.fldLength;
        int resultLength = thisLength + (newLength - oldLength);
        if(resultLength < 0)
        {
            throw new BufferTooLargeError(package.getResourceString("!error.buffer-too-large"));
        }
        int thisOffset = fldOffset;
        char[] thisChars = fldChars;
        char[] resultChars = new char[resultLength];
        Array.copy(thisChars, thisOffset, resultChars, 0, thisIndex);
        Array.copy(newString.fldChars, newString.fldOffset, resultChars, thisIndex, newLength);
        Array.copy(thisChars, thisOffset + thisIndex + oldLength, resultChars, thisIndex += newLength, resultLength - thisIndex);
        return new String(0, resultLength, resultChars);
    }

    public String replaceLast(char oldCharacter, char newCharacter) { return replaceLast(oldCharacter, newCharacter, Int.MAX_VALUE); }

    public String replaceLast(char oldCharacter, char newCharacter, int startFromIndex) {
        int thisLength = fldLength;
        if(thisLength <= 0 || oldCharacter == newCharacter) return this;
        if(startFromIndex >= thisLength) startFromIndex = thisLength - 1;
        if(startFromIndex < 0) return this;
        int thisOffset = fldOffset;
        char[] thisChars = fldChars;
        int thisIndex = Array.lastIndexOf(oldCharacter, thisChars, thisOffset + startFromIndex, startFromIndex + 1);
        if(thisIndex < 0) return this;
        char[] resultChars = new char[thisLength];
        Array.copy(thisChars, thisOffset, resultChars, 0, thisLength);
        resultChars[thisIndex - thisOffset] = newCharacter;
        return new String(0, thisLength, resultChars);
    }

    public String replaceLast(String oldString, String newString) { return replaceLast(oldString, newString, Int.MAX_VALUE); }

    public String replaceLast(String oldString, String newString, int startFromIndex) {
        if(oldString == null)
        {
            throw new NullPointerException(String.format(package.getResourceString("null-pointer.argument"), new Object[] { "oldString" }));
        }
        if(newString == null)
        {
            throw new NullPointerException(String.format(package.getResourceString("null-pointer.argument"), new Object[] { "newString" }));
        }
        int thisLength = fldLength;
        int oldLength = oldString.fldLength;
        if(thisLength <= 0 || oldLength <= 0 || oldString.equals(newString)) return this;
        int thisIndex = lastIndexOf(oldString, startFromIndex);
        if(thisIndex < 0) return this;
        int newLength = newString.fldLength;
        int resultLength = thisLength + (newLength - oldLength);
        if(resultLength < 0)
        {
            throw new BufferTooLargeError(package.getResourceString("!error.buffer-too-large"));
        }
        int thisOffset = fldOffset;
        char[] thisChars = fldChars;
        char[] resultChars = new char[resultLength];
        Array.copy(thisChars, thisOffset, resultChars, 0, thisIndex);
        Array.copy(newString.fldChars, newString.fldOffset, resultChars, thisIndex, newLength);
        Array.copy(thisChars, thisOffset + thisIndex + oldLength, resultChars, thisIndex += newLength, resultLength - thisIndex);
        return new String(0, resultLength, resultChars);
    }

    public int length { read = fldLength }

    public char operator [](int index) {
        if(index < 0 || index >= fldLength)
        {
            throw new StringIndexOutOfBoundsException(package.getResourceString("out-of-bounds.string-index"));
        }
        return fldChars[fldOffset + index];
    }

    public String operator +(char anot) {
        int thisLength = fldLength;
        if(thisLength <= 0) return new String(anot);
        int resultLength = thisLength + 1;
        if(resultLength < 0)
        {
            throw new BufferTooLargeError(package.getResourceString("!error.buffer-too-large"));
        }
        char[] resultChars = new char[resultLength];
        Array.copy(fldChars, fldOffset, resultChars, 0, thisLength);
        resultChars[thisLength] = anot;
        return new String(0, resultLength, resultChars);
    }

    public String operator +(String anot) {
        if(anot == null)
        {
            throw new NullPointerException(String.format(package.getResourceString("null-pointer.argument"), new Object[] { "anot" }));
        }
        int anotLength = anot.fldLength;
        if(anotLength <= 0) return this;
        int thisLength = fldLength;
        if(thisLength <= 0) return anot;
        int resultLength = thisLength + anotLength;
        if(resultLength < 0)
        {
            throw new BufferTooLargeError(package.getResourceString("!error.buffer-too-large"));
        }
        char[] resultChars = new char[resultLength];
        Array.copy(fldChars, fldOffset, resultChars, 0, thisLength);
        Array.copy(anot.fldChars, anot.fldOffset, resultChars, thisLength, anotLength);
        return new String(0, resultLength, resultChars);
    }

    public String operator +`(char anot) {
        int thisLength = fldLength;
        if(thisLength <= 0) return new String(anot);
        int resultLength = thisLength + 1;
        if(resultLength < 0)
        {
            throw new BufferTooLargeError(package.getResourceString("!error.buffer-too-large"));
        }
        char[] resultChars = new char[resultLength];
        resultChars[0] = anot;
        Array.copy(fldChars, fldOffset, resultChars, 1, thisLength);
        return new String(0, resultLength, resultChars);
    }
}