001: // Copyright (c) 2001 Per M.A. Bothner and Brainfood Inc.
002: // This is free software; for terms and warranty disclaimer see ./COPYING.
003:
004: package gnu.lists;
005:
006: /** A sequence consisting of a sub-range of the elements of a base sequence.
007: * The start and end positions are positions triples (on the same sequence).
008: */
009:
010: public class SubSequence extends AbstractSequence implements Sequence,
011: PositionContainer {
012: /** Normally the Sequence this a sub-sequence of.
013: * Actually the sequence that provides context for the
014: * start and end position pairs. */
015: AbstractSequence base;
016:
017: /** Integer part of start position. */
018: int ipos0;
019:
020: /** Pointer part of start position. */
021: Object xpos0;
022:
023: /** Integer part of end position. */
024: int ipos1;
025:
026: /** Pointer part of end position. */
027: Object xpos1;
028:
029: public SubSequence() {
030: }
031:
032: public SubSequence(AbstractSequence base) {
033: this .base = base;
034: }
035:
036: public Object get(int index) {
037: if (index < 0)
038: throw new IndexOutOfBoundsException();
039: int start = base.nextIndex(ipos0, xpos0);
040: return base.get(start + index);
041: }
042:
043: public int size() {
044: return base.getIndexDifference(ipos1, xpos1, ipos0, xpos0);
045: }
046:
047: public void remove(int ipos0, Object xpos0, int ipos1, Object xpos1) {
048: base.remove(ipos0, xpos0, ipos1, xpos1);
049: }
050:
051: public int getPositionInt(int positionNumber) {
052: return positionNumber == 0 ? ipos0 : ipos1;
053: }
054:
055: public Object getPositionPtr(int positionNumber) {
056: return positionNumber == 0 ? xpos0 : xpos1;
057: }
058:
059: public void setPosition(int positionNumber, int ipos, Object xpos) {
060: if (positionNumber == 0) {
061: ipos0 = ipos;
062: xpos0 = xpos;
063: } else {
064: ipos1 = ipos;
065: xpos1 = xpos;
066: }
067: }
068:
069: public void setSequence(int positionNumber, AbstractSequence seq) {
070: }
071:
072: public int countPositions() {
073: return 2;
074: }
075:
076: protected boolean isAfter(int ipos, Object xpos) {
077: return base.isAfter(ipos, xpos);
078: }
079:
080: public void makePosition(int offset, boolean isAfter,
081: PositionContainer posSet, int posNumber) {
082: base.makeRelativePosition(ipos0, xpos0, offset, isAfter,
083: posSet, posNumber);
084: }
085:
086: public void makeRelativePosition(int istart, Object xstart,
087: int offset, boolean isAfter, PositionContainer posSet,
088: int posNumber) {
089: base.makeRelativePosition(istart, xstart, offset, isAfter,
090: posSet, posNumber);
091: }
092:
093: protected int getIndexDifference(int ipos1, Object xpos1,
094: int ipos0, Object xpos0) {
095: return base.getIndexDifference(ipos1, xpos1, ipos0, xpos0);
096: }
097:
098: public void releasePosition(int ipos, Object xpos) {
099: base.releasePosition(ipos, xpos);
100: }
101:
102: protected int nextIndex(int ipos, Object xpos) {
103: return getIndexDifference(ipos, xpos, ipos0, xpos0);
104: }
105:
106: public int compare(int ipos1, Object xpos1, int ipos2, Object xpos2) {
107: return base.compare(ipos1, xpos1, ipos2, xpos2);
108: }
109:
110: protected Object getNext(int ipos, Object xpos) {
111: if (base.compare(ipos, xpos, ipos1, xpos1) >= 0)
112: return eofValue;
113: return base.getNext(ipos, xpos);
114: }
115:
116: public int getNextKind(int ipos, Object xpos) {
117: if (base.compare(ipos, xpos, ipos1, xpos1) >= 0)
118: return EOF_VALUE;
119: return base.getNextKind(ipos, xpos);
120: }
121:
122: protected Object getPrevious(int ipos, Object xpos) {
123: if (base.compare(ipos, xpos, ipos0, xpos0) <= 0)
124: return eofValue;
125: return base.getPrevious(ipos, xpos);
126: }
127:
128: public void clear() {
129: remove(ipos0, xpos0, ipos1, xpos1);
130: }
131:
132: public void finalize() {
133: base.releasePosition(ipos0, xpos0);
134: base.releasePosition(ipos1, xpos1);
135: }
136: }
|