00001 #ifndef XMLTOKENIZER_H_
00002 #define XMLTOKENIZER_H_
00003
00004 #include "../Fl_String.h"
00005 #include "../Fl_String_Stack.h"
00006 #include "../Fl_Export.h"
00007
00008 #include <stdio.h>
00009
00010 #define BUF_SIZE 4096
00011
00016
00021 class FL_API Fl_XmlLocator
00022 {
00023 friend class Fl_XmlTokenizer;
00024 public:
00025 Fl_XmlLocator() { m_line=m_col=1; }
00026
00030 int line() const { return m_line; }
00031
00035 int col() const { return m_col; }
00036
00040 static Fl_String error_line(const char *filename, const Fl_XmlLocator &locator);
00041
00042 private:
00043 int m_line, m_col;
00044 };
00045
00049 class Fl_XmlTokenizer
00050 {
00051 friend class Fl_XmlParser;
00052 public:
00053 Fl_XmlTokenizer();
00054 virtual ~Fl_XmlTokenizer() { }
00055
00059 Fl_XmlLocator *locator() const { return m_locator; }
00060
00065 void locator(Fl_XmlLocator *locator) { m_locator = locator; }
00066
00067 protected:
00072 virtual bool stream_eos() const = 0;
00073
00081 virtual int stream_read(char *buf, int length) = 0;
00082
00083 private:
00084 bool eos() const { return stream_eos() && read_buf_len<=0; }
00085
00086
00087 void cdata_mode(bool val) { cdata_mode_ = val; }
00088 bool cdata_mode() const { return cdata_mode_ || auto_cdata_; }
00089
00090
00091 void prolog_mode(bool val) { prolog_mode_ = val; }
00092 bool prolog_mode() const { return prolog_mode_; }
00093
00094
00095 void attr_mode(bool val) { attr_mode_ = val; }
00096 bool attr_mode() const { return attr_mode_; }
00097
00098
00099 void pre_mode(bool val) { pre_mode_ = val; }
00100 bool pre_mode() const { return pre_mode_; }
00101
00102
00103 const Fl_String &operator*() const { return curtoken; }
00104
00105
00106 Fl_XmlTokenizer &operator++() { read_next(); return *this; }
00107 Fl_XmlTokenizer &operator++(int) { read_next(); return *this; }
00108
00109
00110 void put_back(const Fl_String &token) { putback_stack.push(token); }
00111 void put_back(const char *token) { putback_stack.push(token); }
00112 void put_back() { put_back(curtoken); }
00113
00114
00115 char read_char();
00116
00117 void read_next();
00118
00119
00120 void fill_buffer();
00121 char read_buf[BUF_SIZE];
00122 int read_buf_len, read_buf_pos;
00123
00124
00125 char write_buf[BUF_SIZE];
00126 int write_buf_pos;
00127
00128
00129 Fl_String curtoken;
00130
00131
00132 char putback_char;
00133
00134
00135 Fl_String_Stack putback_stack;
00136
00137
00138 bool is_literal( char c ) const;
00139 bool is_whitespace( char c ) const;
00140 bool is_newline( char c ) const;
00141 bool is_delimiter( char c ) const;
00142
00143
00144
00145 bool cdata_mode_, auto_cdata_;
00146 bool prolog_mode_, attr_mode_;
00147 bool pre_mode_;
00148
00149 Fl_XmlLocator *m_locator;
00150 };
00151
00157 class Fl_XmlDefaultTokenizer : public Fl_XmlTokenizer
00158 {
00159 public:
00165 Fl_XmlDefaultTokenizer(const char *buffer, long buffer_len);
00166
00171 Fl_XmlDefaultTokenizer(FILE *fp);
00172
00173 virtual ~Fl_XmlDefaultTokenizer();
00174
00175 protected:
00177 virtual int stream_read(char *buf, int length);
00179 virtual bool stream_eos() const;
00180
00181 private:
00182 void *io_ctx;
00183 };
00184
00186
00187 inline bool is_literal(const Fl_String &str, bool cdata=false) {
00188 if(str.length()!=1) return false;
00189 switch(str[0]) {
00190 case '/': case '?':
00191 case '=': case '!':
00192 case '>':
00193 if(cdata) return false;
00194 case '<':
00195 return true;
00196 }
00197 return false;
00198 }
00199
00200 inline char literal(const Fl_String &str) { return str[0]; }
00201
00204 #endif