00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef ddx_parser_h
00027 #define ddx_parser_h
00028
00029 #include <string>
00030 #include <map>
00031 #include <stack>
00032
00033 #include <libxml/parserInternals.h>
00034
00035 #ifndef ddx_exceptions_h
00036 #include "DDXExceptions.h"
00037 #endif
00038
00039 #ifndef _dds_h
00040 #include "DDS.h"
00041 #endif
00042
00043 #ifndef _basetype_h
00044 #include "BaseType.h"
00045 #endif
00046
00047 #ifndef base_type_factory_h
00048 #include "BaseTypeFactory.h"
00049 #endif
00050
00051 namespace libdap
00052 {
00053
00079 class DDXParser
00080 {
00081 private:
00084 enum ParseState {
00085 parser_start,
00086
00087 inside_dataset,
00088
00089 inside_attribute_container,
00090 inside_attribute,
00091 inside_attribute_value,
00092 inside_other_xml_attribute,
00093
00094 inside_alias,
00095
00096
00097 inside_simple_type,
00098
00099 inside_array,
00100 inside_dimension,
00101
00102 inside_grid,
00103 inside_map,
00104
00105 inside_structure,
00106 inside_sequence,
00107
00108 inside_blob_href,
00109
00110 parser_unknown,
00111 parser_error
00112 };
00113
00114 BaseTypeFactory *d_factory;
00115
00116
00117 stack<ParseState> s;
00118 stack<BaseType*> bt_stack;
00119 stack<AttrTable*> at_stack;
00120
00121
00122 string other_xml;
00123
00124
00125
00126 unsigned int other_xml_depth;
00127 unsigned int unknown_depth;
00128
00129
00130 string error_msg;
00131 xmlParserCtxtPtr ctxt;
00132
00133
00134 DDS *dds;
00135 string *blob_href;
00136
00137
00138 string dods_attr_name;
00139 string dods_attr_type;
00140 string char_data;
00141 string root_ns;
00142
00143 class XMLAttribute {
00144 public:
00145 string prefix;
00146 string nsURI;
00147 string value;
00148
00149 void clone(const XMLAttribute &src) {
00150 prefix = src.prefix;
00151 nsURI = src.nsURI;
00152 value = src.value;
00153 }
00154
00155 XMLAttribute() : prefix(""), nsURI(""), value("") {}
00156 XMLAttribute(const string &p, const string &ns, const string &v)
00157 : prefix(p), nsURI(ns), value(v) {}
00158
00159
00160 XMLAttribute(const xmlChar **attributes) {
00161 prefix = attributes[0] != 0 ? (const char *)attributes[0]: "";
00162 nsURI = attributes[1] != 0 ? (const char *)attributes[1]: "";
00163 value = string((const char *)attributes[2], (const char *)attributes[3]);
00164 }
00165 XMLAttribute(const XMLAttribute &rhs) {
00166 clone(rhs);
00167 }
00168 XMLAttribute &operator=(const XMLAttribute &rhs) {
00169 if (this == &rhs)
00170 return *this;
00171 clone(rhs);
00172 return *this;
00173 }
00174 };
00175
00176 typedef map<string, XMLAttribute> XMLAttrMap;
00177 XMLAttrMap attribute_table;
00178
00179 XMLAttrMap::iterator attr_table_begin() {
00180 return attribute_table.begin();
00181 }
00182
00183 XMLAttrMap::iterator attr_table_end() {
00184 return attribute_table.end();
00185 }
00186
00187 map<string, string> namespace_table;
00188
00189
00190 void set_state(DDXParser::ParseState state);
00191 DDXParser::ParseState get_state() const;
00192 void pop_state();
00193
00194
00195 BaseType *factory(Type t, const string &name);
00196
00197
00198 void cleanup_parse(xmlParserCtxtPtr &context) const;
00199
00206 void transfer_xml_attrs(const xmlChar **attrs, int nb_attributes);
00207 void transfer_xml_ns(const xmlChar **namespaces, int nb_namespaces);
00208 bool check_required_attribute(const string &attr);
00209 bool check_attribute(const string & attr);
00210
00211 void process_attribute_element(const xmlChar **attrs, int nb_attrs);
00212 void process_attribute_alias(const xmlChar **attrs, int nb_attrs);
00213
00214 void process_variable(Type t, ParseState s, const xmlChar **attrs,
00215 int nb_attributes);
00216
00217 void process_dimension(const xmlChar **attrs, int nb_attrs);
00218 void process_blob(const xmlChar **attrs, int nb_attrs);
00219
00220 bool is_attribute_or_alias(const char *name, const xmlChar **attrs,
00221 int nb_attributes);
00222 bool is_variable(const char *name, const xmlChar **attrs, int nb_attributes);
00223
00224 void finish_variable(const char *tag, Type t, const char *expected);
00226
00228 DDXParser() {}
00229
00230
00231 friend class DDXParserTest;
00232
00233 public:
00234 DDXParser(BaseTypeFactory *factory)
00235 : d_factory(factory),
00236 other_xml(""), other_xml_depth(0), unknown_depth(0),
00237 error_msg(""), ctxt(0), dds(0), dods_attr_name(""), dods_attr_type(""),
00238 char_data(""), root_ns("")
00239 {}
00240
00241 void intern(const string &document, DDS *dest_dds, string &cid);
00242 void intern_stream(FILE *in, DDS *dds, string &cid,
00243 const string &boundary = "");
00244
00245 static void ddx_start_document(void *parser);
00246 static void ddx_end_document(void *parser);
00247
00248 static void ddx_sax2_start_element(void *parser,
00249 const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI,
00250 int nb_namespaces, const xmlChar **namespaces, int nb_attributes,
00251 int nb_defaulted, const xmlChar **attributes);
00252 static void ddx_sax2_end_element(void *parser, const xmlChar *localname,
00253 const xmlChar *prefix, const xmlChar *URI);
00254
00255 static void ddx_get_characters(void *parser, const xmlChar *ch, int len);
00256 static void ddx_ignoreable_whitespace(void *parser,
00257 const xmlChar * ch, int len);
00258 static void ddx_get_cdata(void *parser, const xmlChar *value, int len);
00259
00260 static xmlEntityPtr ddx_get_entity(void *parser, const xmlChar *name);
00261 static void ddx_fatal_error(void *parser, const char *msg, ...);
00262 };
00263
00264 }
00265
00266 #endif // ddx_parser_h