00001 #ifndef _STR_TelnetChunkerData_H_ // -*-c++-*-
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef __GNUG__
00022 # pragma interface
00023 #endif
00024
00025
00026
00027
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
00045
00046
00047
00048
00049
00050 class TelnetChunker::TelnetData : public StrChunk
00051 {
00052 public:
00053 static const STR_ClassIdent identifier;
00054
00055
00056 TelnetData() { }
00057
00058 virtual ~TelnetData() { }
00059
00060 inline virtual int AreYouA(const lcore::ClassIdent &cid) const;
00061
00062
00063
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
00071
00072 virtual void acceptVisitor(ChunkVisitor &visitor)
00073 throw(ChunkVisitor::halt_visitation) = 0;
00074 };
00075
00076
00077
00078
00079
00080
00081 class TelnetChunker::SingleChar : public TelnetChunker::TelnetData
00082 {
00083 public:
00084 static const STR_ClassIdent identifier;
00085
00086
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
00094 TelnetChars::Commands getCommand() const { return(opt_); }
00095
00096
00097 inline static bool isSpecial(U1Byte c);
00098
00099
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];
00112 };
00113
00114
00115
00116
00117
00118
00119
00120
00121 class TelnetChunker::Suboption : public TelnetChunker::TelnetData {
00122 public:
00123 static const STR_ClassIdent identifier;
00124
00125
00126 inline Suboption(U1Byte type,
00127 const StrChunkPtrT<BufferChunk> &cooked,
00128 const StrChunkPtr &raw);
00129
00130
00131
00132
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
00141 inline U1Byte getType() const { return(optstart_[2]); }
00142
00143 inline const StrChunkPtrT<BufferChunk> &getCooked() const;
00144
00145 inline const StrChunkPtr &getRaw() const { return(raw_); }
00146
00147 protected:
00148 virtual const lcore::ClassIdent *i_GetIdent() const { return &identifier; }
00149
00150
00151 virtual void acceptVisitor(ChunkVisitor &visitor)
00152 throw(ChunkVisitor::halt_visitation);
00153
00154 private:
00155 static const U1Byte optend_[2];
00156 U1Byte optstart_[3];
00157 const StrChunkPtr raw_;
00158 const unsigned int rawlen_;
00159
00160 const StrChunkPtrT<BufferChunk> cooked_;
00161
00162 static const StrChunkPtr
00163 cookedToRaw(const StrChunkPtrT<BufferChunk> &cooked);
00164 };
00165
00166
00167
00168
00169
00170
00171 class TelnetChunker::OptionNegotiation : public TelnetChunker::TelnetData {
00172 public:
00173 static const STR_ClassIdent identifier;
00174
00175
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
00184 TelnetChars::OptionNegotiations getRequest() const { return(request_); }
00185
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];
00197 };
00198
00199
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
00230
00231
00232
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
00264
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 };
00285 };
00286
00287 #endif