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

com.sosnoski.util.CharBuffer Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2000-2001 Sosnoski Software Solutions, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights 
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
 * copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in 
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 
 * IN THE SOFTWARE.
 */

package com.sosnoski.util;

import com.sosnoski.util.array.CharArray;

/**
 * Growable char array with added StringBuffer-like
 * functionality. This implementation differs from StringBuffer in
 * that it is unsynchronized so as to provide the best possible performance for 
 * typical usage scenarios. Explicit synchronization must be implemented by a 
 * wrapper class or directly by the application in cases where instances are 
 * modified in a multithreaded environment. See the base classes for other 
 * details of the implementation.

* * This class defines a number of convenience methods for working with * character data (including simple arrays and Strings). Besides * allowing character data to be appended/inserted/replaced in the growable * array, other methods support comparisons between the several forms of * character sequences and calculations of hash codes independent of the form * of the sequence. * * @author Dennis M. Sosnoski * @version 1.0 */ public class CharBuffer extends CharArray { /** Hash value multiplier to scramble bits in accumulation. */ protected static final int KEY_MULTIPLIER = 517; /** * Constructor with full specification. * * @param size number of char values initially allowed in array * @param growth maximum size increment for growing array */ public CharBuffer(int size, int growth) { super(size, growth); } /** * Constructor with initial size specified. * * @param size number of char values initially allowed in array */ public CharBuffer(int size) { super(size); } /** * Default constructor. */ public CharBuffer() { this(DEFAULT_SIZE); } /** * Constructor from String. */ public CharBuffer(String base) { this(base.length()); append(base); } /** * Constructor from char[]. */ public CharBuffer(char[] base) { this(base.length); append(base); } /** * Copy (clone) constructor. * * @param base instance being copied */ public CharBuffer(CharArray base) { super(base); } /** * Appends the characters from a String to the current contents * of the array. * * @param text String of characters to be appended * @return index number of first character appended */ public int append(String text) { // grow array if necessary int length = text.length(); ensureCapacity(m_countPresent + length); // append text after existing content int start = m_countPresent; for (int i = 0; i < length; i++) { m_baseArray[m_countPresent++] = text.charAt(i); } return start; } /** * Appends the characters from an array range to the current contents * of the array. * * @param text array containing characters to be appended * @param offset starting offset in array * @param length length of character range in array * @return index number of first character appended */ public int append(char[] text, int offset, int length) { // grow array if necessary ensureCapacity(m_countPresent + length); // append text after existing content int start = m_countPresent; System.arraycopy(text, offset, m_baseArray, m_countPresent, length); m_countPresent += length; return start; } /** * Appends all the characters from an array to the current contents * of the array. * * @param text array containing characters to be appended * @return index number of first character appended */ public int append(char[] text) { return append(text, 0, text.length); } /** * Appends all the characters from another growable array to the current * contents of the array. * * @param text growable array containing characters to be appended * @return index number of first character appended */ public int append(CharArray text) { return append((char[])getArray(text), 0, text.size()); } /** * Adjust the characters in the array to make room for an insertion or * replacement. Depending on the relative sizes of the range being * replaced and the range being inserted, this may move characters past * the start of the replacement range up or down in the array. * * @param from index number of first character to be replaced * @param to index number past last character to be replaced * @param length length of character range being inserted */ protected void adjust(int from, int to, int length) { if (from >= 0 && to < m_countPresent && from <= to) { int change = from + length - to; if (change > 0) { ensureCapacity(m_countPresent+change); } if (to < m_countPresent){ System.arraycopy(m_baseArray, to, m_baseArray, to + change, m_countPresent - to); m_countPresent += change; } } else { throw new ArrayIndexOutOfBoundsException("Invalid remove range"); } } /** * Replace a character range in the array with the characters from a * String. * * @param from index number of first character to be replaced * @param to index number past last character to be replaced * @param text replacement text */ public void replace(int from, int to, String text) { adjust(from, to, text.length()); text.getChars(0, text.length(), m_baseArray, from); } /** * Replace a character range in the array with the characters from a * char[]. * * @param from index number of first character to be replaced * @param to index number past last character to be replaced * @param text replacement text */ public void replace(int from, int to, char[] text) { adjust(from, to, text.length); System.arraycopy(text, 0, m_baseArray, from, text.length); } /** * Insert the characters from a String into the array. * * @param offset insert position offset in array * @param text insertion text */ public void insert(int offset, String text) { adjust(offset, offset, text.length()); text.getChars(0, text.length(), m_baseArray, offset); } /** * Insert the characters from a char[] into the array. * * @param offset insert position offset in array * @param text insertion text */ public void insert(int offset, char[] text) { adjust(offset, offset, text.length); System.arraycopy(text, 0, m_baseArray, offset, text.length); } /** * Compare the character sequence in the array with a String. * * @param comp String value to be compared * @return true if the character sequences are identical, * false if they're different */ public boolean equals(String comp) { // first check for lengths the same if (comp != null && m_countPresent == comp.length()) { // match character by character for full compare for (int index = 0; index < m_countPresent; index++) { if (m_baseArray[index] != comp.charAt(index)) { return false; } } // return with all characters matched return true; } // fail if matching not done return false; } /** * Compare the character sequence in the array with the characters in a * simple array range. * * @param comp array of characters to be compared * @param offset starting offset in array * @param length length of character range in array * @return true if the character sequences are identical, * false if they're different */ public boolean equals(char[] comp, int offset, int length) { // first check for lengths the same if (comp != null && m_countPresent == length) { // match character by character for full compare for (int index = 0; index < m_countPresent; index++) { if (m_baseArray[index] != comp[index+offset]) { return false; } } // return with all characters matched return true; } // fail if matching not done return false; } /** * Compare the character sequence in the array with that in a simple * array. * * @param comp array of characters to be compared * @return true if the character sequences are identical, * false if they're different */ public boolean equals(char[] comp) { return equals(comp, 0, comp.length); } /** * Compare the character sequence in the array with the sequence in * another growable array. * * @param comp array of characters to be compared * @return true if the character sequences are identical, * false if they're different */ public boolean equals(CharArray comp) { return equals((char[])getArray(comp), 0, comp.size()); } /** * Compare the character sequences in a pair of arrays. * * @param a first character sequence array (non-null) * @param b second character sequence array (may be null) * @return true if the character sequences are identical, * false if they're different */ public static boolean equals(char[] a, char[] b) { // make sure the lengths are the same if (b != null && a.length == b.length) { // match character by character for full compare for (int i = 0; i < a.length; i++) { if (a[i] != b[i]) { return false; } } return true; } else { return false; } } /** * Compare the character sequences in a simple array and a * String. * * @param a simple array character sequence (non-null) * @param b String character sequence (may be * null) * @return true if the character sequences are identical, * false if they're different */ public static boolean equals(char[] a, String b) { // make sure the lengths are the same if (b != null && a.length == b.length()) { // match character by character for full compare for (int i = 0; i < a.length; i++) { if (a[i] != b.charAt(i)) { return false; } } return true; } else { return false; } } /** * Compare the character sequence in the array with a String * without regard to case. * * @param comp String value to be compared * @return true if the character sequences are identical * except perhaps for case, false if they're different */ public boolean equalsNoCase(String comp) { // first check for lengths the same if (comp != null && m_countPresent == comp.length()) { // match character by character for full compare int index = 0; for (; index < m_countPresent; index++) { if (Character.toLowerCase(m_baseArray[index]) != Character.toLowerCase(comp.charAt(index))) { return false; } } // return with all characters matched return true; } // fail if matching not done return false; } /** * Compare the character sequence in the array with the characters in a * simple array range without regard to case. * * @param comp array of characters to be compared * @param offset starting offset in array * @param length length of character range in array * @return true if the character sequences are identical * except perhaps for case, false if they're different */ public boolean equalsNoCase(char[] comp, int offset, int length) { // first check for lengths the same if (comp != null && m_countPresent == length) { // match character by character for full compare for (int index = 0; index < m_countPresent; index++) { if (Character.toLowerCase(m_baseArray[index]) != Character.toLowerCase(comp[index+offset])) { return false; } } // return with all characters matched return true; } // fail if matching not done return false; } /** * Compare the character sequence in the array with that in a simple * array without regard to case. * * @param comp array of characters to be compared * @return true if the character sequences are identical * except perhaps for case, false if they're different */ public boolean equalsNoCase(char[] comp) { return equalsNoCase(comp, 0, comp.length); } /** * Compare the character sequence in the array with the sequence in * another growable array without regard to case. * * @param comp array of characters to be compared * @return true if the character sequences are identical * except perhaps for case, false if they're different */ public boolean equalsNoCase(CharArray comp) { return equalsNoCase((char[])getArray(comp), 0, comp.size()); } /** * Compare the character sequences in a pair of arrays without regard to * case. * * @param a first character sequence array (non-null) * @param b second character sequence array (may be null) * @return true if the character sequences are identical * except perhaps for case, false if they're different */ public static boolean equalsNoCase(char[] a, char[] b) { // make sure the lengths are the same if (b != null && a.length == b.length) { // match character by character for full compare for (int i = 0; i < a.length; i++) { if (Character.toUpperCase(a[i]) != Character.toUpperCase(b[i])) { return false; } } return true; } else { return false; } } /** * Compare the character sequences in a simple array and a * String without regard to case. * * @param a simple array character sequence (non-null) * @param b String character sequence (may be * null) * @return true if the character sequences are identical * except perhaps for case, false if they're different */ public static boolean equalsNoCase(char[] a, String b) { // make sure the lengths are the same if (b != null && a.length == b.length()) { // match character by character for full compare for (int i = 0; i < a.length; i++) { if (Character.toLowerCase(a[i]) != Character.toLowerCase(b.charAt(i))) { return false; } } return true; } else { return false; } } /** * Compute the compatible hash code value for character sequence in a simple * array. * * @param text text to be hashed * @return compatible hash code value */ public static int hashCode(char[] text) { int hash = 0; for (int i = 0; i < text.length; i++) { hash = (hash * KEY_MULTIPLIER) + text[i]; } return hash; } /** * Compute the compatible hash code value for character sequence in a * String. * * @param text text to be hashed * @return compatible hash code value */ public static int hashCode(String text) { int hash = 0; for (int i = 0; i < text.length(); i++) { hash = (hash * KEY_MULTIPLIER) + text.charAt(i); } return hash; } /** * Compute a compatible hash code value for this character sequence. * * @return compatible hash code value */ public int hashCode() { int hash = 0; for (int i = 0; i < size(); i++) { hash = (hash * KEY_MULTIPLIER) + m_baseArray[i]; } return hash; } /** * Duplicates the object with the generic call. * * @return a copy of the object */ public Object clone() { return new CharBuffer(this); } /** * Construct a String from the character sequence present. * * @return copy of data as String */ public String toString() { return new String(m_baseArray, 0, m_countPresent); } /** * Construct a String from a portion of the character sequence * present. * * @param offset start offset in array * @param length number of characters to use * @return copy of data as String */ public String toString(int offset, int length) { if (offset + length <= m_countPresent) { return new String(m_baseArray, offset, length); } else { throw new ArrayIndexOutOfBoundsException(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy