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

PStreamBuf.h

Go to the documentation of this file.
00001 // -*- C++ -*- 00002 00003 // PStreamBuf.h 00004 // 00005 // Copyright (C) 2003 Pascal Vincent 00006 // 00007 // Redistribution and use in source and binary forms, with or without 00008 // modification, are permitted provided that the following conditions are met: 00009 // 00010 // 1. Redistributions of source code must retain the above copyright 00011 // notice, this list of conditions and the following disclaimer. 00012 // 00013 // 2. Redistributions in binary form must reproduce the above copyright 00014 // notice, this list of conditions and the following disclaimer in the 00015 // documentation and/or other materials provided with the distribution. 00016 // 00017 // 3. The name of the authors may not be used to endorse or promote 00018 // products derived from this software without specific prior written 00019 // permission. 00020 // 00021 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00022 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00023 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00024 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00025 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00026 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 // 00032 // This file is part of the PLearn library. For more information on the PLearn 00033 // library, go to the PLearn Web site at www.plearn.org 00034 00035 /* ******************************************************* 00036 * $Id: PStreamBuf.h,v 1.7 2004/07/21 16:30:51 chrish42 Exp $ 00037 ******************************************************* */ 00038 00040 #ifndef PStreamBuf_INC 00041 #define PStreamBuf_INC 00042 00043 #define STREAMBUFVER 1 00044 00045 #include <plearn/base/PP.h> 00046 00047 namespace PLearn { 00048 using namespace std; 00049 00050 class PStreamBuf: public PPointable 00051 { 00052 public: 00053 00054 // typedef Object inherited; 00055 typedef PPointable inherited; 00056 typedef size_t streamsize; 00057 typedef off_t streampos; 00058 00059 // ************************ 00060 // * public build options * 00061 // ************************ 00062 00063 // ### declare public option fields (such as build options) here 00064 // ... 00065 00066 // **************** 00067 // * Constructors * 00068 // **************** 00069 00072 PStreamBuf(streamsize inbuf_capacity=1000, streamsize outbuf_capacity=1000, streamsize unget_capacity=100); 00073 00074 virtual ~PStreamBuf(); 00075 00076 00077 private: 00079 void build_(); 00080 00081 // Input buffer mechanism 00082 // ungetsize+inbuf_chunksize characters are allocated in total for the buffer. 00083 // Calls to read_ are always made as read_(inbuf+ungetsize, inbuf_chunksize); 00084 // The first ungetsize characters of the buffer are reserved for ungets 00085 streamsize ungetsize; 00086 streamsize inbuf_chunksize; 00087 char* inbuf; 00088 char* inbuf_p; 00089 char* inbuf_end; 00090 00091 // Output buffer 00092 streamsize outbuf_chunksize; 00093 char* outbuf; 00094 char* outbuf_p; 00095 char* outbuf_end; 00096 00097 protected: 00098 00099 bool is_readable; 00100 bool is_writable; 00101 bool is_random_accessible; 00102 00103 00107 00116 virtual streamsize read_(char* p, streamsize n); 00117 00120 virtual void write_(const char* p, streamsize n); 00121 00122 private: 00123 // refills the inbuf 00124 inline streamsize refill_in_buf() 00125 { 00126 #ifdef BOUNDCHECK 00127 if(!isReadable()) 00128 PLERROR("Called PStreamBuf::refill_in_buf on a buffer not marked as readable"); 00129 #endif 00130 00131 inbuf_p = inbuf+ungetsize; 00132 streamsize n = read_(inbuf_p, inbuf_chunksize); 00133 inbuf_end = inbuf_p+n; 00134 return n; 00135 } 00136 00137 public: 00138 00139 inline bool isReadable() const 00140 { return is_readable; } 00141 00142 inline bool isWritable() const 00143 { return is_writable; } 00144 00145 inline bool isRandomAccessible() const 00146 { return is_random_accessible; } 00147 00148 inline int get() 00149 { 00150 if(inbuf_p<inbuf_end || refill_in_buf()) 00151 return *inbuf_p++; 00152 else 00153 return -1; 00154 } 00155 00156 inline int peek() 00157 { 00158 if(inbuf_p<inbuf_end || refill_in_buf()) 00159 return *inbuf_p; 00160 else 00161 return -1; 00162 } 00163 00164 00165 inline streamsize read(char* p, streamsize n) 00166 { 00167 #ifdef BOUNDCHECK 00168 if(!isReadable()) 00169 PLERROR("Called PStreamBuf::read on a buffer not marked as readable"); 00170 #endif 00171 00172 streamsize nleft = n; 00173 00174 streamsize inbuf_n = (streamsize)(inbuf_end-inbuf_p); 00175 if(inbuf_n) // First copy what's left in the buffer 00176 { 00177 streamsize k = nleft<inbuf_n ?nleft :inbuf_n; 00178 memcpy(p,inbuf_p,k); 00179 inbuf_p += k; 00180 p += k; 00181 nleft -= k; 00182 } 00183 00184 if(nleft) // need some more ? 00185 { 00186 if(nleft>=inbuf_chunksize) // large block: read it directly 00187 nleft -= read_(p,nleft); 00188 else // small block: read it in the buffer first 00189 { 00190 inbuf_n = refill_in_buf(); 00191 if(inbuf_n) 00192 { 00193 streamsize k = nleft<inbuf_n ?nleft :inbuf_n; 00194 memcpy(p,inbuf_p,k); 00195 inbuf_p += k; 00196 nleft -= k; 00197 } 00198 } 00199 } 00200 00201 streamsize nread = n-nleft; 00202 return nread; 00203 } 00204 00205 00206 00209 inline void unread(const char* p, streamsize n) 00210 { 00211 if(inbuf_p<inbuf) 00212 PLERROR("Cannot unread that many characters: %d, input buffer bound reached", n); 00213 00214 inbuf_p -= n; 00215 memcpy(inbuf_p,p,n); 00216 } 00217 00218 00219 inline void unget(char c) 00220 { 00221 if(inbuf_p<=inbuf) 00222 PLERROR("Cannot unget that many characters, input buffer bound reached"); 00223 00224 inbuf_p--; 00225 *inbuf_p = c; 00226 } 00227 00228 00229 inline void flush() 00230 { 00231 streamsize n = (streamsize)(outbuf_p-outbuf); 00232 if(n) 00233 { 00234 write_(outbuf, n); 00235 outbuf_p = outbuf; 00236 } 00237 } 00238 00239 inline void put(char c) 00240 { 00241 #ifdef BOUNDCHECK 00242 if(!isWritable()) 00243 PLERROR("Called PStreamBuf::put on a buffer not marked as writable"); 00244 #endif 00245 *outbuf_p++ = c; 00246 if(outbuf_p==outbuf_end) 00247 flush(); 00248 } 00249 00250 inline void write(const char* p, streamsize n) 00251 { 00252 #ifdef BOUNDCHECK 00253 if(!isWritable()) 00254 PLERROR("Called PStreamBuf::write on a buffer not marked as writable"); 00255 #endif 00256 00257 streamsize bufrem = (streamsize)(outbuf_end-outbuf_p); 00258 streamsize nn = n<bufrem ?n :bufrem; 00259 memcpy(outbuf_p, p, nn); 00260 p += nn; 00261 outbuf_p += nn; 00262 flush(); 00263 n -= nn; 00264 if(n>outbuf_chunksize) 00265 write_(p, n); 00266 else 00267 { 00268 memcpy(outbuf_p, p, n); 00269 outbuf_p += n; 00270 } 00271 } 00272 00273 // Initially I planned to derive this class from Object. 00274 // But when attempting compilation I found myself back in include hell!!! 00275 // (Object needs PStream which needs PStremBuf which needs Object) 00276 // Getting out of this mess would not be easy: we need efficiency, so many of 00277 // the concerned calls really should stay inline (hence in the .h). 00278 // Finally I opted to have it derive from PPoitable rather than Object. 00279 // That's why all typical Object stuff are commented out. 00280 // (Pascal) 00281 00282 // protected: 00283 // static void declareOptions(OptionList& ol); 00284 00285 // public: 00286 // simply calls inherited::build() then build_() 00287 // virtual void build(); 00288 00290 // virtual void makeDeepCopyFromShallowCopy(map<const void*, void*>& copies); 00291 00293 // PLEARN_DECLARE_ABSTRACT_OBJECT(PStreamBuf); 00294 00295 }; 00296 00297 // Declares a few other classes and functions related to this class 00298 // DECLARE_OBJECT_PTR(PStreamBuf); 00299 00300 } // end of namespace PLearn 00301 00302 #endif

Generated on Tue Aug 17 16:03:17 2004 for PLearn by doxygen 1.3.7