PLearn 0.1
|
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 10372 2011-09-23 19:52:15Z nouiz $ 00037 ******************************************************* */ 00038 00040 #ifndef PStreamBuf_INC 00041 #define PStreamBuf_INC 00042 00043 #include <cstdio> //Needed by g++ 4.5.1 00044 #include <plearn/base/PP.h> 00045 00046 namespace PLearn { 00047 using namespace std; 00048 00049 class PStreamBuf: public PPointable 00050 { 00051 00052 typedef PPointable inherited; 00053 00054 public: 00055 00056 typedef size_t streamsize; 00057 typedef off_t streampos; 00058 00059 // **************** 00060 // * Constructors * 00061 // **************** 00062 00064 PStreamBuf(bool is_readable_, bool is_writable_, 00065 streamsize inbuf_capacity=1, streamsize outbuf_capacity=0, 00066 streamsize unget_capacity=default_ungetsize); 00067 00068 void setBufferCapacities(streamsize inbuf_capacity, 00069 streamsize outbuf_capacity, 00070 streamsize unget_capacity); 00071 00072 virtual ~PStreamBuf(); 00073 00074 protected: 00075 00077 static const streamsize default_ungetsize = 100; 00078 00079 bool is_readable; 00080 bool is_writable; 00081 00084 int last_get; 00085 00086 private: 00087 00088 // Input buffer mechanism 00089 // ungetsize+inbuf_chunksize characters are allocated in total for the buffer. 00090 // Calls to read_ are always made as read_(inbuf+ungetsize, inbuf_chunksize); 00091 // The first ungetsize characters of the buffer are reserved for ungets 00092 streamsize ungetsize; 00093 streamsize inbuf_chunksize; 00094 char* inbuf; 00095 char* inbuf_p; 00096 char* inbuf_end; 00097 00098 // Output buffer 00099 streamsize outbuf_chunksize; 00100 char* outbuf; 00101 char* outbuf_p; 00102 char* outbuf_end; 00103 00104 protected: 00108 00117 virtual streamsize read_(char* p, streamsize n); 00118 00121 virtual void write_(const char* p, streamsize n); 00122 00123 private: 00124 00125 // refills the inbuf 00126 streamsize refill_in_buf(); 00127 00128 public: 00129 00130 bool inbufEmpty() const 00131 { return !(inbuf_p<inbuf_end); } 00132 00133 bool isReadable() const 00134 { return is_readable; } 00135 00136 bool isWritable() const 00137 { return is_writable; } 00138 00139 int get() 00140 { 00141 if(inbuf_p<inbuf_end || refill_in_buf()) 00142 return (last_get = (unsigned char) *inbuf_p++); 00143 else 00144 return (last_get = -1); 00145 } 00146 00150 void putback(char c); 00151 00156 void unget(); 00157 00158 int peek() 00159 { 00160 if(inbuf_p<inbuf_end || refill_in_buf()) 00161 return (unsigned char) *inbuf_p; 00162 else 00163 return -1; 00164 } 00165 00166 00168 streamsize read(char* p, streamsize n); 00169 00172 void unread(const char* p, streamsize n); 00173 00174 virtual void flush(); 00175 00176 void put(char c) 00177 { 00178 #ifdef BOUNDCHECK 00179 if(!isWritable()) 00180 PLERROR("Called PStreamBuf::put on a buffer not marked as writable"); 00181 #endif 00182 if(outbuf_chunksize>0) // buffered 00183 { 00184 if(outbuf_p==outbuf_end) 00185 flush(); 00186 *outbuf_p++ = c; 00187 } 00188 else // unbuffered 00189 write_(&c,1); 00190 } 00191 00192 void write(const char* p, streamsize n); 00193 00195 virtual bool good() const; 00196 00198 bool eof() const 00199 { 00200 return const_cast<PStreamBuf*>(this)->peek() == EOF; 00201 } 00202 00203 }; 00204 00205 } // end of namespace PLearn 00206 00207 #endif 00208 00209 00210 /* 00211 Local Variables: 00212 mode:c++ 00213 c-basic-offset:4 00214 c-file-style:"stroustrup" 00215 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00216 indent-tabs-mode:nil 00217 fill-column:79 00218 End: 00219 */ 00220 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :