/* * Javolution - Java(TM) Solution for Real-Time and Embedded Systems * Copyright (C) 2005 - Javolution (http://javolution.org/) * All rights reserved. * * Permission to use, copy, modify, and distribute this software is * freely granted, provided that this notice is preserved. */ package javolution.text; import j2me.lang.CharSequence; import j2me.lang.Comparable; import javolution.util.FastComparator; /** *
This class represents a character sequence backed up by a
* char
array. Instances of this class are mutable and
* are typically used/reused to hold temporary text (unlike
* String
they do not forces object creation).
Instances of this classes have the following properties:
CharSequence
(e.g. String
).String
and can be
* used to retrieve data from maps for which the keys are
* String
instances.this
*/
public CharArray setArray(char[] array, int offset, int length) {
_array = array;
_offset = offset;
_length = length;
_asString = null;
return this;
}
/**
* Returns the character at the specified index.
*
* @param index the index of the character starting at 0
.
* @return the character at the specified index of this character sequence.
* @throws IndexOutOfBoundsException if ((index < 0) ||
* (index >= length))
*/
public char charAt(int index) {
if ((index < 0) || (index >= _length))
throw new IndexOutOfBoundsException("index: " + index);
return _array[_offset + index];
}
/**
* Returns a new character sequence that is a subsequence of this sequence.
*
* @param start the index of the first character inclusive.
* @param end the index of the last character exclusive.
* @return the character sequence starting at the specified
* start
position and ending just before the specified
* end
position.
* @throws IndexOutOfBoundsException if (start < 0) || (end < 0) ||
* (start > end) || (end > this.length())
*/
public CharSequence subSequence(int start, int end) {
if ((start < 0) || (end < 0) || (start > end) || (end > this.length()))
throw new IndexOutOfBoundsException();
CharArray chars = new CharArray();
chars._array = _array;
chars._offset = _offset + start;
chars._length = end - start;
return chars;
}
/**
* Returns the offset within this character array of the first occurrence
* of the specified characters sequence searching forward from this
* character array {@link #offset()} to offset() + length()
.
*
* @param csq a character sequence searched for.
* @return the offset of the specified character sequence in the range
* [offset(), offset() + length()[
* or -1
if the character sequence is not found.
*/
public final int offsetOf(CharSequence csq) {
final char c = csq.charAt(0);
final int csqLength = csq.length();
for (int i=_offset, end = _offset + _length - csqLength + 1; i < end; i++) {
if (_array[i] == c) { // Potential match.
boolean match = true;
for (int j = 1; j < csqLength; j++) {
if (_array[i + j] != csq.charAt(j)) {
match = false;
break;
}
}
if (match) {
return i;
}
}
}
return -1;
}
/**
* Returns the offset within this character array of the first occurrence
* of the specified character searching forward from this
* character array {@link #offset()} to offset() + length()
.
*
* @param c the character to search for.
* @return the offset of the specified character in the range
* [offset(), offset() + length()[
* or -1
if the character is not found.
*/
public final int offsetOf(char c) {
for (int i=_offset, end = _offset + _length; i < end; i++) {
if (_array[i] == c) return i;
}
return -1;
}
/**
* Returns the String corresponding to this character
* sequence. The String
returned is always allocated on the
* heap and can safely be referenced elsewhere.
*
* @return the java.lang.String
for this character sequence.
*/
public String toString() {
if (_asString == null) {
_asString = new String(_array, _offset, _length);
}
return _asString;
}
/**
* Returns the hash code for this {@link CharArray}.
*
* Note: Returns the same hashCode as java.lang.String
* (consistent with {@link #equals})
* @return the hash code value.
*/
public int hashCode() {
if (_asString != null) return _asString.hashCode();
int h = 0;
for (int i = 0, j = _offset; i < _length; i++) {
h = 31 * h + _array[j++];
}
return h;
}
/**
* Compares this character sequence against the specified object
* (String
or CharSequence
).
*
* @param that the object to compare with.
* @return true
if both objects represent the same sequence;
* false
otherwise.
*/
public boolean equals(Object that) {
if (that instanceof String) {
return equals((String) that);
} else if (that instanceof CharArray) {
return equals((CharArray) that);
} else if (that instanceof CharSequence) {
return equals((CharSequence) that);
} else {
return false;
}
}
// Do not make public or String instances may not use equals(String)
private boolean equals(CharSequence chars) {
if (chars == null)
return false;
if (this._length != chars.length())
return false;
for (int i = _length, j = _offset + _length; --i >= 0;) {
if (_array[--j] != chars.charAt(i))
return false;
}
return true;
}
/**
* Compares this character array against the specified {@link CharArray}.
*
* @param that the character array to compare with.
* @return true
if both objects represent the same sequence;
* false
otherwise.
*/
public boolean equals(CharArray that) {
if (this == that)
return true;
if (that == null)
return false;
if (this._length != that._length)
return false;
final char[] thatData = that._array;
for (int i = that._offset + _length, j = _offset + _length; --j >= _offset;) {
if (_array[j] != thatData[--i])
return false;
}
return true;
}
/**
* Compares this character array against the specified String.
* In case of equality, the CharArray keeps a reference to the
* String for future comparisons.
*
* @param str the string to compare with.
* @return true
if both objects represent the same sequence;
* false
otherwise.
*/
public boolean equals(String str) {
if (_asString != null)
return (_asString == str) ? true : _asString.equals(str) ?
(_asString = str) == str : false;
if (str == null)
return false;
if (_length != str.length())
return false;
for (int i = _length, j = _offset + _length; --i >= 0;) {
if (_array[--j] != str.charAt(i))
return false;
}
_asString = str;
return true;
}
/**
* Compares this character array with the specified character
* sequence lexicographically.
*
* @param seq the character sequence to be compared.
* @return {@link FastComparator#LEXICAL}.compare(this, seq)
* @throws ClassCastException if the specifed object is not a
* CharSequence
.
*/
public int compareTo(Object seq) {
return ((FastComparator)FastComparator.LEXICAL).compare(this, seq);
}
/**
* Returns the boolean
represented by this character array.
*
* @return the corresponding boolean
value.
* @throws NumberFormatException if this character sequence
* does not contain a parsable boolean
.
*/
public boolean toBoolean() {
int i = _offset;
if ((_length == 4) && (_array[i] == 't' || _array[i] == 'T')
&& (_array[++i] == 'r' || _array[i] == 'R')
&& (_array[++i] == 'u' || _array[i] == 'U')
&& (_array[++i] == 'e' || _array[i] == 'E'))
return true;
if ((_length == 5) && (_array[i] == 'f' || _array[i] == 'F')
&& (_array[++i] == 'a' || _array[i] == 'A')
&& (_array[++i] == 'l' || _array[i] == 'L')
&& (_array[++i] == 's' || _array[i] == 'S')
&& (_array[++i] == 'e' || _array[i] == 'E'))
return false;
throw new IllegalArgumentException("Cannot parse " + this
+ " as boolean");
}
/**
* Returns the decimal int
represented by this character array.
*
* @return toInt(10)
* @throws NumberFormatException if this character sequence
* does not contain a parsable int
.
*/
public int toInt() {
return TypeFormat.parseInt(this);
}
/**
* Returns the int
represented by this character array
* in the specified radix.
*
* @param radix the radix (e.g. 16
for hexadecimal).
* @return the corresponding int
value.
* @throws NumberFormatException if this character sequence
* does not contain a parsable int
.
*/
public int toInt(int radix) {
return TypeFormat.parseInt(this, radix);
}
/**
* Returns the decimal long
represented by this character
* array.
*
* @return the corresponding long
value.
* @throws NumberFormatException if this character sequence
* does not contain a parsable long
.
*/
public long toLong() {
return TypeFormat.parseLong(this);
}
/**
* Returns the decimal long
represented by this character
* array in the specified radix.
*
* @param radix the radix (e.g. 16
for hexadecimal).
* @return the corresponding long
value.
* @throws NumberFormatException if this character sequence
* does not contain a parsable long
.
*/
public long toLong(int radix) {
return TypeFormat.parseLong(this, radix);
}
/**
* Returns the float
represented by this character array.
*
* @return the corresponding float
value.
* @return TypeFormat.parseFloat(this)
* @throws NumberFormatException if this character sequence
* does not contain a parsable float
.
/*@JVM-1.1+@
public float toFloat() {
return TypeFormat.parseFloat(this);
}
/**/
/**
* Returns the double
represented by this character array.
*
* @return the corresponding double
value.
* @throws NumberFormatException if this character sequence
* does not contain a parsable double
.
/*@JVM-1.1+@
public double toDouble() {
return TypeFormat.parseDouble(this);
}
/**/
}