[Nice-commit] Nice/src/gnu/lists AbstractSequence.java,NONE,1.1 Convert.java,NONE,1.1 SeqPosition.ja
Brought to you by:
bonniot
Update of /cvsroot/nice/Nice/src/gnu/lists In directory sc8-pr-cvs1:/tmp/cvs-serv9854/F:/nice/src/gnu/lists Modified Files: .cvsignore Added Files: AbstractSequence.java Convert.java SeqPosition.java Sequence.java SimpleVector.java Log Message: Added the converted versions of the java.in files. --- NEW FILE: AbstractSequence.java --- // -*-Java-*- // Copyright (c) 2001 Per M.A. Bothner and Brainfood Inc. // This is free software; for terms and warranty disclaimer see ./COPYING. package gnu.lists; import java.util.*; import java.util.Enumeration; /** * An AbstractSequence is used to implement Sequences, and almost all * classes that extend AbstractSequence will implement Sequence. * However, AbstractSequence itself does not implement Sequence. * This is so we can use AbstractSequence to implement classes that are * "sequence-like" (such as multi-dimesnional arrays) but are not Sequences. * * Additionally, a sequence may have zero or more attributes, which are * name-value pairs. A sequence may also have a named "type". These * extensions are to support XML functionality - it might be cleaner to * moe them to a sub-class of Sequence or some interface. * * Many of the protected methods in Sequence (such as nextIndex) are * only intended to be called from SeqPosition or TreePosition, see those. * * @author Per Bothner */ public abstract class AbstractSequence { /** See java.util.List. */ public abstract int size(); public boolean isEmpty() { return size() > 0; } public int rank() { return 1; } /** See java.util.List. */ public abstract Object get (int index); public int getEffectiveIndex(int[] indexes) { return indexes[0]; } public Object get(int[] indexes) { return get(indexes[0]); } public Object set(int[] indexes, Object value) { return set(indexes[0], value); } protected RuntimeException unsupported (String text) { text = getClass().getName() + " does not implement " + text; return new UnsupportedOperationException(text); } public Object set(int index, Object element) { throw unsupported("set"); } public void fill(Object value) { SeqPosition it = getIterator(); while (gotoNext(it)) setPrevious(it.ipos, it.xpos, value); it.finalize(); } public void fill(int fromIndex, int toIndex, Object value) { for (int i = fromIndex; i < toIndex; i++) set(i, value); } // FIXME? //public final Object elementAt (int index) { return get(index); } /** See java.util.List. */ public int indexOf(Object o) { int i = 0; SeqPosition it = getIterator(); for (; it.hasNext(); i++) { Object e = it.next(); if (o==null ? e==null : o.equals(e)) return i; } return -1; } /** See java.util.List. */ public int lastIndexOf(Object o) { // FIXME use iterator? for (int n = size(); --n >= 0; ) { Object e = get(n); if (o==null ? e == null : o.equals(e)) return n; } return -1; } /** See java.util.List. */ public boolean contains(Object o) { SeqPosition i = getIterator(); while (i.hasNext()) { Object e = i.next(); if (o==null ? e==null : o.equals(e)) return true; } return false; } /** See java.util.List. */ public boolean containsAll(Collection c) { SeqPosition i = getIterator(); while (i.hasNext()) { Object e = i.next(); if (! contains(e)) return false; } return true; } public Enumeration elements() { SeqPosition it = new SeqPosition(); makeStartPosition(it); return it; } public SeqPosition getIterator() { SeqPosition it = new SeqPosition(); makeStartPosition(it); return it; } public Iterator iterator() { SeqPosition it = new SeqPosition(); makeStartPosition(it); return it; } public ListIterator listIterator() { return listIterator(0); } public ListIterator listIterator(int index) { SeqPosition it = new SeqPosition(); makePosition(index, it); return it; } protected void add(PositionContainer posSet, int posNumber, Object value) { throw unsupported("add"); } /** See java.util.Collection. */ public boolean add(Object o) { add(size(), o); return true; } /** See java.util.List. */ public void add(int index, Object o) { throw unsupported("add single Object at index"); } /** See java.util.Collection. */ public boolean addAll(Collection c) { return addAll(size(), c); } /** See java.util.Collection. */ public boolean addAll(int index, Collection c) { boolean changed = false; for (Iterator it = c.iterator(); it.hasNext(); ) { add(index++, it.next()); changed = true; } return changed; } /** * Remove one or more elements. * @param ipos integer part of position where elements should be removed * @param xpos object part of position where elements should be removed * @param count if non-negative, remove that number of elements * following (poses, posNumber); if negative the negative of the number * of elements to remove before (poses, posNumber). * @return number of elements actually removed (non-negative) * @exception java.lang.IndexOutOfBoundsException * if (count >= 0 ? (index < 0 || index + count > size()) * : (index + count < 0 || index > size())), * where index == nextIndex(ipos, xpos). */ protected void remove(int ipos, Object xpos, int count) { SeqPosition it = new SeqPosition(this); makeRelativePosition(ipos, xpos, count, true, it, 0); if (count >= 0) remove (ipos, xpos, it.ipos, it.xpos); else remove (it.ipos, it.xpos, ipos, xpos); } /** Remove a range where each end-point is a position in a container. * @param ipos0 integer part of start of range * @param xpos0 object part of start of range * @param ipos1 integer part of end of range * @param xpos1 object part of end of range * @exception java.lang.IndexOutOfBoundsException * if nextIndex(ipos0, xpos0) > nextIndex(ipos1, xpos1) * || nextIndex(ipos0, xpos0) < 0 || nextIndex(ipos1, xpos1) > size() */ protected void remove(int ipos0, Object xpos0, int ipos1, Object xpos1) { throw unsupported("remove (with range)"); } public Object remove(int index) { if (index < 0 || index >= size()) throw new IndexOutOfBoundsException(); SeqPosition it = new SeqPosition(this); makePosition(index, it); Object result = getNext(it.ipos, it.xpos); remove(it.ipos, it.xpos, 1); return result; } public boolean remove(Object o) { int index = indexOf(o); if (index < 0) return false; SeqPosition it = new SeqPosition(); makePosition(index, it); remove(it.ipos, it.xpos, 1); return true; } public boolean removeAll(Collection c) { boolean changed = false; for (SeqPosition it = getIterator(); it.hasNext(); ) { Object value = it.next(); if (c.contains(value)) { it.remove(); changed = true; } } return changed; } public boolean retainAll(Collection c) { boolean changed = false; for (SeqPosition it = getIterator(); it.hasNext(); ) { Object value = it.next(); if (! c.contains(value)) { it.remove(); changed = true; } } return changed; } public void clear() { SeqPosition it = new SeqPosition(); makeStartPosition(it); remove(it.ipos, it.xpos, size()); } /** Does the position pair have the "isAfter" property? * I.e. if something is inserted at the position, will * the iterator end up being after the new data? */ protected boolean isAfter(int ipos, Object xpos) { return false; } protected final void makePosition(int index, SeqPosition pos) { makePosition(index, true, pos); } /** Generate a position at a given index. * @param index offset from beginning of desired position * @param isAfter should the position have the isAfter property * @param pos where to store the generated position * This old position should be already released, if needed. * @exception IndexOutOfBoundsException if index is out of bounds */ public void makePosition(int index, boolean isAfter, SeqPosition pos) { makePosition(index, isAfter, pos, 0); } /** Generate a position at a given index. * @param index offset from beginning of desired position * @param isAfter should the position have the isAfter property * @param posSet where to store the generated position * @param posNumber index in posSet for the generated position. Any old * position there should be alread released, if needed. * @exception IndexOutOfBoundsException if index is out of bounds */ protected abstract void makePosition(int index, boolean isAfter, PositionContainer posSet, int posNumber); /** Generate a position relative to an existing position. * @param istart int part of initial position * @param xstart object part of initial position * @param offset offset from (istart,xstart) of desired position * @param isAfter should the position have the isAFter property * @param posSet where to store the generated position * @param positionNumber index in posSet for the generated position. Any * old position there should be alread released, if needed. * @exception IndexOutOfBoundsException if resulting index is out of bounds */ protected void makeRelativePosition(int istart, Object xstart, int offset, boolean isAfter, PositionContainer posSet, int posNumber) { makePosition(nextIndex(istart, xstart) + offset, isAfter, posSet, posNumber); } public void makeStartPosition(SeqPosition pos) { makeStartPosition(pos, 0); } /** Set a position to the start of this sequence. */ protected void makeStartPosition(PositionContainer poses, int positionNumber) { makePosition(0, false, poses, positionNumber); } /** Set a position to the end of this sequence. */ public void makeEndPosition(SeqPosition pos) { makeEndPosition(pos, 0); pos.setSequence(0, this); // FIXME - handled by caller? } protected void makeEndPosition(PositionContainer poses, int positionNumber) { makePosition(size(), true, poses, positionNumber); } /** * Reclaim any resources used by the given position pair. * @param ipos integer part of the position being free'd. * @param xpos Object part of the position being free'd. */ protected void releasePosition(int ipos, Object xpos) { } protected final void releasePosition(SeqPosition pos) { releasePosition(pos.ipos, pos.xpos); } protected void releasePosition(PositionContainer posSet, int posNumber) { int ipos = posSet.getPositionInt(posNumber); Object xpos = posSet.getPositionPtr(posNumber); releasePosition(ipos, xpos); } /** Make a copy of a position pair. * For simple positions this is a simple copy (assignment). * However, if the positions are magic cookies that are actively managed * by the sequence (as opposed to for example a simple index), then making * a copy may need to increment a reference count, or maybe allocate a * new position pair. In any case, the new pair is initialized to the * same offset (and isAfter property) as the original. * @param ipos integer part of the position being copied. * @param xpos Object part of the position being copied. * @param posSet where to put the new copy * @param posNumber which psoition in posSet that gets the copy. */ public void copyPosition(int ipos, Object xpos, PositionContainer posSet, int posNumber) { /* makePosition(nextIndex(ipos, xpos), isAfter(ipos, xpos), posSet, posNumber); */ posSet.setSequence(posNumber, this); posSet.setPosition(posNumber, ipos, xpos); } /** Get offset of (ipos1,xpos1) relative to (ipos0,xpos0). */ protected int getIndexDifference(int ipos1, Object xpos1, int ipos0, Object xpos0) { return nextIndex(ipos1, xpos1) - nextIndex(ipos0, xpos0); } /** * Get the offset from the beginning corresponding to a position pair. * Note default implementation only works for array-like sequences! */ protected int nextIndex(int ipos, Object xpos) { throw unsupported("nextIndex"); } protected int fromEndIndex(int ipos, Object xpos) { return size() - nextIndex(ipos, xpos); } /** * Get the size of the (sub-) sequence containing a given position. * Normally the same as size(), but may be different if this Sequence * is a tree and the position points at an interior node. */ protected int getContainingSequenceSize(int ipos, Object xpos) { return size(); } /** Called by SeqPosition.hasNext. */ protected boolean hasNext(int ipos, Object xpos) { return nextIndex(ipos, xpos) != size(); } public int getNextKind(int ipos, Object xpos) { return hasNext(ipos, xpos) ? Sequence.OBJECT_VALUE : Sequence.EOF_VALUE; } public String getNextTypeName(int ipos, Object xpos) { return null; } public Object getNextTypeObject(int ipos, Object xpos) { return null; } /** Called by SeqPosition.hasPrevious. */ protected boolean hasPrevious(int ipos, Object xpos) { return nextIndex(ipos, xpos) != 0; } /** Move forward one element position. * @return true unless at end of sequence. */ public boolean gotoNext(PositionContainer posSet, int posNumber) { int ipos = posSet.getPositionInt(posNumber); Object xpos = posSet.getPositionPtr(posNumber); if (! hasNext(ipos, xpos)) return false; if (true) // FIXME if not managed positions makeRelativePosition(ipos, xpos, 1, true, posSet, posNumber); else { int index = nextIndex(ipos, xpos); releasePosition(posSet, posNumber); makePosition(index + 1, true, posSet, posNumber); } return true; } /** Potential optimization. */ public boolean gotoNext(SeqPosition pos) { return gotoNext(pos, 0); } /** Move backwards one element. * @return false iff already at beginning. */ protected boolean gotoPrevious(PositionContainer posSet, int posNumber) { int ipos = posSet.getPositionInt(posNumber); Object xpos = posSet.getPositionPtr(posNumber); if (! hasPrevious(ipos, xpos)) return false; if (true) // FIXME if not managed positions makeRelativePosition(ipos, xpos, -1, false, posSet, posNumber); else { int index = nextIndex(ipos, xpos); releasePosition(posSet, posNumber); makePosition(index - 1, false, posSet, posNumber); } return true; } /** Set position before first child (of the element following position). * @return true if there is a child sequence (which might be empty); * false if current position is end of sequence or following element * is atomic (cannot have children). */ public boolean gotoChildrenStart(TreePosition pos) { return false; } protected boolean gotoParent(TreePosition pos) { if (pos.depth < 0) return false; pos.pop(); return true; } public int getAttributeLength() { return 0; } public Object getAttribute(int index) { return null; } protected boolean gotoAttributesStart(TreePosition pos) { return false; } /** Get the element following the specified position. * @param ipos integer part of the specified position. * @param xpos Object part of the specified position. * @return the following element, or eofValue if there is none. * Called by SeqPosition.getNext. */ protected Object getNext(int ipos, Object xpos) { // wrong result if out of bounds FIXME return get(nextIndex(ipos, xpos)); } /** Get the element before the specified position. * @param ipos integer part of the specified position. * @param xpos Object part of the specified position. * @return the following element, or eofValue if there is none. * Called by SeqPosition.getNext. */ protected Object getPrevious(int ipos, Object xpos) { return get(nextIndex(ipos, xpos) - 1); } protected void setNext(int ipos, Object xpos, Object value) { int index = nextIndex(ipos, xpos); if (index >= size()) throw new IndexOutOfBoundsException(); set(index, value); } protected void setPrevious(int ipos, Object xpos, Object value) { int index = nextIndex(ipos, xpos); if (index == 0) throw new IndexOutOfBoundsException(); set(index - 1, value); } public final int nextIndex(SeqPosition pos) { return nextIndex(pos.ipos, pos.xpos); } /** Compare two positions, and indicate if the are the same position. */ public boolean equals(int ipos1, Object xpos1, int ipos2, Object xpos2) { return compare(ipos1, xpos1, ipos2, xpos2) == 0; } /** Compare two positions, and indicate their relative order. */ public int compare(int ipos1, Object xpos1, int ipos2, Object xpos2) { int i1 = nextIndex(ipos1, xpos1); int i2 = nextIndex(ipos2, xpos2); return i1 < i2 ? -1 : i1 > i2 ? 1 : 0; } public final int compare(SeqPosition i1, SeqPosition i2) { return compare(i1.ipos, i1.xpos, i2.ipos, i2.xpos); } public Object[] toArray() { int len = size(); Object[] arr = new Object[len]; java.util.Enumeration e = elements(); for (int i = 0; e.hasMoreElements(); i++) arr[i] = e.nextElement(); return arr; } public Object[] toArray(Object[] arr) { int alen = arr.length; int len = size(); if (len > alen) { Class componentType = arr.getClass().getComponentType(); arr = (Object[]) java.lang.reflect.Array.newInstance(componentType, len); alen = len; } java.util.Enumeration e = elements(); for (int i = 0; e.hasMoreElements(); i++) { arr[i] = e.nextElement(); } if (len < alen) arr[len] = null; return arr; } public int hashCode() { // Implementation specified by the Collections specification. int hash = 1; SeqPosition i = getIterator(); while (i.hasNext()) { Object obj = i.next(); hash = 31*hash + (obj==null ? 0 : obj.hashCode()); } return hash; } public boolean equals(Object o) { // Compatible with the Collections specification. // FIXME should also depend on class? if (! (o instanceof java.util.List)) return false; Iterator it1 = iterator(); Iterator it2 = ((java.util.List) o).iterator(); for (;;) { boolean more1 = it1.hasNext(); boolean more2 = it2.hasNext(); if (more1 != more2) return false; if (! more1) return true; Object e1 = it1.next(); Object e2 = it2.next(); if (e1 == null) { if (e2 != null) return false; } else if (! e1.equals(e2)) return false; } } public Sequence subSequence(SeqPosition start, SeqPosition end) { return subSequence(start.ipos, start.xpos, end.ipos, end.xpos); } protected Sequence subSequence(int ipos0, Object xpos0, int ipos1, Object xpos1) { SubSequence sub = new SubSequence(this); copyPosition(ipos0, xpos0, sub, 0); copyPosition(ipos1, xpos1, sub, 1); return sub; } public List subList(int fromIx, int toIx) { SubSequence sub = new SubSequence(this); makePosition(fromIx, false, sub, 0); makePosition(toIx, true, sub, 1); return sub; } /** Copy an element specified by a position pair to a Consumer. * @return if hasNext(ipos, xpos). */ public boolean consumeNext(int ipos, Object xpos, Consumer out) { if (! hasNext(ipos, xpos)) return false; out.writeObject(getNext(ipos, xpos)); return true; } protected void consume(int iposStart, Object xposStart, int iposEnd, Object xposEnd, Consumer out) { if (out.ignoring()) return; SeqPosition it = new SeqPosition(); copyPosition(iposStart, xposStart, it, 0); while (! equals(it.ipos, it.xpos, iposEnd, xposEnd)) { if (! it.hasNext()) throw new RuntimeException(); out.writeObject(it.nextElement()); } it.finalize(); } /* Consume wlements, without any beginGroup/endGroup. public void consumeElements() ... */ public void consume(Consumer out) { String typeName = "#sequence"; String type = typeName; out.beginGroup(typeName, type); java.util.Enumeration e = elements(); for (int i = 0; e.hasMoreElements(); i++) out.writeObject(e.nextElement()); out.endGroup(typeName); } } --- NEW FILE: Convert.java --- // -*-Java-*- // Copyright (c) 2001 Per M.A. Bothner and Brainfood Inc. // This is free software; for terms and warranty disclaimer see ./COPYING. package gnu.lists; /** * A class that encapsulates primitive<->Object conversions. * Applications can override the conversion if desired. * For example charToObject could use an "intern" table. */ public class Convert { public static Convert instance = new Convert(); public static Convert getInstance() { return instance; } public static void setInstance(Convert value) { instance = value; }; public Object booleanToObject(boolean value) { return value ? Boolean.TRUE : Boolean.FALSE; } public boolean objectToBoolean(Object obj) { return ! (obj instanceof Boolean) || ((Boolean) obj).booleanValue(); } public static Object toObject(boolean value) { return instance.booleanToObject(value); } public static boolean toBoolean(Object obj) { return instance.objectToBoolean(obj); } public Object charToObject(char ch) { return new Character(ch); } public char objectToChar(Object obj) { return ((Character) obj).charValue(); } public static Object toObject(char ch) { return instance.charToObject(ch); } public static char toChar(Object obj) { return instance.objectToChar(obj); } public Object byteToObject(byte value) { return new Byte(value); } public byte objectToByte(Object obj) { return ((Number) obj).byteValue(); } public static Object toObject(byte value) { return instance.byteToObject(value); } public static byte toByte(Object obj) { return instance.objectToByte(obj); } public Object byteToObjectUnsigned(byte value) { return new Integer(value & 0xFF); } public byte objectToByteUnsigned(Object obj) { return ((Number) obj).byteValue(); } public static Object toObjectUnsigned(byte value) { return instance.byteToObjectUnsigned(value); } public static byte toByteUnsigned(Object obj) { return instance.objectToByteUnsigned(obj); } public Object shortToObject(short value) { return new Short(value); } public short objectToShort(Object obj) { return ((Number) obj).shortValue(); } public static Object toObject(short value) { return instance.shortToObject(value); } public static short toShort(Object obj) { return instance.objectToShort(obj); } public Object shortToObjectUnsigned(short value) { return new Integer(value & 0xFFFF); } public short objectToShortUnsigned(Object obj) { return ((Number) obj).shortValue(); } public static Object toObjectUnsigned(short value) { return instance.shortToObjectUnsigned(value); } public static short toShortUnsigned(Object obj) { return instance.objectToShortUnsigned(obj); } public Object intToObject(int value) { return new Integer(value); } public int objectToInt(Object obj) { return ((Number) obj).intValue(); } public static Object toObject(int value) { return instance.intToObject(value); } public static int toInt(Object obj) { return instance.objectToInt(obj); } public Object intToObjectUnsigned(int value) { if (value >= 0) return new Integer(value); else return new Long((long) value & 0xffffffffL); } public int objectToIntUnsigned(Object obj) { return ((Number) obj).intValue(); } public static Object toObjectUnsigned(int value) { return instance.intToObjectUnsigned(value); } public static int toIntUnsigned(Object obj) { return instance.objectToIntUnsigned(obj); } public Object longToObject(long value) { return new Long(value); } public long objectToLong(Object obj) { return ((Number) obj).longValue(); } public static Object toObject(long value) { return instance.longToObject(value); } public static long toLong(Object obj) { return instance.objectToLong(obj); } public Object longToObjectUnsigned(long value) { return new Long(value); // FIXME use BigInteger? } public long objectToLongUnsigned(Object obj) { return ((Number) obj).longValue(); } public static Object toObjectUnsigned(long value) { return instance.longToObjectUnsigned(value); } public static long toLongUnsigned(Object obj) { return instance.objectToLongUnsigned(obj); } public Object floatToObject(float value) { return new Float(value); } public float objectToFloat(Object obj) { return ((Number) obj).floatValue(); } public static Object toObject(float value) { return instance.floatToObject(value); } public static float toFloat(Object obj) { return instance.objectToFloat(obj); } public Object doubleToObject(double value) { return new Double(value); } public double objectToDouble(Object obj) { return ((Number) obj).doubleValue(); } public static Object toObject(double value) { return instance.doubleToObject(value); } public static double toDouble(Object obj) { return instance.objectToDouble(obj); } public static double parseDouble(String str) { // We assume that if collections are available the Double.parseDouble // is also available. return Double.parseDouble(str); } } --- NEW FILE: SeqPosition.java --- // -*-Java-*- // Copyright (c) 2001 Per M.A. Bothner and Brainfood Inc. // This is free software; for terms and warranty disclaimer see ./COPYING. package gnu.lists; import java.util.NoSuchElementException; /** * A position in a sequence (list). * * Conceptually similar to Java2's ListIterator, but we use the name "Position" * to indicate that it can be used to both indicate a position in a sequence * and to iterate through a sequence. If you use a SeqPosition as a * "position", you would not modify if (though it is possible the offset * of the position in the sequence may change due to other update operations * on the sequence). If you use a SeqPosition as an "iterator", you would * initialize it to some beginnning position, and then modify the current * position of the SeqPosition so it refers to successive elements. * * See the <a href="package-summary.html#iteration">package overview</a> * for more information. */ public class SeqPosition implements java.util.ListIterator, PositionContainer, java.util.Enumeration { /** * The Sequence relative to which ipos and xpos have meaning. * This is normally the same as the Sequence we iterate through. * However, if this is a TreePosition, it may an ancestor instead. */ public AbstractSequence sequence; /** * An integer that (together with xpos) indicates the current position. * The actual value has no meaning, except as interpreted by sequence. */ public int ipos; /** * An Object that (together with ipos) indicates the current position. * The actual value has no meaning, except as interpreted by sequence. */ public Object xpos; public SeqPosition() { } public SeqPosition(AbstractSequence seq) { this.sequence = seq; } public SeqPosition(AbstractSequence seq, int offset, boolean isAfter) { this.sequence = seq; seq.makePosition(offset, isAfter, this, 0); } public SeqPosition(AbstractSequence seq, int ipos, Object xpos) { this.sequence = seq; this.ipos = ipos; this.xpos = xpos; } /** Creates a new SeqPosition, from a position triple. * The position triple is copied (using copyPosition). */ public static SeqPosition make(AbstractSequence seq, int ipos, Object xpos) { SeqPosition pos = new SeqPosition(); seq.copyPosition(ipos, xpos, pos, 0); return pos; } public final void gotoStart(AbstractSequence seq) { if (sequence != null) sequence.releasePosition(ipos, xpos); sequence = seq; seq.makeStartPosition(this, 0); } public final void gotoEnd(AbstractSequence seq) { if (sequence != null) sequence.releasePosition(ipos, xpos); sequence = seq; seq.makeEndPosition(this, 0); } /** True if there is an element following the current position. * False if we are at the end. See java.util.Enumeration. */ public boolean hasMoreElements() { return sequence.hasNext(ipos, xpos); } /** See java.util.Iterator. */ public boolean hasNext() { return sequence.hasNext(ipos, xpos); } /** Return a code (defined in Sequence) for the type of the next element. */ public int getNextKind() { return sequence.getNextKind(ipos, xpos); } /** Get the "tag name" for the next element, if any. */ public String getNextTypeName() { return sequence.getNextTypeName(ipos, xpos); } /** Get the "tag object" for the next element, if any. */ public Object getNextTypeObject() { return sequence.getNextTypeObject(ipos, xpos); } /** See java.util.Iterator. */ public boolean hasPrevious() { return sequence.hasPrevious(ipos, xpos); } /** See java.util.ListIterator. */ public Object next() { Object result = sequence.getNext(ipos, xpos); if (result == Sequence.eofValue || ! sequence.gotoNext(this)) throw new NoSuchElementException(); return result; } /** Move one element forwards, if possible. * @returns if we succeeded in moving forwards (i.e. not at end of sequence). */ public final boolean gotoNext() { return sequence.gotoNext(this); } /** See java.util.ListIterator. */ public Object previous() { Object result = sequence.getPrevious(ipos, xpos); if (result == Sequence.eofValue || ! sequence.gotoPrevious(this, 0)) throw new NoSuchElementException(); return result; } /** See java.util.Enumeration. */ public Object nextElement() throws NoSuchElementException { Object result = sequence.getNext(ipos, xpos); if (result == Sequence.eofValue || ! sequence.gotoNext(this)) throw new NoSuchElementException(); return result; } /** * Get element following current position. * Does not move the position, in contrast to nextElement method. * @return EOF if at end of sequence, otherwise the value following. */ public Object getNext() { return sequence.getNext(ipos, xpos); } public Object getPrevious() { return sequence.getPrevious(ipos, xpos); } /** See java.util.Iterator. */ public final int nextIndex() { return sequence.nextIndex(ipos, xpos); } public final int fromEndIndex() { return sequence.fromEndIndex(ipos, xpos); } public int getContainingSequenceSize() { return sequence.getContainingSequenceSize(ipos, xpos); } /** See java.util.Iterator. */ public final int previousIndex() { return sequence.nextIndex(ipos, xpos) - 1; } /** Does the position pair have the "isAfter" property? * I.e. if something is inserted at the position, will * the iterator end up being after the new data? * A toNext() or next() command should set isAfter() to true; * a toPrevious or previous command should set isAfter() to false. */ public final boolean isAfter() { return sequence.isAfter(ipos, xpos); } public final void set(Object value) { if (sequence.isAfter(ipos, xpos)) sequence.setPrevious(ipos, xpos, value); else sequence.setNext(ipos, xpos, value); } public void remove() { sequence.remove(ipos, xpos, isAfter() ? -1 : 1); } public void add(Object o) { sequence.add(this, 0, o); } /** Implements PositionContainer. */ public int getPositionInt(int positionNumber) { return ipos; } /** Implements PositionContainer. */ public Object getPositionPtr(int positionNumber) { return xpos; } /** Implements PositionContainer. */ public void setPosition(int positionNumber, int ipos, Object xpos) { this.ipos = ipos; this.xpos = xpos; } /** Implements PositionContainer. */ public void setSequence(int positionNumber, AbstractSequence seq) { sequence = seq; } /** Implements PositionContainer. */ public int countPositions() { return 1; } public void init(AbstractSequence seq, int index, boolean isAfter) { if (sequence != null) sequence.releasePosition(ipos, xpos); sequence = seq; seq.makePosition(index, isAfter, this, 0); } public void init(SeqPosition pos) { if (sequence != null) sequence.releasePosition(ipos, xpos); sequence = pos.sequence; sequence.copyPosition(pos.ipos, pos.xpos, this, 0); } public void release() { if (sequence != null) { sequence.releasePosition(ipos, xpos); sequence = null; } } public void finalize() { release(); } public String toString() { StringBuffer sbuf = new StringBuffer(60); sbuf.append('{'); if (sequence == null) sbuf.append("null sequence"); else { sbuf.append(sequence.getClass().getName()); sbuf.append('@'); sbuf.append(System.identityHashCode(sequence)); } sbuf.append(" ipos: "); sbuf.append(ipos); sbuf.append(" xpos: "); sbuf.append(xpos); sbuf.append('}'); return sbuf.toString(); } } // This is for people using the Emacs editor: // Local Variables: // c-file-style: "gnu" // tab-width: 8 // indent-tabs-mode: t // End: --- NEW FILE: Sequence.java --- // -*-Java-*- // Copyright (c) 2001 Per M.A. Bothner and Brainfood Inc. // This is free software; for terms and warranty disclaimer see ./COPYING. package gnu.lists; import java.util.*; /** * A Sequence is an ordered list of elements. * It is similar to and compatible with the Java2 java.util.List interface, * but does not require it. * * All standard classes that implement Sequence also extend AbstractSequence. * Using AbstractSequence provides default implementations for many methods, * and also makes things a bit more efficient. However, client code should * use Sequence rather than AbstractSequence. * * @author Per Bothner */ public interface Sequence extends java.util.List, Array, Consumable { /** Special magic end-of-file marker. */ public static final Object eofValue = new String[] { "(EOF)" }; /** True is this sequence contains no elements. */ public boolean isEmpty(); /** See java.util.List. */ public int size(); /** See java.util.List. */ public Object get (int index); public void fill(Object value); public java.util.Enumeration elements(); /** Return code used to indicate a position is at end of the sequence. */ public static final int EOF_VALUE = 0; public static final int PRIM_VALUE = 16; public static final int INT_U8_VALUE = PRIM_VALUE + 1; public static final int INT_S8_VALUE = PRIM_VALUE + 2; public static final int INT_U16_VALUE = PRIM_VALUE + 3; public static final int INT_S16_VALUE = PRIM_VALUE + 4; public static final int INT_U32_VALUE = PRIM_VALUE + 5; public static final int INT_S32_VALUE = PRIM_VALUE + 6; public static final int INT_U64_VALUE = PRIM_VALUE + 7; public static final int INT_S64_VALUE = PRIM_VALUE + 8; /** Return code used to indicate next element is 32-bit float. */ public static final int FLOAT_VALUE = PRIM_VALUE + 9; /** Return code used to indicate next element is 64-bit double. */ public static final int DOUBLE_VALUE = PRIM_VALUE + 10; public static final int BOOLEAN_VALUE = PRIM_VALUE + 11; /** A byte in an encoded string. * Part of a char, in contrast with INT_S8_VALUE, which is an integer. */ public static final int TEXT_BYTE_VALUE = PRIM_VALUE + 12; public static final int CHAR_VALUE = PRIM_VALUE + 13; public static final int OBJECT_VALUE = 32; public static final int GROUP_VALUE = 33; public static final int DOCUMENT_VALUE = 34; public static final int ATTRIBUTE_VALUE = 35; /* public static final int NAMESPACE_ATTRIBUTE_VALUE = 16; public static final int COMMENT_VALUE = 16; public static final int PROCESSING_INSTRUCTION_VALUE = 16; public static final int ENTITY_REFERENCE_VALUE = 16; */ } --- NEW FILE: SimpleVector.java --- // -*-Java-*- // Copyright (c) 2001 Per M.A. Bothner and Brainfood Inc. // This is free software; for terms and warranty disclaimer see ./COPYING. package gnu.lists; import java.util.*; /** A SimpleVector implement as a simple array plus a current size. * * Methods with the word "Buffer" are methods which use the underlying * array, ignoring the 'size' field. * * Can be used to implement CommonLisp simple vectors, but all simple * vectors are also adjustable (by re-allocating the buffer) * and have a fill pointer (the size field). */ public abstract class SimpleVector extends AbstractSequence implements Sequence { /** The (current) number of elements. * Must always have size() >= 0 && size() <= getBufferLength(). */ public int size; public final int size() { return size; } /** * Set the size to a specified value. * The data buffer is grown if needed, with new elements set to zero/null. If * size is less than the current value, removed values are set to zero/null.. * (This is because if you decrease and then increase the vector the * should be zero/null, and it is cleaner and better for gc to do the * zeroing/nulling on remove rather than add.) * If you need to change the size without setting removed elements to * zero/null (e.g. to change Common Lisp's fill pointer) set size directly. */ public void setSize(int size) { int oldSize = this.size; this.size = size; if (size < oldSize) clearBuffer(size, oldSize - size); else { int oldLength = getBufferLength(); if (size > oldLength) { int newLength = oldLength < 16 ? 16 : 2 * oldLength; setBufferLength(size > newLength ? size : newLength); } } } /** Get the allocated length of the data buffer. */ public abstract int getBufferLength(); public abstract void setBufferLength(int length); protected boolean isAfter(int ipos, Object xpos) { return (ipos & 1) != 0; } protected int nextIndex(int ipos, Object xpos) { return ipos >>> 1; } public void makePosition(int index, boolean isAfter, PositionContainer posSet, int posNumber) { posSet.setPosition(posNumber, (index << 1) | (isAfter ? 1 : 0), null); posSet.setSequence(posNumber, this); } /* protected void ensureSize(int space) { int oldLength = data.length; int newLength = size + if (size > space) setBufferLength(space < 16 ? 16 : 2 * space); this.size = size; } */ protected abstract Object getBuffer(); public Object get(int index) { if (index >= size) throw new IndexOutOfBoundsException(); return getBuffer(index); } protected Object getNext(int ipos, Object xpos) { int index = ipos >>> 1; return index >= size ? eofValue : getBuffer(index); } public int intAtBuffer(int index) { return Convert.toInt(getBuffer(index)); } public int intAt(int index) { if (index >= size) throw new IndexOutOfBoundsException(); return intAtBuffer(index); } public long longAt(int index) { if (index >= size) throw new IndexOutOfBoundsException(); return longAtBuffer(index); } public long longAtBuffer(int index) { return Convert.toLong(getBuffer(index)); } protected abstract Object getBuffer(int index); public Object set(int index, Object value) { if (index >= size) throw new IndexOutOfBoundsException(); Object old = getBuffer(index); setBuffer(index, value); return old; } protected abstract Object setBuffer(int index, Object value); public void fill(Object value) { for (int i = size; --i >= 0; ) setBuffer(i, value); } public void fill(int fromIndex, int toIndex, Object value) { if (fromIndex < 0 || toIndex > size) throw new IndexOutOfBoundsException(); for (int i = fromIndex; i < toIndex; i++) setBuffer(i, value); } public void shift(int srcStart, int dstStart, int count) { Object data = getBuffer(); System.arraycopy(data, srcStart, data, dstStart, count); } public boolean add(Object o) { add(size, o); return true; } protected void add(PositionContainer posSet, int posNumber, Object value) { int ipos = posSet.getPositionInt(posNumber); add(ipos >>> 1, value); posSet.setPosition(posNumber, ipos + 2, null); } public void add(int index, Object o) { int newSize = size + 1; size = newSize; int length = getBufferLength(); if (newSize > length) setBufferLength(length < 16 ? 16 : 2 * length); this.size = newSize; if (size != index) shift(index, index + 1, size - index); set(index, o); } public boolean addAll(int index, Collection c) { boolean changed = false; int count = c.size(); setSize(size + count); shift(index, index + count, size - count - index); for (Iterator it = c.iterator(); it.hasNext(); ) { set(index++, it.next()); changed = true; } return changed; } protected abstract void clearBuffer(int start, int count); protected void remove(int ipos0, Object xpos0, int ipos1, Object xpos1) { ipos0 = ipos0 >>> 1; ipos1 = ipos1 >>> 1; if (ipos0 < 0 || ipos0 > ipos1 || ipos1 >= size) throw new IndexOutOfBoundsException(); shift(ipos1, ipos0, size - ipos1); int count = ipos1 - ipos0; size = size - count; clearBuffer(size, count); } protected void remove(int ipos, Object xpos, int count) { int index = ipos >>> 1; int ipos0, ipos1; if (count >= 0) { ipos0 = index; ipos1 = index + count; } else { ipos0 = index + count; ipos1 = index; count = - count; } if (ipos0 < 0 || ipos1 >= size) throw new IndexOutOfBoundsException(); shift(ipos1, ipos0, size - ipos1); size = size - count; clearBuffer(size, count); } public Object remove(int index) { if (index < 0 || index >= size) throw new IndexOutOfBoundsException(); Object result = get(index); shift(index + 1, index, 1); size = size - 1; clearBuffer(size, 1); return result; } public boolean remove(Object o) { int index = indexOf(o); if (index < 0) return false; Object result = get(index); shift(index + 1, index, 1); size = size - 1; clearBuffer(size, 1); return true; } public boolean removeAll(Collection c) { boolean changed = false; int j = 0; for (int i = 0; i < size; i++) { Object value = get(i); if (c.contains(value)) { changed = true; } else { if (changed) set(j, value); j++; } } setSize(j); return changed; } public boolean retainAll(Collection c) { boolean changed = false; int j = 0; for (int i = 0; i < size; i++) { Object value = get(i); if (! c.contains(value)) { changed = true; } else { if (changed) set(j, value); j++; } } setSize(j); return changed; } public void clear () { setSize(0); } /** This is convenience hack for printing "uniform vectors" (srfi 4). * It may go away without notice! */ public String getTag() { return null; } public void consume(int start, int length, Consumer out) { consume(start << 1, null, (start + length) << 1, null, out); } public boolean consumeNext(int ipos, Object xpos, Consumer out) { int index = ipos >>> 1; if (index >= size) return false; out.writeObject(getBuffer(index)); return true; } protected void consume(int iposStart, Object xposStart, int iposEnd, Object xposEnd, Consumer out) { if (out.ignoring()) return; int i = iposStart >>> 1; int end = iposEnd >>> 1; for (; i < end; i++) out.writeObject(getBuffer(i)); } public int getNextKind(int ipos, Object xpos) { return hasNext(ipos, xpos) ? getElementKind() : EOF_VALUE; } public int getElementKind() { return OBJECT_VALUE; } } Index: .cvsignore =================================================================== RCS file: /cvsroot/nice/Nice/src/gnu/lists/.cvsignore,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** .cvsignore 30 Oct 2001 16:33:53 -0000 1.1 --- .cvsignore 15 Dec 2003 19:51:37 -0000 1.2 *************** *** 1,29 **** - - - - - - @author Daniel Bonniot (Dan...@in...) - @version $Date$ - */ - /* */ - /* */ - /* N I C E */ - /* (c) Daniel Bonniot 2001 */ - /* A high-level object-oriented research language */ - /* (at your option) any later version. */ - /* This program is free software; you can redistribute it and/or modify */ - /* it under the terms of the GNU General Public License as published by */ - /* the Free Software Foundation; either version 2 of the License, or */ - /** - /**************************************************************************/ - /**************************************************************************/ - AbstractSequence.java - Convert.java - SeqPosition.java - Sequence.java - SimpleVector.java - class - package gnu.lists; - { - } --- 0 ---- |