00001 #ifndef _STR_StreamProcessor_H_ // -*-c++-*- 00002 00003 /* 00004 * Copyright 1991-2002 Eric M. Hopper <hopper@omnifarious.org> 00005 * 00006 * This program is free software; you can redistribute it and/or modify it 00007 * under the terms of the GNU Lesser General Public License as published 00008 * by the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, but 00012 * WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 00019 */ 00020 00021 #ifdef __GNUG__ 00022 # pragma interface 00023 #endif 00024 00025 /* $Header: /home/hopper/src/cvs/C++/StrMod/StrMod/StreamProcessor.h,v 1.7 2002/08/29 00:58:05 hopper Exp $ */ 00026 00027 // For log, see ../ChangeLog 00028 // 00029 // Revision 1.2 1996/09/11 23:18:08 hopper 00030 // Changed StreamProcessor::CanAddIncoming to use StrChunkPtr operator ! 00031 // instead of comparison to 0. 00032 // 00033 // Revision 1.1 1996/09/02 23:33:54 hopper 00034 // Created abstract class (class StreamProcessor) for handling simple 00035 // dataflows where one grabbed incoming data, did stuff to it, and sent 00036 // the result along. 00037 // 00038 00039 #include <cassert> 00040 #include <LCore/GenTypes.h> 00041 #include <LCore/Protocol.h> 00042 #include <StrMod/STR_ClassIdent.h> 00043 #include <StrMod/StrChunkPtr.h> 00044 00045 #define _STR_StreamProcessor_H_ 00046 00047 namespace strmod { 00048 namespace strmod { 00049 00050 /** \class StreamProcessor StreamProcessor.h StrMod/StreamProcessor.h 00051 * Describes a simple non-active processor of a unidirectional data stream 00052 * that has one input and one output. 00053 * 00054 * Non-active means that this things readable or writeable status can't change 00055 * unless it's a result of being read or written to. 00056 * 00057 * This class is intended to be used with a ProcessorModule to create modules 00058 * that do some sort of processing on every chunk that passes through. 00059 * 00060 * A prime example of this sort of thing are streams that re-chunk the data 00061 * passing through them according to some criteria. Another example is a 00062 * stream which simply prepends a header of some sort to every chunk coming 00063 * through. 00064 * 00065 * Another prime example is a process in a Unix pipeline. 00066 */ 00067 class StreamProcessor : virtual public lcore::Protocol 00068 { 00069 public: 00070 static const STR_ClassIdent identifier; 00071 00072 //! Abstract base classes don't have substansive constructors. 00073 inline StreamProcessor(); 00074 //! Abstract base classes don't have substansive destructors. 00075 virtual ~StreamProcessor(); 00076 00077 inline virtual int AreYouA(const lcore::ClassIdent &cid) const; 00078 00079 /** Can you put data into this thing? 00080 * Note that this is \c !incoming_. This means that if you need 00081 * more data to complete your processing, your must clear incoming_ and 00082 * store the partially processed data someplace else, like 00083 * \c outgoing_. 00084 */ 00085 inline bool canWriteTo() const; 00086 //! Shove in some data. Must not be called when !canWriteTo(). 00087 inline void writeTo(const StrChunkPtr &chnk); 00088 /** Can you get any data from this thing? 00089 * Note that this is \c outgoing_ready_. It's a gross error for 00090 * <code>!outgoing_ && outgoing_ready_</code>. Set \c outgoing_ready_ when 00091 * the data in \c outgoing_ is ready to go. 00092 */ 00093 inline bool canReadFrom() const; 00094 //! Pull out some data. Must not be called when !canReadFrom(). 00095 inline const StrChunkPtr readFrom(); 00096 00097 protected: 00098 StrChunkPtr incoming_; //!< Where to find the incoming data when processIncoming() is called. 00099 StrChunkPtr outgoing_; //!< Where to stick data that's ready to go out. 00100 bool outgoing_ready_; //!< Set this when the data in \c outgoing_ is actually ready to go out. 00101 00102 virtual const lcore::ClassIdent *i_GetIdent() const { return &identifier; } 00103 00104 /** Do something with your incoming_ data. 00105 * \pre <code>(incoming_ && !outoing_ready_)</code> will 00106 * <strong>always</strong> be true when entering this function, meaning 00107 * that incoming_ points at a valid chunk. 00108 * 00109 * \post A post condition of this function is <code>(!incoming_ || 00110 * (outgoing_ready_ && outgoing_))</code>. 00111 */ 00112 virtual void processIncoming() = 0; 00113 00114 private: 00115 // Inhibit accidental copying. 00116 StreamProcessor(const StreamProcessor &b); 00117 void operator =(const StreamProcessor &b); 00118 }; 00119 00120 //-----------------------------inline functions-------------------------------- 00121 00122 inline StreamProcessor::StreamProcessor() 00123 : outgoing_ready_(false) 00124 { 00125 } 00126 00127 inline int StreamProcessor::AreYouA(const lcore::ClassIdent &cid) const 00128 { 00129 return((identifier == cid) || Protocol::AreYouA(cid)); 00130 } 00131 00132 inline bool StreamProcessor::canWriteTo() const 00133 { 00134 return(!incoming_); 00135 } 00136 00137 inline void StreamProcessor::writeTo(const StrChunkPtr &chnk) 00138 { 00139 assert(canWriteTo()); 00140 incoming_ = chnk; 00141 if (!outgoing_ready_) { 00142 processIncoming(); 00143 assert(!incoming_ || (outgoing_ready_ && outgoing_)); 00144 } 00145 } 00146 00147 inline bool StreamProcessor::canReadFrom() const 00148 { 00149 return(outgoing_ready_); 00150 } 00151 00152 inline const StrChunkPtr StreamProcessor::readFrom() 00153 { 00154 assert(outgoing_ready_); 00155 00156 StrChunkPtr tmp; 00157 00158 tmp = outgoing_; 00159 outgoing_.ReleasePtr(); 00160 outgoing_ready_ = false; 00161 if (incoming_) 00162 { 00163 processIncoming(); 00164 assert(!incoming_ || (outgoing_ready_ && outgoing_)); 00165 } 00166 return(tmp); 00167 } 00168 00169 }; // namespace strmod 00170 }; // namespace strmod 00171 00172 #endif
1.3-rc1