• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDE Support
  • Sitemap
  • Contact Us
 

strigi/src/streams

bufferedstream.h

Go to the documentation of this file.
00001 /* This file is part of Strigi Desktop Search
00002  *
00003  * Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
00004  *
00005  * This library is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU Library General Public
00007  * License as published by the Free Software Foundation; either
00008  * version 2 of the License, or (at your option) any later version.
00009  *
00010  * This library is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU Library General Public License
00016  * along with this library; see the file COPYING.LIB.  If not, write to
00017  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019  */
00020 #ifndef STRIGI_BUFFEREDSTREAM_H
00021 #define STRIGI_BUFFEREDSTREAM_H
00022 
00023 #include "streambase.h"
00024 #include "streambuffer.h"
00025 #include <cassert>
00026 
00027 namespace Strigi {
00028 
00036 template <class T>
00037 class BufferedStream : public StreamBase<T> {
00038 private:
00039     StreamBuffer<T> buffer;
00040     bool finishedWritingToBuffer;
00041 
00042     void writeToBuffer(int32_t minsize, int32_t maxsize);
00043 protected:
00063     virtual int32_t fillBuffer(T* start, int32_t space) = 0;
00069     void resetBuffer() {
00070         StreamBase<T>::m_size = -1;
00071         StreamBase<T>::m_position = 0;
00072         StreamBase<T>::m_error.assign("");
00073         StreamBase<T>::m_status = Ok;
00074         buffer.readPos = buffer.start;
00075         buffer.avail = 0; 
00076         finishedWritingToBuffer = false;
00077     }
00081     void setMinBufSize(int32_t s) {
00082         buffer.makeSpace(s);
00083     }
00084     BufferedStream<T>();
00085 public:
00086     int32_t read(const T*& start, int32_t min, int32_t max);
00087     int64_t reset(int64_t pos);
00088     virtual int64_t skip(int64_t ntoskip);
00089 };
00090 
00091 
00093 typedef BufferedStream<char> BufferedInputStream;
00094 
00096 typedef BufferedStream<wchar_t> BufferedReader;
00097 
00098 
00099 template <class T>
00100 BufferedStream<T>::BufferedStream() {
00101     finishedWritingToBuffer = false;
00102 }
00103 
00104 template <class T>
00105 void
00106 BufferedStream<T>::writeToBuffer(int32_t ntoread, int32_t maxread) {
00107     int32_t missing = ntoread - buffer.avail;
00108     int32_t nwritten = 0;
00109     while (missing > 0 && nwritten >= 0) {
00110         int32_t space;
00111         space = buffer.makeSpace(missing);
00112         if (maxread >= ntoread && space > maxread) {
00113              space = maxread;
00114         }
00115         T* start = buffer.readPos + buffer.avail;
00116         nwritten = fillBuffer(start, space);
00117         assert(StreamBase<T>::m_status != Eof);
00118         if (nwritten > 0) {
00119             buffer.avail += nwritten;
00120             missing = ntoread - buffer.avail;
00121         }
00122     }
00123     if (nwritten < 0) {
00124         finishedWritingToBuffer = true;
00125     }
00126 }
00127 template <class T>
00128 int32_t
00129 BufferedStream<T>::read(const T*& start, int32_t min, int32_t max) {
00130     if (StreamBase<T>::m_status == Error) return -2;
00131     if (StreamBase<T>::m_status == Eof) return -1;
00132 
00133     // do we need to read data into the buffer?
00134     if (min > max) max = 0;
00135     if (!finishedWritingToBuffer && min > buffer.avail) {
00136         // do we have enough space in the buffer?
00137         writeToBuffer(min, max);
00138         if (StreamBase<T>::m_status == Error) return -2;
00139     }
00140 
00141     int32_t nread = buffer.read(start, max);
00142 
00143     StreamBase<T>::m_position += nread;
00144     if (StreamBase<T>::m_position > StreamBase<T>::m_size
00145         && StreamBase<T>::m_size > 0) {
00146         // error: we read more than was specified in size
00147         // this is an error because all dependent code might have been labouring
00148         // under a misapprehension
00149         StreamBase<T>::m_status = Error;
00150         StreamBase<T>::m_error = "Stream is longer than specified.";
00151         nread = -2;
00152     } else if (StreamBase<T>::m_status == Ok && buffer.avail == 0
00153             && finishedWritingToBuffer) {
00154         StreamBase<T>::m_status = Eof;
00155         if (StreamBase<T>::m_size == -1) {
00156             StreamBase<T>::m_size = StreamBase<T>::m_position;
00157         }
00158         // save one call to read() by already returning -1 if no data is there
00159         if (nread == 0) nread = -1;
00160     }
00161     return nread;
00162 }
00163 template <class T>
00164 int64_t
00165 BufferedStream<T>::reset(int64_t newpos) {
00166     assert(newpos >= 0);
00167     if (StreamBase<T>::m_status == Error) return -2;
00168     // check to see if we have this position
00169     int64_t d = StreamBase<T>::m_position - newpos;
00170     if (buffer.readPos - d >= buffer.start && -d < buffer.avail) {
00171         StreamBase<T>::m_position -= d;
00172         buffer.avail += (int32_t)d;
00173         buffer.readPos -= d;
00174         StreamBase<T>::m_status = Ok;
00175     }
00176     return StreamBase<T>::m_position;
00177 }
00178 template <class T>
00179 int64_t
00180 BufferedStream<T>::skip(int64_t ntoskip) {
00181     const T *begin;
00182     int32_t nread;
00183     int64_t skipped = 0;
00184     while (ntoskip) {
00185         int32_t step = (int32_t)((ntoskip > buffer.size) ?buffer.size :ntoskip);
00186         nread = read(begin, 1, step);
00187         if (nread <= 0) {
00188             return skipped;
00189         }
00190         ntoskip -= nread;
00191         skipped += nread;
00192     }
00193     return skipped;
00194 }
00195 
00196 } // end namespace Strigi
00197 
00198 #endif

strigi/src/streams

Skip menu "strigi/src/streams"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members

KDE Support

Skip menu "KDE Support"
  • akonadi
  • Decibel
  • grantlee
  • kdewin
  • phonon
  •     Backend
  • polkit-qt
  • qca
  • qimageblitz
  • soprano
  • strigi
  •     searchclient
  •     streamanalyzer
  •     streams
Generated for KDE Support by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal