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

StrChunk.h

00001 #ifndef _STR_StrChunk_H_  // -*-c++-*-
00002 
00003 /*
00004  * Copyright (C) 1991-9 Eric M. Hopper <hopper@omnifarious.mn.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/StrChunk.h,v 1.17 2002/11/25 05:40:05 hopper Exp $ */
00026 
00027 // See ../ChangeLog for log.
00028 
00029 #include <cassert>
00030 #include <cstddef>
00031 
00032 #include <LCore/Object.h>
00033 #include <LCore/RefCounting.h>
00034 
00035 #ifndef _STR_STR_ClassIdent_H_
00036 #  include <StrMod/STR_ClassIdent.h>
00037 #endif
00038 #include <StrMod/ChunkVisitor.h>
00039 
00040 #define _STR_StrChunk_H_
00041 
00042 namespace strmod {
00043 namespace strmod {
00044 
00045 class LinearExtent;
00046 
00047 /** \class StrChunk StrChunk.h StrMod/StrChunk.h
00048  * An interface to a reference counted chunk of data.
00049  *
00050  * The chunk of data is actually held by the derived classes.  Some chunks of
00051  * data even consist of other StrChunks.  This is an instance of the <A HREF="http://exciton.cs.oberlin.edu/javaresources/DesignPatterns/composite.htm">Composite</A>
00052  * design pattern.
00053  *
00054  * StrChunks are supposed to be immutable after they're created.  Often
00055  * derived classes will have methods for updating the data held within, but
00056  * StrChunks don't, and they're what the outside world sees.
00057  *
00058  * StrChunks are reference counted.  Use the StrChunkPtr class if you want a
00059  * nice smart pointer that will automatically maintain the reference count and
00060  * delete the chunk when necessary.
00061  *
00062  * StrChunks are reference counted because the containment hierarchy for them
00063  * is a DAG.  Just because the StrChunk is found by traversing a tree rooted
00064  * at a particular StrChunk doesn't mean that same StrChunk can't be found in
00065  * a different tree.  It might even be found twice in the same tree.  This
00066  * complexity requires reference counts for tractable resource handling.
00067  */
00068 class StrChunk : public lcore::Object, public lcore::ReferenceCounting
00069 {
00070    friend class ChunkVisitor;
00071  public:
00072    class __iterator;
00073    friend class __iterator;
00074    //! Give the type an STL name.
00075    typedef __iterator const_iterator;
00076    static const STR_ClassIdent identifier;
00077 
00078    //! Not much to talk about.
00079    StrChunk() : ReferenceCounting(0), iter_storage(0)  { }
00080    //! Not much to talk about.
00081    virtual ~StrChunk()                                 { }
00082 
00083    inline virtual int AreYouA(const lcore::ClassIdent &cid) const;
00084 
00085    //! Number of octets this chunk takes up.  May be deprecated.
00086    virtual unsigned int Length() const = 0;
00087 
00088    //@{
00089    /**
00090     * Get an STL style const bidirectional iterator.
00091     *
00092     * This iterator will range over all the octects of type U1Byte that are in
00093     * the chunk.
00094     */
00095    const_iterator begin();
00096    const_iterator end();
00097    //@}
00098 
00099  protected:
00100    //! See class Protocol
00101    virtual const lcore::ClassIdent *i_GetIdent() const { return(&identifier); }
00102 
00103    //! Accept a ChunkVisitor, and maybe lead it through your children.
00104    virtual void acceptVisitor(ChunkVisitor &visitor)
00105       throw(ChunkVisitor::halt_visitation) = 0;
00106 
00107    //@{
00108    /**
00109     * These are helper functions so derived classes have limited access to
00110     * ChunkVisitor methods.
00111     */
00112    inline void call_visitStrChunk(ChunkVisitor &visitor,
00113                                   const StrChunkPtr &chunk)
00114       throw(ChunkVisitor::halt_visitation);
00115    inline void call_visitStrChunk(ChunkVisitor &visitor,
00116                                   const StrChunkPtr &chunk,
00117                                   const LinearExtent &used)
00118       throw(ChunkVisitor::halt_visitation);
00119    inline void call_visitDataBlock(ChunkVisitor &visitor,
00120                                    void *start, size_t len)
00121       throw(ChunkVisitor::halt_visitation);
00122    //@}
00123 
00124  private:
00125    void *iter_storage;  //!< A kludgey storage area so iterators can avoid constantly running a Visitor over the same StrChunk.
00126 };
00127 
00128 //------------------------inline functions for StrChunk------------------------
00129 
00130 inline int StrChunk::AreYouA(const lcore::ClassIdent &cid) const
00131 {
00132    return((identifier == cid) || Object::AreYouA(cid));
00133 }
00134 
00135 inline void StrChunk::call_visitStrChunk(ChunkVisitor &visitor,
00136                                          const StrChunkPtr &chunk)
00137    throw(ChunkVisitor::halt_visitation)
00138 {
00139    visitor.visitStrChunk(chunk);
00140 }
00141 
00142 inline void StrChunk::call_visitStrChunk(ChunkVisitor &visitor,
00143                                          const StrChunkPtr &chunk,
00144                                          const LinearExtent &used)
00145    throw(ChunkVisitor::halt_visitation)
00146 {
00147    visitor.visitStrChunk(chunk, used);
00148 }
00149 
00150 inline void StrChunk::call_visitDataBlock(ChunkVisitor &visitor,
00151                                           void *start, size_t len)
00152    throw(ChunkVisitor::halt_visitation)
00153 {
00154    visitor.visitDataBlock(start, len);
00155 }
00156 
00157 }  // namespace strmod
00158 }  // namespace strmod
00159 
00160 #endif

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