package lux.index; /** * Stores character data, like StringBuilder, but provides equals() that compares contents * so this can be used as a key in a map, where it will compare equals() to any CharSequence * containing the same sequence of chars. */ public class MutableString implements CharSequence { private int length; private char[] buffer; //private int hash; public MutableString (int capacity) { buffer = new char[capacity]; length = 0; //hash = 0; } public MutableString () { this (64); } public MutableString(MutableString o) { this (o.length()); append (o); } public MutableString(CharSequence o) { this (o.length()); append (o.toString()); } @Override public int hashCode() { //int h = hash; int h = 0; //if (h == 0) { for (int i = 0; i < length; i++) { h = 31*h + buffer[i]; } // hash = h; // } return h; } @Override public boolean equals (Object other) { if (other == null) { return false; } if (other instanceof MutableString) { return equals ((MutableString) other); } if (other instanceof CharSequence) { return equals ((CharSequence) other); } return false; } private boolean equals (CharSequence o) { if (o.length() != length) { return false; } for (int i = 0; i < length; i++) { // is there no native method for doing memcmp? if (buffer[i] != o.charAt(i)) { return false; } } return true; } private boolean equals (MutableString o) { if (o.length != length) { return false; } for (int i = 0; i < length; i++) { // is there no native method for doing memcmp? if (buffer[i] != o.buffer[i]) { return false; } } return true; } @Override public String toString () { return new String(buffer, 0, length); } public MutableString append (char c) { assureCapacity (1); buffer[length++] = c; return this; } public MutableString append (String s) { int l = s.length(); assureCapacity (l); s.getChars(0, l, buffer, length); length += l; return this; } public MutableString append(MutableString s) { assureCapacity(s.length); System.arraycopy(s.buffer, 0, buffer, length, s.length); length += s.length; return this; } public MutableString append(char[] s) { assureCapacity(s.length); System.arraycopy(s, 0, buffer, length, s.length); length += s.length; return this; } private final void assureCapacity (int n) { if (length + n > buffer.length) { char[] expanded = new char[buffer.length * 2]; System.arraycopy (buffer, 0, expanded, 0, buffer.length); buffer = expanded; } } @Override public char charAt(int index) { return buffer[index]; } @Override public int length() { return length; } @Override public CharSequence subSequence(int start, int end) { char[] sub = new char[end-start]; System.arraycopy(buffer, start, sub, 0, end-start); return new String(sub); } public void setLength(int i) { length = i; } }