00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stlib/PositionableStream.h>
00025 #include <stlib/Character.h>
00026 #include <stlib/SequenceableCollection.h>
00027 #include <stlib/String.h>
00028 #include <stlib/WriteStream.h>
00029
00030 #include <stlib/IncompleteNextCountError.h>
00031
00032
00033 void PositionableStream::initialize(SequenceableCollection *coll)
00034 {
00035 collection = coll;
00036 read_limit = write_limit = coll->size();
00037 _position = 0;
00038 }
00039
00040
00041 String *PositionableStream::className(void) const
00042 {
00043 return new String("PositionableStream");
00044 }
00045
00046
00047 SequenceableCollection *PositionableStream::contents(void)
00048 {
00049 return dynamic_cast<SequenceableCollection *>(collection->copy(0, read_limit - 1));
00050 }
00051
00052 SequenceableCollection *PositionableStream::next(long items,
00053 SequenceableCollection *newColl,
00054 long startIndex)
00055 {
00056 if (items < 1) return newColl;
00057 if (atEnd())
00058 (new IncompleteNextCountError(__PRETTY_FUNCTION__, 0))->raiseFrom(this);
00059
00060
00061 newColl->put(startIndex, next());
00062
00063 long howManyRead = 1;
00064 while (howManyRead < items) {
00065 long increment, newHowManyRead;
00066 if (atEnd())
00067 (new IncompleteNextCountError(__PRETTY_FUNCTION__, howManyRead))->raiseFrom(this);
00068 long m1 = read_limit - _position;
00069 long m2 = items - howManyRead;
00070 increment = (m1 < m2) ? m1 : m2;
00071 newHowManyRead = howManyRead + increment;
00072 newColl->replace(startIndex + howManyRead, startIndex + newHowManyRead,
00073 collection, _position);
00074 _position += increment;
00075 howManyRead = newHowManyRead;
00076 }
00077 return newColl;
00078 }
00079
00080 bool PositionableStream::peekFor(Object *object)
00081 {
00082 if (atEnd()) return false;
00083 Object *element = next();
00084 if (element->isEqual(object)) return true;
00085 skip(-1);
00086 return false;
00087 }
00088
00089
00090 long PositionableStream::position(void)
00091 {
00092 return _position;
00093 }
00094
00095 void PositionableStream::position(long pos)
00096 {
00097 read_limit = (read_limit < _position) ? _position : read_limit;
00098
00099 if (pos >= 0 && pos <= read_limit)
00100 _position = pos;
00101 else
00102 positionOutOfBoundsError(new String(__PRETTY_FUNCTION__), pos);
00103 }
00104
00105 void PositionableStream::reset(void)
00106 {
00107 read_limit = (read_limit < _position) ? _position : read_limit;
00108 _position = 0;
00109 }
00110
00111 void PositionableStream::skip(long length)
00112 {
00113 position(_position + length);
00114 }
00115
00116
00117 bool PositionableStream::atEnd(void)
00118 {
00119 return basicAtEnd();
00120 }
00121
00122 bool PositionableStream::isEmpty(void)
00123 {
00124 return _position == 0;
00125 }
00126
00127 bool PositionableStream::notEmpty(void)
00128 {
00129 return _position > 0;
00130 }
00131
00132 bool PositionableStream::isBinary(void)
00133 {
00134 return collection->isByteArray();
00135 }
00136
00137
00138 bool PositionableStream::basicAtEnd(void)
00139 {
00140 return _position >= read_limit;
00141 }
00142
00143 SequenceableCollection *PositionableStream::contentSpeciesFor(long items)
00144 {
00145 return (SequenceableCollection *) collection->copyEmpty(items);
00146 }