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
00036
00037 static char rcsid[]not_used =
00038 "$Id: AttrTable.cc 23473 2010-09-01 20:33:22Z mjohnson $";
00039
00040 #include <cassert>
00041
00042 #include "AttrTable.h"
00043
00044 #include "util.h"
00045 #include "escaping.h"
00046
00047 #include "debug.h"
00048
00049 using std::cerr;
00050 using std::string;
00051 using std::endl;
00052 using std::vector;
00053
00054 namespace libdap {
00055
00059 string AttrType_to_String(const AttrType at)
00060 {
00061 switch (at) {
00062 case Attr_container:
00063 return "Container";
00064 case Attr_byte:
00065 return "Byte";
00066 case Attr_int16:
00067 return "Int16";
00068 case Attr_uint16:
00069 return "UInt16";
00070 case Attr_int32:
00071 return "Int32";
00072 case Attr_uint32:
00073 return "UInt32";
00074 case Attr_float32:
00075 return "Float32";
00076 case Attr_float64:
00077 return "Float64";
00078 case Attr_string:
00079 return "String";
00080 case Attr_url:
00081 return "Url";
00082 case Attr_other_xml:
00083 return "OtherXML";
00084 default:
00085 return "";
00086 }
00087 }
00088
00089 AttrType String_to_AttrType(const string &s)
00090 {
00091 string s2 = s;
00092 downcase(s2);
00093
00094 if (s2 == "container")
00095 return Attr_container;
00096 else if (s2 == "byte")
00097 return Attr_byte;
00098 else if (s2 == "int16")
00099 return Attr_int16;
00100 else if (s2 == "uint16")
00101 return Attr_uint16;
00102 else if (s2 == "int32")
00103 return Attr_int32;
00104 else if (s2 == "uint32")
00105 return Attr_uint32;
00106 else if (s2 == "float32")
00107 return Attr_float32;
00108 else if (s2 == "float64")
00109 return Attr_float64;
00110 else if (s2 == "string")
00111 return Attr_string;
00112 else if (s2 == "url")
00113 return Attr_url;
00114 else if (s2 == "otherxml")
00115 return Attr_other_xml;
00116 else
00117 return Attr_unknown;
00118 }
00119
00122 void AttrTable::clone(const AttrTable &at)
00123 {
00124 d_name = at.d_name;
00125 d_is_global_attribute = at.d_is_global_attribute;
00126
00127
00128
00129
00130 d_parent = 0;
00131
00132 Attr_citer i = at.attr_map.begin();
00133 Attr_citer ie = at.attr_map.end();
00134 for (; i != ie; ++i) {
00135
00136 entry *e = new entry(*(*i));
00137 attr_map.push_back(e);
00138
00139
00140
00141 if (e->type == Attr_container) {
00142 assert(e->attributes);
00143 e->attributes->d_parent = this;
00144 }
00145 }
00146 }
00147
00151 AttrTable::AttrTable()
00152 : DapObj()
00153 , d_name("")
00154 , d_parent(0)
00155 , attr_map()
00156 , d_is_global_attribute(true)
00157 {
00158 }
00159
00160 AttrTable::AttrTable(const AttrTable &rhs)
00161 : DapObj()
00162 {
00163 clone(rhs);
00164 }
00165
00166
00167 void AttrTable::delete_attr_table()
00168 {
00169 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); ++i) {
00170 delete *i;
00171 *i = 0;
00172 }
00173 attr_map.clear();
00174 }
00175
00176 AttrTable::~AttrTable()
00177 {
00178 DBG(cerr << "Entering ~AttrTable (" << this << ")" << endl);
00179 delete_attr_table();DBG(cerr << "Exiting ~AttrTable" << endl);
00180 }
00181
00182 AttrTable &
00183 AttrTable::operator=(const AttrTable &rhs)
00184 {
00185 if (this != &rhs) {
00186 delete_attr_table();
00187 clone(rhs);
00188 }
00189
00190 return *this;
00191 }
00193
00199 unsigned int
00200 AttrTable::get_size() const
00201 {
00202 return attr_map.size();
00203 }
00204
00207 string
00208 AttrTable::get_name() const
00209 {
00210 return d_name;
00211 }
00212
00215 void
00216 AttrTable::set_name(const string &n)
00217 {
00218 d_name = www2id(n);
00219 }
00220
00238 unsigned int
00239 AttrTable::append_attr(const string &name, const string &type,
00240 const string &attribute)
00241 {
00242 DBG(cerr << "Entering AttrTable::append_attr" << endl);
00243 string lname = www2id(name);
00244
00245 Attr_iter iter = simple_find(lname);
00246
00247
00248
00249 if (iter != attr_map.end() && ((*iter)->type != String_to_AttrType(type)))
00250 throw Error(string("An attribute called `") + name
00251 + string("' already exists but is of a different type"));
00252 if (iter != attr_map.end() && (get_type(iter) == "Container"))
00253 throw Error(string("An attribute called `") + name
00254 + string("' already exists but is a container."));
00255
00256 if (iter != attr_map.end()) {
00257 (*iter)->attr->push_back(attribute);
00258 return (*iter)->attr->size();
00259 }
00260 else {
00261 entry *e = new entry;
00262
00263 e->name = lname;
00264 e->is_alias = false;
00265 e->type = String_to_AttrType(type);
00266 e->attr = new vector<string>;
00267 e->attr->push_back(attribute);
00268
00269 attr_map.push_back(e);
00270
00271 return e->attr->size();
00272 }
00273 }
00274
00293 unsigned int
00294 AttrTable::append_attr(const string &name, const string &type,
00295 vector<string> *values)
00296 {
00297 DBG(cerr << "Entering AttrTable::append_attr(..., vector)" << endl);
00298 string lname = www2id(name);
00299
00300 Attr_iter iter = simple_find(lname);
00301
00302
00303
00304 if (iter != attr_map.end() && ((*iter)->type != String_to_AttrType(type)))
00305 throw Error(string("An attribute called `") + name
00306 + string("' already exists but is of a different type"));
00307 if (iter != attr_map.end() && (get_type(iter) == "Container"))
00308 throw Error(string("An attribute called `") + name
00309 + string("' already exists but is a container."));
00310
00311 if (iter != attr_map.end()) {
00312 vector<string>::iterator i = values->begin();
00313 while (i != values->end())
00314 (*iter)->attr->push_back(*i++);
00315
00316 return (*iter)->attr->size();
00317 }
00318 else {
00319 entry *e = new entry;
00320
00321 e->name = lname;
00322 e->is_alias = false;
00323 e->type = String_to_AttrType(type);
00324 e->attr = new vector<string>(*values);
00325
00326 attr_map.push_back(e);
00327
00328 return e->attr->size();
00329 }
00330 }
00331
00340 AttrTable *
00341 AttrTable::append_container(const string &name)
00342 {
00343 AttrTable *new_at = new AttrTable;
00344 AttrTable *ret = NULL;
00345 try {
00346 ret = append_container(new_at, name);
00347 }
00348 catch (Error &e) {
00349
00350 delete new_at; new_at = 0;
00351 throw e;
00352 }
00353 return ret;
00354 }
00355
00368 AttrTable *
00369 AttrTable::append_container(AttrTable *at, const string &name)
00370 {
00371 string lname = www2id(name);
00372
00373 if (simple_find(name) != attr_end())
00374 throw Error(string("There already exists a container called `")
00375 + name + string("' in this attribute table."));
00376 DBG(cerr << "Setting appended attribute container name to: "
00377 << lname << endl);
00378 at->set_name(lname);
00379
00380 entry *e = new entry;
00381 e->name = lname;
00382 e->is_alias = false;
00383 e->type = Attr_container;
00384 e->attributes = at;
00385
00386 attr_map.push_back(e);
00387
00388 at->d_parent = this;
00389
00390 return e->attributes;
00391 }
00392
00407 void
00408 AttrTable::find(const string &target, AttrTable **at, Attr_iter *iter)
00409 {
00410 string::size_type dotpos = target.rfind('.');
00411 if (dotpos != string::npos) {
00412 string container = target.substr(0, dotpos);
00413 string field = target.substr(dotpos + 1);
00414
00415 *at = find_container(container);
00416 if (*at) {
00417 *iter = (*at)->simple_find(field);
00418 }
00419 else {
00420 *iter = attr_map.end();
00421 }
00422 }
00423 else {
00424 *at = recurrsive_find(target, iter);
00425 }
00426 }
00427
00439 AttrTable *
00440 AttrTable::recurrsive_find(const string &target, Attr_iter *location)
00441 {
00442
00443 Attr_iter i = attr_begin();
00444 while (i != attr_end()) {
00445 if (target == (*i)->name) {
00446 *location = i;
00447 return this;
00448 }
00449 else if ((*i)->type == Attr_container) {
00450 AttrTable *at = (*i)->attributes->recurrsive_find(target, location);
00451 if (at)
00452 return at;
00453 }
00454
00455 ++i;
00456 }
00457
00458 *location = i;
00459 return 0;
00460 }
00461
00462
00469 AttrTable::Attr_iter
00470 AttrTable::simple_find(const string &target)
00471 {
00472 Attr_iter i;
00473 for (i = attr_map.begin(); i != attr_map.end(); ++i) {
00474 if (target == (*i)->name) {
00475 break;
00476 }
00477 }
00478 return i;
00479 }
00480
00494 AttrTable *
00495 AttrTable::find_container(const string &target)
00496 {
00497 string::size_type dotpos = target.find('.');
00498 if (dotpos != string::npos) {
00499 string container = target.substr(0, dotpos);
00500 string field = target.substr(dotpos + 1);
00501
00502 AttrTable *at = simple_find_container(container);
00503 return (at) ? at->find_container(field) : 0;
00504 }
00505 else {
00506 return simple_find_container(target);
00507 }
00508 }
00509
00510
00511 AttrTable *
00512 AttrTable::simple_find_container(const string &target)
00513 {
00514 if (get_name() == target)
00515 return this;
00516
00517 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); ++i) {
00518 if (is_container(i) && target == (*i)->name) {
00519 return (*i)->attributes;
00520 }
00521 }
00522
00523 return 0;
00524 }
00525
00533
00535 AttrTable *
00536 AttrTable::get_attr_table(const string &name)
00537 {
00538 return find_container(name);
00539 }
00540
00542 string
00543 AttrTable::get_type(const string &name)
00544 {
00545 Attr_iter p = simple_find(name);
00546 return (p != attr_map.end()) ? get_type(p) : (string)"";
00547 }
00548
00551 AttrType
00552 AttrTable::get_attr_type(const string &name)
00553 {
00554 Attr_iter p = simple_find(name);
00555 return (p != attr_map.end()) ? get_attr_type(p) : Attr_unknown;
00556 }
00557
00565 unsigned int
00566 AttrTable::get_attr_num(const string &name)
00567 {
00568 Attr_iter iter = simple_find(name);
00569 return (iter != attr_map.end()) ? get_attr_num(iter) : 0;
00570 }
00571
00584 vector<string> *
00585 AttrTable::get_attr_vector(const string &name)
00586 {
00587 Attr_iter p = simple_find(name);
00588 return (p != attr_map.end()) ? get_attr_vector(p) : 0;
00589 }
00590
00607 void
00608 AttrTable::del_attr(const string &name, int i)
00609 {
00610 string lname = www2id(name);
00611
00612 Attr_iter iter = simple_find(lname);
00613 if (iter != attr_map.end()) {
00614 if (i == -1) {
00615 entry *e = *iter;
00616 attr_map.erase(iter);
00617 delete e; e = 0;
00618 }
00619 else {
00620
00621
00622 if ((*iter)->type == Attr_container)
00623 return;
00624
00625 vector<string> *sxp = (*iter)->attr;
00626
00627 assert(i >= 0 && i < (int)sxp->size());
00628 sxp->erase(sxp->begin() + i);
00629 }
00630 }
00631 }
00632
00634
00639 AttrTable::Attr_iter
00640 AttrTable::attr_begin()
00641 {
00642 return attr_map.begin();
00643 }
00644
00648 AttrTable::Attr_iter
00649 AttrTable::attr_end()
00650 {
00651 return attr_map.end();
00652 }
00653
00662 AttrTable::Attr_iter
00663 AttrTable::get_attr_iter(int i)
00664 {
00665 return attr_map.begin() + i;
00666 }
00667
00669 string
00670 AttrTable::get_name(Attr_iter iter)
00671 {
00672 assert(iter != attr_map.end());
00673
00674 return (*iter)->name;
00675 }
00676
00678 bool
00679 AttrTable::is_container(Attr_iter i)
00680 {
00681 return (*i)->type == Attr_container;
00682 }
00683
00689 AttrTable *
00690 AttrTable::get_attr_table(Attr_iter iter)
00691 {
00692 assert(iter != attr_map.end());
00693 return (*iter)->type == Attr_container ? (*iter)->attributes : 0;
00694 }
00695
00704 AttrTable::Attr_iter
00705 AttrTable::del_attr_table(Attr_iter iter)
00706 {
00707 if ((*iter)->type != Attr_container)
00708 return ++iter;
00709
00710
00711
00712
00713 struct entry* e = *iter;
00714
00715 if (e->attributes) {
00716 e->attributes->d_parent = 0;
00717 }
00718 e->attributes = 0;
00719 delete e;
00720
00721 return attr_map.erase(iter);
00722 }
00723
00727 string
00728 AttrTable::get_type(Attr_iter iter)
00729 {
00730 assert(iter != attr_map.end());
00731 return AttrType_to_String((*iter)->type);
00732 }
00733
00737 AttrType
00738 AttrTable::get_attr_type(Attr_iter iter)
00739 {
00740 return (*iter)->type;
00741 }
00742
00750 unsigned int
00751 AttrTable::get_attr_num(Attr_iter iter)
00752 {
00753 assert(iter != attr_map.end());
00754 return ((*iter)->type == Attr_container)
00755 ? (*iter)->attributes->get_size()
00756 : (*iter)->attr->size();
00757 }
00758
00775 string
00776 AttrTable::get_attr(Attr_iter iter, unsigned int i)
00777 {
00778 assert(iter != attr_map.end());
00779 #if 1
00780 return (*iter)->type == Attr_container ? (string)"None" : (*(*iter)->attr)[i];
00781 #else
00782 if ((*iter)->type == Attr_container) {
00783 return "None";
00784 }
00785 else {
00786 cerr << "(*iter)->attr: " << (*iter)->attr << endl;
00787 cerr << "(*iter)->name: " << (*iter)->name << endl;
00788 cerr << "(*iter)->type: " << (*iter)->type << endl;
00789
00790 if ((*iter)->name == "SIS_ID")
00791 return "SIS_ID_value";
00792 else
00793 return (*(*iter)->attr)[i];
00794 }
00795 #endif
00796 }
00797
00798 string
00799 AttrTable::get_attr(const string &name, unsigned int i)
00800 {
00801 Attr_iter p = simple_find(name);
00802 return (p != attr_map.end()) ? get_attr(p, i) : (string)"";
00803 }
00804
00816 vector<string> *
00817 AttrTable::get_attr_vector(Attr_iter iter)
00818 {
00819 assert(iter != attr_map.end());
00820 return (*iter)->type != Attr_container ? (*iter)->attr : 0;
00821 }
00822
00823 bool
00824 AttrTable::is_global_attribute(Attr_iter iter)
00825 {
00826 assert(iter != attr_map.end());
00827 if ((*iter)->type == Attr_container)
00828 return (*iter)->attributes->is_global_attribute();
00829 else
00830 return (*iter)->is_global;
00831 }
00832
00833 void
00834 AttrTable::set_is_global_attribute(Attr_iter iter, bool ga)
00835 {
00836 assert(iter != attr_map.end());
00837 if ((*iter)->type == Attr_container)
00838 (*iter)->attributes->set_is_global_attribute(ga);
00839 else
00840 (*iter)->is_global = ga;
00841 }
00842
00844
00845
00851 void
00852 AttrTable::add_container_alias(const string &name, AttrTable *src)
00853 {
00854 string lname = www2id(name);
00855
00856 if (simple_find(lname) != attr_end())
00857 throw Error(string("There already exists a container called `")
00858 + name + string("in this attribute table."));
00859
00860 entry *e = new entry;
00861 e->name = lname;
00862 e->is_alias = true;
00863 e->aliased_to = src->get_name();
00864 e->type = Attr_container;
00865
00866 e->attributes = src;
00867
00868 attr_map.push_back(e);
00869 }
00870
00883 void
00884 AttrTable::add_value_alias(AttrTable *das, const string &name,
00885 const string &source)
00886 {
00887 string lname = www2id(name);
00888 string lsource = www2id(source);
00889
00890
00891
00892
00893 AttrTable *at;
00894 Attr_iter iter;
00895 das->find(lsource, &at, &iter);
00896
00897
00898
00899
00900
00901 if (!at || (iter == at->attr_end()) || !*iter) {
00902 find(lsource, &at, &iter);
00903 if (!at || (iter == at->attr_end()) || !*iter)
00904 throw Error(string("Could not find the attribute `")
00905 + source + string("' in the attribute object."));
00906 }
00907
00908
00909
00910 if (at && !at->is_container(iter) && this == das)
00911 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."));
00912
00913 if (simple_find(lname) != attr_end())
00914 throw Error(string("There already exists a container called `")
00915 + name + string("in this attribute table."));
00916
00917 entry *e = new entry;
00918 e->name = lname;
00919 e->is_alias = true;
00920 e->aliased_to = lsource;
00921 e->type = get_attr_type(iter);
00922 if (at && e->type == Attr_container)
00923 e->attributes = at->get_attr_table(iter);
00924 else
00925 e->attr = (*iter)->attr;
00926
00927 attr_map.push_back(e);
00928 }
00929
00930
00949 bool
00950 AttrTable::attr_alias(const string &alias, AttrTable *at, const string &name)
00951 {
00952 add_value_alias(at, alias, name);
00953 return true;
00954 }
00955
00963 bool
00964 AttrTable::attr_alias(const string &alias, const string &name)
00965 {
00966 return attr_alias(alias, this, name);
00967 }
00968
00972 void
00973 AttrTable::erase()
00974 {
00975 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); ++i) {
00976 delete *i; *i = 0;
00977 }
00978
00979 attr_map.erase(attr_map.begin(), attr_map.end());
00980
00981 d_name = "";
00982 }
00983
00984 const string double_quote = "\"";
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997 static void
00998 write_string_attribute_for_das(ostream &out, const string &value, const string &term)
00999 {
01000 if (is_quoted(value))
01001 out << value << term;
01002 else
01003 out << double_quote << value << double_quote << term;
01004 }
01005
01006 static void
01007 write_string_attribute_for_das(FILE *out, const string &value, const string &term)
01008 {
01009 if (is_quoted(value))
01010 fprintf(out, "%s%s", value.c_str(), term.c_str());
01011 else
01012 fprintf(out, "\"%s\"%s", value.c_str(), term.c_str());
01013 }
01014
01015
01016
01017 static void
01018 write_xml_attribute_for_das(ostream &out, const string &value, const string &term)
01019 {
01020 if (is_quoted(value))
01021 out << escape_double_quotes(value) << term;
01022 else
01023 out << double_quote << escape_double_quotes(value) << double_quote << term;
01024 }
01025
01026 static void
01027 write_xml_attribute_for_das(FILE *out, const string &value, const string &term)
01028 {
01029 if (is_quoted(value))
01030 fprintf(out, "%s%s", escape_double_quotes(value).c_str(), term.c_str());
01031 else
01032 fprintf(out, "\"%s\"%s", escape_double_quotes(value).c_str(), term.c_str());
01033 }
01034
01037 void
01038 AttrTable::simple_print(FILE *out, string pad, Attr_iter i,
01039 bool dereference)
01040 {
01041 switch ((*i)->type) {
01042 case Attr_container:
01043 fprintf(out, "%s%s {\n", pad.c_str(), id2www(get_name(i)).c_str());
01044
01045 (*i)->attributes->print(out, pad + " ", dereference);
01046
01047 fprintf(out, "%s}\n", pad.c_str());
01048 break;
01049
01050 case Attr_string: {
01051 fprintf(out, "%s%s %s ", pad.c_str(), get_type(i).c_str(),
01052 id2www(get_name(i)).c_str());
01053
01054 vector<string> *sxp = (*i)->attr;
01055 vector<string>::iterator last = sxp->end() - 1;
01056 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01057 write_string_attribute_for_das(out, *i, ", ");
01058 }
01059 write_string_attribute_for_das(out, *last, ";\n");
01060 }
01061 break;
01062
01063 case Attr_other_xml: {
01064 fprintf(out, "%s%s %s ", pad.c_str(), get_type(i).c_str(),
01065 id2www(get_name(i)).c_str());
01066
01067 vector<string> *sxp = (*i)->attr;
01068 vector<string>::iterator last = sxp->end() - 1;
01069 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01070 write_xml_attribute_for_das(out, *i, ", ");
01071 }
01072 write_xml_attribute_for_das(out, *last, ";\n");
01073 }
01074 break;
01075
01076 default: {
01077 fprintf(out, "%s%s %s ", pad.c_str(), get_type(i).c_str(),
01078 id2www(get_name(i)).c_str());
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 fprintf(out, "%s%s", (*i).c_str(), ", ");
01084 }
01085 fprintf(out, "%s%s", (*last).c_str(), ";\n");
01086 }
01087 break;
01088 }
01089 }
01090
01093 void
01094 AttrTable::simple_print(ostream &out, string pad, Attr_iter i,
01095 bool dereference)
01096 {
01097 switch ((*i)->type) {
01098 case Attr_container:
01099 out << pad << id2www(get_name(i)) << " {\n";
01100
01101 (*i)->attributes->print(out, pad + " ", dereference);
01102
01103 out << pad << "}\n";
01104 break;
01105
01106 case Attr_string: {
01107 out << pad << get_type(i) << " " << id2www(get_name(i)) << " ";
01108
01109 vector<string> *sxp = (*i)->attr;
01110 vector<string>::iterator last = sxp->end() - 1;
01111 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01112 write_string_attribute_for_das(out, *i, ", ");
01113 }
01114 write_string_attribute_for_das(out, *last, ";\n");
01115 }
01116 break;
01117
01118 case Attr_other_xml: {
01119 out << pad << get_type(i) << " " << id2www(get_name(i)) << " ";
01120
01121 vector<string> *sxp = (*i)->attr;
01122 vector<string>::iterator last = sxp->end() - 1;
01123 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01124 write_xml_attribute_for_das(out, *i, ", ");
01125 }
01126 write_xml_attribute_for_das(out, *last, ";\n");
01127 }
01128 break;
01129
01130 default: {
01131 out << pad << get_type(i) << " " << id2www(get_name(i)) << " ";
01132
01133 vector<string> *sxp = (*i)->attr;
01134 vector<string>::iterator last = sxp->end() - 1;
01135 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01136 out << *i <<", ";
01137 }
01138 out << *last << ";\n";
01139 }
01140 break;
01141 }
01142 }
01143
01154 void
01155 AttrTable::print(FILE *out, string pad, bool dereference)
01156 {
01157 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); ++i) {
01158 if ((*i)->is_alias) {
01159 if (dereference) {
01160 simple_print(out, pad, i, dereference);
01161 }
01162 else {
01163 fprintf(out, "%sAlias %s %s;\n",
01164 pad.c_str(),
01165 id2www(get_name(i)).c_str(),
01166 id2www((*i)->aliased_to).c_str());
01167 }
01168 }
01169 else {
01170 simple_print(out, pad, i, dereference);
01171 }
01172 }
01173 }
01174
01185 void
01186 AttrTable::print(ostream &out, string pad, bool dereference)
01187 {
01188 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); ++i) {
01189 if ((*i)->is_alias) {
01190 if (dereference) {
01191 simple_print(out, pad, i, dereference);
01192 }
01193 else {
01194 out << pad << "Alias " << id2www(get_name(i))
01195 << " " << id2www((*i)->aliased_to) << ";\n";
01196 }
01197 }
01198 else {
01199 simple_print(out, pad, i, dereference);
01200 }
01201 }
01202 }
01203
01208 void
01209 AttrTable::print_xml(FILE *out, string pad, bool )
01210 {
01211
01212
01213
01214
01215
01216
01217
01218
01219 for (Attr_iter i = attr_begin(); i != attr_end(); ++i) {
01220 if ((*i)->is_alias) {
01221 fprintf(out, "%s<Alias name=\"%s\" Attribute=\"%s\"/>\n",
01222 pad.c_str(), id2xml(get_name(i)).c_str(),
01223 (*i)->aliased_to.c_str());
01224
01225 }
01226 else if (is_container(i)) {
01227 fprintf(out, "%s<Attribute name=\"%s\" type=\"%s\">\n",
01228 pad.c_str(), id2xml(get_name(i)).c_str(),
01229 get_type(i).c_str());
01230
01231 get_attr_table(i)->print_xml(out, pad + " ");
01232
01233 fprintf(out, "%s</Attribute>\n", pad.c_str());
01234 }
01235 else {
01236 fprintf(out, "%s<Attribute name=\"%s\" type=\"%s\">\n",
01237 pad.c_str(), id2xml(get_name(i)).c_str(), get_type(i).c_str());
01238
01239 string value_pad = pad + " ";
01240
01241
01242
01243 if (get_attr_type(i) == Attr_other_xml) {
01244 if (get_attr_num(i) != 1)
01245 throw Error("OtherXML attributes cannot be vector-valued.");
01246 fprintf(out, "%s%s\n", value_pad.c_str(), get_attr(i, 0).c_str());
01247 }
01248 else {
01249 for (unsigned j = 0; j < get_attr_num(i); ++j) {
01250 fprintf(out, "%s<value>%s</value>\n", value_pad.c_str(),
01251 id2xml(get_attr(i, j)).c_str());
01252 }
01253 }
01254 fprintf(out, "%s</Attribute>\n", pad.c_str());
01255 }
01256 }
01257 }
01258
01263 void
01264 AttrTable::print_xml(ostream &out, string pad, bool )
01265 {
01266 for (Attr_iter i = attr_begin(); i != attr_end(); ++i) {
01267 if ((*i)->is_alias) {
01268 out << pad << "<Alias name=\"" << id2xml(get_name(i))
01269 << "\" Attribute=\"" << (*i)->aliased_to << "\"/>\n";
01270
01271 }
01272 else if (is_container(i)) {
01273 out << pad << "<Attribute name=\"" << id2xml(get_name(i))
01274 << "\" type=\"" << get_type(i) << "\">\n";
01275
01276 get_attr_table(i)->print_xml(out, pad + " ");
01277
01278 out << pad << "</Attribute>\n";
01279 }
01280 else {
01281 out << pad << "<Attribute name=\"" << id2xml(get_name(i))
01282 << "\" type=\"" << get_type(i) << "\">\n";
01283
01284 string value_pad = pad + " ";
01285 if (get_attr_type(i) == Attr_other_xml) {
01286 if (get_attr_num(i) != 1)
01287 throw Error("OtherXML attributes cannot be vector-valued.");
01288 out << value_pad << get_attr(i, 0) << "\n";
01289 }
01290 else {
01291 string value_pad = pad + " ";
01292 for (unsigned j = 0; j < get_attr_num(i); ++j) {
01293 out << value_pad << "<value>" << id2xml(get_attr(i, j)) << "</value>\n";
01294 }
01295 }
01296 out << pad << "</Attribute>\n";
01297 }
01298 }
01299 }
01300
01308 void
01309 AttrTable::dump(ostream &strm) const
01310 {
01311 strm << DapIndent::LMarg << "AttrTable::dump - ("
01312 << (void *)this << ")" << endl;
01313 DapIndent::Indent();
01314 strm << DapIndent::LMarg << "table name: " << d_name << endl;
01315 if (attr_map.size()) {
01316 strm << DapIndent::LMarg << "attributes: " << endl;
01317 DapIndent::Indent();
01318 Attr_citer i = attr_map.begin();
01319 Attr_citer ie = attr_map.end();
01320 for (; i != ie; ++i) {
01321 entry *e = (*i);
01322 string type = AttrType_to_String(e->type);
01323 if (e->is_alias) {
01324 strm << DapIndent::LMarg << "alias: " << e->name
01325 << " aliased to: " << e->aliased_to
01326 << endl;
01327 }
01328 else if (e->type == Attr_container) {
01329 strm << DapIndent::LMarg << "attr: " << e->name
01330 << " of type " << type
01331 << endl;
01332 DapIndent::Indent();
01333 e->attributes->dump(strm);
01334 DapIndent::UnIndent();
01335 }
01336 else {
01337 strm << DapIndent::LMarg << "attr: " << e->name
01338 << " of type " << type
01339 << endl;
01340 DapIndent::Indent();
01341 strm << DapIndent::LMarg;
01342 vector<string>::const_iterator iter = e->attr->begin();
01343 vector<string>::const_iterator last = e->attr->end() - 1;
01344 for (; iter != last; iter++) {
01345 strm << (*iter) << ", ";
01346 }
01347 strm << (*(e->attr->end() - 1)) << endl;
01348 DapIndent::UnIndent();
01349 }
01350 }
01351 DapIndent::UnIndent();
01352 }
01353 else {
01354 strm << DapIndent::LMarg << "attributes: empty" << endl;
01355 }
01356 if (d_parent) {
01357 strm << DapIndent::LMarg << "parent table:"
01358 << d_name << ":" << (void *)d_parent << endl;
01359 }
01360 else {
01361 strm << DapIndent::LMarg << "parent table: none" << d_name << endl;
01362 }
01363 DapIndent::UnIndent();
01364 }
01365
01366 }
01367