/*
* `gnu.iou'
* Copyright (C) 2006 John Pritchard.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 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 Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
* 02111-1307 USA
*/
package gnu.iou ;
/**
* String oriented character buffer used by `utf8' and others.
*
* @author John Pritchard (john@syntelos.org)
*/
public class chbuf extends Object {
public static String line_separator = "\r\n";
private char[] buf = null;
private int p = 0;
private int f = 10;
private char token_infix = (char)0;
public chbuf(){this(-1);}
public chbuf( int initsz){
super();
if ( 0 < initsz)
f = initsz;
buf = new char[f];
}
public chbuf ( Object obj){
this();
append(obj);
}
/**
* Append a SPACE character after each array element, but not the
* last. */
public chbuf ( String[] text){
this(text,' ');
}
/**
* Append the argument character after each array element, but not
* the last.
*
* @param text Source
*
* @param ch Source string delimeter
*/
public chbuf ( String[] text, char ch){
this();
if ( 0 < ch)
token_infix = ch;
append(text);
}
/**
* Append the argument character after each array element, but not
* the last.
*
* @param text Source
*
* @param ch_head Source string head
*
* @param ch Source string delimeter
*/
public chbuf ( char ch_head, String[] text, char ch){
this(text,ch);
prepend(ch_head);
}
/**
* Set a character to separate strings appended or printed into
* this buffer. Characters appended or prepended to this buffer
* will not be prefixed with the token infix character.
*
* <p> Set this to zero, or a negative value, to disable the token
* infix process.
*
* <p> Disabled by default.
*/
public void token_infix ( char ch){
if ( 0 < ch)
token_infix = ch;
else
token_infix = (char)0;
}
/**
* Inserts character at head of buffer, maintains content. */
public chbuf prepend(char ch){
if ( p >= buf.length){
char[] copier = new char[buf.length+f];
System.arraycopy(buf,0,copier,1,buf.length); // shift up
buf = copier;
}
else {
char[] copier = new char[buf.length];
System.arraycopy(buf,0,copier,1,p); // shift up
buf = copier;
}
p += 1;
buf[0] = ch;
return this;
}
public chbuf append(char ch){
int count = p;
if ( count >= buf.length){
char[] copier = new char[buf.length+f];
System.arraycopy(buf,0,copier,0,buf.length);
buf = copier;
}
buf[count] = ch;
p = count+1;
return this;
}
public char charAt ( int idx){
return buf[idx];
}
public void setCharAt( int idx, char ch) {
buf[idx] = ch;
}
public chbuf delete(int start, int end) {
int count = p;
if (end > count)
end = count;
int len = end - start;
if (len > 0) {
System.arraycopy(buf, start+len, buf, start, count-end);
p = count-len;
}
return this;
}
public chbuf deleteCharAt( int idx) {
int count = p;
System.arraycopy( buf, idx+1, buf, idx, count-idx-1);
p = count-1;
return this;
}
public chbuf insert ( int idx, char ch){
int count = p;
if ( count >= buf.length){
char[] copier = new char[buf.length+f];
System.arraycopy(buf,0,copier,0,buf.length);
buf = copier;
}
System.arraycopy( buf, idx, buf, idx+1, count-idx);
buf[idx] = ch;
p = count+1;
return this;
}
public chbuf insert ( int idx, String s){
if ( null == s || 0 > idx || idx > p)
return this;
else {
char[] cary = s.toCharArray();
int slen = cary.length;
if ( 1 > slen)
return this;
else {
int bound = idx+slen,
count = p+slen;
if ( count >= buf.length){
int grow = (f>bound)?(f):(bound);
char[] copier = new char[buf.length+grow];
System.arraycopy(buf,0,copier,0,buf.length);
buf = copier;
}
System.arraycopy( buf, idx, buf, idx+slen, count-idx);
System.arraycopy( cary, 0, buf, idx, slen);
p = count+1;
return this;
}
}
}
public void ensureCapacity(int min) {
if (min > buf.length) {
int delt = min-buf.length;
int nlen = buf.length+f;
char[] copier;
if ( nlen < min)
copier = new char[nlen+delt];
else
copier = new char[nlen];
System.arraycopy(buf,0,copier,0,p);
this.buf = copier;
}
}
public int capacity() {
return buf.length;
}
/**
* Typically used to truncate the string. Can be used to expand
* the string with null characters.
*/
public void setLength ( int len){
if (len < 0)
throw new StringIndexOutOfBoundsException(len);
else if ( len < p){
// truncate
p = len;
return;
}
else {
// grow
int many = len- p;
char ZERO = (char)0;
appendMany( ZERO, many);
}
}
public final void printMany( char ch, int many){
this.appendMany(ch,many);
}
public final void printMany( String str, int many){
if (null != str && 0 < str.length())
for (int idx = 0; idx < many; idx++)
this.print(str);
}
/**
* Repeat `ch' into this buffer `many' times.
*/
public void appendMany( char ch, int many){
for ( int cc = 0; cc < many; cc++){
if ( p >= buf.length){
char[] copier;
if ( f < many)
copier = new char[buf.length+f+many];
else
copier = new char[buf.length+f];
System.arraycopy(buf,0,copier,0,buf.length);
buf = copier;
}
buf[p++] = ch;
}
}
public final void appendMany( String str, int many){
if (null != str && 0 < str.length())
for (int idx = 0; idx < many; idx++)
this.append(str);
}
public void nprint(int many, String str){
if (null != str && 0 < str.length())
for (int idx = 0; idx < many; idx++)
this.print(str);
}
public void nappend(int many, String str){
if (null != str && 0 < str.length())
for (int idx = 0; idx < many; idx++)
this.append(str);
}
public void print( String s){
append(s);
}
public void print( char ch){
append(ch);
}
public void print( boolean bool){
append(java.lang.String.valueOf(bool));
}
public void print( int dval){
append(java.lang.String.valueOf(dval));
}
public void print( long dval){
append(java.lang.String.valueOf(dval));
}
public void print( float rval){
append(java.lang.String.valueOf(rval));
}
public void print( double rval){
append(java.lang.String.valueOf(rval));
}
public void print( Object ob){
append(ob);
}
public void println( String s){
append(s);
append(line_separator);
}
public void println( char ch){
append(ch);
append(line_separator);
}
public void println( boolean bool){
append(java.lang.String.valueOf(bool));
append(line_separator);
}
public void println( int dval){
append(java.lang.String.valueOf(dval));
append(line_separator);
}
public void println( long dval){
append(java.lang.String.valueOf(dval));
append(line_separator);
}
public void println( float rval){
append(java.lang.String.valueOf(rval));
append(line_separator);
}
public void println( double rval){
append(java.lang.String.valueOf(rval));
append(line_separator);
}
public void println( Object ob){
append(ob);
append(line_separator);
}
public void println(){
append(line_separator);
}
public chbuf append ( String s){
if ( null == s)
return this;
else {
char[] cary = s.toCharArray();
int sl = cary.length;
return append( cary, 0, sl);
}
}
public chbuf append ( char[] cary, int ofs, int len){
if ( 0 < p && 0 < token_infix && 0 < len){
char[] copier = new char[len+1];
copier[0] = token_infix;
System.arraycopy(cary,ofs,copier,1,len);
cary = copier;
len = cary.length;
}
else if ( 0 >= len)
return this;
if ( p+len >= buf.length){
if ( len > f) f = len;
char[] copier = new char[buf.length+f];
System.arraycopy(buf,0,copier,0,buf.length);
buf = copier;
}
System.arraycopy(cary,ofs,buf,p,len);
p += len;
return this;
}
/**
* Calls on <code>Object.toString</code>. */
public chbuf append ( Object o){
if ( null == o){
return this;
}
else if ( o instanceof String){
append( (String)o);
return this;
}
else {
Class cla = o.getClass();
if ( cla.isArray()){
Class ccla = cla.getComponentType();
if ( ccla.isPrimitive()){
switch(cla.getName().charAt(1)){
case 'I':
append( (int[])o);
return this;
case 'B':
append( (byte[])o);
return this;
case 'C':
append( (char[])o);
return this;
case 'J':
append( (long[])o);
return this;
case 'F':
append( (float[])o);
return this;
case 'S':
append( (short[])o);
return this;
case 'D':
append( (double[])o);
return this;
case 'Z':
append( (boolean[])o);
return this;
case '[':
append( (Object[])o);
return this;
default:
throw new IllegalArgumentException("Unrecognized primitive array component type `"+ccla.getName()+"'.");
}
}
else {
append( (Object[])o);
return this;
}
}
else {
append(o.toString());
return this;
}
}
}
/**
* In support of autogenerated source use of chbuf in 'toString'.
*/
public chbuf append ( Object[] oary){
if ( null == oary || 0 >= oary.length)
return this;
else {
append('[');
int len = oary.length;
for ( int cc = 0; cc < len; cc++){
if ( 0 < cc)
append(',');
append( oary[cc]);
}
append(']');
return this;
}
}
/**
* Appends each element, followed by the`token_infix'
* character when defined. */
public chbuf append ( String[] ary){
if ( null == ary)
return this;
else {
char infix = token_infix ;
String arg;
for ( int c = 0; c < ary.length; c++){
arg = ary[c];
if ( null != arg){
if ( 0 < infix && 0 < c)
append(infix);
append(arg);
}
}
return this;
}
}
/**
* Appends the characters, followed by the`token_infix'
* character when defined. */
public chbuf append ( char[] ary){
if ( null == ary)
return this;
else {
char infix = token_infix ;
for ( int c = 0; c < ary.length; c++){
append(ary[c]);
}
if ( 0 < infix)
append(infix);
return this;
}
}
/**
* Uses "true" and "false". */
public chbuf append ( boolean truf){
if ( truf)
return append("true");
else
return append("false");
}
/**
* Calls on <code>String.valueOf</code>. */
public chbuf append ( byte b){
return append(String.valueOf(b));
}
/**
* Calls on <code>String.valueOf</code>. */
public chbuf append ( short s){
return append(String.valueOf(s));
}
/**
* Calls on <code>String.valueOf</code>. */
public chbuf append ( int i){
return append(String.valueOf(i));
}
/**
* Calls on <code>String.valueOf</code>. */
public chbuf append ( long l){
return append(String.valueOf(l));
}
/**
* Calls on <code>String.valueOf</code>. */
public chbuf append ( float f){
return append(String.valueOf(f));
}
/**
* Calls on <code>String.valueOf</code>. */
public chbuf append ( double d){
return append(String.valueOf(d));
}
private final static char setopen = '[';
private final static char setclose = ']';
private final static char comma = ',';
/**
* Uses "true" and "false". */
public chbuf append ( boolean[] ary){
if ( null == ary)
return this;
else {
int alen = ary.length;
append(setopen);
for ( int cc = 0; cc < alen; cc++){
if ( 0 < cc)
append(comma);
append(String.valueOf(ary[cc]));
}
return append(setclose);
}
}
/**
* Calls on <code>String.valueOf</code>. */
public chbuf append ( byte[] ary){
if ( null == ary)
return this;
else {
append( utf8.decode(ary));
return this;
}
}
/**
* Calls on <code>String.valueOf</code>. */
public chbuf append ( short[] ary){
if ( null == ary)
return this;
else {
int alen = ary.length;
append(setopen);
for ( int cc = 0; cc < alen; cc++){
if ( 0 < cc)
append(comma);
append(String.valueOf(ary[cc]));
}
return append(setclose);
}
}
/**
* Calls on <code>String.valueOf</code>. */
public chbuf append ( int[] ary){
if ( null == ary)
return this;
else {
int alen = ary.length;
append(setopen);
for ( int cc = 0; cc < alen; cc++){
if ( 0 < cc)
append(comma);
append(String.valueOf(ary[cc]));
}
return append(setclose);
}
}
/**
* Calls on <code>String.valueOf</code>. */
public chbuf append ( long[] ary){
if ( null == ary)
return this;
else {
int alen = ary.length;
append(setopen);
for ( int cc = 0; cc < alen; cc++){
if ( 0 < cc)
append(comma);
append(String.valueOf(ary[cc]));
}
return append(setclose);
}
}
/**
* Calls on <code>String.valueOf</code>. */
public chbuf append ( float[] ary){
if ( null == ary)
return this;
else {
int alen = ary.length;
append(setopen);
for ( int cc = 0; cc < alen; cc++){
if ( 0 < cc)
append(comma);
append(String.valueOf(ary[cc]));
}
return append(setclose);
}
}
/**
* Calls on <code>String.valueOf</code>. */
public chbuf append ( double[] ary){
if ( null == ary)
return this;
else {
int alen = ary.length;
append(setopen);
for ( int cc = 0; cc < alen; cc++){
if ( 0 < cc)
append(comma);
append(String.valueOf(ary[cc]));
}
return append(setclose);
}
}
/**
* Returns null for an empty buffer. Doesn't reset the buffer,
* but allows continuation.
*
* @see #reset */
public char[] toCary(){
int pp = p;
if ( 0 == pp)
return null;
else {
char[] copier = new char[pp];
System.arraycopy(buf,0,copier,0,pp);
return copier;
}
}
/**
* Returns null for an empty buffer. Doesn't reset the buffer,
* but allows continuation.
*
* @see #reset */
public char[] toCharArray(){
return toCary();
}
/**
* Returns UTF-8 encoded bytes. Returns null for an empty buffer.
* Doesn't reset the buffer, but allows continuation.
*
* @see #reset */
public byte[] toByteArray(){
int pp = p;
if ( 0 == pp)
return null;
else {
char[] copier = new char[pp];
System.arraycopy(buf,0,copier,0,pp);
return utf8.encode(copier);
}
}
/**
* Returns null for an empty buffer. */
public String toString(){
char[] cary = toCary();
if ( null != cary)
return new String(cary,0,cary.length);
else
return null;
}
/**
* Content length. */
public int length(){
return p;
}
/**
* Discard content, reuse buffer. */
public void reset(){
p = 0;
}
/**
* Read one character from the buffer and reset to previous
* character for overwriting the popped character. */
public char popChar(){
if ( 0 < p)
return buf[p--];
else
return (char)0;
}
/**
* Similar to popChar, reset back "many" characters for using
* `chbuf' like a stream buffer.
*
* @param many Return "many", or fewer characters.
*/
public char[] popBuf( int many){
if ( 0 == p)
return null;
else if ( 0 < many && many <= p){
char[] copier = new char[many];
p -= many;
System.arraycopy(buf,p,copier,0,many);
return copier;
}
else {
char[] ret = toCary();
p = 0;
return ret;
}
}
/**
* Return buffer and reset. */
public char[] popBuf(){
char[] ret = toCary();
p = 0;
return ret;
}
public final static char[] toCharArray ( Object[] oary){
if ( null == oary)
return null;
else {
chbuf cb = new chbuf();
int olen = oary.length;
Object o;
for ( int cc = 0; cc < olen; cc++){
o = oary[cc];
if ( null != o){
if ( o instanceof boolean[])
cb.append((boolean[])o);
else if ( o instanceof byte[])
cb.append((byte[])o);
else if ( o instanceof short[])
cb.append((short[])o);
else if ( o instanceof int[])
cb.append((int[])o);
else if ( o instanceof long[])
cb.append((long[])o);
else if ( o instanceof float[])
cb.append((float[])o);
else if ( o instanceof double[])
cb.append((double[])o);
else if ( o instanceof Object[])
cb.append((Object[])o);
else
cb.append(o);
}
}
return cb.toCary();
}
}
public final static String toString ( Object[] oary){
char[] cary = toCharArray(oary);
if ( null == cary)
return null;
else
return new String(cary);
}
public final static String toString ( Object obj){
return new chbuf(obj).toString();
}
public final static char[] cat (char a, char[] b){
if (null == b)
return new char[]{a};
else {
int b_len = b.length;
if (1 > b_len)
return new char[]{a};
else {
char[] r = new char[b_len+1];
System.arraycopy(b,0,r,1,b_len);
r[0] = a;
return r;
}
}
}
/**
* Concatenate two character arrays */
public final static char[] cat ( char[] a, char[] b){
if ( null == a)
return b;
else if ( null == b)
return a;
else {
char[] rcary;
int aclen = a.length, bclen = b.length;
rcary = new char[aclen+bclen];
System.arraycopy( a, 0, rcary, 0, aclen);
System.arraycopy( b, 0, rcary, aclen, bclen);
return rcary;
}
}
/**
* Concatenate two character arrays */
public final static char[] cat ( char[] a, char[] b, int bofs, int blen){
if ( null == a)
return b;
else if ( null == b || 1 > blen)
return a;
else {
char[] rcary;
int aclen = a.length;
rcary = new char[aclen+blen];
System.arraycopy( a, 0, rcary, 0, aclen);
System.arraycopy( b, bofs, rcary, aclen, blen);
return rcary;
}
}
/**
* Concatenate three character arrays */
public final static char[] cat ( char[] a, char[] b, char[] c){
if ( null == a)
return cat(b,c);
else if ( null == b)
return cat(a,c);
else if ( null == c)
return cat(a,b);
else {
char[] rcary;
int a_clen = a.length,
b_clen = b.length,
c_clen = c.length;
rcary = new char[a_clen+b_clen+c_clen];
System.arraycopy( a, 0, rcary, 0, a_clen);
System.arraycopy( b, 0, rcary, a_clen, b_clen);
System.arraycopy( c, 0, rcary, a_clen+b_clen, c_clen);
return rcary;
}
}
/**
* Concatenate two strings. (This is faster than using the string
* concatenation operator in Java programming which results in a
* StringBuffer object allocation and its synchronized use at
* runtime.) */
public final static String cat ( String a, String b){
if ( null == a)
return b;
else if ( null == b)
return a;
else {
char[] acary = a.toCharArray(), bcary = b.toCharArray(), rcary;
int aclen = acary.length, bclen = bcary.length;
rcary = new char[aclen+bclen];
System.arraycopy( acary, 0, rcary, 0, aclen);
System.arraycopy( bcary, 0, rcary, aclen, bclen);
return new String(rcary);
}
}
/**
* Concatenate two character arrays */
public final static String cat ( String a, char[] bcary){
if ( null == a){
if ( null == bcary)
return null;
else
return new String(bcary);
}
else if ( null == bcary)
return a;
else {
char[] acary = a.toCharArray(), rcary;
int aclen = acary.length, bclen = bcary.length;
rcary = new char[aclen+bclen];
System.arraycopy( acary, 0, rcary, 0, aclen);
System.arraycopy( bcary, 0, rcary, aclen, bclen);
return new String(rcary);
}
}
/**
* Concatenate two character arrays */
public final static String cat ( String a, char[] bcary, int bofs, int blen){
if ( null == a){
if ( null == bcary || 1 > blen)
return null;
else
return new String(bcary,bofs,blen);
}
else if ( null == bcary)
return a;
else {
char[] acary = a.toCharArray(), rcary;
int aclen = acary.length;
rcary = new char[aclen+blen];
System.arraycopy( acary, 0, rcary, 0, aclen);
System.arraycopy( bcary, bofs, rcary, aclen, blen);
return new String(rcary);
}
}
/**
* Concatenate three strings
*/
public final static String cat ( String a, String b, String c){
if ( null == a)
return cat(b,c);
else if ( null == b)
return cat(a,c);
else if ( null == c)
return cat(a,b);
else {
char[] acary = a.toCharArray(),
bcary = b.toCharArray(),
ccary = c.toCharArray(),
rcary;
int aclen = acary.length, bclen = bcary.length, cclen = ccary.length;
rcary = new char[aclen+bclen+cclen];
System.arraycopy( acary, 0, rcary, 0, aclen);
System.arraycopy( bcary, 0, rcary, aclen, bclen);
System.arraycopy( ccary, 0, rcary, aclen+bclen, cclen);
return new String(rcary);
}
}
/**
* Concatenate three strings
*/
public final static String cat ( String a, String b, char[] ccary){
if ( null == a)
return cat(b,ccary);
else if ( null == b)
return cat(a,ccary);
else if ( null == ccary)
return cat(a,b);
else {
char[] acary = a.toCharArray(),
bcary = b.toCharArray(),
rcary;
int aclen = acary.length, bclen = bcary.length, cclen = ccary.length;
rcary = new char[aclen+bclen+cclen];
System.arraycopy( acary, 0, rcary, 0, aclen);
System.arraycopy( bcary, 0, rcary, aclen, bclen);
System.arraycopy( ccary, 0, rcary, aclen+bclen, cclen);
return new String(rcary);
}
}
/**
* Concatenate three strings
*/
public final static String cat ( String a, String b, char[] ccary, int ccary_ofs, int ccary_len){
if ( null == a)
return cat(b,ccary);
else if ( null == b)
return cat(a,ccary);
else if ( null == ccary)
return cat(a,b);
else {
char[] acary = a.toCharArray(),
bcary = b.toCharArray(),
rcary;
int aclen = acary.length, bclen = bcary.length;
rcary = new char[aclen+bclen+ccary_len];
System.arraycopy( acary, 0, rcary, 0, aclen);
System.arraycopy( bcary, 0, rcary, aclen, bclen);
System.arraycopy( ccary, ccary_ofs, rcary, aclen+bclen, ccary_len);
return new String(rcary);
}
}
/**
* Concatenate four strings
*/
public final static String cat ( String a, String b, String c, String d){
if ( null == a)
return cat(b,c,d);
else if ( null == b)
return cat(a,c,d);
else if ( null == c)
return cat(a,b,d);
else if ( null == d)
return cat(a,b,c);
else {
char[] a_cary = a.toCharArray(),
b_cary = b.toCharArray(),
c_cary = c.toCharArray(),
d_cary = d.toCharArray(),
r_cary;
int a_clen = a_cary.length,
b_clen = b_cary.length,
c_clen = c_cary.length,
d_clen = d_cary.length,
clen = a_clen;
r_cary = new char[a_clen+b_clen+c_clen+d_clen];
System.arraycopy( a_cary, 0, r_cary, 0, a_clen);
System.arraycopy( b_cary, 0, r_cary, clen, b_clen);
clen += b_clen;
System.arraycopy( c_cary, 0, r_cary, clen, c_clen);
clen += c_clen;
System.arraycopy( d_cary, 0, r_cary, clen, d_clen);
return new String(r_cary);
}
}
/**
* Concatenate five strings
*/
public final static String cat ( String a, String b, String c, String d, String e){
if ( null == a)
return cat(b,c,d,e);
else if ( null == b)
return cat(a,c,d,e);
else if ( null == c)
return cat(a,b,d,e);
else if ( null == d)
return cat(a,b,c,e);
else if ( null == e)
return cat(a,b,c,d);
else {
char[] a_cary = a.toCharArray(),
b_cary = b.toCharArray(),
c_cary = c.toCharArray(),
d_cary = d.toCharArray(),
e_cary = e.toCharArray(),
r_cary;
int a_clen = a_cary.length,
b_clen = b_cary.length,
c_clen = c_cary.length,
d_clen = d_cary.length,
e_clen = e_cary.length,
clen = a_clen;
r_cary = new char[a_clen+b_clen+c_clen+d_clen+e_clen];
System.arraycopy( a_cary, 0, r_cary, 0, a_clen);
System.arraycopy( b_cary, 0, r_cary, clen, b_clen);
clen += b_clen;
System.arraycopy( c_cary, 0, r_cary, clen, c_clen);
clen += c_clen;
System.arraycopy( d_cary, 0, r_cary, clen, d_clen);
clen += d_clen;
System.arraycopy( e_cary, 0, r_cary, clen, e_clen);
return new String(r_cary);
}
}
/**
* Concatenate six strings
*/
public final static String cat ( String a, String b, String c, String d, String e, String f){
if ( null == a)
return cat(b,c,d,e,f);
else if ( null == b)
return cat(a,c,d,e,f);
else if ( null == c)
return cat(a,b,d,e,f);
else if ( null == d)
return cat(a,b,c,e,f);
else if ( null == e)
return cat(a,b,c,d,f);
else if ( null == f)
return cat(a,b,c,d,e);
else {
char[] a_cary = a.toCharArray(),
b_cary = b.toCharArray(),
c_cary = c.toCharArray(),
d_cary = d.toCharArray(),
e_cary = e.toCharArray(),
f_cary = f.toCharArray(),
r_cary;
int a_clen = a_cary.length,
b_clen = b_cary.length,
c_clen = c_cary.length,
d_clen = d_cary.length,
e_clen = e_cary.length,
f_clen = f_cary.length,
clen = a_clen;
r_cary = new char[a_clen+b_clen+c_clen+d_clen+e_clen+f_clen];
System.arraycopy( a_cary, 0, r_cary, 0, a_clen);
System.arraycopy( b_cary, 0, r_cary, clen, b_clen);
clen += b_clen;
System.arraycopy( c_cary, 0, r_cary, clen, c_clen);
clen += c_clen;
System.arraycopy( d_cary, 0, r_cary, clen, d_clen);
clen += d_clen;
System.arraycopy( e_cary, 0, r_cary, clen, e_clen);
clen += e_clen;
System.arraycopy( f_cary, 0, r_cary, clen, f_clen);
return new String(r_cary);
}
}
/**
* Concatenate seven strings
*/
public final static String cat ( String a, String b, String c, String d, String e, String f, String g){
if ( null == a)
return cat(b,c,d,e,f,g);
else if ( null == b)
return cat(a,c,d,e,f,g);
else if ( null == c)
return cat(a,b,d,e,f,g);
else if ( null == d)
return cat(a,b,c,e,f,g);
else if ( null == e)
return cat(a,b,c,d,f,g);
else if ( null == f)
return cat(a,b,c,d,e,g);
else if ( null == g)
return cat(a,b,c,d,e,f);
else {
char[] a_cary = a.toCharArray(),
b_cary = b.toCharArray(),
c_cary = c.toCharArray(),
d_cary = d.toCharArray(),
e_cary = e.toCharArray(),
f_cary = f.toCharArray(),
g_cary = g.toCharArray(),
r_cary;
int a_clen = a_cary.length,
b_clen = b_cary.length,
c_clen = c_cary.length,
d_clen = d_cary.length,
e_clen = e_cary.length,
f_clen = f_cary.length,
g_clen = g_cary.length,
clen = a_clen;
r_cary = new char[a_clen+b_clen+c_clen+d_clen+e_clen+f_clen+g_clen];
System.arraycopy( a_cary, 0, r_cary, 0, a_clen);
System.arraycopy( b_cary, 0, r_cary, clen, b_clen);
clen += b_clen;
System.arraycopy( c_cary, 0, r_cary, clen, c_clen);
clen += c_clen;
System.arraycopy( d_cary, 0, r_cary, clen, d_clen);
clen += d_clen;
System.arraycopy( e_cary, 0, r_cary, clen, e_clen);
clen += e_clen;
System.arraycopy( f_cary, 0, r_cary, clen, f_clen);
clen += f_clen;
System.arraycopy( g_cary, 0, r_cary, clen, g_clen);
return new String(r_cary);
}
}
/**
* Concatenate eight strings
*/
public final static String cat ( String a, String b, String c, String d, String e, String f, String g, String h){
if ( null == a)
return cat(b,c,d,e,f,g,h);
else if ( null == b)
return cat(a,c,d,e,f,g,h);
else if ( null == c)
return cat(a,b,d,e,f,g,h);
else if ( null == d)
return cat(a,b,c,e,f,g,h);
else if ( null == e)
return cat(a,b,c,d,f,g,h);
else if ( null == f)
return cat(a,b,c,d,e,g,h);
else if ( null == g)
return cat(a,b,c,d,e,f,h);
else if ( null == h)
return cat(a,b,c,d,e,f,g);
else {
char[] a_cary = a.toCharArray(),
b_cary = b.toCharArray(),
c_cary = c.toCharArray(),
d_cary = d.toCharArray(),
e_cary = e.toCharArray(),
f_cary = f.toCharArray(),
g_cary = g.toCharArray(),
h_cary = h.toCharArray(),
r_cary;
int a_clen = a_cary.length,
b_clen = b_cary.length,
c_clen = c_cary.length,
d_clen = d_cary.length,
e_clen = e_cary.length,
f_clen = f_cary.length,
g_clen = g_cary.length,
h_clen = h_cary.length,
clen = a_clen;
r_cary = new char[a_clen+b_clen+c_clen+d_clen+e_clen+f_clen+g_clen+h_clen];
System.arraycopy( a_cary, 0, r_cary, 0, a_clen);
System.arraycopy( b_cary, 0, r_cary, clen, b_clen);
clen += b_clen;
System.arraycopy( c_cary, 0, r_cary, clen, c_clen);
clen += c_clen;
System.arraycopy( d_cary, 0, r_cary, clen, d_clen);
clen += d_clen;
System.arraycopy( e_cary, 0, r_cary, clen, e_clen);
clen += e_clen;
System.arraycopy( f_cary, 0, r_cary, clen, f_clen);
clen += f_clen;
System.arraycopy( g_cary, 0, r_cary, clen, g_clen);
clen += g_clen;
System.arraycopy( h_cary, 0, r_cary, clen, h_clen);
return new String(r_cary);
}
}
/**
* Concatenate nine strings
*/
public final static String cat ( String a, String b, String c, String d, String e, String f, String g, String h, String i){
if ( null == a)
return cat(b,c,d,e,f,g,h,i);
else if ( null == b)
return cat(a,c,d,e,f,g,h,i);
else if ( null == c)
return cat(a,b,d,e,f,g,h,i);
else if ( null == d)
return cat(a,b,c,e,f,g,h,i);
else if ( null == e)
return cat(a,b,c,d,f,g,h,i);
else if ( null == f)
return cat(a,b,c,d,e,g,h,i);
else if ( null == g)
return cat(a,b,c,d,e,f,h,i);
else if ( null == h)
return cat(a,b,c,d,e,f,g,i);
else if ( null == i)
return cat(a,b,c,d,e,f,g,h);
else {
char[] a_cary = a.toCharArray(),
b_cary = b.toCharArray(),
c_cary = c.toCharArray(),
d_cary = d.toCharArray(),
e_cary = e.toCharArray(),
f_cary = f.toCharArray(),
g_cary = g.toCharArray(),
h_cary = h.toCharArray(),
i_cary = i.toCharArray(),
r_cary;
int a_clen = a_cary.length,
b_clen = b_cary.length,
c_clen = c_cary.length,
d_clen = d_cary.length,
e_clen = e_cary.length,
f_clen = f_cary.length,
g_clen = g_cary.length,
h_clen = h_cary.length,
i_clen = i_cary.length,
clen = a_clen;
r_cary = new char[a_clen+b_clen+c_clen+d_clen+e_clen+f_clen+g_clen+h_clen+i_clen];
System.arraycopy( a_cary, 0, r_cary, 0, a_clen);
System.arraycopy( b_cary, 0, r_cary, clen, b_clen);
clen += b_clen;
System.arraycopy( c_cary, 0, r_cary, clen, c_clen);
clen += c_clen;
System.arraycopy( d_cary, 0, r_cary, clen, d_clen);
clen += d_clen;
System.arraycopy( e_cary, 0, r_cary, clen, e_clen);
clen += e_clen;
System.arraycopy( f_cary, 0, r_cary, clen, f_clen);
clen += f_clen;
System.arraycopy( g_cary, 0, r_cary, clen, g_clen);
clen += g_clen;
System.arraycopy( h_cary, 0, r_cary, clen, h_clen);
clen += h_clen;
System.arraycopy( i_cary, 0, r_cary, clen, i_clen);
return new String(r_cary);
}
}
private final static char fcat_ch = '/';
private final static char[] fcat_ca = {fcat_ch};
/**
* Concatenate two file or url path strings, guaranteeing exactly one url
* path separator <tt>("/")</tt> between each string.
*/
public final static String fcat ( String a, String b){
if ( null == a){
/*
* Prepend
*/
if (null == b)
return null;
else {
char[] b_cary = b.toCharArray();
int b_len = b_cary.length;
if ( 0 >= b_len)
return null;
else if (fcat_ch == b_cary[0])
return b;
else {
char[] r_cary = new char[b_len+1];
r_cary[0] = fcat_ch;
System.arraycopy(b_cary,0,r_cary,1,b_len);
return new String(r_cary);
}
}
}
else if ( null == b){
/*
* Append
*/
if (null == a)
return null;
else {
char[] a_cary = a.toCharArray();
int a_len = a_cary.length;
if ( 0 >= a_len)
return null;
else if (fcat_ch == a_cary[ (a_len - 1) ])
return a;
else {
char[] r_cary = new char[a_len+1];
r_cary[a_len] = fcat_ch;
System.arraycopy(a_cary,0,r_cary,0,a_len);
return new String(r_cary);
}
}
}
else {
char[] a_cary = a.toCharArray(),
b_cary = b.toCharArray();
if ( 1 > a_cary.length)
return b;
else if ( 1 > b_cary.length)
return a;
else {
char aN = a_cary[a_cary.length-1];
char b0 = b_cary[0];
if ( fcat_ch != aN && fcat_ch != b0)
return new String( cat( a_cary, fcat_ca, b_cary));
else if ( fcat_ch == aN && fcat_ch == b0)
return new String( cat( a_cary, b_cary,1,b_cary.length-1));
else
return new String( cat( a_cary, b_cary));
}
}
}
public final static char[] substring ( char[] cary, int idx){
if ( null == cary)
return null;
else
return substring(cary,idx,cary.length);
}
public final static char[] substring ( char[] cary, int from_idx, int to_idx){
if ( null == cary || 0 >= to_idx || 0 > from_idx)
return null;
else {
char[] copier = new char[to_idx-from_idx];
System.arraycopy(cary,from_idx,copier,0,copier.length);
return copier;
}
}
public final static int indexOf ( char[] str, char ch){
if ( null == str)
return -1;
else {
int strlen = str.length;
for ( int cc = 0; cc < strlen; cc++){
if ( ch == str[cc])
return cc;
}
return -1;
}
}
public final static int indexOf ( char[] str, char[] term){
return indexOf(str,term,0);
}
public final static int indexOf ( char[] str, char[] term, int fromidx){
if ( null == str || null == term)
return -1;
else {
int strlen = str.length;
int termlen = term.length;
boolean found = true;
for ( int cc = fromidx, tc, tcc; cc < strlen; cc++){
if ( term[0] == str[cc]){
found = true;
for ( tc = 1, tcc = (cc+1); tc < termlen && tcc < strlen; tc++, tcc++){
if ( term[tc] != str[tcc]){
found = false;
break;
}
}
if (found)
return cc;
}
}
return -1;
}
}
public final static int lastIndexOf ( char[] str, char ch){
if ( null == str)
return -1;
else {
for ( int cc = str.length-1; cc >= 0; cc--){
if ( ch == str[cc])
return cc;
}
return -1;
}
}
public final static char[] copy ( char[] valc){
if ( null == valc)
return null;
else {
int valclen = valc.length;
char[] copier = new char[valclen];
System.arraycopy(valc,0,copier,0,valclen);
return copier;
}
}
/**
* Accept hex, octal and decimal number strings using traditional
* string formatting: "0x", "0X" and "#" prefixes for hexidecimal,
* "0" for octal and otherwise presume decimal.
*/
public final static long decode_long ( String s) throws NumberFormatException {
char ch = s.charAt(0);
if ( '0' == ch){
ch = s.charAt(1);
if ( 'x' == ch || 'X' == ch)
return Long.parseLong(s.substring(2), 16);
else
return Long.parseLong(s.substring(1), 8);
}
else if ( '#' == ch)
return Long.parseLong(s.substring(1), 16);
else
return Long.parseLong(s,10);
}
/**
* Accept hex, octal and decimal number strings using traditional
* string formatting: "0x", "0X" and "#" prefixes for hexidecimal,
* "0" for octal and otherwise presume decimal.
*/
public final static int decode_int ( String s) throws NumberFormatException {
char ch = s.charAt(0);
if ( '0' == ch){
ch = s.charAt(1);
if ( 'x' == ch || 'X' == ch)
return Integer.parseInt(s.substring(2), 16);
else
return Integer.parseInt(s.substring(1), 8);
}
else if ( '#' == ch)
return Integer.parseInt(s.substring(1), 16);
else
return Integer.parseInt(s,10);
}
/**
* Return 64 characters in ASCII `1' or `0' representing input number.
*/
public final static String toBinaryString( long ln){
char ret[] = new char[64], one = '1', zero = '0';
for ( int lc = 0; lc < 64; lc++){
if ( 1 == (ln & 1))
ret[63-lc] = one;
else
ret[63-lc] = zero;
ln >>>= 1;
}
return new String(ret);
}
/**
* Return 32 characters in ASCII `1' or `0' representing input number.
*/
public final static String toBinaryString( int ln){
char ret[] = new char[32], one = '1', zero = '0';
for ( int lc = 0; lc < 32; lc++){
if ( 1 == (ln & 1))
ret[31-lc] = one;
else
ret[31-lc] = zero;
ln >>>= 1;
}
return new String(ret);
}
/**
* Convert a string to title case, where an initial alpha
* character, and any alpha character following whitespace, is
* upper case. As the title of a book.
*/
public final static String toTitleCase( String s){
if ( null == s)
return null;
else {
char[] cary = s.toCharArray();
int len = cary.length;
if ( 0 < len){
cary[0] = Character.toUpperCase(cary[0]);
boolean next = false;
for ( int cc = 1; cc < len; cc++){
if (next){
if (!Character.isWhitespace(cary[cc])){
cary[cc] = Character.toUpperCase(cary[cc]);
next = false;
}
}
else if (Character.isWhitespace(cary[cc]))
next = true;
else
continue;
}
return new String(cary);
}
else
return s;
}
}
/**
* Truncate substring from source
* @param src Source string buffer
* @param src_ofs Source string offset within source string buffer
* @param src_len Source string length from offset within buffer
* @param trunc_ofs Truncate substring offset within source string
* in absolute buffer index coordinates --- same as 'src_ofs', not
* relative to 'src_ofs', so that src_ofs value zero points to the
* identical string character as 'trunc_ofs' value zero, etc.
* @param trunc_len Truncate substring length from substring offset
*/
public final static char[] truncate(char[] src, int src_ofs, int src_len,
int trunc_ofs, int trunc_len)
{
if (null == src || 0 > src_ofs || 0 > src_len)
throw new java.lang.IllegalArgumentException("src");
else if (0 > trunc_ofs || 1 > trunc_len || trunc_ofs < src_ofs || trunc_len > src_len)
throw new java.lang.IllegalArgumentException("trunc");
else if (trunc_ofs == src_ofs){
if (trunc_len == src_len){
if (src.length == src_len)
return src;
else if (0 == src_len)
return null;
else {
char[] re = new char[src_len];
System.arraycopy(src,src_ofs,re,0,src_len);
return re;
}
}
else /*(trunc_len < src_len)*/{
int re_len = (src_len - trunc_len);
if (0 == re_len)
return null;
else {
char[] re = new char[src_len];
System.arraycopy(src,src_ofs,re,0,re_len);
return re;
}
}
}
else if (trunc_len == src_len)
throw new java.lang.IllegalArgumentException("trunc");
else /*(trunc_ofs > src_ofs)&&
*(trunc_len < src_len)
*/
{
int a_ofs = src_ofs;
int a_len = (trunc_ofs-src_ofs);
char[] a = substring(src,a_ofs,a_len);
int b_ofs = trunc_ofs+trunc_len;
int b_len = (src_len - (b_ofs + 1));
char[] b = substring(src,b_ofs,b_len);
return cat(a,b);
}
}
/**
* Truncate substring from source
* @param src Source string
* @param trunc_ofs Truncate substring offset
* @param trunc_len Truncate substring length
*/
public final static char[] truncate(char[] src, int trunc_ofs, int trunc_len){
if (null == src)
throw new java.lang.IllegalArgumentException("Null src");
else
return truncate(src,0,src.length,trunc_ofs,trunc_len);
}
/**
* Truncate substring from source
* @param src Source string
* @param trunc_ofs Truncate substring offset
* @param trunc_len Truncate substring length
*/
public final static java.lang.String truncate(java.lang.String src, int trunc_ofs, int trunc_len){
if (null == src)
throw new java.lang.IllegalArgumentException("Null src");
else {
char[] cary = src.toCharArray();
char[] re = truncate(cary,0,cary.length,trunc_ofs,trunc_len);
if (null == re)
return null;
else
return new java.lang.String(re);
}
}
private final static char[] hexchars = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
/**
* From binary to ASCII
*/
public final static String hex ( byte[] buffer){
chbuf strbuf = new chbuf();
int val;
for ( int len = buffer.length, cc = 0; cc < len; cc++){
val = (buffer[cc]&0xff);
strbuf.append(hexchars[(val>>4)&0xf]);
strbuf.append(hexchars[ val&0xf]);
}
return strbuf.toString();
}
/**
* From binary to ASCII
*/
public final static byte[] hex_ascii ( byte[] buffer){
bbuf out = new bbuf();
int val;
for ( int len = buffer.length, cc = 0; cc < len; cc++){
val = (buffer[cc]&0xff);
out.write( hexchars[(val>>4)&0xf]);
out.write( hexchars[ val&0xf]);
}
return out.toByteArray();
}
/**
* From ASCII to binary
*/
public final static byte[] hex ( String h){
int len = h.length();
byte[] cary = new byte[len];
h.toUpperCase().getBytes(0,len,cary,0);
return ascii_hex( cary, 0, len);
}
/**
* From ASCII to binary
*/
public final static byte[] ascii_hex ( byte[] b){
return ascii_hex( b, 0, b.length);
}
/**
* From ASCII to binary
*/
public final static byte[] ascii_hex ( byte[] cary, int ofs, int len){
int term = len-1;
if ( 1 == (len&1)){ // odd number of digits in `cary'
len += 1;
term = len-1;
}
byte[] buffer = new byte[len/2];
int bcm = 1;
if ( 0 < ofs){
if (1 == (ofs&1))
bcm = 2;
else
bcm = 1;
len += ofs;
}
byte ch;
for ( int cc = ofs, bc = 0; cc < len; cc++){
if ( cc == term && cc == cary.length)
break; // odd number of digits
else
ch = cary[cc];
if ( ofs < cc && (0 == (cc & bcm)))
bc += 1;
if ( '0' <= ch){
if ( '9' >= ch){
if ( 1 == (cc&1))
buffer[bc] += (byte)(ch-'0');
else
buffer[bc] += (byte)((ch-'0')<<4);
}
else if ( 'a' <= ch && 'f' >= ch){
if ( 1 == (cc&1))
buffer[bc] += (byte)((ch-'a')+10);
else
buffer[bc] += (byte)(((ch-'a')+10)<<4);
}
else if ( 'A' <= ch && 'F' >= ch){
if ( 1 == (cc&1))
buffer[bc] += (byte)((ch-'A')+10);
else
buffer[bc] += (byte)(((ch-'A')+10)<<4);
}
else
throw new IllegalArgumentException("String is not hex.");
}
else
throw new IllegalArgumentException("String is not hex.");
}
return buffer;
}
}