00001 #ifndef _STR_TelnetParser_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 <LCore/Protocol.h>
00031 #include <LCore/HopClTypes.h>
00032 #include <StrMod/TelnetChars.h>
00033 #include <StrMod/STR_ClassIdent.h>
00034
00035 #define _STR_TelnetParser_H_
00036
00037 namespace strmod {
00038 namespace strmod {
00039
00040 class TelnetChunkBuilder;
00041 template <unsigned int n> class PreAllocBuffer;
00042
00043
00044
00045
00046
00047 class TelnetParser : virtual public lcore::Protocol
00048 {
00049 public:
00050 static const STR_ClassIdent identifier;
00051
00052
00053 TelnetParser();
00054
00055 virtual ~TelnetParser();
00056
00057 inline virtual int AreYouA(const lcore::ClassIdent &cid) const;
00058
00059
00060 void processData(const void *data, size_t len,
00061 TelnetChunkBuilder &builder);
00062
00063
00064 void endOfChunk(TelnetChunkBuilder &builder);
00065
00066
00067
00068
00069 size_t getRegionBegin() const { return regionbegin_; }
00070
00071
00072
00073
00074 inline void dropBytes(size_t bytes);
00075
00076
00077 void reset(TelnetChunkBuilder &builder);
00078
00079 protected:
00080
00081
00082
00083
00084
00085 enum ParserState {
00086 PS_Normal,
00087 PS_Escape,
00088 PS_SubNeg,
00089 PS_SuboptNum,
00090 PS_Subopt,
00091 PS_SuboptEscape
00092 };
00093
00094 virtual const lcore::ClassIdent *i_GetIdent() const { return &identifier; }
00095
00096 private:
00097 typedef lcore::U1Byte U1Byte;
00098 TelnetChars::OptionNegotiations negtype_;
00099 U1Byte subopt_type_;
00100 size_t curpos_;
00101 ParserState state_;
00102 size_t regionbegin_;
00103 size_t regionend_;
00104 U1Byte *cookedbuf_;
00105 size_t cooked_total_;
00106 size_t cooked_used_;
00107 PreAllocBuffer<48> *cooked_;
00108
00109 inline void stateNormal(ParserState &state, const U1Byte ch);
00110 inline void stateEscape(ParserState &state, const U1Byte ch, size_t i,
00111 TelnetChunkBuilder &builder);
00112 inline void stateSubNeg(ParserState &state, const U1Byte ch, size_t i,
00113 TelnetChunkBuilder &builder);
00114 inline void stateSuboptNum(ParserState &state, const U1Byte ch, size_t i,
00115 TelnetChunkBuilder &builder);
00116 inline void stateSubopt(ParserState &state, U1Byte ch);
00117 inline void stateSuboptEscape(ParserState &state, U1Byte ch, size_t i,
00118 TelnetChunkBuilder &builder);
00119 };
00120
00121
00122
00123 inline int TelnetParser::AreYouA(const lcore::ClassIdent &cid) const
00124 {
00125 return((identifier == cid) || Protocol::AreYouA(cid));
00126 }
00127
00128 inline void TelnetParser::dropBytes(size_t bytes)
00129 {
00130 if (bytes <= regionbegin_)
00131 {
00132 regionbegin_ -= bytes;
00133 curpos_ -= bytes;
00134 }
00135 }
00136
00137 };
00138 };
00139
00140 #endif