2014-04-21 02:14:48 +00:00
|
|
|
/* Copyright (c) 2008-2014, Avian Contributors
|
2008-02-19 18:06:52 +00:00
|
|
|
|
|
|
|
Permission to use, copy, modify, and/or distribute this software
|
|
|
|
for any purpose with or without fee is hereby granted, provided
|
|
|
|
that the above copyright notice and this permission notice appear
|
|
|
|
in all copies.
|
|
|
|
|
|
|
|
There is NO WARRANTY for this software. See license.txt for
|
|
|
|
details. */
|
|
|
|
|
2007-07-04 22:27:08 +00:00
|
|
|
package java.lang;
|
|
|
|
|
2009-06-02 23:14:38 +00:00
|
|
|
public class StringBuilder implements CharSequence, Appendable {
|
2007-08-30 23:31:32 +00:00
|
|
|
private static final int BufferSize = 32;
|
|
|
|
|
2007-07-04 22:27:08 +00:00
|
|
|
private Cell chain;
|
|
|
|
private int length;
|
2007-08-15 01:14:55 +00:00
|
|
|
private char[] buffer;
|
|
|
|
private int position;
|
2007-07-04 22:27:08 +00:00
|
|
|
|
2007-08-30 23:31:32 +00:00
|
|
|
public StringBuilder(String s) {
|
|
|
|
append(s);
|
|
|
|
}
|
|
|
|
|
2007-07-29 23:32:23 +00:00
|
|
|
public StringBuilder(int capacity) { }
|
|
|
|
|
|
|
|
public StringBuilder() {
|
|
|
|
this(0);
|
|
|
|
}
|
|
|
|
|
2007-08-15 01:14:55 +00:00
|
|
|
private void flush() {
|
|
|
|
if (position > 0) {
|
2007-12-13 16:19:58 +00:00
|
|
|
chain = new Cell(new String(buffer, 0, position, false), chain);
|
2007-08-15 01:14:55 +00:00
|
|
|
buffer = null;
|
|
|
|
position = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-04 22:27:08 +00:00
|
|
|
public StringBuilder append(String s) {
|
2007-08-15 01:14:55 +00:00
|
|
|
if (s == null) {
|
|
|
|
return append("null");
|
|
|
|
} else {
|
|
|
|
if (s.length() > 0) {
|
2007-08-30 23:31:32 +00:00
|
|
|
if (buffer != null && s.length() <= buffer.length - position) {
|
|
|
|
s.getChars(0, s.length(), buffer, position);
|
|
|
|
position += s.length();
|
|
|
|
} else {
|
|
|
|
flush();
|
|
|
|
chain = new Cell(s, chain);
|
|
|
|
}
|
2007-08-15 01:14:55 +00:00
|
|
|
length += s.length();
|
|
|
|
}
|
|
|
|
return this;
|
2007-07-29 02:15:45 +00:00
|
|
|
}
|
2007-07-04 22:27:08 +00:00
|
|
|
}
|
|
|
|
|
2009-08-20 14:59:22 +00:00
|
|
|
public StringBuilder append(StringBuffer sb) {
|
|
|
|
return append(sb.toString());
|
|
|
|
}
|
|
|
|
|
2009-06-02 23:14:38 +00:00
|
|
|
public StringBuilder append(CharSequence sequence) {
|
|
|
|
return append(sequence.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
public Appendable append(CharSequence sequence, int start, int end) {
|
|
|
|
return append(sequence.subSequence(start, end));
|
|
|
|
}
|
|
|
|
|
2007-07-29 02:15:45 +00:00
|
|
|
public StringBuilder append(char[] b, int offset, int length) {
|
|
|
|
return append(new String(b, offset, length));
|
|
|
|
}
|
|
|
|
|
2014-04-20 11:06:39 +00:00
|
|
|
public StringBuilder append(char[] b) {
|
|
|
|
return append(new String(b));
|
|
|
|
}
|
|
|
|
|
2007-07-20 03:18:25 +00:00
|
|
|
public StringBuilder append(Object o) {
|
|
|
|
return append(o == null ? "null" : o.toString());
|
|
|
|
}
|
|
|
|
|
2007-08-15 01:14:55 +00:00
|
|
|
public StringBuilder append(char v) {
|
|
|
|
if (buffer == null) {
|
2007-08-30 23:31:32 +00:00
|
|
|
buffer = new char[BufferSize];
|
2007-08-15 01:14:55 +00:00
|
|
|
} else if (position >= buffer.length) {
|
|
|
|
flush();
|
2007-08-30 23:31:32 +00:00
|
|
|
buffer = new char[BufferSize];
|
2007-08-15 01:14:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
buffer[position++] = v;
|
|
|
|
++ length;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2007-08-24 00:20:42 +00:00
|
|
|
public StringBuilder append(boolean v) {
|
|
|
|
return append(String.valueOf(v));
|
|
|
|
}
|
|
|
|
|
2007-07-04 22:27:08 +00:00
|
|
|
public StringBuilder append(int v) {
|
2007-07-20 03:18:25 +00:00
|
|
|
return append(String.valueOf(v));
|
2007-07-04 22:27:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public StringBuilder append(long v) {
|
2007-07-20 03:18:25 +00:00
|
|
|
return append(String.valueOf(v));
|
2007-07-04 22:27:08 +00:00
|
|
|
}
|
|
|
|
|
2007-10-02 14:58:35 +00:00
|
|
|
public StringBuilder append(float v) {
|
|
|
|
return append(String.valueOf(v));
|
|
|
|
}
|
|
|
|
|
|
|
|
public StringBuilder append(double v) {
|
|
|
|
return append(String.valueOf(v));
|
|
|
|
}
|
|
|
|
|
2007-08-30 23:31:32 +00:00
|
|
|
public char charAt(int i) {
|
|
|
|
if (i < 0 || i >= length) {
|
|
|
|
throw new IndexOutOfBoundsException();
|
|
|
|
}
|
|
|
|
|
|
|
|
flush();
|
|
|
|
|
|
|
|
int index = length;
|
|
|
|
for (Cell c = chain; c != null; c = c.next) {
|
|
|
|
int start = index - c.value.length();
|
|
|
|
index = start;
|
|
|
|
|
|
|
|
if (i >= start) {
|
|
|
|
return c.value.charAt(i - start);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new RuntimeException();
|
|
|
|
}
|
|
|
|
|
|
|
|
public StringBuilder insert(int i, String s) {
|
2008-03-05 19:10:59 +00:00
|
|
|
if (i < 0 || i > length) {
|
2007-08-30 23:31:32 +00:00
|
|
|
throw new IndexOutOfBoundsException();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (i == length) {
|
|
|
|
append(s);
|
|
|
|
} else {
|
|
|
|
flush();
|
|
|
|
|
|
|
|
int index = length;
|
|
|
|
for (Cell c = chain; c != null; c = c.next) {
|
|
|
|
int start = index - c.value.length();
|
|
|
|
index = start;
|
|
|
|
|
|
|
|
if (i >= start) {
|
|
|
|
if (i == start) {
|
|
|
|
c.next = new Cell(s, c.next);
|
|
|
|
} else {
|
|
|
|
String v = c.value;
|
|
|
|
c.value = v.substring(i - start, v.length());
|
|
|
|
c.next = new Cell(s, new Cell(v.substring(0, i - start), c.next));
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2007-12-13 16:19:58 +00:00
|
|
|
|
|
|
|
length += s.length();
|
2007-08-30 23:31:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2009-06-02 23:14:38 +00:00
|
|
|
public StringBuilder insert(int i, CharSequence s) {
|
|
|
|
return insert(i, s.toString());
|
|
|
|
}
|
|
|
|
|
2007-09-13 00:21:37 +00:00
|
|
|
public StringBuilder insert(int i, char c) {
|
|
|
|
return insert(i, new String(new char[] { c }, 0, 1, false));
|
|
|
|
}
|
|
|
|
|
2008-11-11 15:20:49 +00:00
|
|
|
public StringBuilder insert(int i, int v) {
|
|
|
|
return insert(i, String.valueOf(v));
|
|
|
|
}
|
|
|
|
|
2007-10-29 21:07:36 +00:00
|
|
|
public StringBuilder delete(int start, int end) {
|
2007-10-29 21:40:05 +00:00
|
|
|
if (start >= end) {
|
|
|
|
return this;
|
2007-10-29 21:07:36 +00:00
|
|
|
}
|
|
|
|
|
2007-10-29 21:40:05 +00:00
|
|
|
if (start < 0 || end > length) {
|
2007-07-29 02:15:45 +00:00
|
|
|
throw new IndexOutOfBoundsException();
|
|
|
|
}
|
|
|
|
|
2007-08-15 01:14:55 +00:00
|
|
|
flush();
|
|
|
|
|
2007-07-29 02:15:45 +00:00
|
|
|
int index = length;
|
|
|
|
Cell p = null;
|
|
|
|
for (Cell c = chain; c != null; c = c.next) {
|
2007-10-29 21:40:05 +00:00
|
|
|
int e = index;
|
|
|
|
int s = index - c.value.length();
|
|
|
|
index = s;
|
2007-07-29 02:15:45 +00:00
|
|
|
|
2007-10-29 21:40:05 +00:00
|
|
|
if (end >= e) {
|
|
|
|
if (start <= s) {
|
2007-07-29 02:15:45 +00:00
|
|
|
if (p == null) {
|
|
|
|
chain = c.next;
|
|
|
|
} else {
|
|
|
|
p.next = c.next;
|
2007-10-29 21:40:05 +00:00
|
|
|
}
|
2007-07-29 02:15:45 +00:00
|
|
|
} else {
|
2007-10-29 21:40:05 +00:00
|
|
|
c.value = c.value.substring(0, start - s);
|
|
|
|
break;
|
2007-07-29 02:15:45 +00:00
|
|
|
}
|
2007-10-29 21:40:05 +00:00
|
|
|
} else {
|
|
|
|
if (start <= s) {
|
|
|
|
c.value = c.value.substring(end - s, e - s);
|
|
|
|
} else {
|
|
|
|
String v = c.value;
|
|
|
|
c.value = v.substring(end - s, e - s);
|
|
|
|
c.next = new Cell(v.substring(0, start - s), c.next);
|
|
|
|
break;
|
|
|
|
}
|
2007-07-29 02:15:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-12-13 16:19:58 +00:00
|
|
|
length -= (end - start);
|
|
|
|
|
2007-07-29 02:15:45 +00:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2007-10-29 21:40:05 +00:00
|
|
|
public StringBuilder deleteCharAt(int i) {
|
|
|
|
return delete(i, i + 1);
|
|
|
|
}
|
|
|
|
|
2007-10-29 21:07:36 +00:00
|
|
|
public StringBuilder replace(int start, int end, String str) {
|
|
|
|
delete(start, end);
|
|
|
|
insert(start, str);
|
|
|
|
return this;
|
|
|
|
}
|
2008-07-14 00:59:30 +00:00
|
|
|
|
|
|
|
public int indexOf(String s) {
|
|
|
|
return indexOf(s, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
public int indexOf(String s, int start) {
|
|
|
|
int slength = s.length();
|
|
|
|
if (slength == 0) return start;
|
|
|
|
|
|
|
|
for (int i = start; i < length - slength + 1; ++i) {
|
|
|
|
int j = 0;
|
|
|
|
for (; j < slength; ++j) {
|
|
|
|
if (charAt(i + j) != s.charAt(j)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (j == slength) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
2009-08-13 15:02:00 +00:00
|
|
|
|
|
|
|
public int lastIndexOf(String s) {
|
|
|
|
return lastIndexOf(s, length - s.length());
|
|
|
|
}
|
|
|
|
|
|
|
|
public int lastIndexOf(String s, int lastIndex) {
|
|
|
|
int slength = s.length();
|
|
|
|
if (slength == 0) return lastIndex;
|
|
|
|
|
|
|
|
for (int i = Math.min(length - slength, lastIndex); i >= 0; --i) {
|
|
|
|
int j = 0;
|
|
|
|
for (; j < slength && i + j < length; ++j) {
|
|
|
|
if (charAt(i + j) != s.charAt(j)) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (j == slength) {
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
2007-10-29 21:07:36 +00:00
|
|
|
|
2007-07-29 01:29:01 +00:00
|
|
|
public int length() {
|
|
|
|
return length;
|
|
|
|
}
|
|
|
|
|
2007-07-29 02:15:45 +00:00
|
|
|
public void setLength(int v) {
|
|
|
|
if (v < 0) {
|
|
|
|
throw new IndexOutOfBoundsException();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (v == 0) {
|
|
|
|
length = 0;
|
|
|
|
chain = null;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2007-08-15 01:14:55 +00:00
|
|
|
flush();
|
|
|
|
|
2007-07-29 02:15:45 +00:00
|
|
|
int index = length;
|
|
|
|
length = v;
|
|
|
|
for (Cell c = chain; c != null; c = c.next) {
|
|
|
|
int start = index - c.value.length();
|
|
|
|
|
|
|
|
if (v > start) {
|
|
|
|
if (v < index) {
|
|
|
|
c.value = c.value.substring(0, v - start);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
chain = c.next;
|
|
|
|
index = start;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-13 15:02:00 +00:00
|
|
|
public void getChars(int srcStart, int srcEnd, char[] dst, int dstStart) {
|
|
|
|
if (srcStart < 0 || srcEnd > length) {
|
2007-07-29 01:29:01 +00:00
|
|
|
throw new IndexOutOfBoundsException();
|
|
|
|
}
|
|
|
|
|
2007-08-15 01:14:55 +00:00
|
|
|
flush();
|
|
|
|
|
2007-07-04 22:27:08 +00:00
|
|
|
int index = length;
|
|
|
|
for (Cell c = chain; c != null; c = c.next) {
|
2007-07-29 01:29:01 +00:00
|
|
|
int start = index - c.value.length();
|
|
|
|
int end = index;
|
|
|
|
index = start;
|
|
|
|
|
2009-08-13 15:02:00 +00:00
|
|
|
if (start < srcStart) {
|
|
|
|
start = srcStart;
|
2007-07-29 01:29:01 +00:00
|
|
|
}
|
|
|
|
|
2009-08-13 15:02:00 +00:00
|
|
|
if (end > srcEnd) {
|
|
|
|
end = srcEnd;
|
2007-07-29 01:29:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (start < end) {
|
2009-08-13 15:02:00 +00:00
|
|
|
c.value.getChars(start - index, end - index,
|
|
|
|
dst, dstStart + (start - srcStart));
|
2007-07-29 01:29:01 +00:00
|
|
|
}
|
2007-08-15 01:14:55 +00:00
|
|
|
}
|
2007-07-29 01:29:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public String toString() {
|
|
|
|
char[] array = new char[length];
|
|
|
|
getChars(0, length, array, 0);
|
2007-07-11 01:38:06 +00:00
|
|
|
return new String(array, 0, length, false);
|
2007-07-04 22:27:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private static class Cell {
|
2007-07-29 02:15:45 +00:00
|
|
|
public String value;
|
|
|
|
public Cell next;
|
2007-07-04 22:27:08 +00:00
|
|
|
|
|
|
|
public Cell(String value, Cell next) {
|
|
|
|
this.value = value;
|
|
|
|
this.next = next;
|
|
|
|
}
|
|
|
|
}
|
2008-07-03 15:16:32 +00:00
|
|
|
|
2009-08-13 15:02:00 +00:00
|
|
|
public String substring(int start) {
|
|
|
|
return substring(start, length);
|
|
|
|
}
|
|
|
|
|
2008-07-03 15:16:32 +00:00
|
|
|
public String substring(int start, int end) {
|
|
|
|
int len = end-start;
|
|
|
|
char[] buf = new char[len];
|
2009-08-13 15:02:00 +00:00
|
|
|
getChars(start, end, buf, 0);
|
2008-07-03 15:16:32 +00:00
|
|
|
return new String(buf, 0, len, false);
|
|
|
|
}
|
2008-07-03 16:49:08 +00:00
|
|
|
|
2008-07-03 15:16:32 +00:00
|
|
|
public CharSequence subSequence(int start, int end) {
|
|
|
|
return substring(start, end);
|
|
|
|
}
|
2008-11-11 15:20:49 +00:00
|
|
|
|
|
|
|
public void setCharAt(int index, char ch) {
|
|
|
|
if(index < 0 || index >= length) throw new IndexOutOfBoundsException();
|
|
|
|
deleteCharAt(index);
|
|
|
|
insert(index, ch);
|
|
|
|
}
|
2009-06-02 23:14:38 +00:00
|
|
|
|
|
|
|
public void ensureCapacity(int capacity) {
|
|
|
|
// ignore
|
|
|
|
}
|
2007-07-04 22:27:08 +00:00
|
|
|
}
|