36 #include <libxml/parserInternals.h>
56 static const char *states[] = {
65 "inside_attribute_container",
67 "inside_attribute_value",
68 "inside_other_xml_attribute",
91 static bool is_not(
const char *name,
const char *tag)
93 return strcmp(name, tag) != 0;
105 D4ParserSax2::enum_def()
107 if (!d_enum_def) d_enum_def =
new D4EnumDef;
119 D4ParserSax2::dim_def() {
120 if (!d_dim_def) d_dim_def =
new D4Dimension;
130 void D4ParserSax2::transfer_xml_attrs(
const xmlChar **attributes,
int nb_attributes)
132 if (!xml_attrs.empty())
137 unsigned int index = 0;
138 for (
int i = 0; i < nb_attributes; ++i, index += 5) {
139 xml_attrs.insert(map<string, XMLAttribute>::value_type(
string((
const char *)attributes[index]),
140 XMLAttribute(attributes + index + 1)));
142 DBG(cerr <<
"XML Attribute '" << (
const char *)attributes[index] <<
"': "
143 << xml_attrs[(
const char *)attributes[index]].value << endl);
153 void D4ParserSax2::transfer_xml_ns(
const xmlChar **namespaces,
int nb_namespaces)
156 for (
int i = 0; i < nb_namespaces; ++i) {
157 namespace_table.insert(map<string, string>::value_type(namespaces[i * 2] != 0 ? (
const char *)namespaces[i * 2] :
"",
158 (
const char *)namespaces[i * 2 + 1]));
168 bool D4ParserSax2::check_required_attribute(
const string & attr)
170 if (xml_attrs.find(attr) == xml_attrs.end()) {
171 dmr_error(
this,
"Required attribute '%s' not found.", attr.c_str());
184 bool D4ParserSax2::check_attribute(
const string & attr)
186 return (xml_attrs.find(attr) != xml_attrs.end());
189 bool D4ParserSax2::process_dimension_def(
const char *name,
const xmlChar **attrs,
int nb_attributes)
191 if (is_not(name,
"Dimension"))
194 transfer_xml_attrs(attrs, nb_attributes);
196 if (!(check_required_attribute(
"name") && check_required_attribute(
"size"))) {
197 dmr_error(
this,
"The required attribute 'name' or 'size' was missing from a Dimension element.");
202 dim_def()->
set_name(xml_attrs[
"name"].value);
204 dim_def()->
set_size(xml_attrs[
"size"].value);
207 dmr_error(
this, e.get_error_message().c_str());
231 bool D4ParserSax2::process_dimension(
const char *name,
const xmlChar **attrs,
int nb_attributes)
233 if (is_not(name,
"Dim"))
236 transfer_xml_attrs(attrs, nb_attributes);
238 if (check_attribute(
"size") && check_attribute(
"name")) {
239 dmr_error(
this,
"Only one of 'size' and 'name' are allowed in a Dim element, but both were used.");
242 if (!(check_attribute(
"size") || check_attribute(
"name"))) {
243 dmr_error(
this,
"Either 'size' or 'name' must be used in a Dim element.");
249 BaseType *b = top_basetype();
253 a->set_is_dap4(
true);
254 a->add_var_nocopy(b);
255 a->set_attributes_nocopy(b->attributes());
259 b->set_attributes_nocopy(0);
266 Array *a =
static_cast<Array*
>(top_basetype());
267 if (check_attribute(
"size")) {
268 a->append_dim(atoi(xml_attrs[
"size"].value.c_str()));
271 else if (check_attribute(
"name")) {
272 string name = xml_attrs[
"name"].value;
274 D4Dimension *dim = 0;
281 throw Error(
"The dimension '" + name +
"' was not found while parsing the variable '" + a->name() +
"'.");
289 bool D4ParserSax2::process_map(
const char *name,
const xmlChar **attrs,
int nb_attributes)
291 if (is_not(name,
"Map"))
294 transfer_xml_attrs(attrs, nb_attributes);
296 if (!check_attribute(
"name")) {
297 dmr_error(
this,
"The 'name' attribute must be used in a Map element.");
303 BaseType *b = top_basetype();
307 a->set_is_dap4(
true);
308 a->add_var_nocopy(b);
309 a->set_attributes_nocopy(b->attributes());
313 b->set_attributes_nocopy(0);
320 Array *a =
static_cast<Array*
>(top_basetype());
322 string map_name = xml_attrs[
"name"].value;
323 if (xml_attrs[
"name"].value[0] !=
'/')
324 map_name = top_group()->
FQN() + map_name;
326 Array *map_source = 0;
328 if (map_name[0] ==
'/')
334 throw Error(
"The Map '" + map_name +
"' was not found while parsing the variable '" + a->name() +
"'.");
336 a->
maps()->
add_map(
new D4Map(map_name, map_source));
341 bool D4ParserSax2::process_group(
const char *name,
const xmlChar **attrs,
int nb_attributes)
343 if (is_not(name,
"Group"))
346 transfer_xml_attrs(attrs, nb_attributes);
348 if (!check_required_attribute(
"name")) {
349 dmr_error(
this,
"The required attribute 'name' was missing from a Group element.");
355 dmr_fatal_error(
this,
"Could not instantiate the Group '%s'.", xml_attrs[
"name"].value.c_str());
359 D4Group *grp =
static_cast<D4Group*
>(btp);
363 grp->set_is_dap4(
true);
366 D4Group *parent = top_group();
372 grp->set_parent(parent);
373 parent->add_group_nocopy(grp);
376 push_attributes(grp->attributes());
386 inline bool D4ParserSax2::process_attribute(
const char *name,
const xmlChar **attrs,
int nb_attributes)
388 if (is_not(name,
"Attribute"))
392 transfer_xml_attrs(attrs, nb_attributes);
395 if (!(check_required_attribute(
string(
"name")) && check_required_attribute(
string(
"type")))) {
396 dmr_error(
this,
"The required attribute 'name' or 'type' was missing from an Attribute element.");
400 if (xml_attrs[
"type"].value ==
"Container") {
401 push_state(inside_attribute_container);
403 DBG(cerr <<
"Pushing attribute container " << xml_attrs[
"name"].value << endl);
404 D4Attribute *child =
new D4Attribute(xml_attrs[
"name"].value,
attr_container_c);
406 D4Attributes *tos = top_attributes();
409 dmr_fatal_error(
this,
"Expected an Attribute container on the top of the attribute stack.");
413 tos->add_attribute_nocopy(child);
414 push_attributes(child->attributes());
416 else if (xml_attrs[
"type"].value ==
"OtherXML") {
417 push_state(inside_other_xml_attribute);
419 dods_attr_name = xml_attrs[
"name"].value;
420 dods_attr_type = xml_attrs[
"type"].value;
423 push_state(inside_attribute);
425 dods_attr_name = xml_attrs[
"name"].value;
426 dods_attr_type = xml_attrs[
"type"].value;
437 inline bool D4ParserSax2::process_enum_def(
const char *name,
const xmlChar **attrs,
int nb_attributes)
439 if (is_not(name,
"Enumeration"))
442 transfer_xml_attrs(attrs, nb_attributes);
444 if (!(check_required_attribute(
"name") && check_required_attribute(
"basetype"))) {
445 dmr_error(
this,
"The required attribute 'name' or 'basetype' was missing from an Enumeration element.");
451 dmr_error(
this,
"The Enumeration '%s' must have an integer type, instead the type '%s' was used.",
452 xml_attrs[
"name"].value.c_str(), xml_attrs[
"basetype"].value.c_str());
457 string enum_def_path = xml_attrs[
"name"].value;
460 if (xml_attrs[
"name"].value[0] !=
'/')
461 enum_def_path = top_group()->
FQN() + enum_def_path;
463 enum_def()->
set_name(enum_def_path);
469 inline bool D4ParserSax2::process_enum_const(
const char *name,
const xmlChar **attrs,
int nb_attributes)
471 if (is_not(name,
"EnumConst"))
475 transfer_xml_attrs(attrs, nb_attributes);
477 if (!(check_required_attribute(
"name") && check_required_attribute(
"value"))) {
478 dmr_error(
this,
"The required attribute 'name' or 'value' was missing from an EnumConst element.");
482 istringstream iss(xml_attrs[
"value"].value);
484 iss >> skipws >> value;
485 if (iss.fail() || iss.bad()) {
486 dmr_error(
this,
"Expected an integer value for an Enumeration constant, got '%s' instead.",
487 xml_attrs[
"value"].value.c_str());
490 dmr_error(
this,
"In an Enumeration constant, the value '%s' cannot fit in a variable of type '%s'.",
491 xml_attrs[
"value"].value.c_str(),
D4type_name(d_enum_def->
type()).c_str());
495 enum_def()->
add_value(xml_attrs[
"name"].value, value);
506 inline bool D4ParserSax2::process_variable(
const char *name,
const xmlChar **attrs,
int nb_attributes)
510 process_variable_helper(t, inside_simple_type, attrs, nb_attributes);
516 process_variable_helper(t, inside_constructor, attrs, nb_attributes);
520 process_variable_helper(t, inside_constructor, attrs, nb_attributes);
536 void D4ParserSax2::process_variable_helper(
Type t, ParseState s,
const xmlChar **attrs,
int nb_attributes)
538 transfer_xml_attrs(attrs, nb_attributes);
540 if (check_required_attribute(
"name")) {
543 dmr_fatal_error(
this,
"Could not instantiate the variable '%s'.", xml_attrs[
"name"].value.c_str());
547 if ((t ==
dods_enum_c) && check_required_attribute(
"enum")) {
548 D4EnumDef *enum_def = 0;
549 string enum_path = xml_attrs[
"enum"].value;
550 if (enum_path[0] ==
'/')
556 dmr_fatal_error(
this,
"Could not find the Enumeration definition '%s'.", enum_path.c_str());
558 static_cast<D4Enum*
>(btp)->set_enumeration(enum_def);
561 btp->set_is_dap4(
true);
564 push_attributes(btp->attributes());
584 parser->error_msg =
"";
585 parser->char_data =
"";
594 if (parser->debug()) cerr <<
"Parser start state: " << states[parser->get_state()] << endl;
603 if (parser->debug()) cerr <<
"Parser end state: " << states[parser->get_state()] << endl;
605 if (parser->get_state() != parser_end)
610 if (parser->get_state() == parser_error || parser->get_state() == parser_fatal_error)
613 if (!parser->empty_basetype() || parser->empty_group())
614 D4ParserSax2::dmr_error(parser,
"The document did not contain a valid root Group or contained unbalanced tags.");
617 parser->pop_attributes();
621 int nb_namespaces,
const xmlChar **namespaces,
int nb_attributes,
int ,
622 const xmlChar **attributes)
625 const char *localname = (
const char *) l;
627 if (parser->debug()) cerr <<
"Start element " << localname <<
" (state " << states[parser->get_state()] <<
")" << endl;
629 switch (parser->get_state()) {
631 if (is_not(localname,
"Dataset"))
632 D4ParserSax2::dmr_error(parser,
"Expected DMR to start with a Dataset element; found '%s' instead.", localname);
634 parser->root_ns = URI ? (
const char *) URI :
"";
635 parser->transfer_xml_attrs(attributes, nb_attributes);
637 if (parser->check_required_attribute(
string(
"name")))
638 parser->dmr()->
set_name(parser->xml_attrs[
"name"].value);
640 if (parser->check_attribute(
"dapVersion"))
643 if (parser->check_attribute(
"dmrVersion"))
646 if (parser->check_attribute(
"base"))
649 if (!parser->root_ns.empty())
653 parser->push_group(parser->dmr()->
root());
655 parser->push_state(inside_dataset);
664 if (parser->process_enum_def(localname, attributes, nb_attributes))
665 parser->push_state(inside_enum_def);
666 else if (parser->process_dimension_def(localname, attributes, nb_attributes))
667 parser->push_state(inside_dim_def);
668 else if (parser->process_group(localname, attributes, nb_attributes))
669 parser->push_state(inside_group);
670 else if (parser->process_variable(localname, attributes, nb_attributes))
674 else if (parser->process_attribute(localname, attributes, nb_attributes))
679 D4ParserSax2::dmr_error(parser,
"Expected an Attribute, Enumeration, Dimension, Group or variable element; found '%s' instead.", localname);
682 case inside_attribute_container:
683 if (parser->process_attribute(localname, attributes, nb_attributes))
689 case inside_attribute:
690 if (parser->process_attribute(localname, attributes, nb_attributes))
692 else if (strcmp(localname,
"Value") == 0)
693 parser->push_state(inside_attribute_value);
695 dmr_error(parser,
"Expected an 'Attribute' or 'Value' element; found '%s' instead.", localname);
698 case inside_attribute_value:
702 case inside_other_xml_attribute:
703 parser->other_xml_depth++;
706 parser->other_xml.append(
"<");
708 parser->other_xml.append((
const char *) prefix);
709 parser->other_xml.append(
":");
711 parser->other_xml.append(localname);
713 if (nb_namespaces != 0) {
714 parser->transfer_xml_ns(namespaces, nb_namespaces);
716 for (map<string, string>::iterator i = parser->namespace_table.begin();
717 i != parser->namespace_table.end(); ++i) {
718 parser->other_xml.append(
" xmlns");
719 if (!i->first.empty()) {
720 parser->other_xml.append(
":");
721 parser->other_xml.append(i->first);
723 parser->other_xml.append(
"=\"");
724 parser->other_xml.append(i->second);
725 parser->other_xml.append(
"\"");
729 if (nb_attributes != 0) {
730 parser->transfer_xml_attrs(attributes, nb_attributes);
731 for (XMLAttrMap::iterator i = parser->xml_attr_begin(); i != parser->xml_attr_end(); ++i) {
732 parser->other_xml.append(
" ");
733 if (!i->second.prefix.empty()) {
734 parser->other_xml.append(i->second.prefix);
735 parser->other_xml.append(
":");
737 parser->other_xml.append(i->first);
738 parser->other_xml.append(
"=\"");
739 parser->other_xml.append(i->second.value);
740 parser->other_xml.append(
"\"");
744 parser->other_xml.append(
">");
747 case inside_enum_def:
749 if (parser->process_enum_const(localname, attributes, nb_attributes))
750 parser->push_state(inside_enum_const);
752 dmr_error(parser,
"Expected an 'EnumConst' element; found '%s' instead.", localname);
755 case inside_enum_const:
763 case inside_dimension:
775 case inside_simple_type:
776 if (parser->process_attribute(localname, attributes, nb_attributes))
778 else if (parser->process_dimension(localname, attributes, nb_attributes))
779 parser->push_state(inside_dim);
780 else if (parser->process_map(localname, attributes, nb_attributes))
781 parser->push_state(inside_map);
783 dmr_error(parser,
"Expected an 'Attribute', 'Dim' or 'Map' element; found '%s' instead.", localname);
786 case inside_constructor:
787 if (parser->process_variable(localname, attributes, nb_attributes))
791 else if (parser->process_attribute(localname, attributes, nb_attributes))
793 else if (parser->process_dimension(localname, attributes, nb_attributes))
794 parser->push_state(inside_dim);
795 else if (parser->process_map(localname, attributes, nb_attributes))
796 parser->push_state(inside_map);
798 D4ParserSax2::dmr_error(parser,
"Expected an Attribute, Dim, Map or variable element; found '%s' instead.", localname);
804 parser->push_state(parser_unknown);
808 case parser_fatal_error:
816 if (parser->debug()) cerr <<
"Start element exit state: " << states[parser->get_state()] << endl;
822 const char *localname = (
const char *) l;
824 if (parser->debug()) cerr <<
"End element " << localname <<
" (state " << states[parser->get_state()] <<
")" << endl;
826 switch (parser->get_state()) {
828 dmr_fatal_error(parser,
"Unexpected state, inside start state while processing element '%s'.", localname);
832 if (is_not(localname,
"Dataset"))
836 if (parser->get_state() != parser_start)
840 parser->push_state(parser_end);
845 if (is_not(localname,
"Group"))
848 if (!parser->empty_basetype() || parser->empty_group())
849 D4ParserSax2::dmr_error(parser,
"The document did not contain a valid root Group or contained unbalanced tags.");
856 case inside_attribute_container:
857 if (is_not(localname,
"Attribute"))
861 parser->pop_attributes();
864 case inside_attribute:
865 if (is_not(localname,
"Attribute"))
871 case inside_attribute_value: {
872 if (is_not(localname,
"Value"))
888 parser->char_data =
"";
892 case inside_other_xml_attribute: {
893 if (strcmp(localname,
"Attribute") == 0 && parser->root_ns == (
const char *) URI) {
907 parser->other_xml =
"";
910 if (parser->other_xml_depth == 0) {
914 parser->other_xml_depth--;
916 parser->other_xml.append(
"</");
918 parser->other_xml.append((
const char *) prefix);
919 parser->other_xml.append(
":");
921 parser->other_xml.append(localname);
922 parser->other_xml.append(
">");
927 case inside_enum_def:
928 if (is_not(localname,
"Enumeration"))
930 if (!parser->top_group())
937 parser->clear_enum_def();
942 case inside_enum_const:
943 if (is_not(localname,
"EnumConst"))
949 case inside_dim_def: {
950 if (is_not(localname,
"Dimension"))
953 if (!parser->top_group())
965 parser->clear_dim_def();
970 case inside_simple_type:
972 BaseType *btp = parser->top_basetype();
973 parser->pop_basetype();
974 parser->pop_attributes();
977 if (!parser->empty_basetype())
978 parent = parser->top_basetype();
979 else if (!parser->empty_group())
980 parent = parser->top_group();
982 dmr_fatal_error(parser,
"Both the Variable and Groups stacks are empty while closing a %s element.", localname);
997 if (parent && parent->is_constructor_type())
1001 "Tried to add the simple-type variable '%s' to a non-constructor type (%s %s).", localname,
1002 parser->top_basetype()->
type_name().c_str(), parser->top_basetype()->
name().c_str());
1014 if (is_not(localname,
"Dim"))
1017 parser->pop_state();
1021 if (is_not(localname,
"Map"))
1024 parser->pop_state();
1028 case inside_dimension:
1029 if (is_not(localname,
"dimension"))
1032 parser->pop_state();
1035 case inside_constructor: {
1036 if (strcmp(localname,
"Structure") != 0 && strcmp(localname,
"Sequence") != 0) {
1041 BaseType *btp = parser->top_basetype();
1042 parser->pop_basetype();
1043 parser->pop_attributes();
1046 if (!parser->empty_basetype())
1047 parent = parser->top_basetype();
1048 else if (!parser->empty_group())
1049 parent = parser->top_group();
1051 dmr_fatal_error(parser,
"Both the Variable and Groups stacks are empty while closing a %s element.", localname);
1058 parser->pop_state();
1062 case parser_unknown:
1063 parser->pop_state();
1067 case parser_fatal_error:
1075 if (parser->debug()) cerr <<
"End element exit state: " << states[parser->get_state()] << endl;
1081 void D4ParserSax2::dmr_get_characters(
void * p,
const xmlChar * ch,
int len)
1085 switch (parser->get_state()) {
1086 case inside_attribute_value:
1087 parser->char_data.append((
const char *) (ch), len);
1088 DBG(cerr <<
"Characters: '" << parser->char_data <<
"'" << endl);
1091 case inside_other_xml_attribute:
1092 parser->other_xml.append((
const char *) (ch), len);
1093 DBG(cerr <<
"Other XML Characters: '" << parser->other_xml <<
"'" << endl);
1105 void D4ParserSax2::dmr_ignoreable_whitespace(
void *p,
const xmlChar *ch,
int len)
1109 switch (parser->get_state()) {
1110 case inside_other_xml_attribute:
1111 parser->other_xml.append((
const char *) (ch), len);
1124 void D4ParserSax2::dmr_get_cdata(
void *p,
const xmlChar *value,
int len)
1128 switch (parser->get_state()) {
1129 case inside_other_xml_attribute:
1130 parser->other_xml.append((
const char *) (value), len);
1133 case parser_unknown:
1137 D4ParserSax2::dmr_error(parser,
"Found a CData block but none are allowed by DAP4.");
1147 xmlEntityPtr D4ParserSax2::dmr_get_entity(
void *,
const xmlChar * name)
1149 return xmlGetPredefinedEntity(name);
1162 void D4ParserSax2::dmr_fatal_error(
void * p,
const char *msg, ...)
1167 parser->push_state(parser_fatal_error);
1169 va_start(args, msg);
1171 vsnprintf(str, 1024, msg, args);
1174 int line = xmlSAX2GetLineNumber(parser->context);
1176 if (!parser->error_msg.empty()) parser->error_msg +=
"\n";
1177 parser->error_msg +=
"At line " +
long_to_string(line) +
": " + string(str);
1180 void D4ParserSax2::dmr_error(
void *p,
const char *msg, ...)
1185 parser->push_state(parser_error);
1187 va_start(args, msg);
1189 vsnprintf(str, 1024, msg, args);
1192 int line = xmlSAX2GetLineNumber(parser->context);
1194 if (!parser->error_msg.empty()) parser->error_msg +=
"\n";
1195 parser->error_msg +=
"At line " +
long_to_string(line) +
": " + string(str);
1202 void D4ParserSax2::cleanup_parse()
1204 bool wellFormed = context->wellFormed;
1205 bool valid = context->valid;
1207 context->sax = NULL;
1208 xmlFreeParserCtxt(context);
1218 while (!btp_stack.empty()) {
1219 delete top_basetype();
1224 throw Error(
"The DMR was not well formed. " + error_msg);
1226 throw Error(
"The DMR was not valid." + error_msg);
1227 else if (get_state() == parser_error)
1228 throw Error(error_msg);
1229 else if (get_state() == parser_fatal_error)
1230 throw InternalErr(error_msg);
1247 void D4ParserSax2::intern(istream &f,
DMR *dest_dmr,
bool debug)
1254 throw Error(
"Input stream not open or read error");
1256 throw InternalErr(__FILE__, __LINE__,
"DMR object is null");
1260 const int size = 1024;
1264 f.getline(chars, size);
1265 int res = f.gcount();
1266 if (res == 0)
throw Error(
"No input found while parsing the DMR.");
1268 if (debug) cerr <<
"line: (" << line++ <<
"): " << chars << endl;
1270 context = xmlCreatePushParserCtxt(&ddx_sax_parser,
this, chars, res - 1,
"stream");
1271 context->validate =
true;
1272 push_state(parser_start);
1274 f.getline(chars, size);
1275 while ((f.gcount() > 0) && (get_state() != parser_end)) {
1276 if (debug) cerr <<
"line: (" << line++ <<
"): " << chars << endl;
1277 xmlParseChunk(context, chars, f.gcount() - 1, 0);
1278 f.getline(chars, size);
1282 xmlParseChunk(context, chars, 0, 1);
1299 void D4ParserSax2::intern(
const string &document,
DMR *dest_dmr,
bool debug)
1301 intern(document.c_str(), document.length(), dest_dmr, debug);
1314 void D4ParserSax2::intern(
const char *buffer,
int size,
DMR *dest_dmr,
bool debug)
1316 if (!(size > 0))
return;
1322 if (!dest_dmr)
throw InternalErr(__FILE__, __LINE__,
"DMR object is null");
1325 push_state(parser_start);
1326 context = xmlCreatePushParserCtxt(&ddx_sax_parser,
this, buffer, size,
"stream");
1327 context->validate =
true;
1332 xmlParseChunk(context, buffer, 0, 1);
D4AttributeType StringToD4AttributeType(string s)
void add_value(const string &label, long long value)
void set_dmr_version(const string &v)
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)
void set_name(const string &n)
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)
bool is_vector_type(Type t)
Returns true if the instance is a vector (i.e., array) type variable.
Array * find_map_source(const string &path)
void set_size(unsigned long size)
void set_request_xml_base(const string &xb)
Type
Identifies the data type.
Type type() const
Returns the type of the class instance.
A class for software fault reporting.
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)
string type_name() const
Returns the type of the class instance as a string.
void add_dim_nocopy(D4Dimension *dim)
virtual D4BaseTypeFactory * factory()
D4EnumDef * find_enum_def(const string &path)
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...
static void dmr_end_element(void *parser, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI)
bool is_simple_type(Type t)
Returns true if the instance is a numeric, string or URL type variable.
virtual D4Attributes * attributes()
virtual void add_var_nocopy(BaseType *bt, Part part=nil)
string name() const
Returns the name of the class instance.
string long_to_string(long val, int base)
void add_attribute_nocopy(D4Attribute *attr)
void add_enum_nocopy(D4EnumDef *enum_def)
The basic data type for the DODS DAP types.
void set_dap_version(const string &version_string)
D4Attribute * get(const string &fqn)
A class for error processing.
void add_value(const string &value)
void set_name(const string &n)
virtual std::string FQN() const
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)
static void dmr_error(void *parser, const char *msg,...)
D4Dimensions * dims()
Get the dimensions defined for this Group.
virtual BaseType * NewVariable(Type t, const string &name) const
void set_name(const string &name)