/*
* Copyright 2009-2012 Michael Dalton
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package java.lang;
import java.util.BitSet;
import jtaint.SafeTaint;
import jtaint.Taint;
public final class SafeStringBuilder
implements SafeCharSequence
{
private SafeTaint taint;
private OrigStringBuilder builder;
public SafeStringBuilder() {
taint = new SafeTaint();
builder = new OrigStringBuilder();
}
public SafeStringBuilder(int capacity) {
taint = new SafeTaint();
builder = new OrigStringBuilder(capacity);
}
public SafeStringBuilder(SafeString str) {
taint = str.taint();
builder = new OrigStringBuilder(str.origString());
}
public SafeStringBuilder(SafeCharSequence seq) {
this(seq.toSafeString());
}
public SafeStringBuilder append(Object obj) {
return append(SafeString.valueOf(obj));
}
public SafeStringBuilder append(SafeString str) {
builder.append(str.origString());
taint.append(str.taint());
return this;
}
public SafeStringBuilder append(SafeStringBuffer sb) {
return append(sb.toSafeString());
}
public SafeStringBuilder append(SafeCharSequence s) {
return append(s.toSafeString());
}
public SafeStringBuilder append(SafeCharSequence s, int start, int end) {
return append(s.toSafeString().substring(start,end));
}
public SafeStringBuilder append(char str[]) {
return append(new SafeString(str));
}
public SafeStringBuilder append(char str[], int offset, int len) {
return append(new SafeString(str, offset, len));
}
public SafeStringBuilder append(boolean b) {
return append(SafeString.valueOf(b));
}
public SafeStringBuilder append(char c) {
return append(SafeString.valueOf(c));
}
public SafeStringBuilder append(int i) {
return append(SafeString.valueOf(i));
}
public SafeStringBuilder append(long lng) {
return append(SafeString.valueOf(lng));
}
public SafeStringBuilder append(float f) {
return append(SafeString.valueOf(f));
}
public SafeStringBuilder append(double d) {
return append(SafeString.valueOf(d));
}
public SafeStringBuilder appendCodePoint(int codePoint) {
builder.appendCodePoint(codePoint);
taint.setLength(builder.length());
return this;
}
public SafeString substring(int start) {
return substring(start, builder.length());
}
public SafeString substring(int start, int end) {
return toSafeString().substring(start, end);
}
public SafeCharSequence subSequence(int start, int end) {
return substring(start, end);
}
public SafeStringBuilder delete(int start, int end) {
builder.delete(start, end);
taint.delete(start, end);
return this;
}
public SafeStringBuilder deleteCharAt(int index) {
builder.deleteCharAt(index);
taint.delete(index, index+1);
return this;
}
public SafeStringBuilder replace(int start, int end, SafeString str) {
builder.replace(start, end, str.origString());
taint.delete(start, end);
taint.insert(start, str.taint());
return this;
}
public SafeStringBuilder insert(int index, char str[], int offset,
int len)
{
return insert(index, new SafeString(str, offset, len));
}
public SafeStringBuilder insert(int offset, Object obj) {
return insert(offset, SafeString.valueOf(obj));
}
public SafeStringBuilder insert(int offset, SafeString str) {
builder.insert(offset, str.origString());
taint.insert(offset, str.taint());
return this;
}
public SafeStringBuilder insert(int offset, char str[]) {
return insert(offset, new SafeString(str));
}
public SafeStringBuilder insert(int dstOffset, SafeCharSequence s) {
return insert(dstOffset, s.toSafeString());
}
public SafeStringBuilder insert(int dstOffset, SafeCharSequence s,
int start, int end)
{
return insert(dstOffset, s.toSafeString().substring(start, end));
}
public SafeStringBuilder insert(int offset, boolean b) {
return insert(offset, SafeString.valueOf(b));
}
public SafeStringBuilder insert(int offset, char c) {
return insert(offset, SafeString.valueOf(c));
}
public SafeStringBuilder insert(int offset, int i) {
return insert(offset, SafeString.valueOf(i));
}
public SafeStringBuilder insert(int offset, long l) {
return insert(offset, SafeString.valueOf(l));
}
public SafeStringBuilder insert(int offset, float f) {
return insert(offset, SafeString.valueOf(f));
}
public SafeStringBuilder insert(int offset, double d) {
return insert(offset, SafeString.valueOf(d));
}
public int indexOf(SafeString str) {
return builder.indexOf(str.origString());
}
public int indexOf(SafeString str, int fromIndex) {
return builder.indexOf(str.origString(), fromIndex);
}
public int lastIndexOf(SafeString str) {
return builder.lastIndexOf(str.origString());
}
public int lastIndexOf(SafeString str, int fromIndex) {
return builder.lastIndexOf(str.origString(), fromIndex);
}
public SafeStringBuilder reverse() {
builder.reverse();
taint.reverse();
return this;
}
public String toString() {
String s = builder.toString();
if (!taint.isTainted())
return s;
else
return new String(s, new Taint(taint.asBitSet(), s.length()));
}
public SafeString toSafeString() {
return new SafeString(builder.toOrigString(), (SafeTaint)taint.clone());
}
public boolean verify(StringBuilder sb) throws IllegalArgumentException {
Taint t = sb.toString().@internal@taint();
if (!builder.toString().equals(sb.toString()) || !taint.verify(t))
return false;
return true;
}
public int length() {
return builder.length();
}
public int capacity() {
return builder.capacity();
}
public void ensureCapacity(int minimumCapacity) {
builder.ensureCapacity(minimumCapacity);
}
void expandCapacity(int minimumCapacity) {
builder.expandCapacity(minimumCapacity);
}
public void trimToSize() {
builder.trimToSize();
}
public void setLength(int newLength) {
builder.setLength(newLength);
taint.setLength(newLength);
}
public char charAt(int index) {
return builder.charAt(index);
}
public int codePointAt(int index) {
return builder.codePointAt(index);
}
public int codePointBefore(int index) {
return builder.codePointBefore(index);
}
public int codePointCount(int beginIndex, int endIndex) {
return builder.codePointCount(beginIndex, endIndex);
}
public int offsetByCodePoints(int index, int codePointOffset) {
return builder.offsetByCodePoints(index, codePointOffset);
}
public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
builder.getChars(srcBegin, srcEnd, dst, dstBegin);
}
public void setCharAt(int index, char ch) {
builder.setCharAt(index, ch);
taint.clear(index);
}
char[] getValue() {
return builder.getValue();
}
public SafeTaint taint() { return (SafeTaint) taint.clone(); }
}