38 "$Id: AttrTable.cc 25066 2011-11-30 18:39:37Z jimg $";
52 #define WWW_ENCODING 0
62 static string remove_space_encoding(
const string &s)
64 string::size_type pos = s.find(
"%20");
65 if (pos != string::npos) {
68 n.replace(pos, 3,
" ");
70 }
while (pos != string::npos);
79 static string add_space_encoding(
const string &s)
81 string::size_type pos = s.find(
" ");
82 if (pos != string::npos) {
85 n.replace(pos, 1,
"%20");
87 }
while (pos != string::npos);
133 if (s2 ==
"container")
135 else if (s2 ==
"byte")
137 else if (s2 ==
"int16")
139 else if (s2 ==
"uint16")
141 else if (s2 ==
"int32")
143 else if (s2 ==
"uint32")
145 else if (s2 ==
"float32")
147 else if (s2 ==
"float64")
149 else if (s2 ==
"string")
151 else if (s2 ==
"url")
153 else if (s2 ==
"otherxml")
164 d_is_global_attribute = at.d_is_global_attribute;
173 for (; i != ie; ++i) {
176 attr_map.push_back(e);
191 DapObj(), d_name(
""), d_parent(0), attr_map(), d_is_global_attribute(true)
202 void AttrTable::delete_attr_table()
204 for (
Attr_iter i = attr_map.begin(); i != attr_map.end(); ++i) {
213 DBG(cerr <<
"Entering ~AttrTable (" <<
this <<
")" << endl);
215 DBG(cerr <<
"Exiting ~AttrTable" << endl);
237 return attr_map.size();
254 d_name = remove_space_encoding(n);
262 static void add_bad_attribute(
AttrTable *attr,
const string &type,
const string &name,
const string &value,
273 if (attr->
get_name().find(
"_dods_errors") != string::npos) {
278 string error_cont_name = attr->
get_name() +
"_dods_errors";
285 #ifndef ATTR_STRING_QUOTE_FIX
286 error_cont->append_attr(name +
"_dap_explanation",
"String",
"\"" + msg +
"\"");
288 error_cont->append_attr(name +
"_dap_explanation",
"String", msg);
313 DBG(cerr <<
"Entering AttrTable::append_attr" << endl);
315 string lname =
www2id(name);
317 string lname = remove_space_encoding(name);
325 throw Error(
string(
"An attribute called `") + name +
string(
"' already exists but is of a different type"));
326 if (iter != attr_map.end() && (
get_type(iter) ==
"Container"))
327 throw Error(
string(
"An attribute called `") + name +
string(
"' already exists but is a container."));
329 if (iter != attr_map.end()) {
330 (*iter)->attr->push_back(value);
331 return (*iter)->attr->size();
339 e->
attr =
new vector<string> ;
340 e->
attr->push_back(value);
342 attr_map.push_back(e);
344 return e->
attr->size();
368 DBG(cerr <<
"Entering AttrTable::append_attr(..., vector)" << endl);
370 string lname =
www2id(name);
372 string lname = remove_space_encoding(name);
379 throw Error(
string(
"An attribute called `") + name +
string(
"' already exists but is of a different type"));
380 if (iter != attr_map.end() && (
get_type(iter) ==
"Container"))
381 throw Error(
string(
"An attribute called `") + name +
string(
"' already exists but is a container."));
383 if (iter != attr_map.end()) {
384 vector<string>::iterator i = values->begin();
385 while (i != values->end())
386 (*iter)->attr->push_back(*i++);
388 return (*iter)->attr->size();
396 e->
attr =
new vector<string> (*values);
398 attr_map.push_back(e);
400 return e->
attr->size();
447 string lname =
www2id(name);
449 string lname = remove_space_encoding(name);
454 string(
"There already exists a container called `") + name +
string(
"' in this attribute table. (1)"));
455 DBG(cerr <<
"Setting appended attribute container name to: "
465 attr_map.push_back(e);
488 string::size_type dotpos = target.rfind(
'.');
489 if (dotpos != string::npos) {
490 string container = target.substr(0, dotpos);
491 string field = target.substr(dotpos + 1);
495 *iter = (*at)->simple_find(field);
498 *iter = attr_map.end();
522 if (target == (*i)->name) {
549 for (i = attr_map.begin(); i != attr_map.end(); ++i) {
550 if (target == (*i)->name) {
573 string::size_type dotpos = target.
find(
'.');
574 if (dotpos != string::npos) {
575 string container = target.substr(0, dotpos);
576 string field = target.substr(dotpos + 1);
593 for (
Attr_iter i = attr_map.begin(); i != attr_map.end(); ++i) {
595 return (*i)->attributes;
621 return (p != attr_map.end()) ?
get_type(p) : (string)
"";
642 return (iter != attr_map.end()) ?
get_attr_num(iter) : 0;
683 string lname =
www2id(name);
685 string lname = remove_space_encoding(name);
689 if (iter != attr_map.end()) {
692 attr_map.erase(iter);
702 vector<string> *sxp = (*iter)->
attr;
704 assert(i >= 0 && i < (
int) sxp->size());
705 sxp->erase(sxp->begin() + i);
718 return attr_map.begin();
726 return attr_map.end();
739 return attr_map.begin() + i;
745 assert(iter != attr_map.end());
747 return (*iter)->name;
764 assert(iter != attr_map.end());
784 struct entry* e = *iter;
792 return attr_map.erase(iter);
800 assert(iter != attr_map.end());
809 return (*iter)->type;
821 assert(iter != attr_map.end());
822 return ((*iter)->type ==
Attr_container) ? (*iter)->attributes->get_size() : (*iter)->attr->size();
843 assert(iter != attr_map.end());
845 return (*iter)->type ==
Attr_container ? (
string)
"None" : (*(*iter)->attr)[i];
851 return (p != attr_map.end()) ?
get_attr(p, i) : (string)
"";
868 assert(iter != attr_map.end());
874 assert(iter != attr_map.end());
876 return (*iter)->attributes->is_global_attribute();
878 return (*iter)->is_global;
883 assert(iter != attr_map.end());
885 (*iter)->attributes->set_is_global_attribute(ga);
887 (*iter)->is_global = ga;
901 string lname =
www2id(name);
903 string lname = remove_space_encoding(name);
907 throw Error(
string(
"There already exists a container called `") + name +
string(
"in this attribute table. (2)"));
917 attr_map.push_back(e);
935 string lname =
www2id(name);
937 string lname = remove_space_encoding(name);
941 string lsource =
www2id(source);
943 string lsource = remove_space_encoding(source);
951 das->
find(lsource, &at, &iter);
957 if (!at || (iter == at->
attr_end()) || !*iter) {
958 find(lsource, &at, &iter);
959 if (!at || (iter == at->
attr_end()) || !*iter)
960 throw Error(
string(
"Could not find the attribute `") + source +
string(
"' in the attribute object."));
968 "A value cannot be aliased to the top level of the DAS;\nOnly containers may be present at that level of the DAS."));
971 throw Error(
string(
"There already exists a container called `") + name + string(
"in this attribute table. (3)"));
981 e->
attr = (*iter)->attr;
983 attr_map.push_back(e);
1028 for (
Attr_iter i = attr_map.begin(); i != attr_map.end(); ++i) {
1033 attr_map.erase(attr_map.begin(), attr_map.end());
1051 static void write_string_attribute_for_das(ostream &out,
const string &value,
const string &term)
1054 out << value << term;
1061 write_string_attribute_for_das(FILE *out,
const string &value,
const string &term)
1064 fprintf(out,
"%s%s", value.c_str(), term.c_str());
1066 fprintf(out,
"\"%s\"%s", value.c_str(), term.c_str());
1072 static void write_xml_attribute_for_das(ostream &out,
const string &value,
const string &term)
1082 write_xml_attribute_for_das(FILE *out,
const string &value,
const string &term)
1097 fwrite(oss.str().data(), 1, oss.str().length(), out);
1100 switch ((*i)->type) {
1103 fprintf(out,
"%s%s {\n", pad.c_str(),
id2www(
get_name(i)).c_str());
1105 fprintf(out,
"%s%s {\n", pad.c_str(),
get_name(i).c_str());
1107 (*i)->attributes->print(out, pad +
" ", dereference);
1109 fprintf(out,
"%s}\n", pad.c_str());
1116 fprintf(out,
"%s%s %s ", pad.c_str(),
get_type(i).c_str(),
get_name(i).c_str());
1118 vector<string> *sxp = (*i)->attr;
1119 vector<string>::iterator last = sxp->end() - 1;
1120 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
1121 write_string_attribute_for_das(out, *i,
", ");
1123 write_string_attribute_for_das(out, *last,
";\n");
1131 fprintf(out,
"%s%s %s ", pad.c_str(),
get_type(i).c_str(),
get_name(i).c_str());
1133 vector<string> *sxp = (*i)->attr;
1134 vector<string>::iterator last = sxp->end() - 1;
1135 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
1136 write_xml_attribute_for_das(out, *i,
", ");
1138 write_xml_attribute_for_das(out, *last,
";\n");
1146 fprintf(out,
"%s%s %s ", pad.c_str(),
get_type(i).c_str(),
get_name(i).c_str());
1149 vector<string> *sxp = (*i)->attr;
1150 vector<string>::iterator last = sxp->end() - 1;
1151 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
1152 fprintf(out,
"%s%s", (*i).c_str(),
", ");
1154 fprintf(out,
"%s%s", (*last).c_str(),
";\n");
1165 switch ((*i)->type) {
1170 out << pad << add_space_encoding(
get_name(i)) <<
" {\n";
1172 (*i)->attributes->print(out, pad +
" ", dereference);
1173 out << pad <<
"}\n";
1180 out << pad <<
get_type(i) <<
" " << add_space_encoding(
get_name(i)) <<
" ";
1182 vector<string> *sxp = (*i)->attr;
1183 vector<string>::iterator last = sxp->end() - 1;
1184 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
1185 write_string_attribute_for_das(out, *i,
", ");
1187 write_string_attribute_for_das(out, *last,
";\n");
1195 out << pad <<
get_type(i) <<
" " << add_space_encoding(
get_name(i)) <<
" ";
1197 vector<string> *sxp = (*i)->attr;
1198 vector<string>::iterator last = sxp->end() - 1;
1199 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
1200 write_xml_attribute_for_das(out, *i,
", ");
1202 write_xml_attribute_for_das(out, *last,
";\n");
1210 out << pad <<
get_type(i) <<
" " << add_space_encoding(
get_name(i)) <<
" ";
1212 vector<string> *sxp = (*i)->attr;
1213 vector<string>::iterator last = sxp->end() - 1;
1214 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
1217 out << *last <<
";\n";
1236 print(oss, pad, dereference);
1237 fwrite(oss.str().data(), 1, oss.str().length(), out);
1240 for (
Attr_iter i = attr_map.begin(); i != attr_map.end(); ++i) {
1241 if ((*i)->is_alias) {
1247 fprintf(out,
"%sAlias %s %s;\n",
1250 id2www((*i)->aliased_to).c_str());
1252 fprintf(out,
"%sAlias %s %s;\n",
1253 pad.c_str(), add_space_encoding(
get_name(i)).c_str(), add_space_encoding((*i)->aliased_to).c_str());
1277 for (
Attr_iter i = attr_map.begin(); i != attr_map.end(); ++i) {
1278 if ((*i)->is_alias) {
1285 <<
" " <<
id2www((*i)->aliased_to) <<
";\n";
1287 out << pad <<
"Alias " << add_space_encoding(
get_name(i)) <<
" "
1288 << add_space_encoding((*i)->aliased_to) <<
";\n";
1307 fwrite(oss.str().data(), 1, oss.str().length(), out);
1319 if ((*i)->is_alias) {
1320 fprintf(out,
"%s<Alias name=\"%s\" Attribute=\"%s\"/>\n",
1322 (*i)->aliased_to.c_str());
1326 fprintf(out,
"%s<Attribute name=\"%s\" type=\"%s\">\n",
1332 fprintf(out,
"%s</Attribute>\n", pad.c_str());
1335 fprintf(out,
"%s<Attribute name=\"%s\" type=\"%s\">\n",
1338 string value_pad = pad +
" ";
1344 throw Error(
"OtherXML attributes cannot be vector-valued.");
1345 fprintf(out,
"%s%s\n", value_pad.c_str(),
get_attr(i, 0).c_str());
1349 fprintf(out,
"%s<value>%s</value>\n", value_pad.c_str(),
1353 fprintf(out,
"%s</Attribute>\n", pad.c_str());
1370 if ((*i)->is_alias) {
1372 <<
"\" Attribute=\"" << (*i)->aliased_to <<
"\"/>\n";
1377 <<
"\" type=\"" <<
get_type(i) <<
"\">\n";
1381 out << pad <<
"</Attribute>\n";
1385 <<
"\" type=\"" <<
get_type(i) <<
"\">\n";
1387 string value_pad = pad +
" ";
1390 throw Error(
"OtherXML attributes cannot be vector-valued.");
1391 out << value_pad <<
get_attr(i, 0) <<
"\n";
1394 string value_pad = pad +
" ";
1396 out << value_pad <<
"<value>" <<
id2xml(
get_attr(i, j)) <<
"</value>\n";
1399 out << pad <<
"</Attribute>\n";
1412 if ((*i)->is_alias) {
1413 if (xmlTextWriterStartElement(xml.
get_writer(), (
const xmlChar*)
"Alias") < 0)
1414 throw InternalErr(__FILE__, __LINE__,
"Could not write Alias element");
1415 if (xmlTextWriterWriteAttribute(xml.
get_writer(), (
const xmlChar*)
"name",
1416 (
const xmlChar*)
get_name(i).c_str()) < 0)
1417 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1418 if (xmlTextWriterWriteAttribute(xml.
get_writer(), (
const xmlChar*)
"Attribute",
1419 (
const xmlChar*) (*i)->aliased_to.c_str()) < 0)
1420 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1421 if (xmlTextWriterEndElement(xml.
get_writer()) < 0)
1422 throw InternalErr(__FILE__, __LINE__,
"Could not end Alias element");
1425 if (xmlTextWriterStartElement(xml.
get_writer(), (
const xmlChar*)
"Attribute") < 0)
1426 throw InternalErr(__FILE__, __LINE__,
"Could not write Attribute element");
1427 if (xmlTextWriterWriteAttribute(xml.
get_writer(), (
const xmlChar*)
"name",
1428 (
const xmlChar*)
get_name(i).c_str()) < 0)
1429 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1430 if (xmlTextWriterWriteAttribute(xml.
get_writer(), (
const xmlChar*)
"type",
1431 (
const xmlChar*)
get_type(i).c_str()) < 0)
1432 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1436 if (xmlTextWriterEndElement(xml.
get_writer()) < 0)
1437 throw InternalErr(__FILE__, __LINE__,
"Could not end Attribute element");
1440 if (xmlTextWriterStartElement(xml.
get_writer(), (
const xmlChar*)
"Attribute") < 0)
1441 throw InternalErr(__FILE__, __LINE__,
"Could not write Attribute element");
1442 if (xmlTextWriterWriteAttribute(xml.
get_writer(), (
const xmlChar*)
"name",
1443 (
const xmlChar*)
get_name(i).c_str()) < 0)
1444 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1445 if (xmlTextWriterWriteAttribute(xml.
get_writer(), (
const xmlChar*)
"type",
1446 (
const xmlChar*)
get_type(i).c_str()) < 0)
1447 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute for name");
1451 throw Error(
"OtherXML attributes cannot be vector-valued.");
1455 if (xmlTextWriterWriteRaw(xml.
get_writer(), (
const xmlChar*)
get_attr(i, 0).c_str()) < 0)
1456 throw InternalErr(__FILE__, __LINE__,
"Could not write OtherXML value");
1460 if (xmlTextWriterStartElement(xml.
get_writer(), (
const xmlChar*)
"value") < 0)
1461 throw InternalErr(__FILE__, __LINE__,
"Could not write value element");
1463 if (xmlTextWriterWriteString(xml.
get_writer(), (
const xmlChar*)
get_attr(i, j).c_str()) < 0)
1464 throw InternalErr(__FILE__, __LINE__,
"Could not write attribute value");
1466 if (xmlTextWriterEndElement(xml.
get_writer()) < 0)
1467 throw InternalErr(__FILE__, __LINE__,
"Could not end value element");
1470 if (xmlTextWriterEndElement(xml.
get_writer()) < 0)
1471 throw InternalErr(__FILE__, __LINE__,
"Could not end Attribute element");
1485 strm <<
DapIndent::LMarg <<
"AttrTable::dump - (" << (
void *)
this <<
")" << endl;
1488 if (attr_map.size()) {
1490 DapIndent::Indent();
1493 for (; i != ie; ++i) {
1501 DapIndent::Indent();
1507 DapIndent::Indent();
1509 vector<string>::const_iterator iter = e->
attr->begin();
1510 vector<string>::const_iterator last = e->
attr->end() - 1;
1511 for (; iter != last; ++iter) {
1512 strm << (*iter) <<
", ";
1514 strm << (*(e->
attr->end() - 1)) << endl;
1524 strm <<
DapIndent::LMarg <<
"parent table:" << d_name <<
":" << (
void *) d_parent << endl;