Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

PositionableStream.cc

Go to the documentation of this file.
00001 /*
00002  * PositionableStream.cc
00003  *
00004  * Smalltalk like class library for C++
00005  * Abstract stream with positioning feature.
00006  *
00007  * Copyright (c) 2003 Milan Cermak
00008  */
00009 /*
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or (at your option) any later version.
00014  *
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 /* Initialize/release protocol */
00033 void PositionableStream::initialize(SequenceableCollection *coll)
00034 {
00035     collection = coll;
00036     read_limit = write_limit = coll->size();
00037     _position = 0;
00038 }
00039 
00040 /* Class-accessing protocol */
00041 String *PositionableStream::className(void) const
00042 {
00043     return new String("PositionableStream");
00044 }
00045 
00046 /* Accessing protocol */
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     /* Use next for the first read to make sure that the receiver is readable. */
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 /* Positioning protocol */
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     // PositionableStream::position(pos);
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 /* Testing protocol */
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 /* Private protocol */
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 }

Generated on Mon Nov 27 09:47:55 2006 for Smalltalk like C++ Class Library by  doxygen 1.4.2