/* XBN Java: Generically useful, non-GUI Java code. http://sourceforge.net/projects/xbnjava Copyright (C) 1997-2003, Jeff Epstein All rights reserved. Modifications: No Redistribution in binary form, with or without modifications, are permitted provided that the following conditions are met: * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * If modifications are made to source code then this license should indicate that fact in the "Modifications" section above. * Neither the author, nor the contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [NOTE: This license contains NO advertising clause.] */ package xbn.string; import xbn.XBNObject; /**

Base class of "wrappers" for Strings and StringBuffers, to prevent duplication of functions used by both.

Source code:  StringOrBuffer.java.  Unit tests:  xbn_junit.JUTStringOrBuffer.java.

@version 0.9b @author Jeff Epstein, http://sourceforge.net/projects/xbnjava. **/ public abstract class StringOrBuffer extends XBNObject { /**

Does this StringOrBuffer contain a String?

@return true If this StringOrBuffer contains a string.
false If it contains a StringBuffer. **/ public abstract boolean isString(); /**

Does this StringOrBuffer contain a StringBuffer?

@return !isString() **/ public final boolean isStringBuffer() { return !isString(); } /**

How long is this StringOrBuffer?

@return A number greater-than-or-equal-to zero, representing the number of characters. **/ public abstract int length(); /**

Are there zero characters in this StringOrBuffer?

@return (length() == 0) **/ public final boolean isEmpty() { return (length() == 0); } /**

Is the search string found at index 0?

@param s_toSearchFor The string to search at index zero for. May not be null or zero characters in length. @return true If characters 0..[s_toSearchFor.length()] in the StringOrBuffer are equal to the corresponding characters in s_toSearchFor, with none missing.
false If not. **/ public abstract boolean startsWith(String s_toSearchFor); /**

Is the search string found at the end of the StringOrBuffer?

@param s_toSearchFor The string that should be searched for, at the end of the StringOrBuffer. May not be null or zero characters in length. @return true If every character starting at (length() - s_toSearchFor.length()) in the StringOrBuffer are equal to the corresponding characters in s_toSearchFor, with none missing.
false If not. **/ public abstract boolean endsWith(String s_toSearchFor); /**

Get the value of this StringOrBuffer, after trimming whitespace from the ends. This does not alter the internally-held value.

**/ public abstract String getTrimmed(); /**

Trim whitespace from the value of this StringOrBuffer. Unlike the java.lang.String version of this function, this does not return anything, but rather just trims the internally-held value. See getTrimmed().

**/ public abstract void trim(); /**

Get the character located at the requested array index.

@param i_dx The array index of the character you want. Must range 0..[length() - 1], inclusive. **/ public abstract char charAt(int i_dx); /**

Append a string onto the end (right).

@param s_toAppend The string to append. **/ public abstract void append(String s_toAppend); /**

Append a string to the start.

@param s_toAppend The string to append. **/ public abstract void appendToLeft(String s_toAppend); /**

Insert a string.

@param i_dx The array index at which s_toInsert should be inserted. Must range 0..[length() - 1], inclusive. @param s_toInsert The string to insert. **/ public abstract void insert(int i_dx, String s_toInsert); /**

Append a character onto the end (right).

@param s_toAppend The character to insert. **/ public abstract void append(char c_toAppend); /**

Append a character to the start.

@param c_toAppend The character to insert. **/ public abstract void appendToLeft(char c_toAppend); /**

Insert a character.

@param i_dx The array index at which c_toInsert should be inserted. Must range 0..[length() - 1], inclusive. @param c_toInsert The character to insert. **/ public abstract void insert(int i_dx, char c_toInsert); /**

Delete a character.

@param i_dx The array index containing the character to delete. Must range 0..[length() - 1], inclusive. **/ public abstract void deleteCharAt(int i_dx); /**

Delete a range of characters.

@param i_idxLeft The array index of the left-most character to be deleted. Must range 0..[length() - 1], inclusive, and must be less than or equal to i_idxAfterRight. @param i_idxAfterRight The array index after the right-most to be retrieved. Must be between i_idxLeft and length, inclusive. **/ public abstract void delete(int i_idxLeft, int i_idxAfterRight); /**

Set the length.

@param i_newLength The desired length. If less than length, then every character at and after (array index) i_newLength is deleted. If greater than length, then spaces are appended to the right hand side until the new length is achieved. **/ public abstract void setLength(int i_newLength); /**

Get a range of characters starting at the requested index.

This returns the same thing as substring(i_idxLeft, (length() - 1))

@param i_idxLeft The array index of the left-most character to be retrieved. Must range 0..[length() - 1], inclusive, and must be less than or equal to i_idxAfterRight. **/ public abstract String substring(int i_idxLeft); /**

Get a range of characters.

See substring.

@param i_idxLeft The array index of the left-most character to be retrieved. Must range 0..[length() - 1], inclusive, and must be less than or equal to i_idxAfterRight. @param i_idxAfterRight The array index after the right-most to be retrieved. Must be between i_idxLeft and length, inclusive. **/ public abstract String substring(int i_idxLeft, int i_idxAfterRight); /**

Delete all characters.

Equal to setLength(0)

**/ public final void deleteAll() { setLength(0); } /**

Get the array index of the right-most occurance of the search string.

@return indexOf(s_toSearchFor, 0) **/ public final int indexOf(String s_toSearchFor) { return indexOf(s_toSearchFor, 0); } /**

Get the array index of the right-most occurance of the search string.

@return indexOf(s_toSearchFor, i_idxLeft, length()) **/ public final int indexOf(String s_toSearchFor, int i_idxLeft) { return indexOf(s_toSearchFor, i_idxLeft, length()); } /**

Get the array index of the right-most occurance of the search string.

@return indexOf(s_toSearchFor, i_idxLeft, i_idxAfterRight, true) **/ public final int indexOf(String s_toSearchFor, int i_idxLeft, int i_idxAfterRight) { return indexOf(s_toSearchFor, i_idxLeft, i_idxAfterRight, true); } /**

Get the array index of the left-most occurance of the search string.

@param s_toSearchFor The string to search for.. May not be null or zero characters in length. @param i_idxLeft The array index of the left-most (first) character to search. Must be between 0 and (length() - 1), inclusive. @param i_idxAfterRight The array index of the first character after the end of the search area. Must be between i_idxLeft and length, inclusive. @param b_bounded If true, then the search string must be fully contained between i_idxLeft (inclusive) and i_idxAfterRight (exclusive). If false, the search string must start between i_idxLeft and i_idxAfterRight, but the search string may exceed i_idxAfterRight (as long as it exists fully in the string as a whole). @return A number between i_idxLeft and (i_idxAfterRight - 1) referring to the first character in the left-most occurance of the search string.
-1 If the search string is not found

Examples

Assume the value of this StringOrBuffer is "abcdef" and s_toSearchFor is "bcde"

i_idxLeft i_idxAfterRight b_bounded RETURNED INT
0 0 true -1
0 length() true 1
0 1 true -1
0 1 false 1
1 1 true -1
1 1 false 1
0 3 true -1
0 3 false 1
2 length() true -1
2 length() false -1

**/ public final int indexOf(String s_toSearchFor, int i_idxLeft, int i_idxAfterRight, boolean b_bounded) { return indexOf(true, "i", s_toSearchFor, i_idxLeft, i_idxAfterRight, b_bounded); } /**

Get the array index of the right-most occurance of the search string.

@return lastIndexOf(s_toSearchFor, length()) **/ public final int lastIndexOf(String s_toSearchFor) { return lastIndexOf(s_toSearchFor, length()); } /**

Get the array index of the right-most occurance of the search string.

@return lastIndexOf(s_toSearchFor, i_idxAfterRight, true) **/ public final int lastIndexOf(String s_toSearchFor, int i_idxAfterRight) { return lastIndexOf(s_toSearchFor, i_idxAfterRight, true); } /**

Get the array index of the right-most occurance of the search string.

@return lastIndexOf(s_toSearchFor, 0, i_idxAfterRight, b_bounded) **/ public final int lastIndexOf(String s_toSearchFor, int i_idxAfterRight, boolean b_bounded) { return lastIndexOf(s_toSearchFor, 0, i_idxAfterRight, b_bounded); } /**

Get the array index of the right-most occurance of the search string.

@return lastIndexOf(s_toSearchFor, i_idxLeft, i_idxAfterRight, true) **/ public final int lastIndexOf(String s_toSearchFor, int i_idxLeft, int i_idxAfterRight) { return lastIndexOf(s_toSearchFor, i_idxLeft, i_idxAfterRight, true); } /**

Get the array index of the right-most occurance of the search string.

@param s_toSearchFor The string to search for. May not be null or zero characters in length. @param i_idxLeft The array index of the left-most (first) character to search. Must be between 0 and (length() - 1), inclusive. @param i_idxAfterRight The array index of the first character after the end of the search area. Must be between i_idxLeft and length, inclusive. @param b_bounded If true, then the search string must be fully contained between i_idxLeft (inclusive) and i_idxAfterRight (exclusive). If false, the search string must start between i_idxLeft and i_idxAfterRight, but the search string may exceed i_idxAfterRight (as long as it exists fully in the string as a whole). Note: The default behavior of java.lang.String.lastIndexOf(s,i) is for the search to not be bounded (as if this were equal to false). @return A number between i_idxLeft and (i_idxAfterRight - 1) referring to the first character in the left-most occurance of the search string.
-1 If the search string does not exist completely between the search bounds.

Examples

Assume the value of this StringOrBuffer is "abcdef" and s_toSearchFor is "bcde"

i_idxLeft i_idxAfterRight b_bounded RETURNED INT
0 0 true -1
0 length() true 1
0 1 true -1
0 1 false 1
1 1 true -1
1 1 false 1
0 3 true -1
0 3 false 1
2 length() true -1
2 length() false -1

**/ public final int lastIndexOf(String s_toSearchFor, int i_idxLeft, int i_idxAfterRight, boolean b_bounded) { return indexOf(false, "lastI", s_toSearchFor, i_idxLeft, i_idxAfterRight, b_bounded); } /**

Get the array index of the right-most occurance of the search string.

@return indexOf((new Character(c_toSearchFor)).toString()) **/ public final int indexOf(char c_toSearchFor) { return indexOf((new Character(c_toSearchFor)).toString()); } /**

Get the array index of the right-most occurance of the search string.

@return indexOf((new Character(c_toSearchFor)).toString()) **/ public final int indexOf(char c_toSearchFor, int i_idxLeft) { return indexOf((new Character(c_toSearchFor)).toString(), i_idxLeft); } /**

Get the array index of the right-most occurance of the search string.

@return indexOf((new Character(c_toSearchFor)).toString(), i_idxLeft, i_idxAfterRight) **/ public final int indexOf(char c_toSearchFor, int i_idxLeft, int i_idxAfterRight) { return indexOf((new Character(c_toSearchFor)).toString(), i_idxLeft, i_idxAfterRight); } /**

Get the array index of the left-most occurance of the search string.

@return lastIndexOf((new Character(c_toSearchFor)).toString(), i_idxLeft, i_idxAfterRight) **/ public final int indexOf(char c_toSearchFor, int i_idxLeft, int i_idxAfterRight, boolean b_bounded) { return indexOf(true, "i", (new Character(c_toSearchFor)).toString(), i_idxLeft, i_idxAfterRight, b_bounded); } /**

Get the array index of the right-most occurance of the search string.

@return lastIndexOf((new Character(c_toSearchFor)).toString()) **/ public final int lastIndexOf(char c_toSearchFor) { return lastIndexOf((new Character(c_toSearchFor)).toString()); } /**

Get the array index of the right-most occurance of the search string.

@return lastIndexOf((new Character(c_toSearchFor)).toString(), i_idxAfterRight) **/ public final int lastIndexOf(char c_toSearchFor, int i_idxAfterRight) { return lastIndexOf((new Character(c_toSearchFor)).toString(), i_idxAfterRight); } /**

Get the array index of the right-most occurance of the search string.

@return lastIndexOf((new Character(c_toSearchFor)).toString(), i_idxAfterRight, b_bounded) **/ public final int lastIndexOf(char c_toSearchFor, int i_idxAfterRight, boolean b_bounded) { return lastIndexOf((new Character(c_toSearchFor)).toString(), i_idxAfterRight, b_bounded); } /**

Get the array index of the right-most occurance of the search string.

@return lastIndexOf((new Character(c_toSearchFor)).toString(), i_idxLeft, i_idxAfterRight) **/ public final int lastIndexOf(char c_toSearchFor, int i_idxLeft, int i_idxAfterRight) { return lastIndexOf((new Character(c_toSearchFor)).toString(), i_idxLeft, i_idxAfterRight); } /**

Get the array index of the right-most occurance of the search string.

@return lastIndexOf((new Character(c_toSearchFor)).toString(), i_idxLeft, i_idxAfterRight) **/ public final int lastIndexOf(char c_toSearchFor, int i_idxLeft, int i_idxAfterRight, boolean b_bounded) { return indexOf(false, "lastI", (new Character(c_toSearchFor)).toString(), i_idxLeft, i_idxAfterRight, b_bounded); } /**

Is the search string found at the specific array index?

@param s_toSearchFor What to search for. May not be null or zero characters in length. @param i_dx The array index at which s_toSearchFor should begin. Must be between zero and (length() - 1), inclusive. @return true If s_toSearchFor, as a whole, was found at i_dx
false If not. **/ public final boolean isStringAt(String s_toSearchFor, int i_dx) { try { if(s_toSearchFor.length() < 1) { throwAX("isStringAt: s_toSearchFor is zero in length."); } } catch(NullPointerException npx) { throwAX("isStringAt: s_toSearchFor is null."); } try { if(charAt(i_dx) != s_toSearchFor.charAt(0)) { return false; } } catch(IndexOutOfBoundsException ioobx) { throwAX("isStringAt: i_dx (" + i_dx + ") is invalid for this SOBStringBuffer (length being " + length() + ")."); } for(int i = 1; i < s_toSearchFor.length(); i++) { if(length() <= (i_dx + i) || charAt(i_dx + i) != s_toSearchFor.charAt(i)) { return false; } } //Every character starting at charAt(i_dx) is equal to //every character in s_toSearchFor. return true; } private void crashIfBadBounds(String s_funcPrefix, int i_idxLeft, int i_idxAfterRight) { if(i_idxLeft < 0) { throwAX(s_funcPrefix + "ndexOf: i_idxLeft (" + i_idxLeft + ") is less than zero."); } if(i_idxAfterRight > length()) { throwAX(s_funcPrefix + "ndexOf: i_idxAfterRight (" + i_idxAfterRight + ") is greater than length() (" + length() + ")."); } if(i_idxLeft > i_idxAfterRight) { throwAX(s_funcPrefix + "ndexOf: i_idxLeft (" + i_idxLeft + ") is greater than or equal to i_idxAfterRight (" + i_idxAfterRight + ")."); } } private int indexOf(boolean b_firstLast, String s_funcPrefix, String s_toSearchFor, int i_idxLeft, int i_idxAfterRight, boolean b_bounded) { crashIfBadBounds(s_funcPrefix, i_idxLeft, i_idxAfterRight); int iRightBound = -1; if(b_bounded) { //Bounded. iRightBound = i_idxAfterRight; } else { //Not bounded. iRightBound = length(); } try { if((iRightBound - i_idxLeft) < s_toSearchFor.length()) { //The search string is too large to even fit in the //search area. return -1; } else { //It can fit, as long as it starts somewhere between //i_idxLeft and... iRightBound = (iRightBound - s_toSearchFor.length()); if(iRightBound > i_idxAfterRight) { iRightBound = i_idxAfterRight; } } } catch(NullPointerException npx) { throwAX(s_funcPrefix + "ndexOf: s_toSearchFor is null."); } int iIdx = -1; int iIncrement = -1; if(b_firstLast) { //indexOf. Go left to right. iIdx = i_idxLeft; iIncrement = 1; } else { //lastIndexOf. Go right to left. iIdx = iRightBound; iIncrement = -1; } while(true) { if(b_firstLast) { if(iIdx > iRightBound) { break; } } else if(iIdx < i_idxLeft) { break; } if(isStringAt(s_toSearchFor, iIdx)) { return iIdx; } //Increment if indexOf, decrement if lastIndexOf iIdx += iIncrement; } //The search string was not found in the search area. return -1; } }