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 22624 2010-04-30 16:55:58Z jimg $";
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 d_name(""), d_parent(0), d_is_global_attribute(true)
00153 {
00154 }
00155
00156 AttrTable::AttrTable(const AttrTable &rhs) :
00157 DapObj()
00158 {
00159 clone(rhs);
00160 }
00161
00162
00163 void AttrTable::delete_attr_table()
00164 {
00165 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); i++) {
00166 delete *i;
00167 *i = 0;
00168 }
00169 }
00170
00171 AttrTable::~AttrTable()
00172 {
00173 DBG(cerr << "Entering ~AttrTable (" << this << ")" << endl);
00174 delete_attr_table();DBG(cerr << "Exiting ~AttrTable" << endl);
00175 }
00176
00177 AttrTable &
00178 AttrTable::operator=(const AttrTable &rhs)
00179 {
00180 if (this != &rhs) {
00181 delete_attr_table();
00182 clone(rhs);
00183 }
00184
00185 return *this;
00186 }
00188
00194 unsigned int
00195 AttrTable::get_size() const
00196 {
00197 return attr_map.size();
00198 }
00199
00202 string
00203 AttrTable::get_name() const
00204 {
00205 return d_name;
00206 }
00207
00210 void
00211 AttrTable::set_name(const string &n)
00212 {
00213 d_name = www2id(n);
00214 }
00215
00233 unsigned int
00234 AttrTable::append_attr(const string &name, const string &type,
00235 const string &attribute)
00236 {
00237 DBG(cerr << "Entering AttrTable::append_attr" << endl);
00238 string lname = www2id(name);
00239
00240 Attr_iter iter = simple_find(lname);
00241
00242
00243
00244 if (iter != attr_map.end() && ((*iter)->type != String_to_AttrType(type)))
00245 throw Error(string("An attribute called `") + name
00246 + string("' already exists but is of a different type"));
00247 if (iter != attr_map.end() && (get_type(iter) == "Container"))
00248 throw Error(string("An attribute called `") + name
00249 + string("' already exists but is a container."));
00250
00251 if (iter != attr_map.end()) {
00252 (*iter)->attr->push_back(attribute);
00253 return (*iter)->attr->size();
00254 }
00255 else {
00256 entry *e = new entry;
00257
00258 e->name = lname;
00259 e->is_alias = false;
00260 e->type = String_to_AttrType(type);
00261 e->attr = new vector<string>;
00262 e->attr->push_back(attribute);
00263
00264 attr_map.push_back(e);
00265
00266 return e->attr->size();
00267 }
00268 }
00269
00288 unsigned int
00289 AttrTable::append_attr(const string &name, const string &type,
00290 vector<string> *values)
00291 {
00292 DBG(cerr << "Entering AttrTable::append_attr(..., vector)" << endl);
00293 string lname = www2id(name);
00294
00295 Attr_iter iter = simple_find(lname);
00296
00297
00298
00299 if (iter != attr_map.end() && ((*iter)->type != String_to_AttrType(type)))
00300 throw Error(string("An attribute called `") + name
00301 + string("' already exists but is of a different type"));
00302 if (iter != attr_map.end() && (get_type(iter) == "Container"))
00303 throw Error(string("An attribute called `") + name
00304 + string("' already exists but is a container."));
00305
00306 if (iter != attr_map.end()) {
00307 vector<string>::iterator i = values->begin();
00308 while (i != values->end())
00309 (*iter)->attr->push_back(*i++);
00310
00311 return (*iter)->attr->size();
00312 }
00313 else {
00314 entry *e = new entry;
00315
00316 e->name = lname;
00317 e->is_alias = false;
00318 e->type = String_to_AttrType(type);
00319 e->attr = new vector<string>(*values);
00320
00321 attr_map.push_back(e);
00322
00323 return e->attr->size();
00324 }
00325 }
00326
00335 AttrTable *
00336 AttrTable::append_container(const string &name)
00337 {
00338 AttrTable *new_at = new AttrTable;
00339 AttrTable *ret = NULL;
00340 try {
00341 ret = append_container(new_at, name);
00342 }
00343 catch (Error &e) {
00344
00345 delete new_at; new_at = 0;
00346 throw e;
00347 }
00348 return ret;
00349 }
00350
00363 AttrTable *
00364 AttrTable::append_container(AttrTable *at, const string &name)
00365 {
00366 string lname = www2id(name);
00367
00368 if (simple_find(name) != attr_end())
00369 throw Error(string("There already exists a container called `")
00370 + name + string("' in this attribute table."));
00371 DBG(cerr << "Setting appended attribute container name to: "
00372 << lname << endl);
00373 at->set_name(lname);
00374
00375 entry *e = new entry;
00376 e->name = lname;
00377 e->is_alias = false;
00378 e->type = Attr_container;
00379 e->attributes = at;
00380
00381 attr_map.push_back(e);
00382
00383 at->d_parent = this;
00384
00385 return e->attributes;
00386 }
00387
00402 void
00403 AttrTable::find(const string &target, AttrTable **at, Attr_iter *iter)
00404 {
00405 string::size_type dotpos = target.rfind('.');
00406 if (dotpos != string::npos) {
00407 string container = target.substr(0, dotpos);
00408 string field = target.substr(dotpos + 1);
00409
00410 *at = find_container(container);
00411 if (*at) {
00412 *iter = (*at)->simple_find(field);
00413 }
00414 else {
00415 *iter = attr_map.end();
00416 }
00417 }
00418 else {
00419 *at = recurrsive_find(target, iter);
00420 }
00421 }
00422
00434 AttrTable *
00435 AttrTable::recurrsive_find(const string &target, Attr_iter *location)
00436 {
00437
00438 Attr_iter i = attr_begin();
00439 while (i != attr_end()) {
00440 if (target == (*i)->name) {
00441 *location = i;
00442 return this;
00443 }
00444 else if ((*i)->type == Attr_container) {
00445 AttrTable *at = (*i)->attributes->recurrsive_find(target, location);
00446 if (at)
00447 return at;
00448 }
00449
00450 ++i;
00451 }
00452
00453 *location = i;
00454 return 0;
00455 }
00456
00457
00464 AttrTable::Attr_iter
00465 AttrTable::simple_find(const string &target)
00466 {
00467 Attr_iter i;
00468 for (i = attr_map.begin(); i != attr_map.end(); i++) {
00469 if (target == (*i)->name) {
00470 break;
00471 }
00472 }
00473 return i;
00474 }
00475
00489 AttrTable *
00490 AttrTable::find_container(const string &target)
00491 {
00492 string::size_type dotpos = target.find('.');
00493 if (dotpos != string::npos) {
00494 string container = target.substr(0, dotpos);
00495 string field = target.substr(dotpos + 1);
00496
00497 AttrTable *at = simple_find_container(container);
00498 return (at) ? at->find_container(field) : 0;
00499 }
00500 else {
00501 return simple_find_container(target);
00502 }
00503 }
00504
00505
00506 AttrTable *
00507 AttrTable::simple_find_container(const string &target)
00508 {
00509 if (get_name() == target)
00510 return this;
00511
00512 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); i++) {
00513 if (is_container(i) && target == (*i)->name) {
00514 return (*i)->attributes;
00515 }
00516 }
00517
00518 return 0;
00519 }
00520
00528
00530 AttrTable *
00531 AttrTable::get_attr_table(const string &name)
00532 {
00533 return find_container(name);
00534 }
00535
00537 string
00538 AttrTable::get_type(const string &name)
00539 {
00540 Attr_iter p = simple_find(name);
00541 return (p != attr_map.end()) ? get_type(p) : (string)"";
00542 }
00543
00546 AttrType
00547 AttrTable::get_attr_type(const string &name)
00548 {
00549 Attr_iter p = simple_find(name);
00550 return (p != attr_map.end()) ? get_attr_type(p) : Attr_unknown;
00551 }
00552
00560 unsigned int
00561 AttrTable::get_attr_num(const string &name)
00562 {
00563 Attr_iter iter = simple_find(name);
00564 return (iter != attr_map.end()) ? get_attr_num(iter) : 0;
00565 }
00566
00579 vector<string> *
00580 AttrTable::get_attr_vector(const string &name)
00581 {
00582 Attr_iter p = simple_find(name);
00583 return (p != attr_map.end()) ? get_attr_vector(p) : 0;
00584 }
00585
00602 void
00603 AttrTable::del_attr(const string &name, int i)
00604 {
00605 string lname = www2id(name);
00606
00607 Attr_iter iter = simple_find(lname);
00608 if (iter != attr_map.end()) {
00609 if (i == -1) {
00610 entry *e = *iter;
00611 attr_map.erase(iter);
00612 delete e; e = 0;
00613 }
00614 else {
00615
00616
00617 if ((*iter)->type == Attr_container)
00618 return;
00619
00620 vector<string> *sxp = (*iter)->attr;
00621
00622 assert(i >= 0 && i < (int)sxp->size());
00623 sxp->erase(sxp->begin() + i);
00624 }
00625 }
00626 }
00627
00629
00634 AttrTable::Attr_iter
00635 AttrTable::attr_begin()
00636 {
00637 return attr_map.begin();
00638 }
00639
00643 AttrTable::Attr_iter
00644 AttrTable::attr_end()
00645 {
00646 return attr_map.end();
00647 }
00648
00657 AttrTable::Attr_iter
00658 AttrTable::get_attr_iter(int i)
00659 {
00660 return attr_map.begin() + i;
00661 }
00662
00664 string
00665 AttrTable::get_name(Attr_iter iter)
00666 {
00667 assert(iter != attr_map.end());
00668
00669 return (*iter)->name;
00670 }
00671
00673 bool
00674 AttrTable::is_container(Attr_iter i)
00675 {
00676 return (*i)->type == Attr_container;
00677 }
00678
00684 AttrTable *
00685 AttrTable::get_attr_table(Attr_iter iter)
00686 {
00687 assert(iter != attr_map.end());
00688 return (*iter)->type == Attr_container ? (*iter)->attributes : 0;
00689 }
00690
00699 AttrTable::Attr_iter
00700 AttrTable::del_attr_table(Attr_iter iter)
00701 {
00702 if ((*iter)->type != Attr_container)
00703 return ++iter;
00704
00705
00706
00707
00708 struct entry* e = *iter;
00709
00710 if (e->attributes) {
00711 e->attributes->d_parent = 0;
00712 }
00713 e->attributes = 0;
00714 delete e;
00715
00716 return attr_map.erase(iter);
00717 }
00718
00722 string
00723 AttrTable::get_type(Attr_iter iter)
00724 {
00725 assert(iter != attr_map.end());
00726 return AttrType_to_String((*iter)->type);
00727 }
00728
00732 AttrType
00733 AttrTable::get_attr_type(Attr_iter iter)
00734 {
00735 return (*iter)->type;
00736 }
00737
00745 unsigned int
00746 AttrTable::get_attr_num(Attr_iter iter)
00747 {
00748 assert(iter != attr_map.end());
00749 return ((*iter)->type == Attr_container)
00750 ? (*iter)->attributes->get_size()
00751 : (*iter)->attr->size();
00752 }
00753
00770 string
00771 AttrTable::get_attr(Attr_iter iter, unsigned int i)
00772 {
00773 assert(iter != attr_map.end());
00774 #if 1
00775 return (*iter)->type == Attr_container ? (string)"None" : (*(*iter)->attr)[i];
00776 #else
00777 if ((*iter)->type == Attr_container) {
00778 return "None";
00779 }
00780 else {
00781 cerr << "(*iter)->attr: " << (*iter)->attr << endl;
00782 cerr << "(*iter)->name: " << (*iter)->name << endl;
00783 cerr << "(*iter)->type: " << (*iter)->type << endl;
00784
00785 if ((*iter)->name == "SIS_ID")
00786 return "SIS_ID_value";
00787 else
00788 return (*(*iter)->attr)[i];
00789 }
00790 #endif
00791 }
00792
00793 string
00794 AttrTable::get_attr(const string &name, unsigned int i)
00795 {
00796 Attr_iter p = simple_find(name);
00797 return (p != attr_map.end()) ? get_attr(p, i) : (string)"";
00798 }
00799
00811 vector<string> *
00812 AttrTable::get_attr_vector(Attr_iter iter)
00813 {
00814 assert(iter != attr_map.end());
00815 return (*iter)->type != Attr_container ? (*iter)->attr : 0;
00816 }
00817
00818 bool
00819 AttrTable::is_global_attribute(Attr_iter iter)
00820 {
00821 assert(iter != attr_map.end());
00822 if ((*iter)->type == Attr_container)
00823 return (*iter)->attributes->is_global_attribute();
00824 else
00825 return (*iter)->is_global;
00826 }
00827
00828 void
00829 AttrTable::set_is_global_attribute(Attr_iter iter, bool ga)
00830 {
00831 assert(iter != attr_map.end());
00832 if ((*iter)->type == Attr_container)
00833 (*iter)->attributes->set_is_global_attribute(ga);
00834 else
00835 (*iter)->is_global = ga;
00836 }
00837
00839
00840
00846 void
00847 AttrTable::add_container_alias(const string &name, AttrTable *src)
00848 {
00849 string lname = www2id(name);
00850
00851 if (simple_find(lname) != attr_end())
00852 throw Error(string("There already exists a container called `")
00853 + name + string("in this attribute table."));
00854
00855 entry *e = new entry;
00856 e->name = lname;
00857 e->is_alias = true;
00858 e->aliased_to = src->get_name();
00859 e->type = Attr_container;
00860
00861 e->attributes = src;
00862
00863 attr_map.push_back(e);
00864 }
00865
00878 void
00879 AttrTable::add_value_alias(AttrTable *das, const string &name,
00880 const string &source)
00881 {
00882 string lname = www2id(name);
00883 string lsource = www2id(source);
00884
00885
00886
00887
00888 AttrTable *at;
00889 Attr_iter iter;
00890 das->find(lsource, &at, &iter);
00891
00892
00893
00894
00895
00896 if (!at || (iter == at->attr_end()) || !*iter) {
00897 find(lsource, &at, &iter);
00898 if (!at || (iter == at->attr_end()) || !*iter)
00899 throw Error(string("Could not find the attribute `")
00900 + source + string("' in the attribute object."));
00901 }
00902
00903
00904
00905 if (at && !at->is_container(iter) && this == das)
00906 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."));
00907
00908 if (simple_find(lname) != attr_end())
00909 throw Error(string("There already exists a container called `")
00910 + name + string("in this attribute table."));
00911
00912 entry *e = new entry;
00913 e->name = lname;
00914 e->is_alias = true;
00915 e->aliased_to = lsource;
00916 e->type = get_attr_type(iter);
00917 if (at && e->type == Attr_container)
00918 e->attributes = at->get_attr_table(iter);
00919 else
00920 e->attr = (*iter)->attr;
00921
00922 attr_map.push_back(e);
00923 }
00924
00925
00944 bool
00945 AttrTable::attr_alias(const string &alias, AttrTable *at, const string &name)
00946 {
00947 add_value_alias(at, alias, name);
00948 return true;
00949 }
00950
00958 bool
00959 AttrTable::attr_alias(const string &alias, const string &name)
00960 {
00961 return attr_alias(alias, this, name);
00962 }
00963
00967 void
00968 AttrTable::erase()
00969 {
00970 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); i++) {
00971 delete *i; *i = 0;
00972 }
00973
00974 attr_map.erase(attr_map.begin(), attr_map.end());
00975
00976 d_name = "";
00977 }
00978
00979 const string double_quote = "\"";
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992 static void
00993 write_string_attribute_for_das(ostream &out, const string &value, const string &term)
00994 {
00995 if (is_quoted(value))
00996 out << value << term;
00997 else
00998 out << double_quote << value << double_quote << term;
00999 }
01000
01001 static void
01002 write_string_attribute_for_das(FILE *out, const string &value, const string &term)
01003 {
01004 if (is_quoted(value))
01005 fprintf(out, "%s%s", value.c_str(), term.c_str());
01006 else
01007 fprintf(out, "\"%s\"%s", value.c_str(), term.c_str());
01008 }
01009
01010
01011
01012 static void
01013 write_xml_attribute_for_das(ostream &out, const string &value, const string &term)
01014 {
01015 if (is_quoted(value))
01016 out << escape_double_quotes(value) << term;
01017 else
01018 out << double_quote << escape_double_quotes(value) << double_quote << term;
01019 }
01020
01021 static void
01022 write_xml_attribute_for_das(FILE *out, const string &value, const string &term)
01023 {
01024 if (is_quoted(value))
01025 fprintf(out, "%s%s", escape_double_quotes(value).c_str(), term.c_str());
01026 else
01027 fprintf(out, "\"%s\"%s", escape_double_quotes(value).c_str(), term.c_str());
01028 }
01029
01032 void
01033 AttrTable::simple_print(FILE *out, string pad, Attr_iter i,
01034 bool dereference)
01035 {
01036 switch ((*i)->type) {
01037 case Attr_container:
01038 fprintf(out, "%s%s {\n", pad.c_str(), id2www(get_name(i)).c_str());
01039
01040 (*i)->attributes->print(out, pad + " ", dereference);
01041
01042 fprintf(out, "%s}\n", pad.c_str());
01043 break;
01044
01045 case Attr_string: {
01046 fprintf(out, "%s%s %s ", pad.c_str(), get_type(i).c_str(),
01047 id2www(get_name(i)).c_str());
01048
01049 vector<string> *sxp = (*i)->attr;
01050 vector<string>::iterator last = sxp->end() - 1;
01051 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01052 write_string_attribute_for_das(out, *i, ", ");
01053 }
01054 write_string_attribute_for_das(out, *last, ";\n");
01055 }
01056 break;
01057
01058 case Attr_other_xml: {
01059 fprintf(out, "%s%s %s ", pad.c_str(), get_type(i).c_str(),
01060 id2www(get_name(i)).c_str());
01061
01062 vector<string> *sxp = (*i)->attr;
01063 vector<string>::iterator last = sxp->end() - 1;
01064 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01065 write_xml_attribute_for_das(out, *i, ", ");
01066 }
01067 write_xml_attribute_for_das(out, *last, ";\n");
01068 }
01069 break;
01070
01071 default: {
01072 fprintf(out, "%s%s %s ", pad.c_str(), get_type(i).c_str(),
01073 id2www(get_name(i)).c_str());
01074
01075 vector<string> *sxp = (*i)->attr;
01076 vector<string>::iterator last = sxp->end() - 1;
01077 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01078 fprintf(out, "%s%s", (*i).c_str(), ", ");
01079 }
01080 fprintf(out, "%s%s", (*last).c_str(), ";\n");
01081 }
01082 break;
01083 }
01084 }
01085
01088 void
01089 AttrTable::simple_print(ostream &out, string pad, Attr_iter i,
01090 bool dereference)
01091 {
01092 switch ((*i)->type) {
01093 case Attr_container:
01094 out << pad << id2www(get_name(i)) << " {\n";
01095
01096 (*i)->attributes->print(out, pad + " ", dereference);
01097
01098 out << pad << "}\n";
01099 break;
01100
01101 case Attr_string: {
01102 out << pad << get_type(i) << " " << id2www(get_name(i)) << " ";
01103
01104 vector<string> *sxp = (*i)->attr;
01105 vector<string>::iterator last = sxp->end() - 1;
01106 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01107 write_string_attribute_for_das(out, *i, ", ");
01108 }
01109 write_string_attribute_for_das(out, *last, ";\n");
01110 }
01111 break;
01112
01113 case Attr_other_xml: {
01114 out << pad << get_type(i) << " " << id2www(get_name(i)) << " ";
01115
01116 vector<string> *sxp = (*i)->attr;
01117 vector<string>::iterator last = sxp->end() - 1;
01118 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01119 write_xml_attribute_for_das(out, *i, ", ");
01120 }
01121 write_xml_attribute_for_das(out, *last, ";\n");
01122 }
01123 break;
01124
01125 default: {
01126 out << pad << get_type(i) << " " << id2www(get_name(i)) << " ";
01127
01128 vector<string> *sxp = (*i)->attr;
01129 vector<string>::iterator last = sxp->end() - 1;
01130 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01131 out << *i <<", ";
01132 }
01133 out << *last << ";\n";
01134 }
01135 break;
01136 }
01137 }
01138
01149 void
01150 AttrTable::print(FILE *out, string pad, bool dereference)
01151 {
01152 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); i++) {
01153 if ((*i)->is_alias) {
01154 if (dereference) {
01155 simple_print(out, pad, i, dereference);
01156 }
01157 else {
01158 fprintf(out, "%sAlias %s %s;\n",
01159 pad.c_str(),
01160 id2www(get_name(i)).c_str(),
01161 id2www((*i)->aliased_to).c_str());
01162 }
01163 }
01164 else {
01165 simple_print(out, pad, i, dereference);
01166 }
01167 }
01168 }
01169
01180 void
01181 AttrTable::print(ostream &out, string pad, bool dereference)
01182 {
01183 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); i++) {
01184 if ((*i)->is_alias) {
01185 if (dereference) {
01186 simple_print(out, pad, i, dereference);
01187 }
01188 else {
01189 out << pad << "Alias " << id2www(get_name(i))
01190 << " " << id2www((*i)->aliased_to) << ";\n";
01191 }
01192 }
01193 else {
01194 simple_print(out, pad, i, dereference);
01195 }
01196 }
01197 }
01198
01203 void
01204 AttrTable::print_xml(FILE *out, string pad, bool )
01205 {
01206
01207
01208
01209
01210
01211
01212
01213
01214 for (Attr_iter i = attr_begin(); i != attr_end(); ++i) {
01215 if ((*i)->is_alias) {
01216 fprintf(out, "%s<Alias name=\"%s\" Attribute=\"%s\"/>\n",
01217 pad.c_str(), id2xml(get_name(i)).c_str(),
01218 (*i)->aliased_to.c_str());
01219
01220 }
01221 else if (is_container(i)) {
01222 fprintf(out, "%s<Attribute name=\"%s\" type=\"%s\">\n",
01223 pad.c_str(), id2xml(get_name(i)).c_str(),
01224 get_type(i).c_str());
01225
01226 get_attr_table(i)->print_xml(out, pad + " ");
01227
01228 fprintf(out, "%s</Attribute>\n", pad.c_str());
01229 }
01230 else {
01231 fprintf(out, "%s<Attribute name=\"%s\" type=\"%s\">\n",
01232 pad.c_str(), id2xml(get_name(i)).c_str(), get_type(i).c_str());
01233
01234 string value_pad = pad + " ";
01235
01236
01237
01238 if (get_attr_type(i) == Attr_other_xml) {
01239 if (get_attr_num(i) != 1)
01240 throw Error("OtherXML attributes cannot be vector-valued.");
01241 fprintf(out, "%s%s\n", value_pad.c_str(), get_attr(i, 0).c_str());
01242 }
01243 else {
01244 for (unsigned j = 0; j < get_attr_num(i); ++j) {
01245 fprintf(out, "%s<value>%s</value>\n", value_pad.c_str(),
01246 id2xml(get_attr(i, j)).c_str());
01247 }
01248 }
01249 fprintf(out, "%s</Attribute>\n", pad.c_str());
01250 }
01251 }
01252 }
01253
01258 void
01259 AttrTable::print_xml(ostream &out, string pad, bool )
01260 {
01261 for (Attr_iter i = attr_begin(); i != attr_end(); ++i) {
01262 if ((*i)->is_alias) {
01263 out << pad << "<Alias name=\"" << id2xml(get_name(i))
01264 << "\" Attribute=\"" << (*i)->aliased_to << "\"/>\n";
01265
01266 }
01267 else if (is_container(i)) {
01268 out << pad << "<Attribute name=\"" << id2xml(get_name(i))
01269 << "\" type=\"" << get_type(i) << "\">\n";
01270
01271 get_attr_table(i)->print_xml(out, pad + " ");
01272
01273 out << pad << "</Attribute>\n";
01274 }
01275 else {
01276 out << pad << "<Attribute name=\"" << id2xml(get_name(i))
01277 << "\" type=\"" << get_type(i) << "\">\n";
01278
01279 string value_pad = pad + " ";
01280 if (get_attr_type(i) == Attr_other_xml) {
01281 if (get_attr_num(i) != 1)
01282 throw Error("OtherXML attributes cannot be vector-valued.");
01283 out << value_pad << get_attr(i, 0) << "\n";
01284 }
01285 else {
01286 string value_pad = pad + " ";
01287 for (unsigned j = 0; j < get_attr_num(i); ++j) {
01288 out << value_pad << "<value>" << id2xml(get_attr(i, j)) << "</value>\n";
01289 }
01290 }
01291 out << pad << "</Attribute>\n";
01292 }
01293 }
01294 }
01295
01303 void
01304 AttrTable::dump(ostream &strm) const
01305 {
01306 strm << DapIndent::LMarg << "AttrTable::dump - ("
01307 << (void *)this << ")" << endl;
01308 DapIndent::Indent();
01309 strm << DapIndent::LMarg << "table name: " << d_name << endl;
01310 if (attr_map.size()) {
01311 strm << DapIndent::LMarg << "attributes: " << endl;
01312 DapIndent::Indent();
01313 Attr_citer i = attr_map.begin();
01314 Attr_citer ie = attr_map.end();
01315 for (; i != ie; i++) {
01316 entry *e = (*i);
01317 string type = AttrType_to_String(e->type);
01318 if (e->is_alias) {
01319 strm << DapIndent::LMarg << "alias: " << e->name
01320 << " aliased to: " << e->aliased_to
01321 << endl;
01322 }
01323 else if (e->type == Attr_container) {
01324 strm << DapIndent::LMarg << "attr: " << e->name
01325 << " of type " << type
01326 << endl;
01327 DapIndent::Indent();
01328 e->attributes->dump(strm);
01329 DapIndent::UnIndent();
01330 }
01331 else {
01332 strm << DapIndent::LMarg << "attr: " << e->name
01333 << " of type " << type
01334 << endl;
01335 DapIndent::Indent();
01336 strm << DapIndent::LMarg;
01337 vector<string>::const_iterator iter = e->attr->begin();
01338 vector<string>::const_iterator last = e->attr->end() - 1;
01339 for (; iter != last; iter++) {
01340 strm << (*iter) << ", ";
01341 }
01342 strm << (*(e->attr->end() - 1)) << endl;
01343 DapIndent::UnIndent();
01344 }
01345 }
01346 DapIndent::UnIndent();
01347 }
01348 else {
01349 strm << DapIndent::LMarg << "attributes: empty" << endl;
01350 }
01351 if (d_parent) {
01352 strm << DapIndent::LMarg << "parent table:"
01353 << d_name << ":" << (void *)d_parent << endl;
01354 }
01355 else {
01356 strm << DapIndent::LMarg << "parent table: none" << d_name << endl;
01357 }
01358 DapIndent::UnIndent();
01359 }
01360
01361 }
01362