36#include <libxml2/libxml/parserInternals.h>
56static const char *states[] = {
"parser_start",
64 "inside_attribute_container",
"inside_attribute",
"inside_attribute_value",
65 "inside_other_xml_attribute",
67 "inside_enum_def",
"inside_enum_const",
75 "inside_dim",
"inside_map",
81 "parser_unknown",
"parser_error",
"parser_fatal_error",
85static bool is_not(
const char *name,
const char *tag) {
return strcmp(name, tag) != 0; }
97 d_enum_def =
new D4EnumDef;
110 d_dim_def =
new D4Dimension;
120void D4ParserSax2::transfer_xml_attrs(
const xmlChar **attributes,
int nb_attributes) {
121 if (!xml_attrs.empty())
126 unsigned int index = 0;
127 for (
int i = 0; i < nb_attributes; ++i, index += 5) {
128 xml_attrs.insert(map<string, XMLAttribute>::value_type(
string((
const char *)attributes[index]),
129 XMLAttribute(attributes + index + 1)));
131 DBG(cerr <<
"XML Attribute '" << (
const char *)attributes[index]
132 <<
"': " << xml_attrs[(
const char *)attributes[index]].value << endl);
142void D4ParserSax2::transfer_xml_ns(
const xmlChar **namespaces,
int nb_namespaces) {
144 for (
int i = 0; i < nb_namespaces; ++i) {
145 namespace_table.insert(map<string, string>::value_type(
146 namespaces[i * 2] != 0 ? (
const char *)namespaces[i * 2] :
"", (
const char *)namespaces[i * 2 + 1]));
156bool D4ParserSax2::check_required_attribute(
const string &attr) {
157 if (xml_attrs.find(attr) == xml_attrs.end()) {
158 dmr_error(
this,
"Required attribute '%s' not found.", attr.c_str());
170bool D4ParserSax2::check_attribute(
const string &attr) {
return (xml_attrs.find(attr) != xml_attrs.end()); }
172bool D4ParserSax2::process_dimension_def(
const char *name,
const xmlChar **attrs,
int nb_attributes) {
173 if (is_not(name,
"Dimension"))
176 transfer_xml_attrs(attrs, nb_attributes);
178 if (!(check_required_attribute(
"name") && check_required_attribute(
"size"))) {
179 dmr_error(
this,
"The required attribute 'name' or 'size' was missing from a Dimension element.");
184 dim_def()->set_name(xml_attrs[
"name"].value);
186 dim_def()->set_size(xml_attrs[
"size"].value);
188 dmr_error(
this,
"%s", e.get_error_message().c_str());
212bool D4ParserSax2::process_dimension(
const char *name,
const xmlChar **attrs,
int nb_attributes) {
213 if (is_not(name,
"Dim"))
216 transfer_xml_attrs(attrs, nb_attributes);
218 if (check_attribute(
"size") && check_attribute(
"name")) {
219 dmr_error(
this,
"Only one of 'size' and 'name' are allowed in a Dim element, but both were used.");
222 if (!(check_attribute(
"size") || check_attribute(
"name"))) {
223 dmr_error(
this,
"Either 'size' or 'name' must be used in a Dim element.");
229 BaseType *b = top_basetype();
232 Array *a =
static_cast<Array *
>(dmr()->factory()->NewVariable(
dods_array_c, b->name()));
233 a->set_is_dap4(
true);
234 a->add_var_nocopy(b);
235 a->set_attributes_nocopy(b->attributes());
239 b->set_attributes_nocopy(0);
246 Array *a =
static_cast<Array *
>(top_basetype());
247 if (check_attribute(
"size")) {
249 a->append_dim_ll(strtoll(xml_attrs[
"size"].value.c_str(),
nullptr, 10));
251 a->append_dim(atoi(xml_attrs[
"size"].value.c_str()));
254 }
else if (check_attribute(
"name")) {
255 string name = xml_attrs[
"name"].value;
257 D4Dimension *dim = 0;
259 dim = dmr()->root()->find_dim(name);
261 dim = top_group()->find_dim(name);
264 throw Error(
"The dimension '" + name +
"' was not found while parsing the variable '" + a->name() +
"'.");
272bool D4ParserSax2::process_map(
const char *name,
const xmlChar **attrs,
int nb_attributes) {
273 if (is_not(name,
"Map"))
276 transfer_xml_attrs(attrs, nb_attributes);
278 if (!check_attribute(
"name")) {
279 dmr_error(
this,
"The 'name' attribute must be used in a Map element.");
285 BaseType *b = top_basetype();
288 Array *a =
static_cast<Array *
>(dmr()->factory()->NewVariable(
dods_array_c, b->name()));
289 a->set_is_dap4(
true);
290 a->add_var_nocopy(b);
291 a->set_attributes_nocopy(b->attributes());
295 b->set_attributes_nocopy(0);
302 Array *a =
static_cast<Array *
>(top_basetype());
304 string map_name = xml_attrs[
"name"].value;
305 if (xml_attrs[
"name"].value[0] !=
'/')
306 map_name = top_group()->FQN() + map_name;
308 Array *map_source = 0;
310 if (map_name[0] ==
'/')
311 map_source = dmr()->root()->find_map_source(map_name);
313 map_source = top_group()->find_map_source(map_name);
321 if (!map_source && d_strict)
322 throw Error(
"The Map '" + map_name +
"' was not found while parsing the variable '" + a->name() +
"'.");
324 a->maps()->add_map(
new D4Map(map_name, map_source));
329bool D4ParserSax2::process_group(
const char *name,
const xmlChar **attrs,
int nb_attributes) {
330 if (is_not(name,
"Group"))
333 transfer_xml_attrs(attrs, nb_attributes);
335 if (!check_required_attribute(
"name")) {
336 dmr_error(
this,
"The required attribute 'name' was missing from a Group element.");
340 BaseType *btp = dmr()->factory()->NewVariable(
dods_group_c, xml_attrs[
"name"].value);
342 dmr_fatal_error(
this,
"Could not instantiate the Group '%s'.", xml_attrs[
"name"].value.c_str());
346 D4Group *grp =
static_cast<D4Group *
>(btp);
350 grp->set_is_dap4(
true);
353 D4Group *parent = top_group();
359 grp->set_parent(parent);
360 parent->add_group_nocopy(grp);
363 push_attributes(grp->attributes());
373inline bool D4ParserSax2::process_attribute(
const char *name,
const xmlChar **attrs,
int nb_attributes) {
374 if (is_not(name,
"Attribute"))
378 transfer_xml_attrs(attrs, nb_attributes);
381 if (!(check_required_attribute(
string(
"name")) && check_required_attribute(
string(
"type")))) {
382 dmr_error(
this,
"The required attribute 'name' or 'type' was missing from an Attribute element.");
386 if (xml_attrs[
"type"].value ==
"Container") {
387 push_state(inside_attribute_container);
389 DBG(cerr <<
"Pushing attribute container " << xml_attrs[
"name"].value << endl);
390 D4Attribute *child =
new D4Attribute(xml_attrs[
"name"].value,
attr_container_c);
392 D4Attributes *tos = top_attributes();
396 dmr_fatal_error(
this,
"Expected an Attribute container on the top of the attribute stack.");
400 tos->add_attribute_nocopy(child);
401 push_attributes(child->attributes());
402 }
else if (xml_attrs[
"type"].value ==
"OtherXML") {
403 push_state(inside_other_xml_attribute);
405 dods_attr_name = xml_attrs[
"name"].value;
406 dods_attr_type = xml_attrs[
"type"].value;
408 push_state(inside_attribute);
410 dods_attr_name = xml_attrs[
"name"].value;
411 dods_attr_type = xml_attrs[
"type"].value;
422inline bool D4ParserSax2::process_enum_def(
const char *name,
const xmlChar **attrs,
int nb_attributes) {
423 if (is_not(name,
"Enumeration"))
426 transfer_xml_attrs(attrs, nb_attributes);
428 if (!(check_required_attribute(
"name") && check_required_attribute(
"basetype"))) {
429 dmr_error(
this,
"The required attribute 'name' or 'basetype' was missing from an Enumeration element.");
435 dmr_error(
this,
"The Enumeration '%s' must have an integer type, instead the type '%s' was used.",
436 xml_attrs[
"name"].value.c_str(), xml_attrs[
"basetype"].value.c_str());
441 string enum_def_path = xml_attrs[
"name"].value;
444 if (xml_attrs[
"name"].value[0] !=
'/')
445 enum_def_path = top_group()->FQN() + enum_def_path;
447 enum_def()->set_name(enum_def_path);
448 enum_def()->set_type(t);
453inline bool D4ParserSax2::process_enum_const(
const char *name,
const xmlChar **attrs,
int nb_attributes) {
454 if (is_not(name,
"EnumConst"))
458 transfer_xml_attrs(attrs, nb_attributes);
460 if (!(check_required_attribute(
"name") && check_required_attribute(
"value"))) {
461 dmr_error(
this,
"The required attribute 'name' or 'value' was missing from an EnumConst element.");
465 istringstream iss(xml_attrs[
"value"].value);
467 iss >> skipws >> value;
468 if (iss.fail() || iss.bad()) {
469 dmr_error(
this,
"Expected an integer value for an Enumeration constant, got '%s' instead.",
470 xml_attrs[
"value"].value.c_str());
471 }
else if (!enum_def()->is_valid_enum_value(value)) {
472 dmr_error(
this,
"In an Enumeration constant, the value '%s' cannot fit in a variable of type '%s'.",
473 xml_attrs[
"value"].value.c_str(),
D4type_name(d_enum_def->type()).c_str());
476 enum_def()->add_value(xml_attrs[
"name"].value, value);
487inline bool D4ParserSax2::process_variable(
const char *name,
const xmlChar **attrs,
int nb_attributes) {
490 process_variable_helper(t, inside_simple_type, attrs, nb_attributes);
495 process_variable_helper(t, inside_constructor, attrs, nb_attributes);
499 process_variable_helper(t, inside_constructor, attrs, nb_attributes);
515void D4ParserSax2::process_variable_helper(
Type t, ParseState s,
const xmlChar **attrs,
int nb_attributes) {
516 transfer_xml_attrs(attrs, nb_attributes);
518 if (check_required_attribute(
"name")) {
519 BaseType *btp = dmr()->factory()->NewVariable(t, xml_attrs[
"name"].value);
521 dmr_fatal_error(
this,
"Could not instantiate the variable '%s'.", xml_attrs[
"name"].value.c_str());
525 if ((t ==
dods_enum_c) && check_required_attribute(
"enum")) {
526 D4EnumDef *enum_def = 0;
527 string enum_path = xml_attrs[
"enum"].value;
528 if (enum_path[0] ==
'/')
529 enum_def = dmr()->root()->find_enum_def(enum_path);
531 enum_def = top_group()->find_enum_def(enum_path);
534 dmr_fatal_error(
this,
"Could not find the Enumeration definition '%s'.", enum_path.c_str());
536 static_cast<D4Enum *
>(btp)->set_enumeration(enum_def);
539 btp->set_is_dap4(
true);
542 push_attributes(btp->attributes());
561 parser->d_error_msg =
"";
562 parser->char_data =
"";
572 cerr <<
"Parser start state: " << states[parser->get_state()] << endl;
581 cerr <<
"Parser end state: " << states[parser->get_state()] << endl;
583 if (parser->get_state() != parser_end)
588 if (parser->get_state() == parser_error || parser->get_state() == parser_fatal_error)
591 if (!parser->empty_basetype() || parser->empty_group())
593 "The document did not contain a valid root Group or contained unbalanced tags.");
596 parser->pop_attributes();
613 int nb_namespaces,
const xmlChar **namespaces,
int nb_attributes,
614 int ,
const xmlChar **attributes) {
616 const char *localname = (
const char *)l;
619 cerr <<
"Start element " << localname <<
" prefix: " << (prefix ? (
char *)prefix :
"null")
620 <<
" ns: " << (URI ? (
char *)URI :
"null") <<
" (state: " << states[parser->get_state()] <<
")" << endl;
622 if (parser->get_state() != parser_error) {
625 cerr <<
"dap4_ns_name: " << dap4_ns_name << endl;
627 string this_element_ns_name = (URI != 0) ? ((
char *)URI) :
"";
629 cerr <<
"this_element_ns_name: " << this_element_ns_name << endl;
631 if (this_element_ns_name.compare(dap4_ns_name)) {
633 cerr <<
"Start of non DAP4 element: " << localname <<
" detected." << endl;
634 parser->push_state(not_dap4_element);
639 switch (parser->get_state()) {
641 if (is_not(localname,
"Dataset"))
645 parser->root_ns = URI ? (
const char *)URI :
"";
646 parser->transfer_xml_attrs(attributes, nb_attributes);
648 if (parser->check_required_attribute(
string(
"name")))
649 parser->dmr()->
set_name(parser->xml_attrs[
"name"].value);
651 if (parser->check_attribute(
"dapVersion"))
654 if (parser->check_attribute(
"dmrVersion"))
657 if (parser->check_attribute(
"base"))
660 if (!parser->root_ns.empty())
664 parser->push_group(parser->dmr()->
root());
666 parser->push_state(inside_dataset);
675 if (parser->process_enum_def(localname, attributes, nb_attributes))
676 parser->push_state(inside_enum_def);
677 else if (parser->process_dimension_def(localname, attributes, nb_attributes))
678 parser->push_state(inside_dim_def);
679 else if (parser->process_group(localname, attributes, nb_attributes))
680 parser->push_state(inside_group);
681 else if (parser->process_variable(localname, attributes, nb_attributes))
685 else if (parser->process_attribute(localname, attributes, nb_attributes))
691 parser,
"Expected an Attribute, Enumeration, Dimension, Group or variable element; found '%s' instead.",
695 case inside_attribute_container:
696 if (parser->process_attribute(localname, attributes, nb_attributes))
702 case inside_attribute:
703 if (parser->process_attribute(localname, attributes, nb_attributes))
705 else if (strcmp(localname,
"Value") == 0)
706 parser->push_state(inside_attribute_value);
708 dmr_error(parser,
"Expected an 'Attribute' or 'Value' element; found '%s' instead.", localname);
711 case inside_attribute_value:
715 case inside_other_xml_attribute:
716 parser->other_xml_depth++;
719 parser->other_xml.append(
"<");
721 parser->other_xml.append((
const char *)prefix);
722 parser->other_xml.append(
":");
724 parser->other_xml.append(localname);
726 if (nb_namespaces != 0) {
727 parser->transfer_xml_ns(namespaces, nb_namespaces);
729 for (map<string, string>::iterator i = parser->namespace_table.begin(); i != parser->namespace_table.end();
731 parser->other_xml.append(
" xmlns");
732 if (!i->first.empty()) {
733 parser->other_xml.append(
":");
734 parser->other_xml.append(i->first);
736 parser->other_xml.append(
"=\"");
737 parser->other_xml.append(i->second);
738 parser->other_xml.append(
"\"");
742 if (nb_attributes != 0) {
743 parser->transfer_xml_attrs(attributes, nb_attributes);
744 for (XMLAttrMap::iterator i = parser->xml_attr_begin(); i != parser->xml_attr_end(); ++i) {
745 parser->other_xml.append(
" ");
746 if (!i->second.prefix.empty()) {
747 parser->other_xml.append(i->second.prefix);
748 parser->other_xml.append(
":");
750 parser->other_xml.append(i->first);
751 parser->other_xml.append(
"=\"");
752 parser->other_xml.append(i->second.value);
753 parser->other_xml.append(
"\"");
757 parser->other_xml.append(
">");
760 case inside_enum_def:
762 if (parser->process_enum_const(localname, attributes, nb_attributes))
763 parser->push_state(inside_enum_const);
765 dmr_error(parser,
"Expected an 'EnumConst' element; found '%s' instead.", localname);
768 case inside_enum_const:
776 case inside_dimension:
788 case inside_simple_type:
789 if (parser->process_attribute(localname, attributes, nb_attributes))
791 else if (parser->process_dimension(localname, attributes, nb_attributes))
792 parser->push_state(inside_dim);
793 else if (parser->process_map(localname, attributes, nb_attributes))
794 parser->push_state(inside_map);
796 dmr_error(parser,
"Expected an 'Attribute', 'Dim' or 'Map' element; found '%s' instead.", localname);
799 case inside_constructor:
800 if (parser->process_variable(localname, attributes, nb_attributes))
804 else if (parser->process_attribute(localname, attributes, nb_attributes))
806 else if (parser->process_dimension(localname, attributes, nb_attributes))
807 parser->push_state(inside_dim);
808 else if (parser->process_map(localname, attributes, nb_attributes))
809 parser->push_state(inside_map);
815 case not_dap4_element:
817 cerr <<
"Inside non DAP4 element. localname: " << localname << endl;
823 parser->push_state(parser_unknown);
827 case parser_fatal_error:
836 cerr <<
"Start element exit state: " << states[parser->get_state()] << endl;
841 const char *localname = (
const char *)l;
844 cerr <<
"End element " << localname <<
" (state " << states[parser->get_state()] <<
")" << endl;
846 switch (parser->get_state()) {
848 dmr_fatal_error(parser,
"Unexpected state, inside start state while processing element '%s'.", localname);
852 if (is_not(localname,
"Dataset"))
856 if (parser->get_state() != parser_start)
860 parser->push_state(parser_end);
865 if (is_not(localname,
"Group"))
868 if (!parser->empty_basetype() || parser->empty_group())
870 "The document did not contain a valid root Group or contained unbalanced tags.");
877 case inside_attribute_container:
878 if (is_not(localname,
"Attribute"))
882 parser->pop_attributes();
885 case inside_attribute:
886 if (is_not(localname,
"Attribute"))
892 case inside_attribute_value: {
893 if (is_not(localname,
"Value"))
909 parser->char_data =
"";
913 case inside_other_xml_attribute: {
914 if (strcmp(localname,
"Attribute") == 0 && parser->root_ns == (
const char *)URI) {
928 parser->other_xml =
"";
930 if (parser->other_xml_depth == 0) {
935 parser->other_xml_depth--;
937 parser->other_xml.append(
"</");
939 parser->other_xml.append((
const char *)prefix);
940 parser->other_xml.append(
":");
942 parser->other_xml.append(localname);
943 parser->other_xml.append(
">");
948 case inside_enum_def:
949 if (is_not(localname,
"Enumeration"))
951 if (!parser->top_group())
953 parser,
"Expected a Group to be the current item, while finishing up an Enumeration.");
959 parser->clear_enum_def();
964 case inside_enum_const:
965 if (is_not(localname,
"EnumConst"))
971 case inside_dim_def: {
972 if (is_not(localname,
"Dimension"))
975 if (!parser->top_group())
977 "Expected a Group to be the current item, while finishing up an Dimension.");
988 parser->clear_dim_def();
993 case inside_simple_type:
995 BaseType *btp = parser->top_basetype();
996 parser->pop_basetype();
997 parser->pop_attributes();
1000 if (!parser->empty_basetype())
1001 parent = parser->top_basetype();
1002 else if (!parser->empty_group())
1003 parent = parser->top_group();
1005 dmr_fatal_error(parser,
"Both the Variable and Groups stacks are empty while closing a %s element.",
1008 parser->pop_state();
1019 parser->pop_state();
1023 if (is_not(localname,
"Dim"))
1026 parser->pop_state();
1030 if (is_not(localname,
"Map"))
1033 parser->pop_state();
1036 case inside_constructor: {
1037 if (strcmp(localname,
"Structure") != 0 && strcmp(localname,
"Sequence") != 0) {
1042 BaseType *btp = parser->top_basetype();
1043 parser->pop_basetype();
1044 parser->pop_attributes();
1047 if (!parser->empty_basetype())
1048 parent = parser->top_basetype();
1049 else if (!parser->empty_group())
1050 parent = parser->top_group();
1052 dmr_fatal_error(parser,
"Both the Variable and Groups stacks are empty while closing a %s element.",
1055 parser->pop_state();
1062 parser->pop_state();
1066 case not_dap4_element:
1067 if (parser->debug())
1068 cerr <<
"End of non DAP4 element: " << localname << endl;
1069 parser->pop_state();
1072 case parser_unknown:
1073 parser->pop_state();
1077 case parser_fatal_error:
1085 if (parser->debug())
1086 cerr <<
"End element exit state: " << states[parser->get_state()] << endl;
1095 switch (parser->get_state()) {
1096 case inside_attribute_value:
1097 parser->char_data.append((
const char *)(ch), len);
1098 DBG(cerr <<
"Characters: '" << parser->char_data <<
"'" << endl);
1101 case inside_other_xml_attribute:
1102 parser->other_xml.append((
const char *)(ch), len);
1103 DBG(cerr <<
"Other XML Characters: '" << parser->other_xml <<
"'" << endl);
1118 switch (parser->get_state()) {
1119 case inside_other_xml_attribute:
1120 parser->other_xml.append((
const char *)(ch), len);
1136 switch (parser->get_state()) {
1137 case inside_other_xml_attribute:
1138 parser->other_xml.append((
const char *)(value), len);
1141 case parser_unknown:
1171 parser->push_state(parser_fatal_error);
1173 va_start(args, msg);
1175 vsnprintf(str, 1024, msg, args);
1178 int line = xmlSAX2GetLineNumber(parser->d_context);
1180 if (!parser->d_error_msg.empty())
1181 parser->d_error_msg +=
"\n";
1182 parser->d_error_msg +=
"At line " +
long_to_string(line) +
": " + string(str);
1189 parser->push_state(parser_error);
1191 va_start(args, msg);
1193 vsnprintf(str, 1024, msg, args);
1196 int line = xmlSAX2GetLineNumber(parser->d_context);
1198 if (!parser->d_error_msg.empty())
1199 parser->d_error_msg +=
"\n";
1200 parser->d_error_msg +=
"At line " +
long_to_string(line) +
": " + string(str);
1207void D4ParserSax2::cleanup_parse() {
1208 bool wellFormed = d_context->wellFormed;
1209 bool valid = d_context->valid;
1212 xmlFreeParserCtxt(d_context);
1222 while (!btp_stack.empty()) {
1223 delete top_basetype();
1228 throw Error(
"The DMR was not well formed. " + d_error_msg);
1230 throw Error(
"The DMR was not valid." + d_error_msg);
1231 else if (get_state() == parser_error)
1232 throw Error(d_error_msg);
1233 else if (get_state() == parser_fatal_error)
1234 throw InternalErr(d_error_msg);
1257 throw Error(
"Input stream not open or read error");
1259 throw InternalErr(__FILE__, __LINE__,
"DMR object is null");
1268 if (line.length() == 0)
throw Error(
"No input found while parsing the DMR.");
1270 if (debug) cerr <<
"line: (" << line_num <<
"): " << endl << line << endl << endl;
1272 d_context = xmlCreatePushParserCtxt(&d_dmr_sax_parser,
this, line.c_str(), line.length(),
"stream");
1273 d_context->validate =
true;
1274 push_state(parser_start);
1280 if (debug) cerr <<
"line: (" << line_num <<
"): " << endl << line << endl << endl;
1282 while (!f.eof() && (get_state() != parser_end)) {
1283 xmlParseChunk(d_context, line.c_str(), line.length(), 0);
1289 if (debug) cerr <<
"line: (" << line_num <<
"): " << endl << line << endl << endl;
1292 xmlParseChunk(d_context, line.c_str(), 0, 1);
1300 if (line.length() == 0)
1301 throw Error(
"No input found while parsing the DMR.");
1304 cerr <<
"line: (" << line_num <<
"): " << endl << line << endl << endl;
1306 d_context = xmlCreatePushParserCtxt(&d_dmr_sax_parser,
this, line.c_str(), line.length(),
"stream");
1307 d_context->validate =
true;
1308 push_state(parser_start);
1311 long chunk_count = 0;
1312 long chunk_size = 0;
1315 chunk_size = f.gcount();
1316 d_parse_buffer[chunk_size] =
1319 cerr <<
"chunk: (" << chunk_count++ <<
"): " << endl << d_parse_buffer << endl << endl;
1321 while (!f.eof() && (get_state() != parser_end)) {
1323 xmlParseChunk(d_context, d_parse_buffer, chunk_size, 0);
1327 chunk_size = f.gcount();
1328 d_parse_buffer[chunk_size] = 0;
1331 cerr <<
"chunk: (" << chunk_count++ <<
"): " << endl << d_parse_buffer << endl << endl;
1335 xmlParseChunk(d_context, d_parse_buffer, chunk_size, 1 );
1358 intern(document.c_str(), document.length(), dest_dmr, debug);
1380 throw InternalErr(__FILE__, __LINE__,
"DMR object is null");
1383 push_state(parser_start);
1384 d_context = xmlCreatePushParserCtxt(&d_dmr_sax_parser,
this, buffer, size,
"stream");
1385 d_context->validate =
true;
1388 xmlParseChunk(d_context, buffer, 0, 1 );
#define D4_PARSE_BUFF_SIZE
A multidimensional array of identical data types.
void add_var_nocopy(BaseType *v, Part p=nil) override
The basic data type for the DODS DAP types.
virtual D4Attributes * attributes()
virtual void add_var_nocopy(BaseType *bt, Part part=nil)
virtual Type type() const
Returns the type of the class instance.
void add_value(const string &value)
D4Attribute * get(const string &fqn)
void add_attribute_nocopy(D4Attribute *attr)
void add_dim_nocopy(D4Dimension *dim)
void add_enum_nocopy(D4EnumDef *enum_def)
D4Dimensions * dims()
Get the dimensions defined for this Group.
D4EnumDefs * enum_defs()
Get the enumerations defined for this Group.
void intern(istream &f, DMR *dest_dmr, bool debug=false)
void set_dap_version(const std::string &version_string)
void set_name(const std::string &n)
void set_dmr_version(const std::string &v)
void set_namespace(const std::string &ns)
Set the namespace for this DMR.
void set_request_xml_base(const std::string &xb)
static std::string getDapNamespaceString(DAPVersion version)
A class for error processing.
A class for software fault reporting.
static void dmr_start_document(void *parser)
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)
static void dmr_error(void *parser, const char *msg,...)
static void dmr_end_element(void *parser, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI)
static void dmr_get_characters(void *parser, const xmlChar *ch, int len)
static void dmr_end_document(void *parser)
static void dmr_get_cdata(void *parser, const xmlChar *value, int len)
static xmlEntityPtr dmr_get_entity(void *parser, const xmlChar *name)
static void dmr_fatal_error(void *parser, const char *msg,...)
top level DAP object to house generic methods
Type
Identifies the data type.
string long_to_string(long val, int base)
D4AttributeType StringToD4AttributeType(string s)
bool is_simple_type(Type t)
Returns true if the instance is a numeric, string or URL type variable.
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_vector_type(Type t)
Returns true if the instance is a vector (i.e., array) type variable.
bool is_integer_type(Type t)
ObjectType get_type(const string &value)