libdap  Updated for version 3.20.6
libdap4 is an implementation of OPeNDAP's DAP protocol.
DDXParserSAX2.h
1 
2 // -*- mode: c++; c-basic-offset:4 -*-
3 
4 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
5 // Access Protocol.
6 
7 // Copyright (c) 2003 OPeNDAP, Inc.
8 // Author: James Gallagher <jgallagher@opendap.org>
9 //
10 // This library is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 2.1 of the License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 //
24 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
25 
26 #ifndef ddx_parser_h
27 #define ddx_parser_h
28 
29 #include <string>
30 #include <map>
31 #include <stack>
32 
33 #include <libxml/parserInternals.h>
34 
35 #ifndef ddx_exceptions_h
36 #include "DDXExceptions.h"
37 #endif
38 
39 #ifndef _dds_h
40 #include "DDS.h"
41 #endif
42 
43 #ifndef _basetype_h
44 #include "BaseType.h"
45 #endif
46 
47 #ifndef base_type_factory_h
48 #include "BaseTypeFactory.h"
49 #endif
50 
51 namespace libdap
52 {
53 
79 class DDXParser
80 {
81 private:
84  enum ParseState {
85  parser_start,
86 
87  inside_dataset,
88 
89  inside_attribute_container,
90  inside_attribute,
91  inside_attribute_value,
92  inside_other_xml_attribute,
93 
94  inside_alias,
95 
96  // This covers Byte, ..., Url.
97  inside_simple_type,
98 
99  inside_array,
100  inside_dimension,
101 
102  inside_grid,
103  inside_map,
104 
105  inside_structure,
106  inside_sequence,
107 
108  inside_blob_href,
109 
110  parser_unknown,
111  parser_error
112  };
113 
114  BaseTypeFactory *d_factory;
115 
116  // These stacks hold the state of the parse as it progresses.
117  stack<ParseState> s; // Current parse state
118  stack<BaseType*> bt_stack; // current variable(s)
119  stack<AttrTable*> at_stack; // current attribute table
120 
121  // Accumulate stuff inside an 'OtherXML' DAP attribute here
122  string other_xml;
123 
124  // When we're parsing unknown XML, how deeply is it nested? This is used
125  // for the OtherXML DAP attributes.
126  unsigned int other_xml_depth;
127  unsigned int unknown_depth;
128 
129  // These are used for processing errors.
130  string error_msg; // Error message(s), if any.
131  xmlParserCtxtPtr ctxt; // used for error message line numbers
132 
133  // The results of the parse operation are stored in these fields.
134  DDS *dds; // dump DDX here
135  string *blob_href; // put href to blob here
136 
137  // These hold temporary values read during the parse.
138  string dods_attr_name; // DAP2 attributes, not XML attributes
139  string dods_attr_type; // ... not XML ...
140  string char_data; // char data in value elements; null after use
141  string root_ns; // What is the namespace of the root node (Dataset)
142 
143  class XMLAttribute {
144  public:
145  string prefix;
146  string nsURI;
147  string value;
148 
149  void clone(const XMLAttribute &src) {
150  prefix = src.prefix;
151  nsURI = src.nsURI;
152  value = src.value;
153  }
154 
155  XMLAttribute() : prefix(""), nsURI(""), value("") {}
156  XMLAttribute(const string &p, const string &ns, const string &v)
157  : prefix(p), nsURI(ns), value(v) {}
158  // 'attributes' as passed from libxml2 is a five element array but this
159  // ctor gets the back four elements.
160  XMLAttribute(const xmlChar **attributes/*[4]*/) {
161  prefix = attributes[0] != 0 ? (const char *)attributes[0]: "";
162  nsURI = attributes[1] != 0 ? (const char *)attributes[1]: "";
163  value = string((const char *)attributes[2], (const char *)attributes[3]);
164  }
165  XMLAttribute(const XMLAttribute &rhs) {
166  clone(rhs);
167  }
168  ~XMLAttribute() {
169  }
170  XMLAttribute &operator=(const XMLAttribute &rhs) {
171  if (this == &rhs)
172  return *this;
173  clone(rhs);
174  return *this;
175  }
176  };
177 
178  typedef map<string, XMLAttribute> XMLAttrMap;
179  XMLAttrMap attribute_table; // dump XML attributes here
180 
181  XMLAttrMap::iterator attr_table_begin() {
182  return attribute_table.begin();
183  }
184 
185  XMLAttrMap::iterator attr_table_end() {
186  return attribute_table.end();
187  }
188 
189  map<string, string> namespace_table;
190 
191  // These are kind of silly...
192  void set_state(DDXParser::ParseState state);
193  DDXParser::ParseState get_state() const;
194  void pop_state();
195 
196  // Glue for the BaseTypeFactory class.
197  BaseType *factory(Type t, const string &name);
198 
199  // Common cleanup code for intern() and intern_stream()
200  void cleanup_parse(xmlParserCtxtPtr &context);
201 
208  void transfer_xml_attrs(const xmlChar **attrs, int nb_attributes);
209  void transfer_xml_ns(const xmlChar **namespaces, int nb_namespaces);
210  bool check_required_attribute(const string &attr);
211  bool check_attribute(const string & attr);
212 
213  void process_attribute_element(const xmlChar **attrs, int nb_attrs);
214  void process_attribute_alias(const xmlChar **attrs, int nb_attrs);
215 
216  void process_variable(Type t, ParseState s, const xmlChar **attrs,
217  int nb_attributes);
218 
219  void process_dimension(const xmlChar **attrs, int nb_attrs);
220  void process_blob(const xmlChar **attrs, int nb_attrs);
221 
222  bool is_attribute_or_alias(const char *name, const xmlChar **attrs,
223  int nb_attributes);
224  bool is_variable(const char *name, const xmlChar **attrs, int nb_attributes);
225 
226  void finish_variable(const char *tag, Type t, const char *expected);
228 
230  DDXParser();
231 
232  friend class DDXParserTest;
233 
234 public:
235  DDXParser(BaseTypeFactory *factory)
236  : d_factory(factory),
237  other_xml(""), other_xml_depth(0), unknown_depth(0),
238  error_msg(""), ctxt(0), dds(0), blob_href(0),
239  dods_attr_name(""), dods_attr_type(""),
240  char_data(""), root_ns("")
241  {}
242 
243  void intern(const string &document, DDS *dest_dds, string &cid);
244  void intern_stream(FILE *in, DDS *dds, string &cid, const string &boundary = "");
245  void intern_stream(istream &in, DDS *dds, string &cid, const string &boundary = "");
246 
247  static void ddx_start_document(void *parser);
248  static void ddx_end_document(void *parser);
249 
250  static void ddx_sax2_start_element(void *parser,
251  const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI,
252  int nb_namespaces, const xmlChar **namespaces, int nb_attributes,
253  int nb_defaulted, const xmlChar **attributes);
254  static void ddx_sax2_end_element(void *parser, const xmlChar *localname,
255  const xmlChar *prefix, const xmlChar *URI);
256 
257  static void ddx_get_characters(void *parser, const xmlChar *ch, int len);
258  static void ddx_ignoreable_whitespace(void *parser,
259  const xmlChar * ch, int len);
260  static void ddx_get_cdata(void *parser, const xmlChar *value, int len);
261 
262  static xmlEntityPtr ddx_get_entity(void *parser, const xmlChar *name);
263  static void ddx_fatal_error(void *parser, const char *msg, ...);
264 };
265 
266 } // namespace libdap
267 
268 #endif // ddx_parser_h
void intern_stream(FILE *in, DDS *dds, string &cid, const string &boundary="")
Read the DDX from a stream instead of a file.
static void ddx_start_document(void *parser)
static void ddx_get_cdata(void *parser, const xmlChar *value, int len)
Type
Identifies the data type.
Definition: Type.h:94
top level DAP object to house generic methods
Definition: AISConnect.cc:30
static void ddx_fatal_error(void *parser, const char *msg,...)
static void ddx_end_document(void *parser)
static xmlEntityPtr ddx_get_entity(void *parser, const xmlChar *name)
static void ddx_get_characters(void *parser, const xmlChar *ch, int len)
The basic data type for the DODS DAP types.
Definition: BaseType.h:117
static void ddx_ignoreable_whitespace(void *parser, const xmlChar *ch, int len)
void intern(const string &document, DDS *dest_dds, string &cid)