package org.nutz.lang.util;
import java.util.ArrayList;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
public class LinkedCharArray {
public LinkedCharArray() {
this(256);
}
public LinkedCharArray(int size) {
if (size <= 0)
Lang.makeThrow("width must >0!");
this.width = size;
cache = new ArrayList<char[]>();
}
public LinkedCharArray(String s) {
this(s.length());
char[] cs = s.toCharArray();
cache.add(cs);
cursor = cs.length;
}
private int offset;
private int cursor;
private int width;
private ArrayList<char[]> cache;
public LinkedCharArray push(int e) {
return push((char) e);
}
public LinkedCharArray push(char e) {
char[] array;
int row = cursor / width;
int i = cursor % width;
if (cache.size() == 0 || (cursor != offset && i == 0)) {
array = new char[width];
cache.add(array);
} else {
array = cache.get(row);
}
array[i] = e;
cursor++;
return this;
}
public LinkedCharArray push(String s) {
char[] cs = s.toCharArray();
for (char c : cs)
push(c);
return this;
}
public char popFirst() {
return innerGet(offset++);
}
public LinkedCharArray popFirst(int num) {
for (int i = 0; i < num; i++)
popFirst();
return this;
}
public char popLast() {
return innerGet(--cursor);
}
public LinkedCharArray popLast(int num) {
for (int i = 0; i < num; i++)
popLast();
return this;
}
public char first() {
if (size() == 0)
return (char) 0;
return innerGet(offset);
}
public char last() {
if (size() == 0)
return (char) 0;
return innerGet(cursor - 1);
}
public LinkedCharArray set(int index, char e) {
checkBound(index);
index += offset;
char[] array = cache.get(index / width);
array[index % width] = e;
return this;
}
private void checkBound(int index) {
if (index >= size() || index < 0)
throw new IndexOutOfBoundsException("Index: "
+ index
+ ", Size: "
+ size());
}
public LinkedCharArray clear() {
cache.clear();
cursor = 0;
offset = 0;
return this;
}
private char innerGet(int index) {
char[] array = cache.get(index / width);
return array[index % width];
}
public char get(int index) {
checkBound(index);
return innerGet(index + offset);
}
public boolean isEmpty() {
return 0 == cursor - offset;
}
public int size() {
return cursor - offset;
}
public boolean startsWith(String s) {
if (null == s)
return false;
if (s.length() > this.size())
return false;
return startsWith(s.toCharArray());
}
public boolean startsWith(char[] cs) {
if (null == cs)
return false;
for (int i = 0; i < cs.length; i++)
if (cs[i] != get(i))
return false;
return true;
}
public boolean endsWith(String s) {
if (null == s)
return false;
if (s.length() > this.size())
return false;
return endsWith(s.toCharArray());
}
public boolean endsWith(char[] cs) {
if (null == cs)
return false;
if (size() < cs.length)
return false;
int of = size() - cs.length;
for (int i = 0; i < cs.length; i++)
if (cs[i] != get(of + i))
return false;
return true;
}
public int[] toIntArray() {
int[] re = new int[size()];
for (int i = 0; i < re.length; i++)
re[i] = this.get(i);
return re;
}
public char[] toArray() {
char[] re = new char[size()];
for (int i = 0; i < re.length; i++)
re[i] = (char) this.get(i);
return re;
}
public String toString() {
return new String(toArray());
}
public String toTrimmed() {
return Strings.trim(toString());
}
public String popAll() {
String re = new String(toArray());
clear();
return re;
}
}