/*
Исходный код среды исполнения ПВТ-ОО.
Этот исходный код является частью проекта ПВТ-ОО.
Copyright © 2021 Малик Разработчик
Это свободная программа: вы можете перераспространять её и/или
изменять её на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она может быть полезна,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<http://www.gnu.org/licenses/>.
*/
package avt.lang;
import avt.io.charset.*;
import avt.lang.array.*;
import avt.math.*;
import platform.independent.streamformat.*;
/* Нужен также тип String32 c символами типа int */
public final class String(Object, CharSequence, Cloneable, DataHolder, Comparable, Measureable, CharArray)
{
private static byte[] created;
private static String[] constants;
private static String empty;
public static String valueOf(boolean src) { return src ? "true" : "false"; }
public static String valueOf(char src) { return new String(src); }
public static String valueOf(byte src) { return Byte.toString(src); }
public static String valueOf(short src) { return Short.toString(src); }
public static String valueOf(int src) { return Int.toString(src); }
public static String valueOf(long src) { return Long.toString(src); }
public static String valueOf(float src) { return Float.toString(src); }
public static String valueOf(double src) { return Double.toString(src); }
public static String valueOf(real src) { return Real.toString(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)
{
throw new NullPointerException("аргумент form равен нулевой ссылке");
}
if(data == null)
{
throw new NullPointerException("аргумент data равен нулевой ссылке");
}
StringBuilder result = new StringBuilder();
int beginIndex = 0;
label0: for(int endIndex = 0, int formLength = form.length, int dataLength = 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 expForm = false;
boolean significandAll = false;
boolean significandSign = false;
boolean orderSign = true;
int significandDigits = 1;
int orderDigits = 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 != '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];
}
significandDigits++;
if(formChar == 'A' || formChar == 'a')
{
significandAll = true;
if(++formIndex >= formLength) break label0;
formChar = form[formIndex];
}
}
if((expForm = 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 minimumLength = 0;
if(formChar == ':')
{
if(++formIndex >= formLength) break label0;
if((formChar = form[formIndex]) < '0' || formChar > '9')
{
result + form.substring(beginIndex, endIndex = formIndex + 1);
continue label0;
}
minimumLength = formChar - '0';
do
{
if(++formIndex >= formLength) break label0;
if((formChar = form[formIndex]) < '0' || formChar > '9') break;
int digit = formChar - '0';
if((minimumLength *= 10) > 1024 - digit)
{
result + form.substring(beginIndex, endIndex = formIndex + 1);
continue label0;
}
minimumLength += digit;
} while(true);
}
if(formChar != '%')
{
result + form.substring(beginIndex, endIndex = formIndex + 1);
continue label0;
}
if(dataIndex < 0 || dataIndex >= dataLength)
{
throw new ArrayIndexOutOfBoundsException("индекс элемента массива данных выходит из диапазона");
}
Object dataElement = data[dataIndex];
if(dataElement == null)
{
throw new NullPointerException("элемент массива данных равен нулевой ссылке");
}
String formatted;
if(isString)
{
formatted = dataElement.toString();
} else
{
if(!(dataElement instanceof Numeric))
{
throw new ClassCastException("элемент массива данных не является числом") { source = dataElement.getClass(), destination = Numeric.class };
}
Numeric dataNumber = (Numeric) dataElement;
if(isReal)
{
formatted = Real.toString(dataNumber.asReal(), significandDigits < 2 ? RealRepresenter.MAX_SIGNIFICAND_DIGITS : significandDigits, orderDigits, significandAll, orderDigits >= 1, expForm, significandSign, orderSign);
} else
{
long number = dataNumber.asLong();
formatted = number < 0L || !significandSign ? Long.toString(number) : "+" + Long.toString(number);
}
}
int formattedLength = formatted.length;
if(formattedLength < minimumLength) for(int i = minimumLength - formattedLength; i-- > 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 String getConstant(int index) {
if(constants == null)
{
int count = getConstantCount();
created = new byte[count + 7 >> 3];
constants = new String[count];
empty = new String();
}
String result = null;
if(index >= 0 && index < constants.length)
{
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));
}
catch(Throwable e)
{
result = empty;
}
constants[index] = result;
}
}
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 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 thisLength = fldLength = src.length;
if(thisLength <= 0) return;
if(src instanceof char[])
{
Array.copy((char[]) src, 0, fldChars = new char[thisLength], 0, thisLength);
}
else if(src instanceof String)
{
String anot = (String) src;
fldOffset = anot.fldOffset;
fldChars = anot.fldChars;
}
else
{
char[] thisChars = fldChars = new char[thisLength];
for(int i = 0; i < thisLength; i++) thisChars[i] = src[i];
}
}
public (CharArray src, int offset, int length) {
if(src == null) return;
int2 bounds = Array.intersectBounds(src, offset, length);
int thisLength = fldLength = bounds[1];
if(thisLength <= 0) return;
if(src instanceof char[])
{
Array.copy((char[]) src, bounds[0], fldChars = new char[thisLength], 0, thisLength);
}
else if(src instanceof String)
{
String anot = (String) src;
fldOffset = anot.fldOffset + bounds[0];
fldChars = anot.fldChars;
}
else
{
char[] thisChars = fldChars = new char[thisLength];
for(int i = 0, int j = bounds[0]; i < thisLength; i++, j++) thisChars[i] = src[j];
}
}
public (ByteArray src) {
if(src == null) return;
char[] thisChars = Charset.getDefault().decode(src);
int thisLength = fldLength = thisChars.length;
if(thisLength > 0) Array.copy(thisChars, 0, fldChars = new char[thisLength], 0, thisLength);
}
public (ByteArray src, int offset, int length) {
if(src == null) return;
int2 bounds = Array.intersectBounds(src, offset, length);
char[] thisChars = Charset.getDefault().decode(src, bounds[0], bounds[1]);
int thisLength = fldLength = thisChars.length;
if(thisLength > 0) Array.copy(thisChars, 0, fldChars = new char[thisLength], 0, thisLength);
}
public (ByteArray src, Charset charset) {
if(src == null) return;
char[] thisChars = (charset == null ? Charset.getDefault() : charset).decode(src);
int thisLength = fldLength = thisChars.length;
if(thisLength > 0) Array.copy(thisChars, 0, fldChars = new char[thisLength], 0, thisLength);
}
public (ByteArray src, int offset, int length, Charset charset) {
if(src == null) return;
int2 bounds = Array.intersectBounds(src, offset, length);
char[] thisChars = (charset == null ? Charset.getDefault() : charset).decode(src, bounds[0], bounds[1]);
int thisLength = fldLength = thisChars.length;
if(thisLength > 0) Array.copy(thisChars, 0, fldChars = new char[thisLength], 0, thisLength);
}
private (int offset, int length, char[] chars) {
fldOffset = offset;
fldLength = length;
fldChars = chars;
}
public boolean equals(Object anot) {
if(anot == this) return true;
label0: if(anot instanceof String)
{
with((String) anot)
{
int thisLength = this.fldLength;
if(thisLength != fldLength) break label0;
int anotOffset = fldOffset;
char[] anotChars = fldChars;
int thisOffset = this.fldOffset;
char[] thisChars = this.fldChars;
if(thisChars != anotChars || thisOffset != anotOffset)
{
while(thisLength-- > 0)
{
if(thisChars[thisOffset++] != anotChars[anotOffset++]) break label0;
}
}
}
return true;
}
return false;
}
public int hashCode() {
int result = 0;
for(char[] thisChars = fldChars, int thisOffset = fldOffset, int thisLength = fldLength, int e = 1; thisLength-- > 0; e *= 31)
{
result += e * (int) thisChars[thisOffset++];
}
return result;
}
public long hashCodeAsLong() {
long result = 0L;
for(char[] thisChars = fldChars, int thisOffset = fldOffset, int thisLength = fldLength, long e = 1L; thisLength-- > 0; e *= 31L)
{
result += e * (long) thisChars[thisOffset++];
}
return result;
}
public long2 hashCodeAsLong2() {
long2 result = 0L;
for(char[] thisChars = fldChars, int thisOffset = fldOffset, int thisLength = fldLength, long2 e = 1L; thisLength-- > 0; e = Int128.mul(e, 31L))
{
result = Int128.add(result, Int128.mul(e, (long2) thisChars[thisOffset++]));
}
return result;
}
public String toString() { return this; }
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);
if(dst instanceof char[])
{
Array.copy(fldChars, fldOffset + beginIndex, (char[]) dst, offset, length);
return;
}
for(char[] thisChars = fldChars, int thisOffset = fldOffset + beginIndex; length-- > 0; ) dst[offset++] = thisChars[thisOffset++];
}
public char[] toCharArray() {
int thisLength = fldLength;
char[] result = new char[thisLength];
Array.copy(fldChars, fldOffset, result, 0, thisLength);
return result;
}
public String subsequence(int beginIndex, int endIndex) { return substring(beginIndex, endIndex); }
public String subsequence(int beginIndex) { return substring(beginIndex, fldLength); }
public String clone() { return new String(fldOffset, fldLength, fldChars); }
public boolean isEmpty() { return fldLength <= 0; }
public int compareTo(Comparable anot) {
if(anot == this) return EQUALS;
if(anot instanceof String)
{
with((String) anot)
{
int anotOffset = fldOffset;
int anotLength = fldLength;
char[] anotChars = fldChars;
int thisOffset = this.fldOffset;
int thisLength = this.fldLength;
char[] thisChars = this.fldChars;
if(thisChars != anotChars || thisOffset != anotOffset || thisLength != anotLength)
{
for(int minLength = thisLength > anotLength ? anotLength : thisLength; minLength-- > 0; )
{
char thisChar = thisChars[thisOffset++];
char anotChar = anotChars[anotOffset++];
if(thisChar != anotChar) return thisChar - anotChar;
}
if(thisLength > anotLength) return 0x00010000;
if(thisLength < anotLength) return 0xffff0000;
}
}
return EQUALS;
}
return INDEFINITE;
}
public boolean contentEquals(CharArray array) {
int thisLength = fldLength;
if(array == null || array.length < thisLength) return false;
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 - fldLength) return false;
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;
char first = array[0];
do
{
label0: if(thisChars[thisOffset++] == first)
{
for(int i = thisOffset, int j = 1; j < length; )
{
if(thisChars[i++] != array[j++]) break label0;
}
return true;
}
} while(thisOffset <= thisLimit);
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;
offset = bounds[0];
int thisOffset = fldOffset;
int thisLimit = thisOffset + fldLength - length;
if(thisOffset > thisLimit) return false;
char[] thisChars = fldChars;
char first = array[offset++];
do
{
label0: if(thisChars[thisOffset++] == first)
{
for(int i = thisOffset, int j = offset, int k = length; k-- > 0; )
{
if(thisChars[i++] != array[j++]) break label0;
}
return true;
}
} while(thisOffset <= thisLimit);
return false;
}
public boolean equalsIgnoreCase(String anot) {
int thisLength = fldLength;
return anot != null && thisLength == anot.fldLength && regionMatches(true, 0, anot, 0, thisLength);
}
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;
thisOffset += fldOffset;
anotOffset += anot.fldOffset;
char[] thisChars = fldChars;
char[] anotChars = anot.fldChars;
do
{
if(length-- <= 0) return true;
} while(thisChars[thisOffset++] == anotChars[anotOffset++]);
return false;
}
public boolean regionMatches(boolean ignoreCase, 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;
thisOffset += fldOffset;
anotOffset += anot.fldOffset;
char[] thisChars = fldChars;
char[] anotChars = anot.fldChars;
char thisChar;
char anotChar;
do
{
do
{
if(length-- <= 0) return true;
} while((thisChar = thisChars[thisOffset++]) == (anotChar = anotChars[anotOffset++]));
if(!ignoreCase) break;
} while(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("аргумент suffix равен нулевой ссылке");
}
return startsWith(suffix, fldLength - suffix.fldLength);
}
public boolean startsWith(String prefix) {
if(prefix == null)
{
throw new NullPointerException("аргумент prefix равен нулевой ссылке");
}
return startsWith(prefix, 0);
}
public boolean startsWith(String prefix, int offset) {
if(prefix == null)
{
throw new NullPointerException("аргумент prefix равен нулевой ссылке");
}
int anotLength = prefix.fldLength;
if(offset < 0 || offset > fldLength - anotLength) return false;
for(char[] thisChars = fldChars, char[] anotChars = prefix.fldChars, int i = fldOffset + offset, int j = prefix.fldOffset; anotLength-- > 0; i++, j++)
{
if(thisChars[i] != anotChars[j]) return false;
}
return true;
}
public int indexOf(int character) {
if(character < 0 || character >= 0xffff) return -1;
int thisLength = fldLength;
if(thisLength <= 0) return -1;
int thisOffset = fldOffset;
int index = Array.indexOf(character, fldChars, thisOffset, thisLength);
return index < 0 ? -1 : index - thisOffset;
}
public int indexOf(int character, int startFromIndex) {
if(character < 0 || character >= 0xffff) return -1;
int thisLength = fldLength;
if(startFromIndex < 0) startFromIndex = 0;
if(startFromIndex >= thisLength) return -1;
int thisOffset = fldOffset;
int index = Array.indexOf(character, fldChars, thisOffset + startFromIndex, thisLength - startFromIndex);
return index < 0 ? -1 : index - thisOffset;
}
public int indexOf(String string) { return indexOf(string, 0); }
public int indexOf(String string, int startFromIndex) {
if(string == null)
{
throw new NullPointerException("аргумент string равен нулевой ссылке");
}
int thisOffset = fldOffset;
int anotLength = string.fldLength;
int thisLimit = fldLength - anotLength;
if(startFromIndex < 0) startFromIndex = 0;
if(startFromIndex > thisLimit) return -1;
if(anotLength <= 0) return startFromIndex;
char[] thisChars = fldChars;
int anotOffset = string.fldOffset;
char[] anotChars = string.fldChars;
char first = anotChars[anotOffset++];
thisOffset += startFromIndex;
do
{
label0: if(thisChars[thisOffset++] == first)
{
for(int i = thisOffset, int j = anotOffset, int k = anotLength; k-- > 1; i++, j++)
{
if(thisChars[i] != anotChars[j]) break label0;
}
return startFromIndex;
}
} while(++startFromIndex <= thisLimit);
return -1;
}
public int lastIndexOf(int character) {
int thisLength = fldLength;
if(thisLength <= 0) return -1;
int thisOffset = fldOffset;
int index = Array.lastIndexOf(character, fldChars, thisOffset + thisLength - 1, thisLength);
return index < 0 ? -1 : index - thisOffset;
}
public int lastIndexOf(int character, int startFromIndex) {
int thisLength = fldLength;
if(startFromIndex >= thisLength) startFromIndex = thisLength - 1;
if(startFromIndex < 0) return -1;
int thisOffset = fldOffset;
int index = Array.lastIndexOf(character, fldChars, thisOffset + startFromIndex, startFromIndex + 1);
return index < 0 ? -1 : index - thisOffset;
}
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 равен нулевой ссылке");
}
int thisOffset = fldOffset;
int anotLength = string.fldLength;
int thisLimit = fldLength - anotLength;
if(startFromIndex > thisLimit) startFromIndex = thisLimit;
if(startFromIndex < 0) return -1;
if(anotLength <= 0) return startFromIndex;
char[] thisChars = fldChars;
int anotOffset = string.fldOffset;
char[] anotChars = string.fldChars;
char first = anotChars[anotOffset++];
thisOffset += startFromIndex;
do
{
label0: if(thisChars[thisOffset--] == first)
{
for(int i = thisOffset, int j = anotOffset, int k = anotLength; k-- > 1; i++, j++)
{
if(thisChars[i] != anotChars[j]) break label0;
}
return startFromIndex;
}
} while(--startFromIndex >= 0);
return -1;
}
public int compareToIgnoreCase(String anot) {
if(anot == this) return EQUALS;
int thisOffset = fldOffset;
int thisLength = fldLength;
char[] thisChars = fldChars;
int anotOffset = anot.fldOffset;
int anotLength = anot.fldLength;
char[] anotChars = anot.fldChars;
if(thisChars != anotChars || thisOffset != anotOffset || thisLength != anotLength)
{
for(int minLength = thisLength > anotLength ? anotLength : thisLength; minLength-- > 0; )
{
char thisChar = Char.toUpperCase(thisChars[thisOffset++]);
char anotChar = Char.toUpperCase(anotChars[anotOffset++]);
if(thisChar != anotChar) return thisChar - anotChar;
}
if(thisLength > anotLength) return 0x00010000;
if(thisLength < anotLength) return 0xffff0000;
}
return EQUALS;
}
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 {
int length = fldLength;
Charset charset = Charset.get(charsetName);
return length <= 0 ? new byte[0] : charset.encode(fldChars, fldOffset, length);
}
public String[] split() {
int boundsLength = 0;
int2[] boundsData = new int2[15];
int thisLength = fldLength;
char[] thisChars = fldChars;
for(int beginIndex = fldOffset, int thisLimit = beginIndex + thisLength; beginIndex <= thisLimit; )
{
char character = '\0';
int endIndex = beginIndex;
while(endIndex < thisLimit && (character = thisChars[endIndex]) != '\n' && character != '\r') endIndex++;
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(character == '\r' && beginIndex < thisLimit && thisChars[beginIndex] == '\n') beginIndex++;
}
String[] result = new String[boundsLength];
while(boundsLength-- > 0)
{
int2 bounds = boundsData[boundsLength];
int resultLength = bounds[1];
result[boundsLength] = resultLength == 0 ? "" : resultLength == thisLength ? this : new String(bounds[0], resultLength, thisChars);
}
return result;
}
public String trim() {
int beginIndex = fldOffset;
int endIndex = beginIndex + fldLength - 1;
int i = beginIndex;
int j = endIndex;
char[] thisChars = fldChars;
while(i <= j && thisChars[i] <= '\u0020') i++;
while(i <= j && thisChars[j] <= '\u0020') j--;
return i > j ? "" : i == beginIndex && j == endIndex ? this : new String(i, j - i + 1, thisChars);
}
public String intern() {
for(int i = constants.length; i-- > 0; )
{
String string = constants[i];
if(string != null && equals(string)) return string;
}
return Runtime.getInstance().intern(this);
}
public String toLowerCase() {
int thisOffset = fldOffset;
int thisLength = fldLength;
char[] thisChars = fldChars;
int i = thisOffset;
label0:
{
for(int thisLimit = thisOffset + thisLength; i < thisLimit; i++)
{
char character = thisChars[i];
if(character != Char.toLowerCase(character)) break label0;
}
return this;
}
char[] resultChars = new char[thisLength];
for(int j = i - thisOffset, Array.copy(thisChars, thisOffset, resultChars, 0, j); j < thisLength; i++, j++)
{
resultChars[j] = Char.toLowerCase(thisChars[i]);
}
return new String(0, thisLength, resultChars);
}
public String toUpperCase() {
int thisOffset = fldOffset;
int thisLength = fldLength;
char[] thisChars = fldChars;
int i = thisOffset;
label0:
{
for(int thisLimit = thisOffset + thisLength; i < thisLimit; i++)
{
char character = thisChars[i];
if(character != Char.toUpperCase(character)) break label0;
}
return this;
}
char[] resultChars = new char[thisLength];
for(int j = i - thisOffset, Array.copy(thisChars, thisOffset, resultChars, 0, j); j < thisLength; i++, j++)
{
resultChars[j] = Char.toUpperCase(thisChars[i]);
}
return new String(0, thisLength, resultChars);
}
public String substring(int beginIndex) {
int thisLength = fldLength;
if(beginIndex < 0 || beginIndex > thisLength)
{
throw new StringIndexOutOfBoundsException("индекс символа строки выходит из диапазона");
}
return beginIndex == thisLength ? "" : beginIndex == 0 ? this : new String(fldOffset + beginIndex, thisLength - beginIndex, fldChars);
}
public String substring(int beginIndex, int endIndex) {
int thisLength = fldLength;
if((beginIndex | endIndex) < 0 || beginIndex > thisLength || endIndex > thisLength || beginIndex > endIndex)
{
throw new StringIndexOutOfBoundsException("индекс символа строки выходит из диапазона");
}
int resultLength = endIndex - beginIndex;
return resultLength == 0 ? "" : resultLength == thisLength ? this : new String(fldOffset + beginIndex, resultLength, fldChars);
}
public String replace(char oldCharacter, char newCharacter) {
int thisLength = fldLength;
if(thisLength <= 0 || oldCharacter == newCharacter) return this;
int thisOffset = fldOffset;
char[] thisChars = fldChars;
int i = Array.indexOf(oldCharacter, thisChars, thisOffset, thisLength);
if(i < 0) return this;
char[] resultChars = new char[thisLength];
for(int j = i - thisOffset, Array.copy(thisChars, thisOffset, resultChars, 0, j); j < thisLength; i++, j++)
{
char character = thisChars[i];
resultChars[j] = (char) (character != oldCharacter ? character : newCharacter);
}
return new String(0, thisLength, resultChars);
}
public String replace(String oldString, String newString) {
if(oldString == null)
{
throw new NullPointerException("аргумент oldString равен нулевой ссылке");
}
if(newString == null)
{
throw new NullPointerException("аргумент newString равен нулевой ссылке");
}
int thisLength = fldLength;
int oldLength = oldString.fldLength;
if(oldLength <= 0 || thisLength <= 0 || oldString.equals(newString)) return this;
int indexLength = 0;
int[] indexData = new int[31];
for(int index = 0; (index = indexOf(oldString, index)) >= 0; index += oldLength)
{
if(indexLength == indexData.length)
{
Array.copy(indexData, 0, indexData = new int[(indexLength << 1) + 1], 0, length);
}
indexData[indexLength++] = index;
}
if(indexLength <= 0) return this;
int newLength = newString.fldLength;
long longLength = (long) thisLength + (long) indexLength * (long) (newLength - oldLength);
if(longLength > (long) Int.MAX_VALUE || longLength < 0L)
{
throw new BufferTooLargeError("объём буфера очень велик");
}
int thisEnd = thisLength;
int thisOffset = fldOffset;
char[] thisChars = fldChars;
int resultEnd = (int) longLength;
int resultLength = resultEnd;
char[] resultChars = new char[resultLength];
int newOffset = newString.fldOffset;
char[] newChars = newString.fldChars;
while(indexLength-- > 0)
{
int thisBegin = indexData[indexLength] + oldLength;
int copyLength = thisEnd - thisBegin;
int resultBegin = resultEnd - copyLength;
Array.copy(thisChars, thisOffset + thisBegin, resultChars, resultBegin, copyLength);
Array.copy(newChars, newOffset, resultChars, resultEnd = resultBegin - newLength, newLength);
thisEnd = thisBegin - oldLength;
}
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(startFromIndex < 0) startFromIndex = 0;
if(startFromIndex >= thisLength) return this;
int thisOffset = fldOffset;
char[] thisChars = fldChars;
int index = Array.indexOf(oldCharacter, thisChars, thisOffset + startFromIndex, thisLength - startFromIndex);
if(index < 0) return this;
char[] resultChars = new char[thisLength];
Array.copy(thisChars, thisOffset, resultChars, 0, thisLength);
resultChars[index - 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("аргумент oldString равен нулевой ссылке");
}
if(newString == null)
{
throw new NullPointerException("аргумент newString равен нулевой ссылке");
}
int thisLength = fldLength;
int oldLength = oldString.fldLength;
if(oldLength <= 0 || thisLength <= 0 || oldString.equals(newString)) return this;
int index = indexOf(oldString, startFromIndex);
if(index < 0) return this;
int newLength = newString.fldLength;
int resultLength = thisLength + (newLength - oldLength);
if(resultLength < 0)
{
throw new BufferTooLargeError("объём буфера очень велик");
}
int thisOffset = fldOffset;
char[] thisChars = fldChars;
char[] resultChars = new char[resultLength];
Array.copy(thisChars, thisOffset, resultChars, 0, index);
Array.copy(newString.fldChars, newString.fldOffset, resultChars, index, newLength);
Array.copy(thisChars, thisOffset + index + oldLength, resultChars, index += newLength, resultLength - index);
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(startFromIndex >= thisLength) startFromIndex = thisLength - 1;
if(startFromIndex < 0) return this;
int thisOffset = fldOffset;
char[] thisChars = fldChars;
int index = Array.lastIndexOf(oldCharacter, thisChars, thisOffset + startFromIndex, startFromIndex + 1);
if(index < 0) return this;
char[] resultChars = new char[thisLength];
Array.copy(thisChars, thisOffset, resultChars, 0, thisLength);
resultChars[index - 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("аргумент oldString равен нулевой ссылке");
}
if(newString == null)
{
throw new NullPointerException("аргумент newString равен нулевой ссылке");
}
int thisLength = fldLength;
int oldLength = oldString.fldLength;
if(oldLength <= 0 || thisLength <= 0 || oldString.equals(newString)) return this;
int index = lastIndexOf(oldString, startFromIndex);
if(index < 0) return this;
int newLength = newString.fldLength;
int resultLength = thisLength + (newLength - oldLength);
if(resultLength < 0)
{
throw new BufferTooLargeError("объём буфера очень велик");
}
int thisOffset = fldOffset;
char[] thisChars = fldChars;
char[] resultChars = new char[resultLength];
Array.copy(thisChars, thisOffset, resultChars, 0, index);
Array.copy(newString.fldChars, newString.fldOffset, resultChars, index, newLength);
Array.copy(thisChars, thisOffset + index + oldLength, resultChars, index += newLength, resultLength - index);
return new String(0, resultLength, resultChars);
}
public int length { read = fldLength }
public char operator [](int index) {
if(index < 0 || index >= fldLength)
{
throw new StringIndexOutOfBoundsException("индекс символа строки выходит из диапазона");
}
return fldChars[fldOffset + index];
}
public String operator +(String anot) {
if(anot == null)
{
throw new NullPointerException("аргумент 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("объём буфера очень велик");
}
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);
}
private void checkBounds(int beginIndex, int endIndex) {
int thisLength = fldLength;
if((beginIndex | endIndex) < 0 || beginIndex > thisLength || endIndex > thisLength || beginIndex > endIndex)
{
throw new StringIndexOutOfBoundsException("индекс символа строки выходит из диапазона");
}
}
}