00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "config.h"
00034
00035 static char rcsid[]not_used =
00036 "$Id: AttrTable.cc 21699 2009-11-05 00:06:01Z jimg $";
00037
00038 #include <cassert>
00039
00040 #include "AttrTable.h"
00041
00042 #include "util.h"
00043 #include "escaping.h"
00044
00045 #include "debug.h"
00046
00047 using std::cerr;
00048 using std::string;
00049 using std::endl;
00050 using std::vector;
00051
00052 namespace libdap {
00053
00057 string AttrType_to_String(const AttrType at)
00058 {
00059 switch (at) {
00060 case Attr_container:
00061 return "Container";
00062 case Attr_byte:
00063 return "Byte";
00064 case Attr_int16:
00065 return "Int16";
00066 case Attr_uint16:
00067 return "UInt16";
00068 case Attr_int32:
00069 return "Int32";
00070 case Attr_uint32:
00071 return "UInt32";
00072 case Attr_float32:
00073 return "Float32";
00074 case Attr_float64:
00075 return "Float64";
00076 case Attr_string:
00077 return "String";
00078 case Attr_url:
00079 return "Url";
00080 case Attr_other_xml:
00081 return "OtherXML";
00082 default:
00083 return "";
00084 }
00085 }
00086
00087 AttrType String_to_AttrType(const string &s)
00088 {
00089 string s2 = s;
00090 downcase(s2);
00091
00092 if (s2 == "container")
00093 return Attr_container;
00094 else if (s2 == "byte")
00095 return Attr_byte;
00096 else if (s2 == "int16")
00097 return Attr_int16;
00098 else if (s2 == "uint16")
00099 return Attr_uint16;
00100 else if (s2 == "int32")
00101 return Attr_int32;
00102 else if (s2 == "uint32")
00103 return Attr_uint32;
00104 else if (s2 == "float32")
00105 return Attr_float32;
00106 else if (s2 == "float64")
00107 return Attr_float64;
00108 else if (s2 == "string")
00109 return Attr_string;
00110 else if (s2 == "url")
00111 return Attr_url;
00112 else if (s2 == "otherxml")
00113 return Attr_other_xml;
00114 else
00115 return Attr_unknown;
00116 }
00117
00120 void AttrTable::clone(const AttrTable &at)
00121 {
00122 d_name = at.d_name;
00123
00124 Attr_citer i = at.attr_map.begin();
00125 Attr_citer ie = at.attr_map.end();
00126 for (; i != ie; i++) {
00127 entry *e = new entry(*(*i));
00128 attr_map.push_back(e);
00129 }
00130
00131 d_parent = at.d_parent;
00132 }
00133
00137 AttrTable::AttrTable() :
00138 d_name(""), d_parent(0)
00139 {
00140 }
00141
00142 AttrTable::AttrTable(const AttrTable &rhs) :
00143 DapObj()
00144 {
00145 clone(rhs);
00146 }
00147
00148
00149 void AttrTable::delete_attr_table()
00150 {
00151 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); i++) {
00152 delete *i;
00153 *i = 0;
00154 }
00155 }
00156
00157 AttrTable::~AttrTable()
00158 {
00159 DBG(cerr << "Entering ~AttrTable (" << this << ")" << endl);
00160 delete_attr_table();DBG(cerr << "Exiting ~AttrTable" << endl);
00161 }
00162
00163 AttrTable &
00164 AttrTable::operator=(const AttrTable &rhs)
00165 {
00166 if (this != &rhs) {
00167 delete_attr_table();
00168 clone(rhs);
00169 }
00170
00171 return *this;
00172 }
00174
00180 unsigned int
00181 AttrTable::get_size() const
00182 {
00183 return attr_map.size();
00184 }
00185
00188 string
00189 AttrTable::get_name() const
00190 {
00191 return d_name;
00192 }
00193
00196 void
00197 AttrTable::set_name(const string &n)
00198 {
00199 d_name = www2id(n);
00200 }
00201
00219 unsigned int
00220 AttrTable::append_attr(const string &name, const string &type,
00221 const string &attribute)
00222 {
00223 string lname = www2id(name);
00224
00225 Attr_iter iter = simple_find(lname);
00226
00227
00228
00229 if (iter != attr_map.end() && ((*iter)->type != String_to_AttrType(type)))
00230 throw Error(string("An attribute called `") + name
00231 + string("' already exists but is of a different type"));
00232 if (iter != attr_map.end() && (get_type(iter) == "Container"))
00233 throw Error(string("An attribute called `") + name
00234 + string("' already exists but is a container."));
00235
00236 if (iter != attr_map.end()) {
00237 (*iter)->attr->push_back(attribute);
00238 return (*iter)->attr->size();
00239 }
00240 else {
00241 entry *e = new entry;
00242
00243 e->name = lname;
00244 e->is_alias = false;
00245 e->type = String_to_AttrType(type);
00246 e->attr = new vector<string>;
00247 e->attr->push_back(attribute);
00248
00249 attr_map.push_back(e);
00250
00251 return e->attr->size();
00252 }
00253 }
00254
00273 unsigned int
00274 AttrTable::append_attr(const string &name, const string &type,
00275 vector<string> *values)
00276 {
00277 string lname = www2id(name);
00278
00279 Attr_iter iter = simple_find(lname);
00280
00281
00282
00283 if (iter != attr_map.end() && ((*iter)->type != String_to_AttrType(type)))
00284 throw Error(string("An attribute called `") + name
00285 + string("' already exists but is of a different type"));
00286 if (iter != attr_map.end() && (get_type(iter) == "Container"))
00287 throw Error(string("An attribute called `") + name
00288 + string("' already exists but is a container."));
00289
00290 if (iter != attr_map.end()) {
00291 vector<string>::iterator i = values->begin();
00292 while (i != values->end())
00293 (*iter)->attr->push_back(*i++);
00294
00295 return (*iter)->attr->size();
00296 }
00297 else {
00298 entry *e = new entry;
00299
00300 e->name = lname;
00301 e->is_alias = false;
00302 e->type = String_to_AttrType(type);
00303 e->attr = new vector<string>(*values);
00304
00305 attr_map.push_back(e);
00306
00307 return e->attr->size();
00308 }
00309 }
00310
00319 AttrTable *
00320 AttrTable::append_container(const string &name)
00321 {
00322 AttrTable *new_at = new AttrTable;
00323 AttrTable *ret = NULL;
00324 try {
00325 ret = append_container(new_at, name);
00326 }
00327 catch (Error &e) {
00328
00329 delete new_at; new_at = 0;
00330 throw e;
00331 }
00332 return ret;
00333 }
00334
00347 AttrTable *
00348 AttrTable::append_container(AttrTable *at, const string &name)
00349 {
00350 string lname = www2id(name);
00351
00352 if (simple_find(name) != attr_end())
00353 throw Error(string("There already exists a container called `")
00354 + name + string("' in this attribute table."));
00355 DBG(cerr << "Setting appended attribute container name to: "
00356 << lname << endl);
00357 at->set_name(lname);
00358
00359 entry *e = new entry;
00360 e->name = lname;
00361 e->is_alias = false;
00362 e->type = Attr_container;
00363 e->attributes = at;
00364
00365 attr_map.push_back(e);
00366
00367 at->d_parent = this;
00368
00369 return e->attributes;
00370 }
00371
00386 void
00387 AttrTable::find(const string &target, AttrTable **at, Attr_iter *iter)
00388 {
00389 string::size_type dotpos = target.rfind('.');
00390 if (dotpos != string::npos) {
00391 string container = target.substr(0, dotpos);
00392 string field = target.substr(dotpos + 1);
00393
00394 *at = find_container(container);
00395 if (*at) {
00396 *iter = (*at)->simple_find(field);
00397 }
00398 else {
00399 *iter = attr_map.end();
00400 }
00401 }
00402 else {
00403 *at = recurrsive_find(target, iter);
00404 }
00405 }
00406
00418 AttrTable *
00419 AttrTable::recurrsive_find(const string &target, Attr_iter *location)
00420 {
00421
00422 Attr_iter i = attr_begin();
00423 while (i != attr_end()) {
00424 if (target == (*i)->name) {
00425 *location = i;
00426 return this;
00427 }
00428 else if ((*i)->type == Attr_container) {
00429 AttrTable *at = (*i)->attributes->recurrsive_find(target, location);
00430 if (at)
00431 return at;
00432 }
00433
00434 ++i;
00435 }
00436
00437 *location = i;
00438 return 0;
00439 }
00440
00441
00448 AttrTable::Attr_iter
00449 AttrTable::simple_find(const string &target)
00450 {
00451 Attr_iter i;
00452 for (i = attr_map.begin(); i != attr_map.end(); i++) {
00453 if (target == (*i)->name) {
00454 break;
00455 }
00456 }
00457 return i;
00458 }
00459
00473 AttrTable *
00474 AttrTable::find_container(const string &target)
00475 {
00476 string::size_type dotpos = target.find('.');
00477 if (dotpos != string::npos) {
00478 string container = target.substr(0, dotpos);
00479 string field = target.substr(dotpos + 1);
00480
00481 AttrTable *at = simple_find_container(container);
00482 return (at) ? at->find_container(field) : 0;
00483 }
00484 else {
00485 return simple_find_container(target);
00486 }
00487 }
00488
00489
00490 AttrTable *
00491 AttrTable::simple_find_container(const string &target)
00492 {
00493 if (get_name() == target)
00494 return this;
00495
00496 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); i++) {
00497 if (is_container(i) && target == (*i)->name) {
00498 return (*i)->attributes;
00499 }
00500 }
00501
00502 return 0;
00503 }
00504
00512
00514 AttrTable *
00515 AttrTable::get_attr_table(const string &name)
00516 {
00517 return find_container(name);
00518 }
00519
00521 string
00522 AttrTable::get_type(const string &name)
00523 {
00524 Attr_iter p = simple_find(name);
00525 return (p != attr_map.end()) ? get_type(p) : (string)"";
00526 }
00527
00530 AttrType
00531 AttrTable::get_attr_type(const string &name)
00532 {
00533 Attr_iter p = simple_find(name);
00534 return (p != attr_map.end()) ? get_attr_type(p) : Attr_unknown;
00535 }
00536
00544 unsigned int
00545 AttrTable::get_attr_num(const string &name)
00546 {
00547 Attr_iter iter = simple_find(name);
00548 return (iter != attr_map.end()) ? get_attr_num(iter) : 0;
00549 }
00550
00563 vector<string> *
00564 AttrTable::get_attr_vector(const string &name)
00565 {
00566 Attr_iter p = simple_find(name);
00567 return (p != attr_map.end()) ? get_attr_vector(p) : 0;
00568 }
00569
00586 void
00587 AttrTable::del_attr(const string &name, int i)
00588 {
00589 string lname = www2id(name);
00590
00591 Attr_iter iter = simple_find(lname);
00592 if (iter != attr_map.end()) {
00593 if (i == -1) {
00594 entry *e = *iter;
00595 attr_map.erase(iter);
00596 delete e; e = 0;
00597 }
00598 else {
00599
00600
00601 if ((*iter)->type == Attr_container)
00602 return;
00603
00604 vector<string> *sxp = (*iter)->attr;
00605
00606 assert(i >= 0 && i < (int)sxp->size());
00607 sxp->erase(sxp->begin() + i);
00608 }
00609 }
00610 }
00611
00613
00618 AttrTable::Attr_iter
00619 AttrTable::attr_begin()
00620 {
00621 return attr_map.begin();
00622 }
00623
00627 AttrTable::Attr_iter
00628 AttrTable::attr_end()
00629 {
00630 return attr_map.end();
00631 }
00632
00641 AttrTable::Attr_iter
00642 AttrTable::get_attr_iter(int i)
00643 {
00644 return attr_map.begin() + i;
00645 }
00646
00648 string
00649 AttrTable::get_name(Attr_iter iter)
00650 {
00651 assert(iter != attr_map.end());
00652
00653 return (*iter)->name;
00654 }
00655
00657 bool
00658 AttrTable::is_container(Attr_iter i)
00659 {
00660 return (*i)->type == Attr_container;
00661 }
00662
00668 AttrTable *
00669 AttrTable::get_attr_table(Attr_iter iter)
00670 {
00671 assert(iter != attr_map.end());
00672 return (*iter)->type == Attr_container ? (*iter)->attributes : 0;
00673 }
00674
00683 AttrTable::Attr_iter
00684 AttrTable::del_attr_table(Attr_iter iter)
00685 {
00686 if ((*iter)->type != Attr_container)
00687 return ++iter;
00688
00689
00690
00691
00692 struct entry* e = *iter;
00693
00694 if (e->attributes) {
00695 e->attributes->d_parent = 0;
00696 }
00697 e->attributes = 0;
00698 delete e;
00699
00700 return attr_map.erase(iter);
00701 }
00702
00706 string
00707 AttrTable::get_type(Attr_iter iter)
00708 {
00709 assert(iter != attr_map.end());
00710 return AttrType_to_String((*iter)->type);
00711 }
00712
00716 AttrType
00717 AttrTable::get_attr_type(Attr_iter iter)
00718 {
00719 return (*iter)->type;
00720 }
00721
00729 unsigned int
00730 AttrTable::get_attr_num(Attr_iter iter)
00731 {
00732 assert(iter != attr_map.end());
00733 return ((*iter)->type == Attr_container)
00734 ? (*iter)->attributes->get_size()
00735 : (*iter)->attr->size();
00736 }
00737
00754 string
00755 AttrTable::get_attr(Attr_iter iter, unsigned int i)
00756 {
00757 assert(iter != attr_map.end());
00758 #if 1
00759 return (*iter)->type == Attr_container ? (string)"None" : (*(*iter)->attr)[i];
00760 #else
00761 if ((*iter)->type == Attr_container) {
00762 return "None";
00763 }
00764 else {
00765 cerr << "(*iter)->attr: " << (*iter)->attr << endl;
00766 cerr << "(*iter)->name: " << (*iter)->name << endl;
00767 cerr << "(*iter)->type: " << (*iter)->type << endl;
00768
00769 if ((*iter)->name == "SIS_ID")
00770 return "SIS_ID_value";
00771 else
00772 return (*(*iter)->attr)[i];
00773 }
00774 #endif
00775 }
00776
00777 string
00778 AttrTable::get_attr(const string &name, unsigned int i)
00779 {
00780 Attr_iter p = simple_find(name);
00781 return (p != attr_map.end()) ? get_attr(p, i) : (string)"";
00782 }
00783
00795 vector<string> *
00796 AttrTable::get_attr_vector(Attr_iter iter)
00797 {
00798 assert(iter != attr_map.end());
00799 return (*iter)->type != Attr_container ? (*iter)->attr : 0;
00800 }
00801
00803
00804
00810 void
00811 AttrTable::add_container_alias(const string &name, AttrTable *src)
00812 {
00813 string lname = www2id(name);
00814
00815 if (simple_find(lname) != attr_end())
00816 throw Error(string("There already exists a container called `")
00817 + name + string("in this attribute table."));
00818
00819 entry *e = new entry;
00820 e->name = lname;
00821 e->is_alias = true;
00822 e->aliased_to = src->get_name();
00823 e->type = Attr_container;
00824
00825 e->attributes = src;
00826
00827 attr_map.push_back(e);
00828 }
00829
00842 void
00843 AttrTable::add_value_alias(AttrTable *das, const string &name,
00844 const string &source)
00845 {
00846 string lname = www2id(name);
00847 string lsource = www2id(source);
00848
00849
00850
00851
00852 AttrTable *at;
00853 Attr_iter iter;
00854 das->find(lsource, &at, &iter);
00855
00856
00857
00858
00859
00860 if (!at || (iter == at->attr_end()) || !*iter) {
00861 find(lsource, &at, &iter);
00862 if (!at || (iter == at->attr_end()) || !*iter)
00863 throw Error(string("Could not find the attribute `")
00864 + source + string("' in the attribute object."));
00865 }
00866
00867
00868
00869 if (at && !at->is_container(iter) && this == das)
00870 throw Error(string("A value cannot be aliased to the top level of the DAS;\nOnly containers may be present at that level of the DAS."));
00871
00872 if (simple_find(lname) != attr_end())
00873 throw Error(string("There already exists a container called `")
00874 + name + string("in this attribute table."));
00875
00876 entry *e = new entry;
00877 e->name = lname;
00878 e->is_alias = true;
00879 e->aliased_to = lsource;
00880 e->type = get_attr_type(iter);
00881 if (at && e->type == Attr_container)
00882 e->attributes = at->get_attr_table(iter);
00883 else
00884 e->attr = (*iter)->attr;
00885
00886 attr_map.push_back(e);
00887 }
00888
00889
00908 bool
00909 AttrTable::attr_alias(const string &alias, AttrTable *at, const string &name)
00910 {
00911 add_value_alias(at, alias, name);
00912 return true;
00913 }
00914
00922 bool
00923 AttrTable::attr_alias(const string &alias, const string &name)
00924 {
00925 return attr_alias(alias, this, name);
00926 }
00927
00931 void
00932 AttrTable::erase()
00933 {
00934 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); i++) {
00935 delete *i; *i = 0;
00936 }
00937
00938 attr_map.erase(attr_map.begin(), attr_map.end());
00939
00940 d_name = "";
00941 }
00942
00943 const string double_quote = "\"";
00944
00945
00946
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956 static void
00957 write_string_attribute_for_das(ostream &out, const string &value, const string &term)
00958 {
00959 if (is_quoted(value))
00960 out << value << term;
00961 else
00962 out << double_quote << value << double_quote << term;
00963 }
00964
00965 static void
00966 write_string_attribute_for_das(FILE *out, const string &value, const string &term)
00967 {
00968 if (is_quoted(value))
00969 fprintf(out, "%s%s", value.c_str(), term.c_str());
00970 else
00971 fprintf(out, "\"%s\"%s", value.c_str(), term.c_str());
00972 }
00973
00974
00975
00976 static void
00977 write_xml_attribute_for_das(ostream &out, const string &value, const string &term)
00978 {
00979 if (is_quoted(value))
00980 out << escape_double_quotes(value) << term;
00981 else
00982 out << double_quote << escape_double_quotes(value) << double_quote << term;
00983 }
00984
00985 static void
00986 write_xml_attribute_for_das(FILE *out, const string &value, const string &term)
00987 {
00988 if (is_quoted(value))
00989 fprintf(out, "%s%s", escape_double_quotes(value).c_str(), term.c_str());
00990 else
00991 fprintf(out, "\"%s\"%s", escape_double_quotes(value).c_str(), term.c_str());
00992 }
00993
00996 void
00997 AttrTable::simple_print(FILE *out, string pad, Attr_iter i,
00998 bool dereference)
00999 {
01000 switch ((*i)->type) {
01001 case Attr_container:
01002 fprintf(out, "%s%s {\n", pad.c_str(), id2www(get_name(i)).c_str());
01003
01004 (*i)->attributes->print(out, pad + " ", dereference);
01005
01006 fprintf(out, "%s}\n", pad.c_str());
01007 break;
01008
01009 case Attr_string: {
01010 fprintf(out, "%s%s %s ", pad.c_str(), get_type(i).c_str(),
01011 id2www(get_name(i)).c_str());
01012
01013 vector<string> *sxp = (*i)->attr;
01014 vector<string>::iterator last = sxp->end() - 1;
01015 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01016 write_string_attribute_for_das(out, *i, ", ");
01017 }
01018 write_string_attribute_for_das(out, *last, ";\n");
01019 }
01020 break;
01021
01022 case Attr_other_xml: {
01023 fprintf(out, "%s%s %s ", pad.c_str(), get_type(i).c_str(),
01024 id2www(get_name(i)).c_str());
01025
01026 vector<string> *sxp = (*i)->attr;
01027 vector<string>::iterator last = sxp->end() - 1;
01028 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01029 write_xml_attribute_for_das(out, *i, ", ");
01030 }
01031 write_xml_attribute_for_das(out, *last, ";\n");
01032 }
01033 break;
01034
01035 default: {
01036 fprintf(out, "%s%s %s ", pad.c_str(), get_type(i).c_str(),
01037 id2www(get_name(i)).c_str());
01038
01039 vector<string> *sxp = (*i)->attr;
01040 vector<string>::iterator last = sxp->end() - 1;
01041 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01042 fprintf(out, "%s%s", (*i).c_str(), ", ");
01043 }
01044 fprintf(out, "%s%s", (*last).c_str(), ";\n");
01045 }
01046 break;
01047 }
01048 }
01049
01052 void
01053 AttrTable::simple_print(ostream &out, string pad, Attr_iter i,
01054 bool dereference)
01055 {
01056 switch ((*i)->type) {
01057 case Attr_container:
01058 out << pad << id2www(get_name(i)) << " {\n";
01059
01060 (*i)->attributes->print(out, pad + " ", dereference);
01061
01062 out << pad << "}\n";
01063 break;
01064
01065 case Attr_string: {
01066 out << pad << get_type(i) << " " << id2www(get_name(i)) << " ";
01067
01068 vector<string> *sxp = (*i)->attr;
01069 vector<string>::iterator last = sxp->end() - 1;
01070 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01071 write_string_attribute_for_das(out, *i, ", ");
01072 }
01073 write_string_attribute_for_das(out, *last, ";\n");
01074 }
01075 break;
01076
01077 case Attr_other_xml: {
01078 out << pad << get_type(i) << " " << id2www(get_name(i)) << " ";
01079
01080 vector<string> *sxp = (*i)->attr;
01081 vector<string>::iterator last = sxp->end() - 1;
01082 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01083 write_xml_attribute_for_das(out, *i, ", ");
01084 }
01085 write_xml_attribute_for_das(out, *last, ";\n");
01086 }
01087 break;
01088
01089 default: {
01090 out << pad << get_type(i) << " " << id2www(get_name(i)) << " ";
01091
01092 vector<string> *sxp = (*i)->attr;
01093 vector<string>::iterator last = sxp->end() - 1;
01094 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01095 out << *i <<", ";
01096 }
01097 out << *last << ";\n";
01098 }
01099 break;
01100 }
01101 }
01102
01113 void
01114 AttrTable::print(FILE *out, string pad, bool dereference)
01115 {
01116 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); i++) {
01117 if ((*i)->is_alias) {
01118 if (dereference) {
01119 simple_print(out, pad, i, dereference);
01120 }
01121 else {
01122 fprintf(out, "%sAlias %s %s;\n",
01123 pad.c_str(),
01124 id2www(get_name(i)).c_str(),
01125 id2www((*i)->aliased_to).c_str());
01126 }
01127 }
01128 else {
01129 simple_print(out, pad, i, dereference);
01130 }
01131 }
01132 }
01133
01144 void
01145 AttrTable::print(ostream &out, string pad, bool dereference)
01146 {
01147 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); i++) {
01148 if ((*i)->is_alias) {
01149 if (dereference) {
01150 simple_print(out, pad, i, dereference);
01151 }
01152 else {
01153 out << pad << "Alias " << id2www(get_name(i))
01154 << " " << id2www((*i)->aliased_to) << ";\n";
01155 }
01156 }
01157 else {
01158 simple_print(out, pad, i, dereference);
01159 }
01160 }
01161 }
01162
01167 void
01168 AttrTable::print_xml(FILE *out, string pad, bool )
01169 {
01170
01171
01172
01173
01174
01175
01176
01177
01178 for (Attr_iter i = attr_begin(); i != attr_end(); ++i) {
01179 if ((*i)->is_alias) {
01180 fprintf(out, "%s<Alias name=\"%s\" Attribute=\"%s\"/>\n",
01181 pad.c_str(), id2xml(get_name(i)).c_str(),
01182 (*i)->aliased_to.c_str());
01183
01184 }
01185 else if (is_container(i)) {
01186 fprintf(out, "%s<Attribute name=\"%s\" type=\"%s\">\n",
01187 pad.c_str(), id2xml(get_name(i)).c_str(),
01188 get_type(i).c_str());
01189
01190 get_attr_table(i)->print_xml(out, pad + " ");
01191
01192 fprintf(out, "%s</Attribute>\n", pad.c_str());
01193 }
01194 else {
01195 fprintf(out, "%s<Attribute name=\"%s\" type=\"%s\">\n",
01196 pad.c_str(), id2xml(get_name(i)).c_str(), get_type(i).c_str());
01197
01198 string value_pad = pad + " ";
01199
01200
01201
01202 if (get_attr_type(i) == Attr_other_xml) {
01203 if (get_attr_num(i) != 1)
01204 throw Error("OtherXML attributes cannot be vector-valued.");
01205 fprintf(out, "%s%s\n", value_pad.c_str(), get_attr(i, 0).c_str());
01206 }
01207 else {
01208 for (unsigned j = 0; j < get_attr_num(i); ++j) {
01209 fprintf(out, "%s<value>%s</value>\n", value_pad.c_str(),
01210 id2xml(get_attr(i, j)).c_str());
01211 }
01212 }
01213 fprintf(out, "%s</Attribute>\n", pad.c_str());
01214 }
01215 }
01216 }
01217
01222 void
01223 AttrTable::print_xml(ostream &out, string pad, bool )
01224 {
01225 for (Attr_iter i = attr_begin(); i != attr_end(); ++i) {
01226 if ((*i)->is_alias) {
01227 out << pad << "<Alias name=\"" << id2xml(get_name(i))
01228 << "\" Attribute=\"" << (*i)->aliased_to << "\"/>\n";
01229
01230 }
01231 else if (is_container(i)) {
01232 out << pad << "<Attribute name=\"" << id2xml(get_name(i))
01233 << "\" type=\"" << get_type(i) << "\">\n";
01234
01235 get_attr_table(i)->print_xml(out, pad + " ");
01236
01237 out << pad << "</Attribute>\n";
01238 }
01239 else {
01240 out << pad << "<Attribute name=\"" << id2xml(get_name(i))
01241 << "\" type=\"" << get_type(i) << "\">\n";
01242
01243 string value_pad = pad + " ";
01244 if (get_attr_type(i) == Attr_other_xml) {
01245 if (get_attr_num(i) != 1)
01246 throw Error("OtherXML attributes cannot be vector-valued.");
01247 out << value_pad << get_attr(i, 0) << "\n";
01248 }
01249 else {
01250 string value_pad = pad + " ";
01251 for (unsigned j = 0; j < get_attr_num(i); ++j) {
01252 out << value_pad << "<value>" << id2xml(get_attr(i, j)) << "</value>\n";
01253 }
01254 }
01255 out << pad << "</Attribute>\n";
01256 }
01257 }
01258 }
01259
01267 void
01268 AttrTable::dump(ostream &strm) const
01269 {
01270 strm << DapIndent::LMarg << "AttrTable::dump - ("
01271 << (void *)this << ")" << endl;
01272 DapIndent::Indent();
01273 strm << DapIndent::LMarg << "table name: " << d_name << endl;
01274 if (attr_map.size()) {
01275 strm << DapIndent::LMarg << "attributes: " << endl;
01276 DapIndent::Indent();
01277 Attr_citer i = attr_map.begin();
01278 Attr_citer ie = attr_map.end();
01279 for (; i != ie; i++) {
01280 entry *e = (*i);
01281 string type = AttrType_to_String(e->type);
01282 if (e->is_alias) {
01283 strm << DapIndent::LMarg << "alias: " << e->name
01284 << " aliased to: " << e->aliased_to
01285 << endl;
01286 }
01287 else if (e->type == Attr_container) {
01288 strm << DapIndent::LMarg << "attr: " << e->name
01289 << " of type " << type
01290 << endl;
01291 DapIndent::Indent();
01292 e->attributes->dump(strm);
01293 DapIndent::UnIndent();
01294 }
01295 else {
01296 strm << DapIndent::LMarg << "attr: " << e->name
01297 << " of type " << type
01298 << endl;
01299 DapIndent::Indent();
01300 strm << DapIndent::LMarg;
01301 vector<string>::const_iterator iter = e->attr->begin();
01302 vector<string>::const_iterator last = e->attr->end() - 1;
01303 for (; iter != last; iter++) {
01304 strm << (*iter) << ", ";
01305 }
01306 strm << (*(e->attr->end() - 1)) << endl;
01307 DapIndent::UnIndent();
01308 }
01309 }
01310 DapIndent::UnIndent();
01311 }
01312 else {
01313 strm << DapIndent::LMarg << "attributes: empty" << endl;
01314 }
01315 if (d_parent) {
01316 strm << DapIndent::LMarg << "parent table:"
01317 << d_name << ":" << (void *)d_parent << endl;
01318 }
01319 else {
01320 strm << DapIndent::LMarg << "parent table: none" << d_name << endl;
01321 }
01322 DapIndent::UnIndent();
01323 }
01324
01325 }
01326