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
00034 #include "config.h"
00035
00036 static char rcsid[] not_used = "$Id: AttrTable.cc 19707 2008-10-08 18:29:21Z 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
00058 AttrType_to_String(const AttrType at)
00059 {
00060 switch (at) {
00061 case Attr_container: return "Container";
00062 case Attr_byte: return "Byte";
00063 case Attr_int16: return "Int16";
00064 case Attr_uint16: return "UInt16";
00065 case Attr_int32: return "Int32";
00066 case Attr_uint32: return "UInt32";
00067 case Attr_float32: return "Float32";
00068 case Attr_float64: return "Float64";
00069 case Attr_string: return "String";
00070 case Attr_url: return "Url";
00071 default: return "";
00072 }
00073 }
00074
00075 AttrType
00076 String_to_AttrType(const string &s)
00077 {
00078 string s2 = s;
00079 downcase(s2);
00080
00081 if (s2 == "container")
00082 return Attr_container;
00083 else if (s2 == "byte")
00084 return Attr_byte;
00085 else if (s2 == "int16")
00086 return Attr_int16;
00087 else if (s2 == "uint16")
00088 return Attr_uint16;
00089 else if (s2 == "int32")
00090 return Attr_int32;
00091 else if (s2 == "uint32")
00092 return Attr_uint32;
00093 else if (s2 == "float32")
00094 return Attr_float32;
00095 else if (s2 == "float64")
00096 return Attr_float64;
00097 else if (s2 == "string")
00098 return Attr_string;
00099 else if (s2 == "url")
00100 return Attr_url;
00101 else
00102 return Attr_unknown;
00103 }
00104
00107 void
00108 AttrTable::clone(const AttrTable &at)
00109 {
00110 d_name = at.d_name;
00111
00112 Attr_citer i = at.attr_map.begin() ;
00113 Attr_citer ie = at.attr_map.end() ;
00114 for (; i != ie; i++) {
00115 entry *e = new entry(*(*i)) ;
00116 attr_map.push_back(e) ;
00117 }
00118
00119 d_parent = at.d_parent;
00120 }
00121
00125 AttrTable::AttrTable() : d_name(""), d_parent(0)
00126 {}
00127
00128 AttrTable::AttrTable(const AttrTable &rhs) : DapObj()
00129 {
00130 clone(rhs);
00131 }
00132
00133
00134 void
00135 AttrTable::delete_attr_table()
00136 {
00137 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); i++) {
00138 delete *i; *i = 0;
00139 }
00140 }
00141
00142 AttrTable::~AttrTable()
00143 {
00144 DBG(cerr << "Entering ~AttrTable (" << this << ")" << endl);
00145 delete_attr_table();
00146 DBG(cerr << "Exiting ~AttrTable" << endl);
00147 }
00148
00149 AttrTable &
00150 AttrTable::operator=(const AttrTable &rhs)
00151 {
00152 if (this != &rhs) {
00153 delete_attr_table();
00154 clone(rhs);
00155 }
00156
00157 return *this;
00158 }
00160
00166 unsigned int
00167 AttrTable::get_size() const
00168 {
00169 return attr_map.size();
00170 }
00171
00174 string
00175 AttrTable::get_name() const
00176 {
00177 return d_name;
00178 }
00179
00182 void
00183 AttrTable::set_name(const string &n)
00184 {
00185 d_name = www2id(n);
00186 }
00187
00205 unsigned int
00206 AttrTable::append_attr(const string &name, const string &type,
00207 const string &attribute)
00208 {
00209 string lname = www2id(name);
00210
00211 Attr_iter iter = simple_find(lname) ;
00212
00213
00214
00215 if (iter != attr_map.end() && ((*iter)->type != String_to_AttrType(type)))
00216 throw Error(string("An attribute called `") + name
00217 + string("' already exists but is of a different type"));
00218 if (iter != attr_map.end() && (get_type(iter) == "Container"))
00219 throw Error(string("An attribute called `") + name
00220 + string("' already exists but is a container."));
00221
00222 if (iter != attr_map.end()) {
00223 (*iter)->attr->push_back(attribute);
00224 return (*iter)->attr->size();
00225 }
00226 else {
00227 entry *e = new entry;
00228
00229 e->name = lname;
00230 e->is_alias = false;
00231 e->type = String_to_AttrType(type);
00232 e->attr = new vector<string>;
00233 e->attr->push_back(attribute);
00234
00235 attr_map.push_back(e);
00236
00237 return e->attr->size();
00238 }
00239 }
00240
00258 unsigned int
00259 AttrTable::append_attr(const string &name, const string &type,
00260 vector<string> *values)
00261 {
00262 string lname = www2id(name);
00263
00264 Attr_iter iter = simple_find(lname) ;
00265
00266
00267
00268 if (iter != attr_map.end() && ((*iter)->type != String_to_AttrType(type)))
00269 throw Error(string("An attribute called `") + name
00270 + string("' already exists but is of a different type"));
00271 if (iter != attr_map.end() && (get_type(iter) == "Container"))
00272 throw Error(string("An attribute called `") + name
00273 + string("' already exists but is a container."));
00274
00275 if (iter != attr_map.end()) {
00276 vector<string>::iterator i = values->begin();
00277 while (i != values->end())
00278 (*iter)->attr->push_back(*i++);
00279
00280 return (*iter)->attr->size();
00281 }
00282 else {
00283 entry *e = new entry;
00284
00285 e->name = lname;
00286 e->is_alias = false;
00287 e->type = String_to_AttrType(type);
00288 e->attr = new vector<string>(*values);
00289
00290 attr_map.push_back(e);
00291
00292 return e->attr->size();
00293 }
00294 }
00295
00304 AttrTable *
00305 AttrTable::append_container(const string &name)
00306 {
00307 AttrTable *new_at = new AttrTable ;
00308 AttrTable *ret = NULL ;
00309 try {
00310 ret = append_container(new_at, name) ;
00311 }
00312 catch (Error &e) {
00313
00314 delete new_at; new_at = 0;
00315 throw e;
00316 }
00317 return ret;
00318 }
00319
00332 AttrTable *
00333 AttrTable::append_container(AttrTable *at, const string &name)
00334 {
00335 string lname = www2id(name);
00336
00337 if (simple_find(name) != attr_end())
00338 throw Error(string("There already exists a container called `")
00339 + name + string("' in this attribute table."));
00340 DBG(cerr << "Setting appended attribute container name to: "
00341 << lname << endl);
00342 at->set_name(lname);
00343
00344 entry *e = new entry;
00345 e->name = lname;
00346 e->is_alias = false;
00347 e->type = Attr_container;
00348 e->attributes = at;
00349
00350 attr_map.push_back(e);
00351
00352 at->d_parent = this;
00353
00354 return e->attributes;
00355 }
00356
00371 void
00372 AttrTable::find(const string &target, AttrTable **at, Attr_iter *iter)
00373 {
00374 string::size_type dotpos = target.rfind('.');
00375 if (dotpos != string::npos) {
00376 string container = target.substr(0, dotpos);
00377 string field = target.substr(dotpos + 1);
00378
00379 *at = find_container(container) ;
00380 if (*at) {
00381 *iter = (*at)->simple_find(field) ;
00382 }
00383 else {
00384 *iter = attr_map.end() ;
00385 }
00386 }
00387 else {
00388 #if 0
00389
00390
00391
00392 *at = this;
00393 *iter = simple_find(target);
00394 #endif
00395 *at = recurrsive_find(target, iter);
00396 }
00397 }
00398
00410 AttrTable *
00411 AttrTable::recurrsive_find(const string &target, Attr_iter *location)
00412 {
00413
00414 Attr_iter i = attr_begin();
00415 while (i != attr_end()) {
00416 if (target == (*i)->name) {
00417 *location = i;
00418 return this;
00419 }
00420 else if ((*i)->type == Attr_container) {
00421 AttrTable *at = (*i)->attributes->recurrsive_find(target, location);
00422 if (at)
00423 return at;
00424 }
00425
00426 ++i;
00427 }
00428
00429 *location = i;
00430 return 0;
00431 }
00432
00433
00440 AttrTable::Attr_iter
00441 AttrTable::simple_find(const string &target)
00442 {
00443 Attr_iter i ;
00444 for (i = attr_map.begin(); i != attr_map.end(); i++) {
00445 if (target == (*i)->name) {
00446 break ;
00447 }
00448 }
00449 return i ;
00450 }
00451
00465 AttrTable *
00466 AttrTable::find_container(const string &target)
00467 {
00468 string::size_type dotpos = target.find('.');
00469 if (dotpos != string::npos) {
00470 string container = target.substr(0, dotpos);
00471 string field = target.substr(dotpos + 1);
00472
00473 AttrTable *at = simple_find_container(container);
00474 return (at) ? at->find_container(field) : 0;
00475 }
00476 else {
00477 return simple_find_container(target);
00478 }
00479 }
00480
00481
00482 AttrTable *
00483 AttrTable::simple_find_container(const string &target)
00484 {
00485 if (get_name() == target)
00486 return this;
00487
00488 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); i++) {
00489 if (is_container(i) && target == (*i)->name) {
00490 return (*i)->attributes;
00491 }
00492 }
00493
00494 return 0;
00495 }
00496
00504
00506 AttrTable *
00507 AttrTable::get_attr_table(const string &name)
00508 {
00509 return find_container(name);
00510 }
00511
00513 string
00514 AttrTable::get_type(const string &name)
00515 {
00516 Attr_iter p = simple_find(name);
00517 return (p != attr_map.end()) ? get_type(p) : (string)"";
00518 }
00519
00522 AttrType
00523 AttrTable::get_attr_type(const string &name)
00524 {
00525 Attr_iter p = simple_find(name);
00526 return (p != attr_map.end()) ? get_attr_type(p) : Attr_unknown;
00527 }
00528
00536 unsigned int
00537 AttrTable::get_attr_num(const string &name)
00538 {
00539 Attr_iter iter = simple_find(name);
00540 return (iter != attr_map.end()) ? get_attr_num(iter) : 0;
00541 }
00542
00555 vector<string> *
00556 AttrTable::get_attr_vector(const string &name)
00557 {
00558 Attr_iter p = simple_find(name);
00559 return (p != attr_map.end()) ? get_attr_vector(p) : 0;
00560 }
00561
00578 void
00579 AttrTable::del_attr(const string &name, int i)
00580 {
00581 string lname = www2id(name);
00582
00583 Attr_iter iter = simple_find(lname) ;
00584 if (iter != attr_map.end()) {
00585 if (i == -1) {
00586 entry *e = *iter ;
00587 attr_map.erase(iter) ;
00588 delete e ; e = 0;
00589 }
00590 else {
00591
00592
00593 if ((*iter)->type == Attr_container)
00594 return;
00595
00596 vector<string> *sxp = (*iter)->attr;
00597
00598 assert(i >= 0 && i < (int)sxp->size());
00599 sxp->erase(sxp->begin() + i);
00600 }
00601 }
00602 }
00603
00605
00610 AttrTable::Attr_iter
00611 AttrTable::attr_begin()
00612 {
00613 return attr_map.begin() ;
00614 }
00615
00619 AttrTable::Attr_iter
00620 AttrTable::attr_end()
00621 {
00622 return attr_map.end() ;
00623 }
00624
00633 AttrTable::Attr_iter
00634 AttrTable::get_attr_iter(int i)
00635 {
00636 return attr_map.begin() + i;
00637 }
00638
00640 string
00641 AttrTable::get_name(Attr_iter iter)
00642 {
00643 assert(iter != attr_map.end()) ;
00644
00645 return (*iter)->name ;
00646 }
00647
00649 bool
00650 AttrTable::is_container(Attr_iter i)
00651 {
00652 return (*i)->type == Attr_container ;
00653 }
00654
00660 AttrTable *
00661 AttrTable::get_attr_table(Attr_iter iter)
00662 {
00663 assert(iter != attr_map.end()) ;
00664 return (*iter)->type == Attr_container ? (*iter)->attributes : 0 ;
00665 }
00666
00674 AttrTable::Attr_iter
00675 AttrTable::del_attr_table(Attr_iter iter)
00676 {
00677 if ((*iter)->type != Attr_container)
00678 return ++iter;
00679
00680 return attr_map.erase(iter);
00681 }
00682
00686 string
00687 AttrTable::get_type(Attr_iter iter)
00688 {
00689 assert(iter != attr_map.end()) ;
00690 return AttrType_to_String((*iter)->type) ;
00691 }
00692
00696 AttrType
00697 AttrTable::get_attr_type(Attr_iter iter)
00698 {
00699 return (*iter)->type ;
00700 }
00701
00709 unsigned int
00710 AttrTable::get_attr_num(Attr_iter iter)
00711 {
00712 assert(iter != attr_map.end()) ;
00713 return ((*iter)->type == Attr_container)
00714 ? (*iter)->attributes->get_size()
00715 : (*iter)->attr->size() ;
00716 }
00717
00734 string
00735 AttrTable::get_attr(Attr_iter iter, unsigned int i)
00736 {
00737 assert(iter != attr_map.end());
00738 #if 1
00739 return (*iter)->type == Attr_container ? (string)"None" : (*(*iter)->attr)[i];
00740 #else
00741 if ((*iter)->type == Attr_container) {
00742 return "None";
00743 }
00744 else {
00745 cerr << "(*iter)->attr: " << (*iter)->attr << endl;
00746 cerr << "(*iter)->name: " << (*iter)->name << endl;
00747 cerr << "(*iter)->type: " << (*iter)->type << endl;
00748
00749 if ((*iter)->name == "SIS_ID")
00750 return "SIS_ID_value";
00751 else
00752 return (*(*iter)->attr)[i];
00753 }
00754 #endif
00755 }
00756
00757 string
00758 AttrTable::get_attr(const string &name, unsigned int i)
00759 {
00760 Attr_iter p = simple_find(name);
00761 return (p != attr_map.end()) ? get_attr(p, i) : (string)"";
00762 }
00763
00775 vector<string> *
00776 AttrTable::get_attr_vector(Attr_iter iter)
00777 {
00778 assert(iter != attr_map.end());
00779 return (*iter)->type != Attr_container ? (*iter)->attr : 0;
00780 }
00781
00783
00784
00790 void
00791 AttrTable::add_container_alias(const string &name, AttrTable *src)
00792 {
00793 string lname = www2id(name);
00794
00795 if (simple_find(lname) != attr_end())
00796 throw Error(string("There already exists a container called `")
00797 + name + string("in this attribute table."));
00798
00799 entry *e = new entry;
00800 e->name = lname;
00801 e->is_alias = true;
00802 e->aliased_to = src->get_name();
00803 e->type = Attr_container;
00804
00805 e->attributes = src;
00806
00807 attr_map.push_back(e);
00808 }
00809
00822 void
00823 AttrTable::add_value_alias(AttrTable *das, const string &name,
00824 const string &source)
00825 {
00826 string lname = www2id(name);
00827 string lsource = www2id(source);
00828
00829
00830
00831
00832 AttrTable *at;
00833 Attr_iter iter;
00834 das->find(lsource, &at, &iter);
00835
00836
00837
00838
00839
00840 if (!at || (iter == at->attr_end()) || !*iter) {
00841 find(lsource, &at, &iter);
00842 if (!at || (iter == at->attr_end()) || !*iter)
00843 throw Error(string("Could not find the attribute `")
00844 + source + string("' in the attribute object."));
00845 }
00846
00847
00848
00849 if (at && !at->is_container(iter) && this == das)
00850 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."));
00851
00852 if (simple_find(lname) != attr_end())
00853 throw Error(string("There already exists a container called `")
00854 + name + string("in this attribute table."));
00855
00856 entry *e = new entry;
00857 e->name = lname;
00858 e->is_alias = true;
00859 e->aliased_to = lsource;
00860 e->type = get_attr_type(iter);
00861 if (at && e->type == Attr_container)
00862 e->attributes = at->get_attr_table(iter);
00863 else
00864 e->attr = (*iter)->attr;
00865
00866 attr_map.push_back(e);
00867 }
00868
00869
00888 bool
00889 AttrTable::attr_alias(const string &alias, AttrTable *at, const string &name)
00890 {
00891 add_value_alias(at, alias, name);
00892 return true;
00893 }
00894
00902 bool
00903 AttrTable::attr_alias(const string &alias, const string &name)
00904 {
00905 return attr_alias(alias, this, name);
00906 }
00907
00911 void
00912 AttrTable::erase()
00913 {
00914 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); i++) {
00915 delete *i; *i = 0;
00916 }
00917
00918 attr_map.erase(attr_map.begin(), attr_map.end());
00919
00920 d_name = "";
00921 }
00922
00923
00924 const string double_quote = "\"";
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936 static void
00937 write_string_attribute_for_das(ostream &out, const string &value, const string &term)
00938 {
00939 if (is_quoted(value))
00940 out << value << term;
00941 else
00942 out << double_quote << value << double_quote << term;
00943 }
00944
00945 static void
00946 write_string_attribute_for_das(FILE *out, const string &value, const string &term)
00947 {
00948 if (is_quoted(value))
00949 fprintf(out, "%s%s", value.c_str(), term.c_str());
00950 else
00951 fprintf(out, "\"%s\"%s", value.c_str(), term.c_str());
00952 }
00953
00954
00957 void
00958 AttrTable::simple_print(FILE *out, string pad, Attr_iter i,
00959 bool dereference)
00960 {
00961 switch ((*i)->type) {
00962 case Attr_container:
00963 fprintf(out, "%s%s {\n", pad.c_str(), id2www(get_name(i)).c_str());
00964
00965 (*i)->attributes->print(out, pad + " ", dereference);
00966
00967 fprintf(out, "%s}\n", pad.c_str());
00968 break;
00969
00970 case Attr_string: {
00971 fprintf(out, "%s%s %s ", pad.c_str(), get_type(i).c_str(),
00972 id2www(get_name(i)).c_str());
00973
00974 vector<string> *sxp = (*i)->attr;
00975 vector<string>::iterator last = sxp->end() - 1;
00976 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
00977 write_string_attribute_for_das(out, *i, ", ");
00978 }
00979 write_string_attribute_for_das(out, *last, ";\n");
00980 }
00981 break;
00982
00983 default: {
00984 fprintf(out, "%s%s %s ", pad.c_str(), get_type(i).c_str(),
00985 id2www(get_name(i)).c_str());
00986
00987 vector<string> *sxp = (*i)->attr;
00988 vector<string>::iterator last = sxp->end() - 1;
00989 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
00990 fprintf(out, "%s%s", (*i).c_str(), ", ");
00991 }
00992 fprintf(out, "%s%s", (*last).c_str(), ";\n");
00993 }
00994 break;
00995 }
00996 }
00997
01000 void
01001 AttrTable::simple_print(ostream &out, string pad, Attr_iter i,
01002 bool dereference)
01003 {
01004 switch ((*i)->type) {
01005 case Attr_container:
01006 out << pad << id2www(get_name(i)) << " {\n";
01007
01008 (*i)->attributes->print(out, pad + " ", dereference);
01009
01010 out << pad << "}\n";
01011 break;
01012
01013 case Attr_string: {
01014 out << pad << get_type(i) << " " << id2www(get_name(i)) << " ";
01015
01016 vector<string> *sxp = (*i)->attr;
01017 vector<string>::iterator last = sxp->end() - 1;
01018 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01019 write_string_attribute_for_das(out, *i, ", ");
01020 }
01021 write_string_attribute_for_das(out, *last, ";\n");
01022 }
01023 break;
01024
01025 default: {
01026 out << pad << get_type(i) << " " << id2www(get_name(i)) << " ";
01027
01028 vector<string> *sxp = (*i)->attr;
01029 vector<string>::iterator last = sxp->end() - 1;
01030 for (vector<string>::iterator i = sxp->begin(); i != last; ++i) {
01031 out << *i <<", ";
01032 }
01033 out << *last << ";\n";
01034 }
01035 break;
01036 }
01037 }
01038
01049 void
01050 AttrTable::print(FILE *out, string pad, bool dereference)
01051 {
01052 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); i++) {
01053 if ((*i)->is_alias) {
01054 if (dereference) {
01055 simple_print(out, pad, i, dereference);
01056 }
01057 else {
01058 fprintf(out, "%sAlias %s %s;\n",
01059 pad.c_str(),
01060 id2www(get_name(i)).c_str(),
01061 id2www((*i)->aliased_to).c_str()) ;
01062 }
01063 }
01064 else {
01065 simple_print(out, pad, i, dereference);
01066 }
01067 }
01068 }
01069
01080 void
01081 AttrTable::print(ostream &out, string pad, bool dereference)
01082 {
01083 for (Attr_iter i = attr_map.begin(); i != attr_map.end(); i++) {
01084 if ((*i)->is_alias) {
01085 if (dereference) {
01086 simple_print(out, pad, i, dereference);
01087 }
01088 else {
01089 out << pad << "Alias " << id2www(get_name(i))
01090 << " " << id2www((*i)->aliased_to) << ";\n";
01091 }
01092 }
01093 else {
01094 simple_print(out, pad, i, dereference);
01095 }
01096 }
01097 }
01098
01104 void
01105 AttrTable::print_xml(FILE *out, string pad, bool constrained)
01106 {
01107
01108
01109
01110
01111
01112
01113
01114
01115 for (Attr_iter i = attr_begin(); i != attr_end(); ++i) {
01116
01117
01118
01119
01120
01121 if ((*i)->is_alias) {
01122 fprintf(out, "%s<Alias name=\"%s\" Attribute=\"%s\"/>\n",
01123 pad.c_str(), id2xml(get_name(i)).c_str(),
01124 (*i)->aliased_to.c_str());
01125
01126 }
01127 else if (is_container(i)) {
01128 fprintf(out, "%s<Attribute name=\"%s\" type=\"%s\">\n",
01129 pad.c_str(), id2xml(get_name(i)).c_str(),
01130 get_type(i).c_str());
01131
01132 get_attr_table(i)->print_xml(out, pad + " ", constrained);
01133
01134 fprintf(out, "%s</Attribute>\n", pad.c_str());
01135 }
01136 else {
01137 fprintf(out, "%s<Attribute name=\"%s\" type=\"%s\">\n",
01138 pad.c_str(), id2xml(get_name(i)).c_str(), get_type(i).c_str());
01139
01140 string value_pad = pad + " ";
01141 for (unsigned j = 0; j < get_attr_num(i); ++j) {
01142 fprintf(out, "%s<value>%s</value>\n", value_pad.c_str(),
01143 id2xml(get_attr(i, j)).c_str());
01144 }
01145
01146 fprintf(out, "%s</Attribute>\n", pad.c_str());
01147 }
01148 }
01149 }
01150
01156 void
01157 AttrTable::print_xml(ostream &out, string pad, bool constrained)
01158 {
01159
01160
01161
01162
01163
01164
01165
01166
01167 for (Attr_iter i = attr_begin(); i != attr_end(); ++i) {
01168
01169
01170
01171
01172
01173 if ((*i)->is_alias) {
01174 out << pad << "<Alias name=\"" << id2xml(get_name(i))
01175 << "\" Attribute=\"" << (*i)->aliased_to << "\"/>\n" ;
01176
01177 }
01178 else if (is_container(i)) {
01179 out << pad << "<Attribute name=\"" << id2xml(get_name(i))
01180 << "\" type=\"" << get_type(i) << "\">\n" ;
01181
01182 get_attr_table(i)->print_xml(out, pad + " ", constrained);
01183
01184 out << pad << "</Attribute>\n" ;
01185 }
01186 else {
01187 out << pad << "<Attribute name=\"" << id2xml(get_name(i))
01188 << "\" type=\"" << get_type(i) << "\">\n" ;
01189
01190 string value_pad = pad + " ";
01191 for (unsigned j = 0; j < get_attr_num(i); ++j) {
01192 out << value_pad << "<value>" << id2xml(get_attr(i, j)) << "</value>\n" ;
01193 }
01194
01195 out << pad << "</Attribute>\n" ;
01196 }
01197 }
01198 }
01199
01207 void
01208 AttrTable::dump(ostream &strm) const
01209 {
01210 strm << DapIndent::LMarg << "AttrTable::dump - ("
01211 << (void *)this << ")" << endl ;
01212 DapIndent::Indent() ;
01213 strm << DapIndent::LMarg << "table name: " << d_name << endl ;
01214 if (attr_map.size()) {
01215 strm << DapIndent::LMarg << "attributes: " << endl ;
01216 DapIndent::Indent() ;
01217 Attr_citer i = attr_map.begin() ;
01218 Attr_citer ie = attr_map.end() ;
01219 for (; i != ie; i++) {
01220 entry *e = (*i) ;
01221 string type = AttrType_to_String(e->type) ;
01222 if (e->is_alias) {
01223 strm << DapIndent::LMarg << "alias: " << e->name
01224 << " aliased to: " << e->aliased_to
01225 << endl ;
01226 }
01227 else if (e->type == Attr_container) {
01228 strm << DapIndent::LMarg << "attr: " << e->name
01229 << " of type " << type
01230 << endl ;
01231 DapIndent::Indent() ;
01232 e->attributes->dump(strm) ;
01233 DapIndent::UnIndent() ;
01234 }
01235 else {
01236 strm << DapIndent::LMarg << "attr: " << e->name
01237 << " of type " << type
01238 << endl ;
01239 DapIndent::Indent() ;
01240 strm << DapIndent::LMarg ;
01241 vector<string>::const_iterator iter = e->attr->begin() ;
01242 vector<string>::const_iterator last = e->attr->end() - 1 ;
01243 for (; iter != last; iter++) {
01244 strm << (*iter) << ", " ;
01245 }
01246 strm << (*(e->attr->end() - 1)) << endl ;
01247 DapIndent::UnIndent() ;
01248 }
01249 }
01250 DapIndent::UnIndent() ;
01251 }
01252 else {
01253 strm << DapIndent::LMarg << "attributes: empty" << endl ;
01254 }
01255 if (d_parent) {
01256 strm << DapIndent::LMarg << "parent table:"
01257 << d_name << ":" << (void *)d_parent << endl ;
01258 }
01259 else {
01260 strm << DapIndent::LMarg << "parent table: none" << d_name << endl ;
01261 }
01262 DapIndent::UnIndent() ;
01263 }
01264
01265 }
01266