All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.xdev.jadoth.util.VarChar Maven / Gradle / Ivy

/**
 *
 */
package com.xdev.jadoth.util;

/*-
 * #%L
 * XDEV Application Framework
 * %%
 * Copyright (C) 2003 - 2020 XDEV Software
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import static com.xdev.jadoth.lang.reflection.JaReflect.accessCharArray;
import static com.xdev.jadoth.lang.reflection.JaReflect.accessOffset;
import static com.xdev.jadoth.util.JaChars.toHexadecimal;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.xdev.jadoth.lang.functional._charOperation;
import com.xdev.jadoth.lang.functional.controlflow._charControllingProcessor;
import com.xdev.jadoth.lang.signalthrows.ThrowBreak;
import com.xdev.jadoth.lang.signalthrows.ThrowContinue;
import com.xdev.jadoth.lang.signalthrows.ThrowReturn;



/**
 * Faster implementation of a StringBuilder. Note that this class is NOT synchronized and only meant for
 * single-thread or thread-safe (i.e. read-only) use.
 *
 * @author Thomas Muenz
 *
 */

public final class VarChar implements CharSequence, Appendable, Externalizable
{
	/**
	 * Implementors of this interface can handle their appending by themselves.
*
* Note that {@link java.lang.Appendable} has a misleading name: it should actually be called "Appending", * as implementors of it can append things. Actually being "Appendable" is what is defined by THIS interface. * * @author Thomas Muenz * */ public interface Appendable { public VarChar appendTo(VarChar vc); } /////////////////////////////////////////////////////////////////////////// // constants // ///////////////////// private static final long serialVersionUID = 876130105778587634L; //have to be 2^n values private static final int CAPACITY_MIN = 4; //needed for appendNull algorithm (and performance) private static final short CAPACITY_TINY = 16; private static final short CAPACITY_SMALL = 64; private static final short CAPACITY_MEDIUM = 1024; private static final short CAPACITY_LARGE = 16384; //larger sizes overtop the constructor capacity checks, so use standard constructor /////////////////////////////////////////////////////////////////////////// // static methods // ///////////////////// private static final int boundPow2(final int n) { //if desired capacity is not boundable by shifting, max capacity is required if(n > 1073741824) { return Integer.MAX_VALUE; } //normal case: start at min capacity and double it until it fits the desired capacity int p2 = CAPACITY_MIN; while(p2 < n){ p2 <<= 1; } return p2; } /** * Use for single words, names, etc. * @return */ public static final VarChar TinyVarChar() { return new VarChar(CAPACITY_TINY); } /** * Use for short sentences, formulas, etc. * @return */ public static final VarChar SmallVarChar() { return new VarChar(CAPACITY_SMALL); } /** * Use for long sentences, short texts, reading config files, SQL queries, etc. * @return */ public static final VarChar MediumVarChar() { return new VarChar(CAPACITY_MEDIUM); } /** * Use for medium sized texts, java source code, reading text files, etc. * @return */ public static final VarChar LargeVarChar() { return new VarChar(CAPACITY_LARGE); } /////////////////////////////////////////////////////////////////////////// // instance fields // //////////////////// private char[] data; private int size; private char listSeperator = ','; /////////////////////////////////////////////////////////////////////////// // constructors // ///////////////// public VarChar() { this(CAPACITY_SMALL); } /** * Use this constructor only if really a specific size is needed or of the text to be handled is really big.
* Otherwise, use the factory methods as they are faster due to skipping capacity checks and bounds adjustment.
*

* Note that the given initialCapacity will still be adjusted to the next higher 2^n bounding value. * @param initialCapacity */ public VarChar(final int initialCapacity) { super(); if(initialCapacity < 0){ throw new IllegalArgumentException("initial capacity may not be negative: "+initialCapacity); } this.data = new char[boundPow2(initialCapacity)]; this.size = 0; } public VarChar(final String s) { super(); if(s == null){ this.data = new char[]{'n', 'u', 'l', 'l'}; this.size = 4; } else { final int length = s.length(); if(length == 0){ this.data = new char[CAPACITY_MIN]; this.size = 0; } else { this.data = new char[boundPow2(length)]; this.internalAppend(s); this.size = length; } } } private VarChar(final short uncheckedInitialCapacity) { super(); this.data = new char[uncheckedInitialCapacity]; this.size = 0; } /////////////////////////////////////////////////////////////////////////// // getters // ///////////////////// /** * @return the listSeperator */ public char getListSeperator() { return this.listSeperator; } /////////////////////////////////////////////////////////////////////////// // setters // ///////////////////// /** * @param listSeperator the listSeperator to set */ public VarChar setListSeperator(final char listSeperator) { this.listSeperator = listSeperator; return this; } /////////////////////////////////////////////////////////////////////////// // override methods // ///////////////////// /** * @param index * @return */ @Override public char charAt(final int index) { if(index < 0 || index >= this.size){ throw new StringIndexOutOfBoundsException(index); } return this.data[index]; } /** * @return */ @Override public int length() { return this.size; } /** * @param start * @param end * @return */ @Override public VarChar subSequence(final int start, final int end) { final VarChar subSequence = new VarChar(end - start); System.arraycopy(this.data, start, subSequence.data, 0, end - start); return subSequence; } /** * @param csq * @return * @throws IOException */ @Override public VarChar append(final CharSequence csq) { if(csq == null){ this.internalAppendNull(); return this; } return this.append(csq.toString()); } /** * @param c * @return * @throws IOException */ @Override public VarChar append(final char c) { if(this.size == this.data.length){ //expandArray() final int length = this.data.length; //always double array size final char[] data = new char[length == 1073741824 ?Integer.MAX_VALUE :length<<1]; System.arraycopy(this.data, 0, data, 0, this.size); this.data = data; } this.data[this.size++] = c; return this; } /** * Useful for including seperator character to build lists like "a,b,c,d,e". * @param c1 * @param c2 * @return * @see VarChar#deleteLastChar() */ public VarChar append(final char c1, final char c2) { int size = this.size; char[] data = this.data; if(size+1 >= data.length){ //expandArray() final int length = this.data.length; //always double array size data = new char[length == 1073741824 ?Integer.MAX_VALUE :length<<1]; System.arraycopy(this.data, 0, data, 0, this.size); this.data = data; } data[size++] = c1; data[size++] = c2; this.size = size; return this; } public VarChar append(final char c1, final char c2, final char c3) { int size = this.size; char[] data = this.data; if(size+2 >= data.length){ //expandArray() final int length = data.length; //always double array size data = new char[length == 1073741824 ?Integer.MAX_VALUE :length<<1]; System.arraycopy(this.data, 0, data, 0, size); this.data = data; } data[size++] = c1; data[size++] = c2; data[size++] = c3; this.size = size; return this; } public VarChar append(final Character c) { if(c == null){ this.internalAppendNull(); return this; } return this.append(c.charValue()); } /** * @param csq * @param start * @param end * @return * @throws IOException */ @Override public VarChar append(final CharSequence csq, final int start, final int end) { if(csq == null){ this.internalAppendNull(); return this; } return this.append(csq.subSequence(start, end)); } /** * @param in * @throws IOException * @throws ClassNotFoundException */ @Override public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException { final int size = in.read(); final char[] data = new char[boundPow2(size)]; for(int i = 0; i < size; i++){ data[i] = in.readChar(); } this.data = data; this.size = size; } /** * @param out * @throws IOException */ @Override public void writeExternal(final ObjectOutput out) throws IOException { final int size = this.size; final char[] data = this.data; out.write(size); for(int i = 0; i < size; i++){ out.writeChar(data[i]); } } /** * @return */ @Override public String toString() { return new String(this.data, 0, this.size); } /////////////////////////////////////////////////////////////////////////// // declared methods // ///////////////////// public VarChar add(final Object o) { this.internalAdd(o); return this; } public VarChar add(final boolean b) { if(b){ this.appendTrue(); } else { this.appendFalse(); } return this; } public VarChar add(final char c) { if(this.size == this.data.length){ //expandArray() final int length = this.data.length; //always double array size final char[] data = new char[length == 1073741824 ?Integer.MAX_VALUE :length<<1]; System.arraycopy(this.data, 0, data, 0, this.size); this.data = data; } this.data[this.size++] = c; return this; } public VarChar add(final byte b) { this.internalAppend(Byte.toString(b)); return this; } public VarChar add(final short s) { this.internalAppend(Short.toString(s)); return this; } public VarChar add(final int i) { this.internalAppend(Integer.toString(i)); return this; } public VarChar add(final long l) { this.internalAppend(Long.toString(l)); return this; } public VarChar add(final float f) { this.internalAppend(Float.toString(f)); return this; } public VarChar add(final double d) { this.internalAppend(Double.toString(d)); return this; } public VarChar append(final Object o) { this.internalAdd(o); return this; } private void internalAdd(final Object o) { //faster than String.valueOf(o) but same result if(o == null){ this.internalAppendNull(); return; } else if(o instanceof CharSequence){ final int length = ((CharSequence)o).length(); if(length == 0) return; if(o instanceof String){ this.internalAppend((String)o); return; } else if(o instanceof VarChar){ final VarChar vc = (VarChar)o; this.internalAppend(vc.data, 0, length); // length == vc.size return; } else if(o instanceof StringBuilder){ final StringBuilder sb = (StringBuilder)o; sb.getChars(0, length, this.data, this.size); this.size += length; return; } else if(o instanceof StringBuffer){ final StringBuffer sb = (StringBuffer)o; sb.getChars(0, length, this.data, this.size); this.size += length; return; } //drop to default } else if(o instanceof VarChar.Appendable){ ((VarChar.Appendable)o).appendTo(this); return; } else if(o instanceof char[]){ this.internalAppend((char[])o); return; } this.internalAppend(o.toString()); } public VarChar appendHexBytes(final byte... bytes) { this.ensureCapacity(this.size + bytes.length<<1); for(final byte b : bytes){ this.append(toHexadecimal((b & 255) >> 4), toHexadecimal(b & 15)); } return this; } public VarChar appendHexInts(final int... ints) { this.ensureCapacity(this.size + ints.length<<3); for(final int i : ints){ this.append(toHexadecimal(i >> 28), toHexadecimal((i & 268435455) >> 24)); this.append(toHexadecimal((i & 16777215) >> 20), toHexadecimal((i & 1048575) >> 16)); this.append(toHexadecimal((i & 65535) >> 12), toHexadecimal((i & 4095) >> 8)); this.append(toHexadecimal((i & 255) >> 4), toHexadecimal(i & 15)); } return this; } public VarChar listHex(final char seperator, final byte... bytes) { this.ensureCapacity(bytes.length*3); for(final byte b : bytes){ this.append(toHexadecimal((b & 255) >> 4), toHexadecimal(b & 15), seperator); } return this; } public VarChar listHexInts(final char seperator, final int... ints) { this.ensureCapacity(this.size + ints.length<<3); for(final int i : ints){ this.append(toHexadecimal(i >> 28), toHexadecimal((i & 268435455) >> 24)); this.append(toHexadecimal((i & 16777215) >> 20), toHexadecimal((i & 1048575) >> 16)); this.append(toHexadecimal((i & 65535) >> 12), toHexadecimal((i & 4095) >> 8)); this.append(toHexadecimal((i & 255) >> 4), toHexadecimal(i & 15), seperator); } return this; } public VarChar appendArray(final Object... objects) { for(final Object o : objects){ this.append(o); } return this; } public VarChar append(final String s) { if(s == null){ this.internalAppendNull(); } else { this.internalAppend(s); } return this; } public VarChar append(final boolean b) { this.internalAppend(Boolean.toString(b)); return this; } public VarChar append(final byte b) { this.internalAppend(Byte.toString(b)); return this; } public VarChar append(final short b) { this.internalAppend(Short.toString(b)); return this; } public VarChar append(final int b) { this.internalAppend(Integer.toString(b)); return this; } public VarChar append(final long b) { this.internalAppend(Long.toString(b)); return this; } public VarChar append(final float b) { this.internalAppend(Float.toString(b)); return this; } public VarChar append(final double b) { this.internalAppend(Double.toString(b)); return this; } public VarChar append(final VarChar varChar) { if(varChar == null){ this.internalAppendNull(); return this; } else if(varChar.size == 0){ return this; } this.internalAppend(varChar.data, 0, varChar.size); return this; } private void internalAppend(final String s) { final int length = s.length(); if(length == 0) return; final int size = this.size; final int newSize = size + length; int capacity = this.data.length; if(newSize >= capacity){ //expandArray() if(newSize > 1073741824) { //this case automatically handles (this.data.length == 1073741824) capacity = Integer.MAX_VALUE; } else { //normale case: capacity up to 1073741824 will suffice while(capacity < newSize){ capacity <<= 1; } } final char[] data = new char[capacity]; System.arraycopy(this.data, 0, data, 0, size); s.getChars(0, length, data, size); this.data = data; } else { s.getChars(0, length, this.data, size); } this.size = newSize; } private void internalAppend(final char[] chars, final int offset, final int length) { char[] data; final int neededSize = this.size + length; int capacity = this.data.length; if(neededSize >= capacity){ //expandArray() if(neededSize > 1073741824) { //this case automatically handles (this.data.length == 1073741824) capacity = Integer.MAX_VALUE; } else { //normale case: capacity up to 1073741824 will suffice while(capacity < neededSize){ capacity <<= 1; } } data = new char[capacity]; System.arraycopy(this.data, 0, data, 0, this.size); this.data = data; } else { data = this.data; } System.arraycopy(chars, offset, data, this.size, length); this.size = neededSize; } private void internalAppend(final char[] chars) { char[] data; final int neededSize = this.size + chars.length; int capacity = this.data.length; if(neededSize >= capacity){ //expandArray() if(neededSize > 1073741824) { //this case automatically handles (this.data.length == 1073741824) capacity = Integer.MAX_VALUE; } else { //normale case: capacity up to 1073741824 will suffice while(capacity < neededSize){ capacity <<= 1; } } data = new char[capacity]; System.arraycopy(this.data, 0, data, 0, this.size); this.data = data; } else { data = this.data; } System.arraycopy(chars, 0, data, this.size, chars.length); this.size = neededSize; } public void ensureCapacity(final int minimumCapacity) { int capacity = this.data.length; if(minimumCapacity <= capacity) return; char[] data; //expandArray() if(minimumCapacity > 1073741824) { //this case automatically handles (this.data.length == 1073741824) capacity = Integer.MAX_VALUE; } else { //normale case: capacity up to 1073741824 will suffice while(capacity < minimumCapacity){ capacity <<= 1; } } data = new char[capacity]; System.arraycopy(this.data, 0, data, 0, this.size); this.data = data; } public VarChar appendArray(final char... chars) { this.internalAppend(chars, 0, chars.length); return this; } public VarChar append(final char[] chars) { this.internalAppend(chars, 0, chars.length); return this; } public VarChar appendArray(final CharSequence... csqs) { for(final CharSequence csq : csqs){ this.append(csq); } return this; } private final void internalAppendNull() { int size = this.size; char[] data = this.data; if(size+4 > data.length){ data = new char[data.length == 1073741824 ?Integer.MAX_VALUE :data.length<<1]; //will suffice as min size is 4, so left shift 1 yields at least 8. System.arraycopy(this.data, 0, data, 0, size); this.data = data; } //significantly faster than arraycopy data[size++] = 'n'; data[size++] = 'u'; data[size++] = 'l'; data[size++] = 'l'; this.size = size; } private final void internalAppendTrue() { int size = this.size; char[] data = this.data; if(size+4 > data.length){ data = new char[data.length == 1073741824 ?Integer.MAX_VALUE :data.length<<1]; //will suffice as min size is 4, so left shift 1 yields at least 8. System.arraycopy(this.data, 0, data, 0, size); this.data = data; } //significantly faster than arraycopy data[size++] = 't'; data[size++] = 'r'; data[size++] = 'u'; data[size++] = 'e'; this.size = size; } private final void internalAppendFalse() { int size = this.size; char[] data = this.data; if(size+5 > data.length){ data = new char[data.length == 1073741824 ?Integer.MAX_VALUE :size==4 ?16 :data.length<<1]; System.arraycopy(this.data, 0, data, 0, size); this.data = data; } //significantly faster than arraycopy data[size++] = 'f'; data[size++] = 'a'; data[size++] = 'l'; data[size++] = 's'; data[size++] = 'e'; this.size = size; } public final VarChar appendNull() { this.internalAppendNull(); return this; } public final VarChar appendTrue() { this.internalAppendTrue(); return this; } public final VarChar appendFalse() { this.internalAppendFalse(); return this; } public VarChar append(final VarChar.Appendable appendable) { if(appendable == null){ this.internalAppendNull(); } else { appendable.appendTo(this); } return this; } public VarChar setChar(final int index, final char c) { if(index < 0 || index >= this.size){ throw new StringIndexOutOfBoundsException(index); } this.data[index] = c; return this; } public VarChar setChars(final int index, final char... c) { if(index+c.length >= this.size){ throw new IndexOutOfBoundsException("Index is out of length: "+index+" > "+this.size); } System.arraycopy(c, 0, this.data, index, c.length); return this; } public VarChar setLastChar(final char c) { this.data[this.size-1] = c; return this; } public VarChar reverse() { final char[] data = this.data; char loopSwapChar; //only swap until size/2 (rounded down, because center element can remain untouched) for(int i = this.size>>1, last = this.size-1; i != 0; i--){ loopSwapChar = data[i]; data[i] = data[last - i]; data[last - i] = loopSwapChar; } return this; } /** * Not implemented yet. * @return currenty exactely what {@link #reverse()} returns. * @deprecated not implemented yet. Currently just does {@link #reverse()}. * @see #reverse() */ @Deprecated public VarChar surrogateCharReverse() { return this.reverse(); } public int indexOf(final char c) { final char[] data = this.data; for(int i = 0, size = this.size; i < size; i++){ if(data[i] == c){ return i; } } return -1; } public int indexOf(final char c, final int fromIndex) { final int size = this.size; if(fromIndex < 0 || fromIndex >= size){ throw new StringIndexOutOfBoundsException(fromIndex); } final char[] data = this.data; for(int i = fromIndex; i < size; i++){ if(data[i] == c){ return i; } } return -1; } public int indexOf(final char[] chars) { return JaChars.indexOf(this.data, this.size, chars, chars.length, 0); } public int indexOf(final char[] chars, final int fromIndex) { return JaChars.indexOf(this.data, this.size, chars, chars.length, fromIndex); } public int indexOf(final String s) { return JaChars.indexOf(this.data, 0, this.size, accessCharArray(s), accessOffset(s), s.length(), 0); } public int indexOf(final String s, final int fromIndex) { return JaChars.indexOf(this.data, 0, this.size, accessCharArray(s), accessOffset(s), s.length(), fromIndex); } public int indexOf(final VarChar vc) { return JaChars.indexOf(this.data, this.size, vc.data, vc.size, 0); } public int indexOf(final VarChar vc, final int fromIndex) { return JaChars.indexOf(this.data, this.size, vc.data, vc.size, fromIndex); } public int indexOf(final StringBuilder sb) { return JaChars.indexOf(this.data, this.size, accessCharArray(sb), sb.length(), 0); } public int indexOf(final StringBuilder sb, final int fromIndex) { return JaChars.indexOf(this.data, this.size, accessCharArray(sb), sb.length(), fromIndex); } public int indexOf(final StringBuffer sb) { return JaChars.indexOf(this.data, this.size, accessCharArray(sb), sb.length(), 0); } public int indexOf(final StringBuffer sb, final int fromIndex) { return JaChars.indexOf(this.data, this.size, accessCharArray(sb), sb.length(), fromIndex); } public boolean contains(final char c) { final char[] data = this.data; for(int i = 0, size = this.size; i < size; i++){ if(data[i] == c){ return true; } } return false; } public boolean contains(final char[] chars) { return JaChars.indexOf(this.data, this.size, chars, chars.length, 0) != -1; } public boolean contains(final String s) { return JaChars.indexOf(this.data, 0, this.size, accessCharArray(s), accessOffset(s), s.length(), 0) != -1; } public boolean contains(final VarChar vc) { return JaChars.indexOf(this.data, this.size, vc.data, vc.size, 0) != -1; } public boolean contains(final StringBuilder sb) { return JaChars.indexOf(this.data, this.size, accessCharArray(sb), sb.length(), 0) != -1; } public boolean contains(final StringBuffer sb) { return JaChars.indexOf(this.data, this.size, accessCharArray(sb), sb.length(), 0) != -1; } public int lastIndexOf(final char c) { final char[] data = this.data; for(int i = this.size; i --> 0;){ if(data[i] == c){ return i; } } return -1; } public int lastIndexOf(final char c, final int fromIndex) { if(fromIndex < 0 || fromIndex >= this.size){ throw new StringIndexOutOfBoundsException(fromIndex); } final char[] data = this.data; for(int i = fromIndex; i > 0; i--){ if(data[i] == c){ return i; } } return -1; } public int count(final char c) { return JaChars.count(this.data, 0, this.size, c); } public int count(final char[] chars) { return JaChars.count(this.data, 0, this.size, chars, 0, chars.length); } public int count(final String s) { return JaChars.count(this.data, 0, this.size, accessCharArray(s), accessOffset(s), s.length()); } public int count(final VarChar vc) { return JaChars.count(this.data, 0, this.size, vc.data, 0, vc.size); } public int count(final StringBuilder sb) { return JaChars.count(this.data, 0, this.size, accessCharArray(sb), 0, sb.length()); } public int count(final StringBuffer sb) { return JaChars.count(this.data, 0, this.size, accessCharArray(sb), 0, sb.length()); } public VarChar deleteCharAt(final int index) { final int lastIndex = this.size - 1; if(index < 0 || index > lastIndex){ throw new StringIndexOutOfBoundsException(index); } //intentionally don't check for index != lastIndex, as there's an extra method for that. System.arraycopy(this.data, index+1, this.data, index, lastIndex-index); this.size--; return this; } public VarChar deleteLastChar() { if(this.size == 0){ throw new StringIndexOutOfBoundsException("Cannot delete last char of no chars"); } this.size--; return this; } public VarChar deleteLast(final int n) { if(this.size < n){ throw new StringIndexOutOfBoundsException(n+" chars cannot be deleted from "+this.size+" chars"); } this.size -= n; return this; } public char[] toCharArray() { final char[] chars = new char[this.size]; System.arraycopy(this.data, 0, chars, 0, this.size); return chars; } public StringBuilder toStringBuilder() { return new StringBuilder(this.size).append(this.data); } public StringBuffer toStringBuffer() { return new StringBuffer(this.size).append(this.data); } public void getChars(final int srcBegin, final int srcEnd, final char dst[], final int dstBegin) { if (srcBegin < 0) { throw new StringIndexOutOfBoundsException(srcBegin); } if (srcEnd > this.size) { throw new StringIndexOutOfBoundsException(srcEnd); } if (srcBegin > srcEnd) { throw new StringIndexOutOfBoundsException(srcEnd - srcBegin); } System.arraycopy(this.data, srcBegin, dst, dstBegin, srcEnd - srcBegin); } public boolean isEmpty() { return this.size == 0; } public void trimToSize() { final int size = this.size; if(size<<1 > this.data.length || size > 1073741824){ return; //not shrinkable, abort } //only run from 4 to 1073741824 int newCapacity = CAPACITY_MIN; while(newCapacity < size){ newCapacity <<= 1; } final char[] data = new char[newCapacity]; System.arraycopy(this.data, 0, data, 0, size); this.data = data; } /** * * @param varChar * @return true if varChar is either null or empty. * @see {@link VarChar#isEmpty()} */ public static final boolean hasNoContent(final VarChar varChar) { return varChar == null || varChar.size == 0; } /** * * @param varChar * @return true if varChar is not null and not empty. * @see {@link VarChar#isEmpty()} */ public static final boolean hasContent(final VarChar varChar) { return varChar != null && varChar.size != 0; } public String replaceAll(final String regex, final String replacement) { return Pattern.compile(regex).matcher(this).replaceAll(replacement); } public String replace(final CharSequence target, final CharSequence replacement) { return Pattern.compile(target.toString(), Pattern.LITERAL).matcher( this).replaceAll(Matcher.quoteReplacement(replacement.toString())); } public String[] split(final String regex, final int limit) { return Pattern.compile(regex).split(this, limit); } public String[] split(final String regex) { return this.split(regex, 0); } public VarChar trim() { int size = this.size; int start = 0; final char[] data = this.data; while(start < size && data[start] <= ' '){ start++; } while(start < size && data[size - 1] <= ' '){ size--; } return start > 0 || size < this.size ? this.subsequence(start, size) : this; } public VarChar subsequence(final int beginIndex, final int endIndex) { if (beginIndex < 0) { throw new StringIndexOutOfBoundsException(beginIndex); } if (endIndex > this.size) { throw new StringIndexOutOfBoundsException(endIndex); } if (beginIndex > endIndex) { throw new StringIndexOutOfBoundsException(endIndex - beginIndex); } final int length = endIndex - beginIndex; final VarChar vc = new VarChar(length); System.arraycopy(this.data, beginIndex, vc.data, 0, length); vc.size = length; return vc; } public String substring(final int beginIndex, final int endIndex) { if (beginIndex < 0) { throw new StringIndexOutOfBoundsException(beginIndex); } if (endIndex > this.size) { throw new StringIndexOutOfBoundsException(endIndex); } if (beginIndex > endIndex) { throw new StringIndexOutOfBoundsException(endIndex - beginIndex); } return new String(this.data, beginIndex, endIndex - beginIndex); } public void process(final _charControllingProcessor processor) { final char[] data = this.data; for(int i = 0, size = this.size; i < size; i++){ try { processor.process(data[i]); } catch(final ThrowBreak e) { break; } catch(final ThrowContinue e){ continue; } catch(final ThrowReturn e) { return; } } } public void process(final _charOperation processor) { final char[] data = this.data; for(int i = 0, size = this.size; i < size; i++){ processor.execute(data[i]); } } public VarChar list(final Object... listElements) { final char sep = this.listSeperator; for(final Object e : listElements){ this.append(e).append(sep); } return this; } public VarChar list(final String... listElements) { final char sep = this.listSeperator; for(final String e : listElements){ this.append(e).append(sep); } return this; } public VarChar list(final VarChar... listElements) { final char sep = this.listSeperator; for(final VarChar e : listElements){ this.append(e).append(sep); } return this; } public VarChar list(final Appendable... listElements) { final char sep = this.listSeperator; for(final Appendable e : listElements){ this.append(e).append(sep); } return this; } public VarChar list(final boolean... listElements) { final char sep = this.listSeperator; for(final boolean e : listElements){ this.append(e).append(sep); } return this; } public VarChar list(final byte... listElements) { final char sep = this.listSeperator; for(final byte e : listElements){ this.append(e).append(sep); } return this; } public VarChar list(final short... listElements) { final char sep = this.listSeperator; for(final short e : listElements){ this.append(e).append(sep); } return this; } public VarChar list(final int... listElements) { final char sep = this.listSeperator; for(final int e : listElements){ this.append(e).append(sep); } return this; } public VarChar list(final long... listElements) { final char sep = this.listSeperator; for(final long e : listElements){ this.append(e).append(sep); } return this; } public VarChar list(final float... listElements) { final char sep = this.listSeperator; for(final float e : listElements){ this.append(e).append(sep); } return this; } public VarChar list(final double... listElements) { final char sep = this.listSeperator; for(final double e : listElements){ this.append(e).append(sep); } return this; } public VarChar list(final char... listElements) { final char sep = this.listSeperator; for(final char e : listElements){ this.append(e).append(sep); } return this; } public VarChar listIterable(final Iterable iterable) { final char sep = this.listSeperator; for(final Object e : iterable){ this.append(e).append(sep); } return this; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy