package lava.net.common; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; /** * **/ public class Value implements Cloneable { /** * Free available index. * For example for preventing denial of service. * Useable - for example - as timestamp buffer. **/ public long index = 0; /** * **/ StringBuffer value = new StringBuffer(); /** * **/ Vector tmpVector = new Vector(); /** * **/ String[] list = null; /** * **/ public final static char[] listSeparator = {' ', '\t'}; /** * **/ public Value() { } /** * **/ public Value(String value) { assign(value); } /** * **/ public String toString() { return value.toString(); } /** * **/ public int toInt() throws NumberFormatException { return Integer.parseInt(value.toString()); } /** * **/ public long toLong() throws NumberFormatException { return Long.parseLong(value.toString()); } /** * **/ public String[] toList() { if(list != null) return list; tmpVector.removeAllElements(); String value = this.value.toString(); int actual = 0; int next = 0; while(actual < value.length()) { for(int i = 0;i < listSeparator.length;++i) if((next = value.indexOf(listSeparator[i],actual)) != -1) break; if(next == -1) next = value.length(); tmpVector.addElement(value.substring(actual,next)); actual = next + 1; } int i = 0; list = new String[tmpVector.size()]; for(Enumeration e = tmpVector.elements();e.hasMoreElements();++i) list[i] = (String)e.nextElement(); return list; } /** * **/ public boolean checkElement(String element) { if(element == null) { if(value.length() <= 0) return true; return false; } String value = this.value.toString(); int index = value.indexOf(element); if(index < 0) return false; if(index > 0) { char prev = value.charAt(index - 1); boolean found = false; for(int i = 0;i < listSeparator.length;++i) if(prev == listSeparator[i]) { found = true; break; } if(!found) return false; } int nextpos = element.length() + index; if(nextpos >= value.length()) return true; char next = value.charAt(nextpos); for(int i = 0;i < listSeparator.length;++i) if(next == listSeparator[i]) return true; return false; } /** * **/ public synchronized void reset() { list = null; value.setLength(0); } /** * **/ public synchronized void assign(String value) { reset(); augment(value); } /** * **/ public synchronized void augment(String value) { if(value == null) return; list = null; if(this.value.length() > 0) this.value.append(listSeparator[0]); this.value.append(value); } /** * **/ public void diminish(String value) { if(value == null || value.length() <= 0) { reset(); } else diminish(new Value(value)); } /** * **/ public synchronized void diminish(Value value) { if(value == null || value.toString().length() <= 0) { reset(); return; } int i; String[] list = value.toList(); Hashtable h = new Hashtable(); for(i = 0;i < list.length;++i) h.put(list[i],list[i]); list = toList(); reset(); for(i = 0;i < list.length;++i) if(h.get(list[i]) == null) augment(list[i]); } /** * **/ public void handle(char glyph, String value) { switch(glyph) { case VariableModifier.GLYPH_SET: case VariableModifier.GLYPH_ASSIGN: assign(value); break; case VariableModifier.GLYPH_AUGMENT: augment(value); break; case VariableModifier.GLYPH_DIMINISH: diminish(value); break; default: break; } } /** * **/ public Object clone() { try { Value v = (Value)super.clone(); v.value = new StringBuffer(value.toString()); v.tmpVector = new Vector(); // I think it isn't needed to reset list here //v.list = null; return v; } catch(CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(); } } /** * **/ public int hashCode() { return value.toString().hashCode(); } }