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

StreamProcessor.h

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

Generated on Wed Jan 29 00:32:44 2003 for libNet by doxygen1.3-rc1