/*
Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
и других спецификаций для функционирования компактных приложений на языке
Java (мидлетов) в среде программного обеспечения Малик Эмулятор.
Copyright © 2016–2017, 2019–2023 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package malik.emulator.util;
import malik.emulator.fileformats.*;
public class StringBuilder extends Object implements DataHolder
{
public static int optimalCapacity(int length) {
int result;
if(length <= 7) return 7;
for(result = length; length != 0; result |= (length >>>= 1));
return result;
}
protected int length;
protected char[] content;
public StringBuilder() {
this.content = new char[0x0f];
}
public StringBuilder(int initialCapacity) {
this.content = new char[initialCapacity < 0x0f ? 0x0f : initialCapacity];
}
public String toString() {
return new String(content, 0, length);
}
public void clear() {
length = 0;
}
public void copy(int beginPosition, int endPosition, char[] dst, int offset) {
int len = length;
int length;
if(beginPosition < 0 || beginPosition > len)
{
throw new StringIndexOutOfBoundsException("StringBuilder.copy: аргумент beginPosition выходит из диапазона.");
}
if(endPosition < beginPosition || endPosition > len)
{
throw new StringIndexOutOfBoundsException("StringBuilder.copy: аргумент endPosition выходит из диапазона.");
}
if(dst == null)
{
throw new NullPointerException("StringBuilder.copy: аргумент dst равен нулевой ссылке.");
}
Array.checkBound("StringBuilder.copy", dst.length, offset, length = endPosition - beginPosition);
if(length > 0) Array.copy(content, beginPosition, dst, offset, length);
}
public void set(int position, char character) {
if(position < 0 || position >= length)
{
throw new StringIndexOutOfBoundsException("StringBuilder.set: аргумент position выходит из диапазона.");
}
content[position] = character;
}
public char get(int position) {
if(position < 0 || position >= length)
{
throw new StringIndexOutOfBoundsException("StringBuilder.get: аргумент position выходит из диапазона.");
}
return content[position];
}
public StringBuilder insert(int position, boolean value) {
insertString(position, value ? "true" : "false");
return this;
}
public StringBuilder insert(int position, char value) {
insertChar(position, value);
return this;
}
public StringBuilder insert(int position, float value) {
insertString(position, Float.toString(value));
return this;
}
public StringBuilder insert(int position, double value) {
insertString(position, Double.toString(value));
return this;
}
public StringBuilder insert(int position, int value) {
insertString(position, Integer.toString(value, 10));
return this;
}
public StringBuilder insert(int position, int value, int radix, boolean upperCase) {
String string = Integer.toString(value, radix);
insertString(position, upperCase ? string.toUpperCase() : string);
return this;
}
public StringBuilder insert(int position, long value) {
insertString(position, Long.toString(value, 10));
return this;
}
public StringBuilder insert(int position, long value, int radix, boolean upperCase) {
String string = Long.toString(value, radix);
insertString(position, upperCase ? string.toUpperCase() : string);
return this;
}
public StringBuilder insert(int position, char[] src) {
if(src != null) insertArray(position, src, 0, src.length);
return this;
}
public StringBuilder insert(int position, char[] src, int offset, int length) {
if(src != null)
{
long bound;
offset = (int) (bound = Array.intersectBound(src.length, offset, length));
length = (int) (bound >> 32);
insertArray(position, src, offset, length);
}
return this;
}
public StringBuilder insert(int position, Object value) {
String string;
if(value != null && (string = value.toString()) != null) insertString(position, string);
return this;
}
public StringBuilder insert(int position, String value) {
if(value != null) insertString(position, value);
return this;
}
public StringBuilder append(boolean value) {
appendString(value ? "true" : "false");
return this;
}
public StringBuilder append(char value) {
appendChar(value);
return this;
}
public StringBuilder append(float value) {
appendString(Float.toString(value));
return this;
}
public StringBuilder append(double value) {
appendString(Double.toString(value));
return this;
}
public StringBuilder append(int value) {
appendString(Integer.toString(value, 10));
return this;
}
public StringBuilder append(int value, int radix, boolean upperCase) {
String string = Integer.toString(value, radix);
appendString(upperCase ? string.toUpperCase() : string);
return this;
}
public StringBuilder append(long value) {
appendString(Long.toString(value, 10));
return this;
}
public StringBuilder append(long value, int radix, boolean upperCase) {
String string = Long.toString(value, radix);
appendString(upperCase ? string.toUpperCase() : string);
return this;
}
public StringBuilder append(char[] src) {
if(src != null) appendArray(src, 0, src.length);
return this;
}
public StringBuilder append(char[] src, int offset, int length) {
if(src != null)
{
long bound;
offset = (int) (bound = Array.intersectBound(src.length, offset, length));
length = (int) (bound >> 32);
appendArray(src, offset, length);
}
return this;
}
public StringBuilder append(Object value) {
String string;
if(value != null && (string = value.toString()) != null) appendString(string);
return this;
}
public StringBuilder append(String value) {
if(value != null) appendString(value);
return this;
}
public StringBuilder delete(int position) {
deletePortion(position, position + 1);
return this;
}
public StringBuilder delete(int beginPosition, int endPosition) {
deletePortion(beginPosition, endPosition);
return this;
}
public final boolean isEmpty() {
return length <= 0;
}
public final int capacity() {
return content.length;
}
public final int length() {
return length;
}
protected void insertChar(int position, char character) {
int oldLength = this.length;
int newLength = 1 + oldLength;
char[] content = madeLarger(newLength);
if(position < 0) position = 0;
if(position > oldLength) position = oldLength;
if(position < oldLength) Array.copy(content, position, content, position + 1, oldLength - position);
content[position] = character;
this.length = newLength;
}
protected void insertArray(int position, char[] src, int offset, int length) {
int oldLength = this.length;
int newLength = length + oldLength;
char[] content = madeLarger(newLength);
if(position < 0) position = 0;
if(position > oldLength) position = oldLength;
if(position < oldLength) Array.copy(content, position, content, position + length, oldLength - position);
Array.copy(src, offset, content, position, length);
this.length = newLength;
}
protected void insertString(int position, String string) {
int length = string.length();
int oldLength = this.length;
int newLength = length + oldLength;
char[] content = madeLarger(newLength);
if(position < 0) position = 0;
if(position > oldLength) position = oldLength;
if(position < oldLength) Array.copy(content, position, content, position + length, oldLength - position);
string.getChars(0, length, content, position);
this.length = newLength;
}
protected void appendChar(char character) {
int oldLength = this.length;
int newLength = 1 + oldLength;
madeLarger(newLength)[oldLength] = character;
this.length = newLength;
}
protected void appendArray(char[] src, int offset, int length) {
int oldLength = this.length;
int newLength = length + oldLength;
Array.copy(src, offset, madeLarger(newLength), oldLength, length);
this.length = newLength;
}
protected void appendString(String string) {
int length = string.length();
int oldLength = this.length;
int newLength = length + oldLength;
string.getChars(0, length, madeLarger(newLength), oldLength);
this.length = newLength;
}
protected void deletePortion(int beginPosition, int endPosition) {
int oldLength = length;
if(beginPosition < 0) beginPosition = 0;
if(beginPosition > oldLength) beginPosition = oldLength;
if(endPosition < beginPosition) endPosition = beginPosition;
if(endPosition > oldLength) endPosition = oldLength;
if(beginPosition < endPosition)
{
char[] buffer;
Array.copy(buffer = content, endPosition, buffer, beginPosition, oldLength - endPosition);
this.length = oldLength - (endPosition - beginPosition);
}
}
private char[] madeLarger(int length) {
int oldLength;
char[] result;
if(length > (oldLength = (result = content).length)) Array.copy(result, 0, result = content = new char[optimalCapacity(length)], 0, oldLength);
return result;
}
}