00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 #ifndef __TAGSCANNER_H__
00021 #define __TAGSCANNER_H__
00022 
00040 #include <string>
00041 #include <vector>
00042 #include <stdlib.h> 
00043 #include <string.h> 
00044 
00045 using namespace std;
00046 
00059 class WeInStream {
00060 public:
00061     virtual char GetChar() = 0;
00062     virtual void PushBack(char c) = 0;
00063     virtual int GetPos() = 0;
00064 };
00065 
00076 class WeStrStream : public WeInStream
00077 {
00078     char* p;
00079     const char* start;
00080     const char* end;
00081 public:
00082     WeStrStream(const char* src): p((char*)src), start(src), end(src + strlen(src)) {}
00083     virtual char GetChar() { return p < end? *p++: 0; }
00084     virtual void PushBack(char c) {if(p > start) {p--;}}
00085     virtual int GetPos() { return p - start; };
00086 };
00087 
00088 enum WeScannerToken {
00089     wstError = -1,
00090     wstEof = 0,
00091     wstTagStart,
00092     wstTagEnd,
00093     wstAttr,
00094     wstWord,
00095     wstSpace,
00096     wstData,
00097     wstCommentStart, wstCommentEnd, 
00098     wstCDataStart, wstCDataEnd,     
00099     wstPiStart, wstPiEnd,           
00100     wstEntityStart, wstEntityEnd    
00101 };
00102 
00112 class WeTagScanner {
00113 public:
00114 
00120     WeTagScanner(WeInStream& is):
00121             input(is),
00122             input_char(0),
00123 
00124 
00125 
00126             got_tail(false) { c_scan = &WeTagScanner::ScanBody; }
00127     virtual ~WeTagScanner(){};
00128 
00135       WeScannerToken    GetToken() { return (this->*c_scan)(); }
00136       const char*       GetValue();
00137       const char*       GetAttrName();
00138       const char*       GetTagName();
00139 
00149       virtual char   ResolveEntity(const char* buf, int buf_size) { return 0; }
00150       virtual int    GetPos() { return input.GetPos(); };
00151 
00152 private:
00153     
00154     static const int MAX_TOKEN_SIZE = 1024;
00155     static const int MAX_NAME_SIZE = 128;
00156 
00166     typedef WeScannerToken (WeTagScanner::*fnScan)();
00167     fnScan        c_scan; 
00168 
00169     
00170     
00171     WeScannerToken  ScanBody();
00172     WeScannerToken  ScanHead();
00173     WeScannerToken  ScanComment();
00174     WeScannerToken  ScanCdata();
00175     WeScannerToken  ScanPi();
00176     WeScannerToken  ScanTag();
00177     WeScannerToken  ScanEntityDecl();
00178 
00179     char            SkipWhitespace();
00180     void            PushBack(char c);
00181 
00182     char            GetChar();
00183     char            ScanEntity();
00184 
00185     bool            IsWhitespace(char c);
00186 
00187     void            AppendValue(char c);
00188     void            AppendAttrName(char c);
00189     void            AppendTagName(char c);
00190 
00191     
00192 #ifndef __DOXYGEN__
00193     WeScannerToken  token;
00194 
00195     vector<char>    value;
00196     
00197 
00198     vector<char>    tag_name;
00199     
00200 
00201     vector<char>    attr_name;
00202     
00203 
00204     WeInStream&     input;              
00205     char            input_char;         
00206 
00207     bool            got_tail;           
00208 #endif //__DOXYGEN__
00209 };
00210 #endif //__TAGSCANNER_H__