00001 #ifndef DV_UTIL_FILTERSTREAMBUF_H 00002 #define DV_UTIL_FILTERSTREAMBUF_H 00003 // $Id: filterstreambuf.h,v 1.8 2009/12/05 11:26:23 dvermeir Exp $ 00004 00005 #include <cstdio> // for EOF and gcc-4.4.1 00006 #include <iostream> 00007 /** @file 00008 * The Dv::Util::filterstreambuf class is a template class that 00009 * is used to define Dv::Util::filterstream objects. 00010 */ 00011 namespace Dv { 00012 namespace Util { 00013 /** 00014 * A streambuf specialization that cooperates with a filter class object. 00015 * A filterstreambuf does not buffer data, but immediately passes them on 00016 * (resp. obtains them from) to the filter. 00017 * 00018 * The requirements for the Filter template parameter are as follows: 00019 * 00020 * @code 00021 * class Filter { 00022 * public: 00023 * int get(); // return next input char or Traits::eof 00024 * int put(int c); // output c if c!=EOF, return EOF if error 00025 * int sync(); // synchronize filter, return 0 (ok) or -1 (EOF) 00026 * void close(); // close filter, no obligations.. 00027 * ios_base::iostate state(); // return status of filter 00028 * }; 00029 * @endcode 00030 * Here, @a state() is not used by filterstreambuf but may be 00031 * convenient for streams based on a filterstreambuf: the 00032 * constructor can use basic_ios::clear(filter.state()) to inherit 00033 * the initial state of the filter. 00034 * 00035 * @see Dv::Util::teestream 00036 */ 00037 template <class Filter> 00038 class filterstreambuf: public std::streambuf { 00039 public: 00040 /** 00041 * The constructor remembers the filter to which I/O will be forwarded. 00042 * @param filter to which I/O operations will be forwarded. 00043 * @warning The filter is not copied, the management of the filter 00044 * is not the filterstreambuf's responsibility (only a reference 00045 * to the filter is kept). 00046 */ 00047 explicit filterstreambuf(Filter& filter): filter_(filter) { 00048 setg(inbuf_,inbuf_+1,inbuf_+1); // very small input buffer 00049 setp(outbuf_,outbuf_); // no output buffer 00050 } 00051 /** 00052 * This is already virtual in streambuf. 00053 */ 00054 virtual ~filterstreambuf() {} 00055 /** 00056 * @return underlying filter (const version). 00057 */ 00058 const Filter& filter() const { return filter_; } 00059 /** 00060 * @return underlying filter (non-const version). 00061 */ 00062 Filter& filter() { return filter_; } 00063 00064 /** 00065 * Set underlying filter. 00066 * @param filter to which I/O operations will be forwarded. 00067 * @warning The filter is not copied, the management of the filter 00068 * is not the filterstreambuf's responsibility. 00069 */ 00070 filterstreambuf& filter(Filter& filter) { filter_ = filter; return *this; } 00071 00072 /** Close -- indicate intention not to use the filter anymore. 00073 * @return return status of Dv::Util::filterstreambuf::sync. 00074 */ 00075 bool close() { int tmp=sync(); filter_.close(); return tmp; } 00076 00077 /** Override iostream::sync(). 00078 * @return return status of @a filter_.sync() . 00079 */ 00080 virtual int sync() { return filter_.sync(); } 00081 00082 protected: 00083 /** Override iostream::underflow(). 00084 * @return next input char or EOF 00085 */ 00086 virtual int underflow() { 00087 if (gptr()<egptr()) // buffer not empty 00088 return *gptr(); 00089 if ( (inbuf_[0] = filter_.get()) != EOF) 00090 setg(inbuf_,inbuf_,inbuf_+1); 00091 return inbuf_[0]; 00092 } 00093 /** 00094 * Override iostream::overflow(). 00095 * @param c next char to put 00096 * @return status of filter_.put(c) 00097 */ 00098 virtual int overflow(int c) { return filter_.put(c); } 00099 00100 private: 00101 Filter& filter_; 00102 char inbuf_[1]; 00103 char outbuf_[1]; // unused 00104 }; 00105 } 00106 } 00107 #endif
dvutil-1.0.10 | [ 5 December, 2009] |