36 #include <libxml/parserInternals.h> 43 #include "D4Attributes.h" 46 #include "D4BaseTypeFactory.h" 48 #include "DapXmlNamespaces.h" 49 #include "D4ParserSax2.h" 57 static const char *states[] = {
66 "inside_attribute_container",
68 "inside_attribute_value",
69 "inside_other_xml_attribute",
94 static bool is_not(
const char *name,
const char *tag)
96 return strcmp(name, tag) != 0;
108 D4ParserSax2::enum_def()
110 if (!d_enum_def) d_enum_def =
new D4EnumDef;
122 D4ParserSax2::dim_def() {
123 if (!d_dim_def) d_dim_def =
new D4Dimension;
133 void D4ParserSax2::transfer_xml_attrs(
const xmlChar **attributes,
int nb_attributes)
135 if (!xml_attrs.empty())
140 unsigned int index = 0;
141 for (
int i = 0; i < nb_attributes; ++i, index += 5) {
142 xml_attrs.insert(map<string, XMLAttribute>::value_type(
string((
const char *)attributes[index]),
143 XMLAttribute(attributes + index + 1)));
145 DBG(cerr <<
"XML Attribute '" << (
const char *)attributes[index] <<
"': " 146 << xml_attrs[(
const char *)attributes[index]].value << endl);
156 void D4ParserSax2::transfer_xml_ns(
const xmlChar **namespaces,
int nb_namespaces)
159 for (
int i = 0; i < nb_namespaces; ++i) {
160 namespace_table.insert(map<string, string>::value_type(namespaces[i * 2] != 0 ? (
const char *)namespaces[i * 2] :
"",
161 (
const char *)namespaces[i * 2 + 1]));
171 bool D4ParserSax2::check_required_attribute(
const string & attr)
173 if (xml_attrs.find(attr) == xml_attrs.end()) {
174 dmr_error(
this,
"Required attribute '%s' not found.", attr.c_str());
187 bool D4ParserSax2::check_attribute(
const string & attr)
189 return (xml_attrs.find(attr) != xml_attrs.end());
192 bool D4ParserSax2::process_dimension_def(
const char *name,
const xmlChar **attrs,
int nb_attributes)
194 if (is_not(name,
"Dimension"))
197 transfer_xml_attrs(attrs, nb_attributes);
199 if (!(check_required_attribute(
"name") && check_required_attribute(
"size"))) {
200 dmr_error(
this,
"The required attribute 'name' or 'size' was missing from a Dimension element.");
205 dim_def()->set_name(xml_attrs[
"name"].value);
207 dim_def()->set_size(xml_attrs[
"size"].value);
210 dmr_error(
this, e.get_error_message().c_str());
234 bool D4ParserSax2::process_dimension(
const char *name,
const xmlChar **attrs,
int nb_attributes)
236 if (is_not(name,
"Dim"))
239 transfer_xml_attrs(attrs, nb_attributes);
241 if (check_attribute(
"size") && check_attribute(
"name")) {
242 dmr_error(
this,
"Only one of 'size' and 'name' are allowed in a Dim element, but both were used.");
245 if (!(check_attribute(
"size") || check_attribute(
"name"))) {
246 dmr_error(
this,
"Either 'size' or 'name' must be used in a Dim element.");
252 BaseType *b = top_basetype();
255 Array *a =
static_cast<Array*
>(dmr()->
factory()->
NewVariable(dods_array_c, b->name()));
256 a->set_is_dap4(
true);
257 a->add_var_nocopy(b);
258 a->set_attributes_nocopy(b->attributes());
262 b->set_attributes_nocopy(0);
269 Array *a =
static_cast<Array*
>(top_basetype());
270 if (check_attribute(
"size")) {
271 a->append_dim(atoi(xml_attrs[
"size"].value.c_str()));
274 else if (check_attribute(
"name")) {
275 string name = xml_attrs[
"name"].value;
277 D4Dimension *dim = 0;
284 throw Error(
"The dimension '" + name +
"' was not found while parsing the variable '" + a->name() +
"'.");
292 bool D4ParserSax2::process_map(
const char *name,
const xmlChar **attrs,
int nb_attributes)
294 if (is_not(name,
"Map"))
297 transfer_xml_attrs(attrs, nb_attributes);
299 if (!check_attribute(
"name")) {
300 dmr_error(
this,
"The 'name' attribute must be used in a Map element.");
306 BaseType *b = top_basetype();
309 Array *a =
static_cast<Array*
>(dmr()->
factory()->
NewVariable(dods_array_c, b->name()));
310 a->set_is_dap4(
true);
311 a->add_var_nocopy(b);
312 a->set_attributes_nocopy(b->attributes());
316 b->set_attributes_nocopy(0);
323 Array *a =
static_cast<Array*
>(top_basetype());
325 string map_name = xml_attrs[
"name"].value;
326 if (xml_attrs[
"name"].value[0] !=
'/')
327 map_name = top_group()->
FQN() + map_name;
329 Array *map_source = 0;
331 if (map_name[0] ==
'/')
332 map_source = dmr()->
root()->find_map_source(map_name);
334 map_source = top_group()->find_map_source(map_name);
342 if (!map_source && d_strict)
343 throw Error(
"The Map '" + map_name +
"' was not found while parsing the variable '" + a->name() +
"'.");
345 a->maps()->
add_map(
new D4Map(map_name, map_source));
350 bool D4ParserSax2::process_group(
const char *name,
const xmlChar **attrs,
int nb_attributes)
352 if (is_not(name,
"Group"))
355 transfer_xml_attrs(attrs, nb_attributes);
357 if (!check_required_attribute(
"name")) {
358 dmr_error(
this,
"The required attribute 'name' was missing from a Group element.");
364 dmr_fatal_error(
this,
"Could not instantiate the Group '%s'.", xml_attrs[
"name"].value.c_str());
368 D4Group *grp =
static_cast<D4Group*
>(btp);
372 grp->set_is_dap4(
true);
375 D4Group *parent = top_group();
381 grp->set_parent(parent);
382 parent->add_group_nocopy(grp);
385 push_attributes(grp->attributes());
395 inline bool D4ParserSax2::process_attribute(
const char *name,
const xmlChar **attrs,
int nb_attributes)
397 if (is_not(name,
"Attribute"))
401 transfer_xml_attrs(attrs, nb_attributes);
404 if (!(check_required_attribute(
string(
"name")) && check_required_attribute(
string(
"type")))) {
405 dmr_error(
this,
"The required attribute 'name' or 'type' was missing from an Attribute element.");
409 if (xml_attrs[
"type"].value ==
"Container") {
410 push_state(inside_attribute_container);
412 DBG(cerr <<
"Pushing attribute container " << xml_attrs[
"name"].value << endl);
413 D4Attribute *child =
new D4Attribute(xml_attrs[
"name"].value, attr_container_c);
415 D4Attributes *tos = top_attributes();
419 dmr_fatal_error(
this,
"Expected an Attribute container on the top of the attribute stack.");
423 tos->add_attribute_nocopy(child);
424 push_attributes(child->attributes());
426 else if (xml_attrs[
"type"].value ==
"OtherXML") {
427 push_state(inside_other_xml_attribute);
429 dods_attr_name = xml_attrs[
"name"].value;
430 dods_attr_type = xml_attrs[
"type"].value;
433 push_state(inside_attribute);
435 dods_attr_name = xml_attrs[
"name"].value;
436 dods_attr_type = xml_attrs[
"type"].value;
447 inline bool D4ParserSax2::process_enum_def(
const char *name,
const xmlChar **attrs,
int nb_attributes)
449 if (is_not(name,
"Enumeration"))
452 transfer_xml_attrs(attrs, nb_attributes);
454 if (!(check_required_attribute(
"name") && check_required_attribute(
"basetype"))) {
455 dmr_error(
this,
"The required attribute 'name' or 'basetype' was missing from an Enumeration element.");
461 dmr_error(
this,
"The Enumeration '%s' must have an integer type, instead the type '%s' was used.",
462 xml_attrs[
"name"].value.c_str(), xml_attrs[
"basetype"].value.c_str());
467 string enum_def_path = xml_attrs[
"name"].value;
470 if (xml_attrs[
"name"].value[0] !=
'/')
471 enum_def_path = top_group()->
FQN() + enum_def_path;
473 enum_def()->set_name(enum_def_path);
474 enum_def()->set_type(t);
479 inline bool D4ParserSax2::process_enum_const(
const char *name,
const xmlChar **attrs,
int nb_attributes)
481 if (is_not(name,
"EnumConst"))
485 transfer_xml_attrs(attrs, nb_attributes);
487 if (!(check_required_attribute(
"name") && check_required_attribute(
"value"))) {
488 dmr_error(
this,
"The required attribute 'name' or 'value' was missing from an EnumConst element.");
492 istringstream iss(xml_attrs[
"value"].value);
494 iss >> skipws >> value;
495 if (iss.fail() || iss.bad()) {
496 dmr_error(
this,
"Expected an integer value for an Enumeration constant, got '%s' instead.",
497 xml_attrs[
"value"].value.c_str());
500 dmr_error(
this,
"In an Enumeration constant, the value '%s' cannot fit in a variable of type '%s'.",
501 xml_attrs[
"value"].value.c_str(),
D4type_name(d_enum_def->type()).c_str());
505 enum_def()->add_value(xml_attrs[
"name"].value, value);
516 inline bool D4ParserSax2::process_variable(
const char *name,
const xmlChar **attrs,
int nb_attributes)
520 process_variable_helper(t, inside_simple_type, attrs, nb_attributes);
525 case dods_structure_c:
526 process_variable_helper(t, inside_constructor, attrs, nb_attributes);
529 case dods_sequence_c:
530 process_variable_helper(t, inside_constructor, attrs, nb_attributes);
546 void D4ParserSax2::process_variable_helper(
Type t, ParseState s,
const xmlChar **attrs,
int nb_attributes)
548 transfer_xml_attrs(attrs, nb_attributes);
550 if (check_required_attribute(
"name")) {
553 dmr_fatal_error(
this,
"Could not instantiate the variable '%s'.", xml_attrs[
"name"].value.c_str());
557 if ((t == dods_enum_c) && check_required_attribute(
"enum")) {
558 D4EnumDef *enum_def = 0;
559 string enum_path = xml_attrs[
"enum"].value;
560 if (enum_path[0] ==
'/')
561 enum_def = dmr()->
root()->find_enum_def(enum_path);
563 enum_def = top_group()->find_enum_def(enum_path);
566 dmr_fatal_error(
this,
"Could not find the Enumeration definition '%s'.", enum_path.c_str());
568 static_cast<D4Enum*
>(btp)->set_enumeration(enum_def);
571 btp->set_is_dap4(
true);
574 push_attributes(btp->attributes());
594 parser->error_msg =
"";
595 parser->char_data =
"";
604 if (parser->debug()) cerr <<
"Parser start state: " << states[parser->get_state()] << endl;
613 if (parser->debug()) cerr <<
"Parser end state: " << states[parser->get_state()] << endl;
615 if (parser->get_state() != parser_end)
616 D4ParserSax2::dmr_error(parser,
"The document contained unbalanced tags.");
620 if (parser->get_state() == parser_error || parser->get_state() == parser_fatal_error)
623 if (!parser->empty_basetype() || parser->empty_group())
624 D4ParserSax2::dmr_error(parser,
"The document did not contain a valid root Group or contained unbalanced tags.");
627 parser->pop_attributes();
644 int nb_namespaces,
const xmlChar **namespaces,
int nb_attributes,
int ,
645 const xmlChar **attributes)
648 const char *localname = (
const char *) l;
650 if (parser->debug()) cerr <<
"Start element " << localname <<
" prefix: "<< (prefix?(
char *)prefix:
"null") <<
" ns: "<< (URI?(
char *)URI:
"null")
651 <<
" (state: " << states[parser->get_state()] <<
")" << endl;
653 if(parser->get_state() != parser_error){
655 if (parser->debug()) cerr <<
"dap4_ns_name: " << dap4_ns_name << endl;
657 string this_element_ns_name((
char *)URI);
658 if (parser->debug()) cerr <<
"this_element_ns_name: " << this_element_ns_name << endl;
660 if(this_element_ns_name.compare(dap4_ns_name)){
661 if (parser->debug()) cerr <<
"Start of non DAP4 element: " << localname <<
" detected." << endl;
662 parser->push_state(not_dap4_element);
668 switch (parser->get_state()) {
670 if (is_not(localname,
"Dataset"))
671 D4ParserSax2::dmr_error(parser,
"Expected DMR to start with a Dataset element; found '%s' instead.", localname);
673 parser->root_ns = URI ? (
const char *) URI :
"";
674 parser->transfer_xml_attrs(attributes, nb_attributes);
676 if (parser->check_required_attribute(
string(
"name")))
677 parser->dmr()->set_name(parser->xml_attrs[
"name"].value);
679 if (parser->check_attribute(
"dapVersion"))
682 if (parser->check_attribute(
"dmrVersion"))
683 parser->dmr()->set_dmr_version(parser->xml_attrs[
"dmrVersion"].value);
685 if (parser->check_attribute(
"base"))
688 if (!parser->root_ns.empty())
692 parser->push_group(parser->dmr()->
root());
694 parser->push_state(inside_dataset);
703 if (parser->process_enum_def(localname, attributes, nb_attributes))
704 parser->push_state(inside_enum_def);
705 else if (parser->process_dimension_def(localname, attributes, nb_attributes))
706 parser->push_state(inside_dim_def);
707 else if (parser->process_group(localname, attributes, nb_attributes))
708 parser->push_state(inside_group);
709 else if (parser->process_variable(localname, attributes, nb_attributes))
713 else if (parser->process_attribute(localname, attributes, nb_attributes))
718 D4ParserSax2::dmr_error(parser,
"Expected an Attribute, Enumeration, Dimension, Group or variable element; found '%s' instead.", localname);
721 case inside_attribute_container:
722 if (parser->process_attribute(localname, attributes, nb_attributes))
725 D4ParserSax2::dmr_error(parser,
"Expected an Attribute element; found '%s' instead.", localname);
728 case inside_attribute:
729 if (parser->process_attribute(localname, attributes, nb_attributes))
731 else if (strcmp(localname,
"Value") == 0)
732 parser->push_state(inside_attribute_value);
734 dmr_error(parser,
"Expected an 'Attribute' or 'Value' element; found '%s' instead.", localname);
737 case inside_attribute_value:
741 case inside_other_xml_attribute:
742 parser->other_xml_depth++;
745 parser->other_xml.append(
"<");
747 parser->other_xml.append((
const char *) prefix);
748 parser->other_xml.append(
":");
750 parser->other_xml.append(localname);
752 if (nb_namespaces != 0) {
753 parser->transfer_xml_ns(namespaces, nb_namespaces);
755 for (map<string, string>::iterator i = parser->namespace_table.begin();
756 i != parser->namespace_table.end(); ++i) {
757 parser->other_xml.append(
" xmlns");
758 if (!i->first.empty()) {
759 parser->other_xml.append(
":");
760 parser->other_xml.append(i->first);
762 parser->other_xml.append(
"=\"");
763 parser->other_xml.append(i->second);
764 parser->other_xml.append(
"\"");
768 if (nb_attributes != 0) {
769 parser->transfer_xml_attrs(attributes, nb_attributes);
770 for (XMLAttrMap::iterator i = parser->xml_attr_begin(); i != parser->xml_attr_end(); ++i) {
771 parser->other_xml.append(
" ");
772 if (!i->second.prefix.empty()) {
773 parser->other_xml.append(i->second.prefix);
774 parser->other_xml.append(
":");
776 parser->other_xml.append(i->first);
777 parser->other_xml.append(
"=\"");
778 parser->other_xml.append(i->second.value);
779 parser->other_xml.append(
"\"");
783 parser->other_xml.append(
">");
786 case inside_enum_def:
788 if (parser->process_enum_const(localname, attributes, nb_attributes))
789 parser->push_state(inside_enum_const);
791 dmr_error(parser,
"Expected an 'EnumConst' element; found '%s' instead.", localname);
794 case inside_enum_const:
802 case inside_dimension:
814 case inside_simple_type:
815 if (parser->process_attribute(localname, attributes, nb_attributes))
817 else if (parser->process_dimension(localname, attributes, nb_attributes))
818 parser->push_state(inside_dim);
819 else if (parser->process_map(localname, attributes, nb_attributes))
820 parser->push_state(inside_map);
822 dmr_error(parser,
"Expected an 'Attribute', 'Dim' or 'Map' element; found '%s' instead.", localname);
825 case inside_constructor:
826 if (parser->process_variable(localname, attributes, nb_attributes))
830 else if (parser->process_attribute(localname, attributes, nb_attributes))
832 else if (parser->process_dimension(localname, attributes, nb_attributes))
833 parser->push_state(inside_dim);
834 else if (parser->process_map(localname, attributes, nb_attributes))
835 parser->push_state(inside_map);
837 D4ParserSax2::dmr_error(parser,
"Expected an Attribute, Dim, Map or variable element; found '%s' instead.", localname);
840 case not_dap4_element:
841 if (parser->debug()) cerr <<
"Inside non DAP4 element. localname: " << localname << endl;
847 parser->push_state(parser_unknown);
851 case parser_fatal_error:
859 if (parser->debug()) cerr <<
"Start element exit state: " << states[parser->get_state()] << endl;
862 void D4ParserSax2::dmr_end_element(
void *p,
const xmlChar *l,
const xmlChar *prefix,
const xmlChar *URI)
865 const char *localname = (
const char *) l;
868 cerr <<
"End element " << localname <<
" (state " << states[parser->get_state()] <<
")" << endl;
870 switch (parser->get_state()) {
872 dmr_fatal_error(parser,
"Unexpected state, inside start state while processing element '%s'.", localname);
876 if (is_not(localname,
"Dataset"))
877 D4ParserSax2::dmr_error(parser,
"Expected an end Dataset tag; found '%s' instead.", localname);
880 if (parser->get_state() != parser_start)
884 parser->push_state(parser_end);
889 if (is_not(localname,
"Group"))
890 D4ParserSax2::dmr_error(parser,
"Expected an end tag for a Group; found '%s' instead.", localname);
892 if (!parser->empty_basetype() || parser->empty_group())
893 D4ParserSax2::dmr_error(parser,
894 "The document did not contain a valid root Group or contained unbalanced tags.");
901 case inside_attribute_container:
902 if (is_not(localname,
"Attribute"))
903 D4ParserSax2::dmr_error(parser,
"Expected an end Attribute tag; found '%s' instead.", localname);
906 parser->pop_attributes();
909 case inside_attribute:
910 if (is_not(localname,
"Attribute"))
911 D4ParserSax2::dmr_error(parser,
"Expected an end Attribute tag; found '%s' instead.", localname);
916 case inside_attribute_value: {
917 if (is_not(localname,
"Value"))
918 D4ParserSax2::dmr_error(parser,
"Expected an end value tag; found '%s' instead.", localname);
925 D4Attributes *attrs = parser->top_attributes();
926 D4Attribute *attr = attrs->
get(parser->dods_attr_name);
928 attr =
new D4Attribute(parser->dods_attr_name, StringToD4AttributeType(parser->dods_attr_type));
929 attrs->add_attribute_nocopy(attr);
931 attr->add_value(parser->char_data);
933 parser->char_data =
"";
937 case inside_other_xml_attribute: {
938 if (strcmp(localname,
"Attribute") == 0 && parser->root_ns == (
const char *) URI) {
944 D4Attributes *attrs = parser->top_attributes();
945 D4Attribute *attr = attrs->
get(parser->dods_attr_name);
947 attr =
new D4Attribute(parser->dods_attr_name, StringToD4AttributeType(parser->dods_attr_type));
948 attrs->add_attribute_nocopy(attr);
950 attr->add_value(parser->other_xml);
952 parser->other_xml =
"";
955 if (parser->other_xml_depth == 0) {
956 D4ParserSax2::dmr_error(parser,
"Expected an OtherXML attribute to end! Instead I found '%s'",
960 parser->other_xml_depth--;
962 parser->other_xml.append(
"</");
964 parser->other_xml.append((
const char *) prefix);
965 parser->other_xml.append(
":");
967 parser->other_xml.append(localname);
968 parser->other_xml.append(
">");
973 case inside_enum_def:
974 if (is_not(localname,
"Enumeration"))
975 D4ParserSax2::dmr_error(parser,
"Expected an end Enumeration tag; found '%s' instead.", localname);
976 if (!parser->top_group())
978 "Expected a Group to be the current item, while finishing up an Enumeration.");
981 parser->top_group()->
enum_defs()->add_enum_nocopy(parser->enum_def());
984 parser->clear_enum_def();
989 case inside_enum_const:
990 if (is_not(localname,
"EnumConst"))
991 D4ParserSax2::dmr_error(parser,
"Expected an end EnumConst tag; found '%s' instead.", localname);
996 case inside_dim_def: {
997 if (is_not(localname,
"Dimension"))
998 D4ParserSax2::dmr_error(parser,
"Expected an end Dimension tag; found '%s' instead.", localname);
1000 if (!parser->top_group())
1001 D4ParserSax2::dmr_error(parser,
1002 "Expected a Group to be the current item, while finishing up an Dimension.");
1013 parser->clear_dim_def();
1014 parser->pop_state();
1018 case inside_simple_type:
1020 BaseType *btp = parser->top_basetype();
1021 parser->pop_basetype();
1022 parser->pop_attributes();
1024 BaseType *parent = 0;
1025 if (!parser->empty_basetype())
1026 parent = parser->top_basetype();
1027 else if (!parser->empty_group())
1028 parent = parser->top_group();
1030 dmr_fatal_error(parser,
"Both the Variable and Groups stacks are empty while closing a %s element.",
1033 parser->pop_state();
1037 if (parent->type() == dods_array_c)
1038 static_cast<Array*>(parent)->prototype()->add_var_nocopy(btp);
1040 parent->add_var_nocopy(btp);
1043 D4ParserSax2::dmr_error(parser,
"Expected an end tag for a simple type; found '%s' instead.", localname);
1045 parser->pop_state();
1049 if (is_not(localname,
"Dim"))
1052 parser->pop_state();
1056 if (is_not(localname,
"Map"))
1059 parser->pop_state();
1062 case inside_constructor: {
1063 if (strcmp(localname,
"Structure") != 0 && strcmp(localname,
"Sequence") != 0) {
1064 D4ParserSax2::dmr_error(parser,
"Expected an end tag for a constructor; found '%s' instead.", localname);
1068 BaseType *btp = parser->top_basetype();
1069 parser->pop_basetype();
1070 parser->pop_attributes();
1072 BaseType *parent = 0;
1073 if (!parser->empty_basetype())
1074 parent = parser->top_basetype();
1075 else if (!parser->empty_group())
1076 parent = parser->top_group();
1078 dmr_fatal_error(parser,
"Both the Variable and Groups stacks are empty while closing a %s element.",
1081 parser->pop_state();
1087 parent->add_var_nocopy(btp);
1088 parser->pop_state();
1092 case not_dap4_element:
1093 if (parser->debug()) cerr <<
"End of non DAP4 element: " << localname << endl;
1094 parser->pop_state();
1097 case parser_unknown:
1098 parser->pop_state();
1102 case parser_fatal_error:
1110 if (parser->debug()) cerr <<
"End element exit state: " << states[parser->get_state()] << endl;
1120 switch (parser->get_state()) {
1121 case inside_attribute_value:
1122 parser->char_data.append((
const char *) (ch), len);
1123 DBG(cerr <<
"Characters: '" << parser->char_data <<
"'" << endl);
1126 case inside_other_xml_attribute:
1127 parser->other_xml.append((
const char *) (ch), len);
1128 DBG(cerr <<
"Other XML Characters: '" << parser->other_xml <<
"'" << endl);
1144 switch (parser->get_state()) {
1145 case inside_other_xml_attribute:
1146 parser->other_xml.append((
const char *) (ch), len);
1163 switch (parser->get_state()) {
1164 case inside_other_xml_attribute:
1165 parser->other_xml.append((
const char *) (value), len);
1168 case parser_unknown:
1172 D4ParserSax2::dmr_error(parser,
"Found a CData block but none are allowed by DAP4.");
1184 return xmlGetPredefinedEntity(name);
1202 parser->push_state(parser_fatal_error);
1204 va_start(args, msg);
1206 vsnprintf(str, 1024, msg, args);
1209 int line = xmlSAX2GetLineNumber(parser->context);
1211 if (!parser->error_msg.empty()) parser->error_msg +=
"\n";
1212 parser->error_msg +=
"At line " + long_to_string(line) +
": " + string(str);
1215 void D4ParserSax2::dmr_error(
void *p,
const char *msg, ...)
1220 parser->push_state(parser_error);
1222 va_start(args, msg);
1224 vsnprintf(str, 1024, msg, args);
1227 int line = xmlSAX2GetLineNumber(parser->context);
1229 if (!parser->error_msg.empty()) parser->error_msg +=
"\n";
1230 parser->error_msg +=
"At line " + long_to_string(line) +
": " + string(str);
1237 void D4ParserSax2::cleanup_parse()
1239 bool wellFormed = context->wellFormed;
1240 bool valid = context->valid;
1242 context->sax = NULL;
1243 xmlFreeParserCtxt(context);
1253 while (!btp_stack.empty()) {
1254 delete top_basetype();
1259 throw Error(
"The DMR was not well formed. " + error_msg);
1261 throw Error(
"The DMR was not valid." + error_msg);
1262 else if (get_state() == parser_error)
1263 throw Error(error_msg);
1264 else if (get_state() == parser_fatal_error)
1265 throw InternalErr(error_msg);
1282 void D4ParserSax2::intern(istream &f, DMR *dest_dmr,
bool debug)
1289 throw Error(
"Input stream not open or read error");
1291 throw InternalErr(__FILE__, __LINE__,
"DMR object is null");
1295 const int size = 1024;
1299 f.getline(chars, size);
1300 int res = f.gcount();
1301 if (res == 0)
throw Error(
"No input found while parsing the DMR.");
1303 if (debug) cerr <<
"line: (" << line++ <<
"): " << chars << endl;
1305 context = xmlCreatePushParserCtxt(&ddx_sax_parser,
this, chars, res - 1,
"stream");
1306 context->validate =
true;
1307 push_state(parser_start);
1309 f.getline(chars, size);
1310 while ((f.gcount() > 0) && (get_state() != parser_end)) {
1311 if (debug) cerr <<
"line: (" << line++ <<
"): " << chars << endl;
1312 xmlParseChunk(context, chars, f.gcount() - 1, 0);
1313 f.getline(chars, size);
1317 xmlParseChunk(context, chars, 0, 1);
1334 void D4ParserSax2::intern(
const string &document, DMR *dest_dmr,
bool debug)
1336 intern(document.c_str(), document.length(), dest_dmr, debug);
1349 void D4ParserSax2::intern(
const char *buffer,
int size,
DMR *dest_dmr,
bool debug)
1351 if (!(size > 0))
return;
1357 if (!dest_dmr)
throw InternalErr(__FILE__, __LINE__,
"DMR object is null");
1360 push_state(parser_start);
1361 context = xmlCreatePushParserCtxt(&ddx_sax_parser,
this, buffer, size,
"stream");
1362 context->validate =
true;
1367 xmlParseChunk(context, buffer, 0, 1);
virtual BaseType * NewVariable(Type t, const string &name) const
static void dmr_end_document(void *parser)
void set_namespace(const string &ns)
Set the namespace for this DDS/DDX object/response.
bool is_valid_enum_value(long long value)
D4Dimension * find_dim(const string &path)
Find the dimension using a path. Using the DAP4 name syntax, lookup a dimension. The dimension must b...
static void dmr_start_document(void *parser)
static xmlEntityPtr dmr_get_entity(void *parser, const xmlChar *name)
bool is_vector_type(Type t)
Returns true if the instance is a vector (i.e., array) type variable.
void set_request_xml_base(const string &xb)
Type
Identifies the data type.
A class for software fault reporting.
static std::string getDapNamespaceString(DAPVersion version)
static void dmr_start_element(void *parser, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI, int nb_namespaces, const xmlChar **namespaces, int nb_attributes, int nb_defaulted, const xmlChar **attributes)
static void dmr_ignoreable_whitespace(void *parser, const xmlChar *ch, int len)
void add_dim_nocopy(D4Dimension *dim)
virtual D4BaseTypeFactory * factory()
static void dmr_get_cdata(void *parser, const xmlChar *value, int len)
ObjectType get_type(const string &value)
string D4type_name(Type t)
Returns the type of the class instance as a string. Supports all DAP4 types and not the DAP2-only typ...
bool is_simple_type(Type t)
Returns true if the instance is a numeric, string or URL type variable.
virtual D4Attributes * attributes()
static void dmr_get_characters(void *parser, const xmlChar *ch, int len)
void set_dap_version(const string &version_string)
virtual std::string FQN() const
D4Attribute * get(const string &fqn)
D4EnumDefs * enum_defs()
Get the enumerations defined for this Group.
static void dmr_fatal_error(void *parser, const char *msg,...)
bool is_integer_type(Type t)
D4Dimensions * dims()
Get the dimensions defined for this Group.