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

TelnetChunkerData.h

00001 #ifndef _STR_TelnetChunkerData_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/TelnetChunkerData.h,v 1.4 2002/08/29 00:58:05 hopper Exp $ */
00026 
00027 // For a log, see ../ChangeLog
00028 
00029 #include <cstddef>
00030 #include <stdexcept>
00031 #include <LCore/GenTypes.h>
00032 #include <StrMod/TelnetChunker.h>
00033 #include <StrMod/TelnetChars.h>
00034 #include <StrMod/StrChunk.h>
00035 #include <StrMod/STR_ClassIdent.h>
00036 #include <StrMod/StrChunkPtrT.h>
00037 #include <StrMod/BufferChunk.h>
00038 
00039 #define _STR_TelnetChunkerData_H_
00040 
00041 namespace strmod {
00042 namespace strmod {
00043 
00044 /** \class TelnetChunker::TelnetData TelnetChunkerData.h StrMod/TelnetChunkerData.h
00045  * This is just a base abstract class for all things recognized as
00046  * telnet protocol messages.  It largely exists so the AreYouA() style
00047  * searches can be used to find out if a StrChunk is a telnet message
00048  * or not.
00049  */
00050 class TelnetChunker::TelnetData : public StrChunk
00051 {
00052  public:
00053    static const STR_ClassIdent identifier;
00054 
00055    //! Constructors for abstract base classes don't do much.
00056    TelnetData()                                         { }
00057    //! Destructors for abstract base classes don't do much.
00058    virtual ~TelnetData()                                { }
00059 
00060    inline virtual int AreYouA(const lcore::ClassIdent &cid) const;
00061 
00062    // Redeclare this just to show we know what we're doing and it's still
00063    // abstract.
00064    virtual unsigned int Length() const = 0;
00065 
00066  protected:
00067    typedef lcore::U1Byte U1Byte;
00068    virtual const lcore::ClassIdent *i_GetIdent() const  { return &identifier; }
00069 
00070    // Redeclare this just to show we know what we're doing and it's still
00071    // abstract.
00072    virtual void acceptVisitor(ChunkVisitor &visitor)
00073       throw(ChunkVisitor::halt_visitation) = 0;
00074 };
00075 
00076 //---
00077 
00078 /** \class TelnetChunker::SingleChar TelnetChunkerData.h StrMod/TelnetChunkerData.h
00079  * A single character telnet command.
00080  */
00081 class TelnetChunker::SingleChar : public TelnetChunker::TelnetData
00082 {
00083  public:
00084    static const STR_ClassIdent identifier;
00085 
00086    //! Construct a SingleChar for a particular command.
00087    inline SingleChar(TelnetChars::Commands opt);
00088 
00089    inline virtual int AreYouA(const lcore::ClassIdent &cid) const;
00090 
00091    virtual unsigned int Length() const                  { return(2); }
00092 
00093    //! What single character command am I?
00094    TelnetChars::Commands getCommand() const             { return(opt_); }
00095 
00096    //! Is this octet a valid single character telnet command?
00097    inline static bool isSpecial(U1Byte c);
00098 
00099    //! Convert the character to a member of the TelnetChars::Commands enum.
00100    inline static TelnetChars::Commands charToCommand(U1Byte c)
00101       throw(std::domain_error);
00102 
00103  protected:
00104    virtual const lcore::ClassIdent *i_GetIdent() const  { return &identifier; }
00105 
00106    virtual void acceptVisitor(ChunkVisitor &visitor)
00107       throw(ChunkVisitor::halt_visitation);
00108 
00109  private:
00110    const TelnetChars::Commands opt_;
00111    U1Byte buf_[2];  // Always <IAC> opt_
00112 };
00113 
00114 //---
00115 
00116 /** \class TelnetChunker::Suboption TelnetChunkerData.h StrMod/TelnetChunkerData.h
00117  * A telnet suboption.
00118  * This should never be seen for a particular option unless we've previously
00119  * agreed to talk about this option in an OptionNegotiation.
00120  */
00121 class TelnetChunker::Suboption : public TelnetChunker::TelnetData {
00122  public:
00123    static const STR_ClassIdent identifier;
00124 
00125    //! Construct a telnet suboption request.
00126    inline Suboption(U1Byte type,
00127                     const StrChunkPtrT<BufferChunk> &cooked,
00128                     const StrChunkPtr &raw);
00129    /** Construct a telnet suboption request, generating the 'raw' data.
00130     *
00131     * The generated raw data is created by replacing any instances of IAC in
00132     * the cooked data with IAC IAC.
00133     */
00134    Suboption(U1Byte type, const StrChunkPtrT<BufferChunk> &cooked);
00135 
00136    inline virtual int AreYouA(const lcore::ClassIdent &cid) const;
00137 
00138    inline virtual unsigned int Length() const;
00139 
00140    //! Which suboption is this data for?
00141    inline U1Byte getType() const                       { return(optstart_[2]); }
00142    //! What's the suboption data with all the escapes processed?
00143    inline const StrChunkPtrT<BufferChunk> &getCooked() const;
00144    //! What's the suboption data without any escape processing?
00145    inline const StrChunkPtr &getRaw() const            { return(raw_); }
00146 
00147  protected:
00148    virtual const lcore::ClassIdent *i_GetIdent() const  { return &identifier; }
00149 
00150    //! Accept a ChunkVisitor, and maybe lead it through your children.
00151    virtual void acceptVisitor(ChunkVisitor &visitor)
00152       throw(ChunkVisitor::halt_visitation);
00153 
00154  private:
00155    static const U1Byte optend_[2];  // Always <IAC> <SE>  (255 240)
00156    U1Byte optstart_[3];  // Always <IAC> <SB> type
00157    const StrChunkPtr raw_;
00158    const unsigned int rawlen_;
00159    // The contents stripped of escape characters and such.
00160    const StrChunkPtrT<BufferChunk> cooked_;
00161 
00162    static const StrChunkPtr
00163    cookedToRaw(const StrChunkPtrT<BufferChunk> &cooked);
00164 };
00165 
00166 //---
00167 
00168 /** \class TelnetChunker::OptionNegotiation TelnetChunkerData.h StrMod/TelnetChunkerData.h
00169  * A telnet suboption negotiation request.
00170  */
00171 class TelnetChunker::OptionNegotiation : public TelnetChunker::TelnetData {
00172  public:
00173    static const STR_ClassIdent identifier;
00174 
00175    //! Create a particular kind of option negotiation for a particular option.
00176    inline OptionNegotiation(TelnetChars::OptionNegotiations request,
00177                             U1Byte type);
00178 
00179    inline virtual int AreYouA(const lcore::ClassIdent &cid) const;
00180 
00181    virtual unsigned int Length() const                  { return(3); }
00182 
00183    //! What kind of negotiation is being made?
00184    TelnetChars::OptionNegotiations getRequest() const   { return(request_); }
00185    //! What option is being negotiated?
00186    U1Byte getType() const                               { return(buf_[2]); }
00187 
00188  protected:
00189    virtual const lcore::ClassIdent *i_GetIdent() const  { return &identifier; }
00190 
00191    virtual void acceptVisitor(ChunkVisitor &visitor)
00192       throw(ChunkVisitor::halt_visitation);
00193 
00194  private:
00195    TelnetChars::OptionNegotiations request_;
00196    U1Byte buf_[3];  //!< Always <IAC> <request> <type>
00197 };
00198 
00199 //-----------------------------inline functions--------------------------------
00200 
00201 inline int TelnetChunker::TelnetData::AreYouA(const lcore::ClassIdent &cid) const
00202 {
00203    return((identifier == cid) || StrChunk::AreYouA(cid));
00204 }
00205 
00206 //---
00207 
00208 inline TelnetChunker::SingleChar::SingleChar(TelnetChars::Commands opt)
00209      : opt_(opt)
00210 {
00211    buf_[0] = TelnetChars::IAC;
00212    buf_[1] = opt_;
00213 }
00214 
00215 inline int TelnetChunker::SingleChar::AreYouA(const lcore::ClassIdent &cid) const
00216 {
00217    return((identifier == cid) || TelnetData::AreYouA(cid));
00218 }
00219 
00220 inline bool TelnetChunker::SingleChar::isSpecial(U1Byte c)
00221 {
00222    return(((c >= TelnetChars::TEOF) && (c <= TelnetChars::EOR)) ||
00223           ((c >= TelnetChars::NOP) && (c <= TelnetChars::GA)));
00224 }
00225 
00226 //---
00227 
00228 /**
00229  * \param type Which suboption is this for?
00230  * \param cooked The suboption data that has had the escape characters
00231  *               processed.
00232  * \param raw The raw suboption data with no escape processing at all.
00233  */
00234 inline
00235 TelnetChunker::Suboption::Suboption(
00236    U1Byte type, const StrChunkPtrT<BufferChunk> &cooked, const StrChunkPtr &raw)
00237      : raw_(raw), rawlen_(raw->Length()), cooked_(cooked)
00238 {
00239    optstart_[0] = TelnetChars::IAC;
00240    optstart_[1] = TelnetChars::SB;
00241    optstart_[2] = type;
00242 }
00243 
00244 inline int TelnetChunker::Suboption::AreYouA(const lcore::ClassIdent &cid) const
00245 {
00246    return((identifier == cid) || TelnetData::AreYouA(cid));
00247 }
00248 
00249 inline unsigned int TelnetChunker::Suboption::Length() const
00250 {
00251    return(5 + rawlen_);
00252 }
00253 
00254 inline const StrChunkPtrT<BufferChunk> &
00255 TelnetChunker::Suboption::getCooked() const
00256 {
00257    return(cooked_);
00258 }
00259 
00260 //---
00261 
00262 /**
00263  * \param request The kind of negotiation
00264  * \param type The option is being negotiated
00265  */
00266 inline
00267 TelnetChunker::OptionNegotiation::OptionNegotiation(
00268    TelnetChars::OptionNegotiations request,
00269    U1Byte type)
00270      : request_(request)
00271 {
00272    assert((request >= TelnetChars::O_WILL) && (request <= TelnetChars::O_DONT));
00273    buf_[0] = 255;
00274    buf_[1] = request_;
00275    buf_[2] = type;
00276 }
00277 
00278 inline int
00279 TelnetChunker::OptionNegotiation::AreYouA(const lcore::ClassIdent &cid) const
00280 {
00281    return((identifier == cid) || TelnetData::AreYouA(cid));
00282 }
00283 
00284 };  // namespace strmod
00285 };  // namespace strmod
00286 
00287 #endif

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