NCBI C++ ToolKit
event_parser.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /*
2  * Copyright (C) 2001-2003 Peter J Jones (pjones@pmade.org)
3  * All Rights Reserved
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * 3. Neither the name of the Author nor the names of its contributors
16  * may be used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
23  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
27  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  */
32 
33 /*
34  * $Id: event_parser.cpp 99402 2023-03-22 18:09:14Z satskyse $
35  * NOTE: This file was modified from its original version 0.6.0
36  * to fit the NCBI C++ Toolkit build framework and
37  * API and functionality requirements.
38  */
39 
40 /** @file
41  * This file contains the implementation of the xml::event_parser class for
42  * the libxml XML parser.
43 **/
44 
45 // make MSVC6 shutup about long template names
46 #if defined(_MSC_VER)
47 # pragma warning(disable : 4786)
48 #endif
49 
50 // xmlwrapp includes
52 #include <misc/xmlwrapp/node.hpp>
54 #include "utility.hpp"
55 #include "https_input_impl.hpp"
56 
57 // libxml includes
58 #include <libxml/parser.h>
59 #include <libxml/xmlversion.h>
60 
61 // standard includes
62 #include <new>
63 #include <cstring>
64 #include <iostream>
65 #include <fstream>
66 #include <stdexcept>
67 #include <memory>
68 
69 using namespace xml;
70 using namespace xml::impl;
71 
72 //####################################################################
73 /*
74  * This is a hack to fix a problem with a change in the libxml2 API for
75  * versions starting at 2.6.0
76  */
77 #if LIBXML_VERSION >= 20600
78 # define initxmlDefaultSAXHandler xmlSAX2InitDefaultSAXHandler
79 # include <libxml/SAX2.h>
80 #endif
81 //####################################################################
82 namespace {
83  const std::size_t const_buffer_size = 4096;
84 }
85 
86 //####################################################################
88 public:
90  ~epimpl (void);
91  void create_context(void);
92  void destroy_context(void);
93  void recreate_context(void);
94 
95  xmlSAXHandler sax_handler_;
96  xmlParserCtxt * parser_context_;
97 
98  bool parser_status_; // true - OK, can continue.
99  // false - user interrupted or failed
101 
102  void event_start_document (void);
103  void event_end_document (void);
104  void event_start_element (const xmlChar *tag, const xmlChar **props);
105  void event_end_element (const xmlChar *tag);
106  void event_text (const xmlChar *text, int length);
107  void event_pi (const xmlChar *target, const xmlChar *data);
108  void event_comment (const xmlChar *text);
109  void event_cdata (const xmlChar *text, int length);
110  void event_notation_declaration (const xmlChar *name,
111  const xmlChar *public_id,
112  const xmlChar *system_id);
113  void event_entity_declaration (const xmlChar * name,
114  int type,
115  const xmlChar * publicId,
116  const xmlChar * systemId,
117  xmlChar * content);
118  void event_unparsed_entity_declaration (const xmlChar *name,
119  const xmlChar *public_id,
120  const xmlChar *system_id,
121  const xmlChar *notation_name);
122  void event_external_subset_declaration (const xmlChar *name,
123  const xmlChar *external_id,
124  const xmlChar *system_id);
125  void event_internal_subset_declaration (const xmlChar *name,
126  const xmlChar *external_id,
127  const xmlChar *system_id);
128  void event_attribute_declaration (const xmlChar *element_name,
129  const xmlChar *attribute_name,
130  int attr_type,
131  int default_type,
132  const xmlChar *default_value,
133  xmlEnumeration *default_values);
134  void event_element_declaration (const xmlChar *element_name,
135  int type,
136  xmlElementContent *content);
137  void event_entity_reference (const xmlChar *name);
138  void event_warning (const std::string &message);
139  void event_error (const std::string &message);
140  void event_fatal_error (const std::string &message);
141 private:
143 
144  epimpl (const epimpl&);
146 };
147 
148 extern "C"
149 {
150  //####################################################################
151  static void cb_start_document (void *parser)
152  { static_cast<epimpl*>(parser)->event_start_document(); }
153  //####################################################################
154  static void cb_end_document (void *parser)
155  { static_cast<epimpl*>(parser)->event_end_document(); }
156  //####################################################################
157  static void cb_start_element (void *parser, const xmlChar *tag, const xmlChar **props)
158  { static_cast<epimpl*>(parser)->event_start_element(tag, props); }
159  //####################################################################
160  static void cb_end_element (void *parser, const xmlChar *tag)
161  { static_cast<epimpl*>(parser)->event_end_element(tag); }
162  //####################################################################
163  static void cb_text (void *parser, const xmlChar *text, int length)
164  { static_cast<epimpl*>(parser)->event_text(text, length); }
165  //####################################################################
166  static void cb_pi (void *parser, const xmlChar *target, const xmlChar *data)
167  { static_cast<epimpl*>(parser)->event_pi(target, data); }
168  //####################################################################
169  static void cb_comment (void *parser, const xmlChar *text)
170  { static_cast<epimpl*>(parser)->event_comment(text); }
171  //####################################################################
172  static void cb_cdata (void *parser, const xmlChar *text, int length)
173  { static_cast<epimpl*>(parser)->event_cdata(text, length); }
174  //####################################################################
175  static void cb_notation_declaration (void *parser, const xmlChar *name,
176  const xmlChar *public_id,
177  const xmlChar *system_id)
178  { static_cast<epimpl*>(parser)->event_notation_declaration(name,
179  public_id,
180  system_id); }
181  //####################################################################
182  static void cb_entity_declaration (void *parser, const xmlChar *name,
183  int type, const xmlChar *public_id,
184  const xmlChar *system_id,
185  xmlChar *content)
186  { static_cast<epimpl*>(parser)->event_entity_declaration(name,
187  type,
188  public_id,
189  system_id,
190  content); }
191  //####################################################################
192  static void cb_unparsed_entity_declaration (void *parser,
193  const xmlChar *name,
194  const xmlChar *public_id,
195  const xmlChar *system_id,
196  const xmlChar *notation_name)
197  { static_cast<epimpl*>(parser)->event_unparsed_entity_declaration(name,
198  public_id,
199  system_id,
200  notation_name); }
201  //####################################################################
202  static void cb_external_subset_declaration (void *parser,
203  const xmlChar *name,
204  const xmlChar *external_id,
205  const xmlChar *system_id)
206  { static_cast<epimpl*>(parser)->event_external_subset_declaration(name,
207  external_id,
208  system_id); }
209  //####################################################################
210  static void cb_internal_subset_declaration (void *parser,
211  const xmlChar *name,
212  const xmlChar *external_id,
213  const xmlChar *system_id)
214  { static_cast<epimpl*>(parser)->event_internal_subset_declaration(name,
215  external_id,
216  system_id); }
217  //####################################################################
218  static void cb_attribute_declaration (void *parser,
219  const xmlChar *element_name,
220  const xmlChar *attribute_name,
221  int attr_type,
222  int default_type,
223  const xmlChar *default_value,
224  xmlEnumeration *default_values)
225  { static_cast<epimpl*>(parser)->event_attribute_declaration(element_name,
226  attribute_name,
227  attr_type,
228  default_type,
229  default_value,
230  default_values); }
231  //####################################################################
232  static void cb_element_declaration (void *parser,
233  const xmlChar *element_name,
234  int type,
235  xmlElementContent *content)
236  { static_cast<epimpl*>(parser)->event_element_declaration(element_name,
237  type,
238  content); }
239  //####################################################################
240  static void cb_entity_reference (void *parser, const xmlChar *name)
241  { static_cast<epimpl*>(parser)->event_entity_reference(name); }
242  //####################################################################
243  static void cb_warning (void *parser, const char *message, ...) {
244  std::string complete_message;
245 
246  va_list ap;
247  va_start(ap, message);
248  printf2string(complete_message, message, ap);
249  va_end(ap);
250 
251  static_cast<epimpl*>(parser)->event_warning(complete_message);
252  }
253  //####################################################################
254  static void cb_error (void *parser, const char *message, ...) {
255  std::string complete_message;
256 
257  va_list ap;
258  va_start(ap, message);
259  printf2string(complete_message, message, ap);
260  va_end(ap);
261 
262  static_cast<epimpl*>(parser)->event_error(complete_message);
263  }
264  //####################################################################
265  static void cb_fatal_error (void *parser, const char *message, ...) {
266  std::string complete_message;
267 
268  va_list ap;
269  va_start(ap, message);
270  printf2string(complete_message, message, ap);
271  va_end(ap);
272 
273  static_cast<epimpl*>(parser)->event_fatal_error(complete_message);
274  }
275  //####################################################################
276  static void cb_ignore (void*, const xmlChar*, int) {
277  return;
278  }
279 } // extern "C"
280 
281 //####################################################################
283  pimpl_ = new epimpl(*this, mask);
284 }
285 //####################################################################
287  if (pimpl_ != NULL)
288  delete pimpl_;
289 }
290 
292  pimpl_(other.pimpl_)
293 {
294  other.pimpl_ = NULL;
295 }
296 
298 {
299  if (this != &other) {
300  if (pimpl_ != NULL)
301  delete pimpl_;
302  pimpl_ = other.pimpl_;
303  other.pimpl_ = NULL;
304  }
305  return *this;
306 }
307 
308 //####################################################################
309 bool event_parser::parse_file (const char *filename, error_messages* messages,
311  if (!parse_finished_)
312  parse_finish(messages, how);
313 
314  if (messages)
315  messages->get_messages().clear();
316  pimpl_->parser_status_ = true;
317 
318  std::ifstream file(filename);
319  if (!file)
320  {
321  pimpl_->parser_status_ = false;
322  if (messages)
323  {
325  if (filename != NULL)
326  file_name = filename;
327  std::string message("Cannot open file" + file_name);
328  messages->get_messages().push_back(
329  error_message(message,
331  0, file_name));
332  }
333  return false;
334  }
335  return parse_stream(file, messages, how);
336 }
337 //####################################################################
338 bool event_parser::parse_stream (std::istream &stream, error_messages* messages,
341  error_messages * temp(messages);
342  std::unique_ptr<error_messages> msgs;
343  if (!messages)
344  msgs.reset(temp = new error_messages);
345 
346  // In a usual scenario the errors_ are initialized when parse_chunk() is
347  // invoked. It is however possible that the stream is broken so
348  // parse_finish() needs errors_ to be initialized as well. So here is the
349  // initialization.
350  pimpl_->errors_ = temp;
351 
352  if (!parse_finished_)
353  parse_finish(temp, how);
354 
355  temp->get_messages().clear();
356  pimpl_->parser_status_ = true;
357 
358  if (stream && (stream.eof() ||
359  stream.peek() == std::istream::traits_type::eof()))
360  {
361  pimpl_->parser_status_ = false;
362  temp->get_messages().push_back(error_message("empty xml document",
364  0, ""));
365  return false;
366  }
367 
368  // Allocate a new parser context. Existing one is destroyed if needed.
370 
371  parse_finished_ = false;
372  while (pimpl_->parser_status_ &&
373  (stream.read(buffer, const_buffer_size) || stream.gcount()))
375  (size_t)stream.gcount(),
376  temp, how);
377 
378  if (!stream && !stream.eof())
379  {
380  parse_finish(temp, how);
381  return false;
382  }
383  return parse_finish(temp, how);
384 }
385 //####################################################################
386 bool event_parser::parse_chunk (const char *chunk, size_type length,
387  error_messages* messages,
389  error_messages * temp(messages);
390  std::unique_ptr<error_messages> msgs;
391  if (!messages)
392  msgs.reset(temp = new error_messages);
393 
394  if (parse_finished_) {
395  // This is first call of the parse_chunk() after parse_finished()
396  temp->get_messages().clear();
398  }
399 
400  parse_finished_ = false;
401  pimpl_->errors_ = temp;
402 
403  if (pimpl_->parser_context_ == NULL)
404  pimpl_->create_context(); // This is the first call of the
405  // parse_chunk so create a context
406  else
407  {
408  // Not first call, check that the callbacks are enabled
409  if (pimpl_->parser_context_->disableSAX != 0) {
411  throw xml::exception("parse_finish(...) was not called after "
412  "an error occured or the user "
413  "stopped the parser");
414  }
415  if (pimpl_->parser_context_->instate == XML_PARSER_EOF) {
417  throw xml::exception("parse_finish(...) was not called "
418  "after the parser has finished");
419  }
420  }
421 
422  xmlParseChunk(pimpl_->parser_context_, chunk,
424  "chunk is too large to parse"), 0);
425  if (!pimpl_->parser_status_)
426  return false;
427  if (is_failure(temp, how))
428  return false;
429  return true;
430 }
431 //####################################################################
434  xmlParseChunk(pimpl_->parser_context_, 0, 0, 1);
435 
436  parse_finished_ = true;
437  error_messages * temp(messages);
438  std::unique_ptr<error_messages> msgs;
439  if (!messages)
440  msgs.reset(temp = new error_messages);
441 
443 
444  // There was an error while parsing or the user interrupted parsing
445  bool ret_val = true;
446  if (!pimpl_->parser_status_)
447  ret_val= false;
448  else
449  {
450  if (is_failure(temp, how))
451  ret_val= false;
452  }
453 
454  // The parser context is not needed any more
456  return ret_val;
457 }
458 //####################################################################
460  warnings_as_errors_type how) const {
461  // if there are fatal errors or errors it is a failure
462  if (messages->has_errors() ||
463  messages->has_fatal_errors())
464  return true;
465  if ((how == type_warnings_are_errors) &&
466  messages->has_warnings())
467  return true;
468  return false;
469 }
470 //####################################################################
472  return true;
473 }
474 //####################################################################
476  return true;
477 }
478 //####################################################################
480  return true;
481 }
482 //####################################################################
484  return true;
485 }
486 //####################################################################
487 bool xml::event_parser::cdata (const std::string &contents) {
488  return text(contents);
489 }
490 //####################################################################
492  const std::string &public_id,
493  const std::string &system_id) {
494  return true;
495 }
496 //####################################################################
498  const std::string &public_id,
499  const std::string &system_id,
500  const std::string &notation_name) {
501  return true;
502 }
503 //####################################################################
505  const std::string &external_id,
506  const std::string &system_id) {
507  return true;
508 }
509 //####################################################################
511  const std::string &external_id,
512  const std::string &system_id) {
513  return true;
514 }
515 //####################################################################
518  const std::string &public_id,
519  const std::string &system_id,
520  const std::string &content) {
521  return true;
522 }
523 //####################################################################
525  const std::string &attribute_name,
526  attribute_type attr_type,
527  attribute_default_type default_type,
528  const std::string &default_value,
529  const values_type &default_values) {
530  return true;
531 }
532 //####################################################################
535  _xmlElementContent *content) {
536  return true;
537 }
538 //####################################################################
540  return true;
541 }
542 //####################################################################
544  return true;
545 }
546 //####################################################################
548  return true;
549 }
550 //####################################################################
552  switch (type) {
553  case XML_INTERNAL_GENERAL_ENTITY: return type_internal_general_entity;
554  case XML_EXTERNAL_GENERAL_PARSED_ENTITY: return type_external_general_parsed_entity;
555  case XML_EXTERNAL_GENERAL_UNPARSED_ENTITY: return type_external_general_unparsed_entity;
556  case XML_INTERNAL_PARAMETER_ENTITY: return type_internal_parameter_entity;
557  case XML_EXTERNAL_PARAMETER_ENTITY: return type_external_parameter_entity;
558  case XML_INTERNAL_PREDEFINED_ENTITY: return type_internal_predefined_entity;
559  default: ;
560  }
561  throw xml::exception("Unknown entity type");
562 }
563 //####################################################################
565  switch (type) {
566  case XML_ATTRIBUTE_CDATA: return type_attribute_cdata;
567  case XML_ATTRIBUTE_ID: return type_attribute_id;
568  case XML_ATTRIBUTE_IDREF: return type_attribute_idref;
569  case XML_ATTRIBUTE_IDREFS: return type_attribute_idrefs;
570  case XML_ATTRIBUTE_ENTITY: return type_attribute_entity;
571  case XML_ATTRIBUTE_ENTITIES: return type_attribute_entities;
572  case XML_ATTRIBUTE_NMTOKEN: return type_attribute_nmtoken;
573  case XML_ATTRIBUTE_NMTOKENS: return type_attribute_nmtokens;
574  case XML_ATTRIBUTE_ENUMERATION: return type_attribute_enumeration;
575  case XML_ATTRIBUTE_NOTATION: return type_attribute_notation;
576  default: ;
577  }
578  throw xml::exception("Unknown attribute type");
579 }
580 //####################################################################
582  switch (type) {
583  case XML_ATTRIBUTE_NONE: return type_attribute_none;
584  case XML_ATTRIBUTE_REQUIRED: return type_attribute_required;
585  case XML_ATTRIBUTE_IMPLIED: return type_attribute_implied;
586  case XML_ATTRIBUTE_FIXED: return type_attribute_fixed;
587  default: ;
588  }
589  throw xml::exception("Unknown attribute default type");
590 }
591 //####################################################################
593  switch (type) {
594  case XML_ELEMENT_TYPE_UNDEFINED: return type_undefined;
595  case XML_ELEMENT_TYPE_EMPTY: return type_empty;
596  case XML_ELEMENT_TYPE_ANY: return type_any;
597  case XML_ELEMENT_TYPE_MIXED: return type_mixed;
598  case XML_ELEMENT_TYPE_ELEMENT: return type_element;
599  default: ;
600  }
601  throw xml::exception("Unknown element type");
602 }
603 //####################################################################
605  : parser_context_(NULL),
606  parser_status_(true),
607  errors_(NULL),
608  parent_(parent)
609 {
610  std::memset(&sax_handler_, 0, sizeof(sax_handler_));
611 
612  // Error handlers are set unconditionally
613  sax_handler_.warning = cb_warning;
614  sax_handler_.error = cb_error;
615  sax_handler_.fatalError = cb_fatal_error;
616 
617  // The rest of SAX handlers depends on the user provided mask
619  sax_handler_.startDocument = cb_start_document;
620 
622  sax_handler_.endDocument = cb_end_document;
623 
625  sax_handler_.startElement = cb_start_element;
626 
628  sax_handler_.endElement = cb_end_element;
629 
631  sax_handler_.characters = cb_text;
632 
634  sax_handler_.processingInstruction = cb_pi;
635 
637  sax_handler_.comment = cb_comment;
638 
640  sax_handler_.cdataBlock = cb_cdata;
641 
643  sax_handler_.notationDecl = cb_notation_declaration;
644 
646  sax_handler_.entityDecl = cb_entity_declaration;
647 
649  sax_handler_.unparsedEntityDecl = cb_unparsed_entity_declaration;
650 
653 
656 
658  sax_handler_.attributeDecl = cb_attribute_declaration;
659 
661  sax_handler_.elementDecl = cb_element_declaration;
662 
664  sax_handler_.reference = cb_entity_reference;
665 
666 
667  if ((xmlKeepBlanksDefaultValue != 0) && (mask & event_parser::characters_handler))
668  sax_handler_.ignorableWhitespace = cb_text;
669  else
670  sax_handler_.ignorableWhitespace = cb_ignore;
671 
672  // Note: parser context is not allocated here.
673  // A new one is allocated each time a new parsing is requested
674 }
675 
677  /* Do I need this? */
678  /* xmlFreeDoc(parser_context_->myDoc); */
679  destroy_context();
680 }
681 
683  parser_context_ = xmlCreatePushParserCtxt(&sax_handler_, this, 0, 0, 0);
684  if (parser_context_ == NULL)
685  throw std::bad_alloc();
686 }
687 
689  if (parser_context_)
690  xmlFreeParserCtxt(parser_context_);
692 }
693 
695  destroy_context();
696  create_context();
697 }
698 
699 void epimpl::event_start_element (const xmlChar *tag, const xmlChar **props) {
700  if (!parser_status_) return;
701 
702  try {
704  const xmlChar **attrp;
705 
706  for (attrp = props; attrp && *attrp; attrp += 2) {
707  attrs[reinterpret_cast<const char*>(*attrp)] = reinterpret_cast<const char*>(*(attrp+1));
708  }
709 
710  std::string name = reinterpret_cast<const char*>(tag);
711  parser_status_ = parent_.start_element(name, attrs);
712  } catch (const std::exception &ex) {
713  event_fatal_error(ex.what());
714  return;
715  } catch ( ... ) {
716  event_fatal_error("user exception in start_element handler");
717  return;
718  }
719  if (!parser_status_) xmlStopParser(parser_context_);
720 }
721 
722 void epimpl::event_end_element (const xmlChar *tag) {
723  if (!parser_status_) return;
724 
725  try {
726  std::string name = reinterpret_cast<const char*>(tag);
728  } catch (const std::exception &ex) {
729  event_fatal_error(ex.what());
730  return;
731  } catch ( ... ) {
732  event_fatal_error("user exception in end_element handler");
733  return;
734  }
735  if (!parser_status_) xmlStopParser(parser_context_);
736 }
737 //####################################################################
738 void epimpl::event_text (const xmlChar *text, int length) {
739  if (!parser_status_) return;
740 
741  try {
742  std::string contents(reinterpret_cast<const char*>(text), static_cast<std::string::size_type>(length));
743  parser_status_ = parent_.text(contents);
744  } catch (const std::exception &ex) {
745  event_fatal_error(ex.what());
746  return;
747  } catch ( ... ) {
748  event_fatal_error("user exception in text handler");
749  return;
750  }
751  if (!parser_status_) xmlStopParser(parser_context_);
752 }
753 //####################################################################
755  if (!parser_status_) return;
756 
757  try {
759  } catch (const std::exception &ex) {
760  event_fatal_error(ex.what());
761  return;
762  } catch ( ... ) {
763  event_fatal_error("user exception in start_document handler");
764  return;
765  }
766  if (!parser_status_) xmlStopParser(parser_context_);
767 }
768 //####################################################################
770  if (!parser_status_) return;
771 
772  try {
774  } catch (const std::exception &ex) {
775  event_fatal_error(ex.what());
776  return;
777  } catch ( ... ) {
778  event_fatal_error("user exception in end_document handler");
779  return;
780  }
781  if (!parser_status_) xmlStopParser(parser_context_);
782 }
783 //####################################################################
784 void epimpl::event_pi (const xmlChar *target, const xmlChar *data) {
785  if (!parser_status_) return;
786 
787  try {
788  std::string s_target = reinterpret_cast<const char*>(target);
789  std::string s_data = reinterpret_cast<const char*>(data);
790  parser_status_ = parent_.processing_instruction(s_target, s_data);
791  } catch (const std::exception &ex) {
792  event_fatal_error(ex.what());
793  return;
794  } catch ( ... ) {
795  event_fatal_error("user exception in processing_instruction handler");
796  return;
797  }
798  if (!parser_status_) xmlStopParser(parser_context_);
799 }
800 //####################################################################
801 void epimpl::event_comment (const xmlChar *text) {
802  if (!parser_status_) return;
803 
804  try {
805  std::string contents = reinterpret_cast<const char*>(text);
806  parser_status_ = parent_.comment(contents);
807  } catch (const std::exception &ex) {
808  event_fatal_error(ex.what());
809  return;
810  } catch ( ... ) {
811  event_fatal_error("user exception in comment handler");
812  return;
813  }
814  if (!parser_status_) xmlStopParser(parser_context_);
815 }
816 //####################################################################
817 void epimpl::event_cdata (const xmlChar *text, int length) {
818  if (!parser_status_) return;
819 
820  try {
821  std::string contents(reinterpret_cast<const char*>(text), static_cast<std::string::size_type>(length));
822  parser_status_ = parent_.cdata(contents);
823  } catch (const std::exception &ex) {
824  event_fatal_error(ex.what());
825  return;
826  } catch ( ... ) {
827  event_fatal_error("user exception in cdata handler");
828  return;
829  }
830  if (!parser_status_) xmlStopParser(parser_context_);
831 }
832 //####################################################################
833 void epimpl::event_notation_declaration (const xmlChar *name,
834  const xmlChar *public_id,
835  const xmlChar *system_id) {
836  if (!parser_status_) return;
837 
838  try {
839  std::string notation_name( name ? reinterpret_cast<const char*>(name) : "" );
840  std::string notation_public_id( public_id ? reinterpret_cast<const char*>(public_id) : "" );
841  std::string notation_system_id( system_id ? reinterpret_cast<const char*>(system_id) : "" );
843  notation_public_id,
844  notation_system_id);
845  } catch (const std::exception &ex) {
846  event_fatal_error(ex.what());
847  return;
848  } catch ( ... ) {
849  event_fatal_error("user exception in notation_declaration handler");
850  return;
851  }
852  if (!parser_status_) xmlStopParser(parser_context_);
853 }
854 //####################################################################
855 void epimpl::event_entity_declaration (const xmlChar *name,
856  int type,
857  const xmlChar *public_id,
858  const xmlChar *system_id,
859  xmlChar * content) {
860  if (!parser_status_) return;
861 
862  try {
863  std::string entity_name( name ? reinterpret_cast<const char*>(name) : "" );
864  std::string entity_public_id( public_id ? reinterpret_cast<const char*>(public_id) : "" );
865  std::string entity_system_id( system_id ? reinterpret_cast<const char*>(system_id) : "" );
866  std::string entity_content( content ? reinterpret_cast<const char*>(content) : "" );
868  entity_public_id, entity_system_id,
869  entity_content);
870  } catch (const std::exception &ex) {
871  event_fatal_error(ex.what());
872  return;
873  } catch ( ... ) {
874  event_fatal_error("user exception in entity_declaration handler");
875  return;
876  }
877  if (!parser_status_) xmlStopParser(parser_context_);
878 }
879 //####################################################################
881  const xmlChar *public_id,
882  const xmlChar *system_id,
883  const xmlChar *notation_name) {
884  if (!parser_status_) return;
885 
886  try {
887  std::string entity_name( name ? reinterpret_cast<const char*>(name) : "" );
888  std::string entity_public_id( public_id ? reinterpret_cast<const char*>(public_id) : "" );
889  std::string entity_system_id( system_id ? reinterpret_cast<const char*>(system_id) : "" );
890  std::string entity_notation_name( notation_name ? reinterpret_cast<const char*>(notation_name) : "" );
892  entity_public_id, entity_system_id,
893  entity_notation_name);
894  } catch (const std::exception &ex) {
895  event_fatal_error(ex.what());
896  return;
897  } catch ( ... ) {
898  event_fatal_error("user exception in unparsed_entity_declaration handler");
899  return;
900  }
901  if (!parser_status_) xmlStopParser(parser_context_);
902 }
903 //####################################################################
905  const xmlChar *external_id,
906  const xmlChar *system_id) {
907  if (!parser_status_) return;
908 
909  try {
910  std::string root_element_name( name ? reinterpret_cast<const char*>(name) : "" );
911  std::string ext_id( external_id ? reinterpret_cast<const char*>(external_id) : "" );
912  std::string sys_id( system_id ? reinterpret_cast<const char*>(system_id) : "" );
914  ext_id,
915  sys_id);
916  } catch (const std::exception &ex) {
917  event_fatal_error(ex.what());
918  return;
919  } catch ( ... ) {
920  event_fatal_error("user exception in external_subset_declaration handler");
921  return;
922  }
923  if (!parser_status_) xmlStopParser(parser_context_);
924 }
925 //####################################################################
927  const xmlChar *external_id,
928  const xmlChar *system_id) {
929  if (!parser_status_) return;
930 
931  try {
932  std::string root_element_name( name ? reinterpret_cast<const char*>(name) : "" );
933  std::string ext_id( external_id ? reinterpret_cast<const char*>(external_id) : "" );
934  std::string sys_id( system_id ? reinterpret_cast<const char*>(system_id) : "" );
936  ext_id,
937  sys_id);
938  } catch (const std::exception &ex) {
939  event_fatal_error(ex.what());
940  return;
941  } catch ( ... ) {
942  event_fatal_error("user exception in internal_subset_declaration handler");
943  return;
944  }
945  if (!parser_status_) xmlStopParser(parser_context_);
946 }
947 //####################################################################
948 void epimpl::event_attribute_declaration (const xmlChar *element_name,
949  const xmlChar *attribute_name,
950  int attr_type,
951  int default_type,
952  const xmlChar *default_value,
953  xmlEnumeration *default_values) {
954  if (!parser_status_) return;
955 
956  try {
957  std::string element( element_name ? reinterpret_cast<const char*>(element_name) : "" );
958  std::string attr_name( attribute_name ? reinterpret_cast<const char*>(attribute_name) : "" );
959  std::string default_val( default_value ? reinterpret_cast<const char*>(default_value) : "" );
960 
962  while (default_values) {
963  if (default_values->name)
964  def_vals.push_back(std::string(reinterpret_cast<const char*>(default_values->name)));
965  default_values = default_values->next;
966  }
967  parser_status_ = parent_.attribute_declaration(element, attr_name,
968  parent_.get_attribute_type(attr_type),
969  parent_.get_attribute_default_type(default_type),
970  default_val,
971  def_vals);
972  } catch (const std::exception &ex) {
973  event_fatal_error(ex.what());
974  return;
975  } catch ( ... ) {
976  event_fatal_error("user exception in attribute_declaration handler");
977  return;
978  }
979  if (!parser_status_) xmlStopParser(parser_context_);
980 }
981 //####################################################################
982 void epimpl::event_element_declaration (const xmlChar *element_name,
983  int type,
984  xmlElementContent *content) {
985  if (!parser_status_) return;
986 
987  try {
988  std::string element( element_name ? reinterpret_cast<const char*>(element_name) : "" );
989 
992  content);
993  } catch (const std::exception &ex) {
994  event_fatal_error(ex.what());
995  return;
996  } catch ( ... ) {
997  event_fatal_error("user exception in element_declaration handler");
998  return;
999  }
1000  if (!parser_status_) xmlStopParser(parser_context_);
1001 }
1002 //####################################################################
1003 void epimpl::event_entity_reference (const xmlChar *name) {
1004  if (!parser_status_) return;
1005 
1006  try {
1007  std::string reference_name( name ? reinterpret_cast<const char*>(name) : "" );
1008 
1009  parser_status_ = parent_.entity_reference(reference_name);
1010  } catch (const std::exception &ex) {
1011  event_fatal_error(ex.what());
1012  return;
1013  } catch ( ... ) {
1014  event_fatal_error("user exception in entity_reference handler");
1015  return;
1016  }
1017  if (!parser_status_) xmlStopParser(parser_context_);
1018 }
1019 //####################################################################
1020 void epimpl::event_warning (const std::string &message) {
1021  if (!parser_status_) return;
1022 
1023  long line = xmlLastError.line;
1024  if (line < 0)
1025  line = 0;
1026  std::string filename;
1027  if (xmlLastError.file != NULL)
1028  filename = xmlLastError.file;
1029  errors_->get_messages().push_back(
1030  error_message(message,
1032  line, filename));
1033  try {
1034  parser_status_ = parent_.warning(message);
1035  } catch (const std::exception &ex) {
1036  event_fatal_error(ex.what());
1037  return;
1038  } catch ( ... ) {
1039  event_fatal_error("user exception in warning handler");
1040  return;
1041  }
1042  if (!parser_status_) xmlStopParser(parser_context_);
1043 }
1044 //####################################################################
1045 void epimpl::event_error (const std::string &message) {
1046  if (!parser_status_) return;
1047 
1048  long line = xmlLastError.line;
1049  if (line < 0)
1050  line = 0;
1051  std::string filename;
1052  if (xmlLastError.file != NULL)
1053  filename = xmlLastError.file;
1054  errors_->get_messages().push_back(
1055  error_message(message,
1057  line, filename));
1058  try {
1059  parser_status_ = parent_.error(message);
1060  } catch (const std::exception &ex) {
1061  event_fatal_error(ex.what());
1062  return;
1063  }
1064  catch ( ... ) {
1065  event_fatal_error("user exception in error handler");
1066  return;
1067  }
1068  if (!parser_status_) xmlStopParser(parser_context_);
1069 }
1070 //####################################################################
1072  if (!parser_status_) return;
1073 
1074  long line = xmlLastError.line;
1075  if (line < 0)
1076  line = 0;
1077  std::string filename;
1078  if (xmlLastError.file != NULL)
1079  filename = xmlLastError.file;
1080  errors_->get_messages().push_back(
1081  error_message(message,
1083  line, filename));
1084  parser_status_ = false;
1085  xmlStopParser(parser_context_);
1086 }
1087 
ncbi::TMaskedQueryRegions mask
#define true
Definition: bool.h:35
The xml::error_message class is used to store a single error message which may appear while parsing o...
Definition: errors.hpp:50
@ type_fatal_error
fatal error
Definition: errors.hpp:54
@ type_warning
warning
Definition: errors.hpp:56
@ type_error
error
Definition: errors.hpp:55
The xml::error_messages class is used to store all the error message which are collected while parsin...
Definition: errors.hpp:137
bool has_fatal_errors(void) const
Check if there are fatal errors in the error messages.
Definition: errors.cpp:126
const error_messages_type & get_messages(void) const
Get the error messages.
Definition: errors.cpp:98
bool has_warnings(void) const
Check if there are warnings in the error messages.
Definition: errors.cpp:118
bool has_errors(void) const
Check if there are errors in the error messages.
Definition: errors.cpp:122
The xml::event_parser is used to parse an XML document by calling member functions when certain thing...
entity_type get_entity_type(int)
std::map< std::string, std::string > attrs_type
a type for holding XML node attributes
attribute_default_type get_attribute_default_type(int)
event_parser & operator=(event_parser &&other)
Moving assignment.
attribute_default_type
enum for different default attribute definition
virtual bool unparsed_entity_declaration(const std::string &name, const std::string &public_id, const std::string &system_id, const std::string &notation_name)
Override this memeber function to receive the unparsed entity declaration message.
bool parse_finish(error_messages *messages, warnings_as_errors_type how=type_warnings_not_errors)
Finish parsing chunked data.
virtual bool external_subset_declaration(const std::string &name, const std::string &external_id, const std::string &system_id)
Override this memeber function to receive the external subset declaration message.
attribute_type get_attribute_type(int)
impl::epimpl * pimpl_
std::vector< std::string > values_type
a type for holding attribute declaration values
bool parse_stream(std::istream &stream, error_messages *messages, warnings_as_errors_type how=type_warnings_not_errors)
Parse what ever data that can be read from the given stream.
virtual bool text(const std::string &contents)=0
Override this member function to receive the text message.
virtual bool attribute_declaration(const std::string &element_name, const std::string &attribute_name, attribute_type attr_type, attribute_default_type default_type, const std::string &default_value, const values_type &default_values)
Override this memeber function to receive the attribute declaration message.
virtual bool start_document()
Override this member function to receive the start_document message.
virtual bool cdata(const std::string &contents)
Override this member function to receive the cdata mesage.
bool is_failure(error_messages *messages, warnings_as_errors_type how) const
virtual bool internal_subset_declaration(const std::string &name, const std::string &external_id, const std::string &system_id)
Override this memeber function to receive the internal subset declaration message.
@ notation_decl_handler
controls the notation declaration handler
@ end_element_handler
controls the end element handler
@ comment_handler
controls the comment handler
@ element_decl_handler
controls the element declaration handler
@ unparsed_entity_decl_handler
controls the unparsed entity declaration handler
@ entity_decl_handler
controls the entity declaration handler
@ internal_subset_handler
controls the internal subset handler
@ external_subset_handler
controls the external subset handler
@ attribute_decl_handler
controls the attribute declaration handler
@ pi_handler
controls the processing instruction handler
@ start_element_handler
controls the start element handler
@ cdata_handler
controls the cdata handler
@ reference_handler
controls the reference handler
@ start_document_handler
controls the start document handler
@ characters_handler
controls the text handler
@ end_document_handler
controls the end document handler
virtual bool element_declaration(const std::string &name, element_content_type type, _xmlElementContent *content)
Override this memeber function to receive the element declaration message.
virtual bool end_element(const std::string &name)=0
Override this member function to receive the end_element message.
virtual bool start_element(const std::string &name, const attrs_type &attrs)=0
Override this member function to receive the start_element message.
int sax_handlers_mask
handlers mask type
virtual bool end_document()
Override this member function to receive the end_document message.
virtual bool warning(const std::string &message)
Override this memeber function to receive parser warnings.
virtual bool entity_reference(const std::string &name)
Override this memeber function to receive the entity reference message.
event_parser(sax_handlers_mask mask=default_set)
xml::event_parser class constructor.
virtual bool entity_declaration(const std::string &name, entity_type type, const std::string &public_id, const std::string &system_id, const std::string &content)
Override this memeber function to receive the entity declaration message.
element_content_type get_element_content_type(int)
entity_type
enum for different types of XML entities
virtual bool notation_declaration(const std::string &name, const std::string &public_id, const std::string &system_id)
Override this memeber function to receive the notation declaration message.
bool parse_chunk(const char *chunk, size_type length, error_messages *messages, warnings_as_errors_type how=type_warnings_not_errors)
Call this function to parse a chunk of xml data.
virtual bool error(const std::string &message)
Override this memeber function to receive parser errors.
virtual bool comment(const std::string &contents)
Override this member function to receive the comment message.
attribute_type
enum for different types of XML attributes
bool parse_file(const char *filename, error_messages *messages, warnings_as_errors_type how=type_warnings_not_errors)
Call this member function to parse the given file.
element_content_type
enum for element content types
virtual ~event_parser(void)
xml::event_parser class destructor.
std::size_t size_type
size type
virtual bool processing_instruction(const std::string &target, const std::string &data)
Override this member function to receive the procesing_instruction message.
This exception class is thrown by xmlwrapp for all runtime XML-related errors along with the xml::par...
Definition: exception.hpp:64
const char * file_name[]
static void cb_pi(void *parser, const xmlChar *target, const xmlChar *data)
static void cb_cdata(void *parser, const xmlChar *text, int length)
static void cb_start_element(void *parser, const xmlChar *tag, const xmlChar **props)
static void cb_external_subset_declaration(void *parser, const xmlChar *name, const xmlChar *external_id, const xmlChar *system_id)
static void cb_end_element(void *parser, const xmlChar *tag)
static void cb_entity_declaration(void *parser, const xmlChar *name, int type, const xmlChar *public_id, const xmlChar *system_id, xmlChar *content)
static void cb_unparsed_entity_declaration(void *parser, const xmlChar *name, const xmlChar *public_id, const xmlChar *system_id, const xmlChar *notation_name)
static void cb_attribute_declaration(void *parser, const xmlChar *element_name, const xmlChar *attribute_name, int attr_type, int default_type, const xmlChar *default_value, xmlEnumeration *default_values)
static void cb_element_declaration(void *parser, const xmlChar *element_name, int type, xmlElementContent *content)
static void cb_text(void *parser, const xmlChar *text, int length)
static void cb_end_document(void *parser)
static void cb_internal_subset_declaration(void *parser, const xmlChar *name, const xmlChar *external_id, const xmlChar *system_id)
static void cb_start_document(void *parser)
static void cb_error(void *parser, const char *message,...)
static void cb_fatal_error(void *parser, const char *message,...)
static void cb_ignore(void *, const xmlChar *, int)
static void cb_entity_reference(void *parser, const xmlChar *name)
static void cb_warning(void *parser, const char *message,...)
static void cb_comment(void *parser, const xmlChar *text)
static void cb_notation_declaration(void *parser, const xmlChar *name, const xmlChar *public_id, const xmlChar *system_id)
This file contains the definition of the xml::event_parser class.
string
Definition: cgiapp.hpp:687
#define NULL
Definition: ncbistd.hpp:225
FILE * file
static void text(MDB_val *v)
Definition: mdb_dump.c:62
static const std::size_t const_buffer_size
Definition: document.cpp:420
This file contains the definition of the xml::exception class.
This file contains the definition of the xml::node class.
void clear_https_messages(void)
void printf2string(std::string &s, const char *message, va_list ap)
Definition: utility.cpp:79
void collect_https_messages(xml::error_messages &append_to)
XML library namespace.
Definition: attributes.hpp:57
warnings_as_errors_type
A type for different approaches to process warnings.
Definition: errors.hpp:259
@ type_warnings_are_errors
Treat warnings as errors.
Definition: errors.hpp:260
int size_t_to_int_conversion(std::size_t value, const std::string &msg)
Definition: utility.cpp:63
const char * tag
const char * entity_name
static pcre_uint8 * buffer
Definition: pcretest.c:1051
Definition: type.c:6
void event_entity_declaration(const xmlChar *name, int type, const xmlChar *publicId, const xmlChar *systemId, xmlChar *content)
void event_internal_subset_declaration(const xmlChar *name, const xmlChar *external_id, const xmlChar *system_id)
void event_external_subset_declaration(const xmlChar *name, const xmlChar *external_id, const xmlChar *system_id)
void recreate_context(void)
void event_warning(const std::string &message)
epimpl(event_parser &parent, event_parser::sax_handlers_mask mask)
void event_unparsed_entity_declaration(const xmlChar *name, const xmlChar *public_id, const xmlChar *system_id, const xmlChar *notation_name)
void event_fatal_error(const std::string &message)
void event_start_document(void)
void event_end_document(void)
error_messages * errors_
epimpl & operator=(const epimpl &)
void event_attribute_declaration(const xmlChar *element_name, const xmlChar *attribute_name, int attr_type, int default_type, const xmlChar *default_value, xmlEnumeration *default_values)
xmlParserCtxt * parser_context_
void event_end_element(const xmlChar *tag)
void event_text(const xmlChar *text, int length)
void event_element_declaration(const xmlChar *element_name, int type, xmlElementContent *content)
epimpl(const epimpl &)
void event_error(const std::string &message)
void create_context(void)
void event_comment(const xmlChar *text)
void event_pi(const xmlChar *target, const xmlChar *data)
void destroy_context(void)
void event_start_element(const xmlChar *tag, const xmlChar **props)
void event_entity_reference(const xmlChar *name)
void event_notation_declaration(const xmlChar *name, const xmlChar *public_id, const xmlChar *system_id)
void event_cdata(const xmlChar *text, int length)
event_parser & parent_
xmlSAXHandler sax_handler_
Modified on Sat Dec 02 09:23:01 2023 by modify_doxy.py rev. 669887