00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00030 #include <s3fc/s3_config_node.h>
00031 #include <cstdlib>
00032 #include <sstream>
00033 #include <string>
00034
00035 s3_config_node s3_config_node::empty_node;
00036 s3_config_node s3_config_node::at_end;
00037
00038
00039 #if 0
00040 void s3_config_node::dump() const
00041 {
00042 std::cerr << endl
00043 << " n: " << name << std::endl
00044 << " v: " << value << std::endl
00045 << " p: " << parent << std::endl
00046 << " e: " << &empty_node << std::endl
00047 << " t: " << this << std::endl
00048 << std::endl << std::flush;
00049 }
00050 #endif
00051
00052
00053 s3_config_node::s3_config_node(
00054 const std::string& n_name,
00055 const std::string& n_value,
00056 const s3_config_node* n_parent,
00057 const std::map<std::string,std::string>& n_attributes,
00058 const std::vector<s3_config_node>& n_children) :
00059 a_name(n_name),
00060 a_value(n_value),
00061 a_parent(const_cast<s3_config_node*>(n_parent)),
00062 a_attributes(n_attributes),
00063 a_children(n_children)
00064 {
00065 for (std::vector<s3_config_node>::iterator it = a_children.begin();
00066 it != a_children.end();
00067 it++)
00068 {
00069 it->a_parent = this;
00070 }
00071 }
00072
00073
00074 s3_config_node::s3_config_node(const s3_config_node& src) :
00075 a_name(src.a_name),
00076 a_value(src.a_value),
00077 a_parent(&empty_node),
00078 a_attributes(src.a_attributes),
00079 a_children(src.a_children)
00080 {
00081 for (std::vector<s3_config_node>::iterator it = a_children.begin();
00082 it != a_children.end();
00083 it++)
00084 {
00085 it->a_parent = this;
00086 }
00087 }
00088
00089
00090 s3_config_node& s3_config_node::operator=(const s3_config_node& src)
00091 {
00092 a_name = src.a_name;
00093 a_value = src.a_value;
00094 a_parent = &empty_node;
00095 a_attributes = src.a_attributes;
00096 a_children = src.a_children;
00097 for (std::vector<s3_config_node>::iterator it = a_children.begin();
00098 it != a_children.end();
00099 it++)
00100 {
00101 it->a_parent = this;
00102 }
00103 return *this;
00104 }
00105
00106
00107 bool s3_config_node::empty() const
00108 {
00109 return (this == &empty_node);
00110 }
00111
00112
00113 bool s3_config_node::is_rootnode() const
00114 {
00115 return (a_parent == &empty_node);
00116 }
00117
00118
00119 s3_config_node*& s3_config_node::parent()
00120 {
00121 return a_parent;
00122 }
00123
00124
00125 std::string& s3_config_node::name()
00126 {
00127 return a_name;
00128 }
00129
00130
00131 std::string& s3_config_node::value()
00132 {
00133 return a_value;
00134 }
00135
00136
00137 std::map<std::string, std::string>& s3_config_node::attributes()
00138 {
00139 return a_attributes;
00140 }
00141
00142
00143 std::vector<s3_config_node>& s3_config_node::children()
00144 {
00145 return a_children;
00146 }
00147
00148
00149 s3_config_node* s3_config_node::insert_child(const s3_config_node& child,
00150 const s3_config_node& before)
00151 {
00152 s3_config_node* rv;
00153
00154 if (&before == &at_end)
00155 {
00156 a_children.push_back(child);
00157 rv = &(a_children.back());
00158 }
00159
00160 else
00161 {
00162 std::vector<s3_config_node>::iterator it = find_child(child);
00163 if (it == a_children.end())
00164 {
00165 throw s3_generic_exception("s3_config_node::insert_child()",
00166 "Precondition violation: "
00167 "find_children(before) != a_children.end()");
00168 }
00169
00170 it = a_children.insert(it, child);
00171
00172 it->a_parent = this;
00173 rv = &(*it);
00174 }
00175 return rv;
00176 }
00177
00178
00179 void s3_config_node::remove_child(const s3_config_node& child)
00180 {
00181 std::vector<s3_config_node>::iterator it = find_child(child);
00182 if (it == a_children.end())
00183 {
00184 throw s3_generic_exception("s3_config_node::remove_child()",
00185 "Precondition violation: "
00186 "find_children(child) != a_children.end()");
00187 }
00188 a_children.erase(it);
00189 }
00190
00191
00192 std::vector<s3_config_node>::iterator s3_config_node::find_child(
00193 const s3_config_node& child)
00194 {
00195 bool found = false;
00196 std::vector<s3_config_node>::iterator it;
00197 for(it = a_children.begin(); it != a_children.end(); it++)
00198 {
00199 if (&(*it) == &child)
00200 {
00201 found = true;
00202 break;
00203 }
00204 }
00205 if (! found)
00206 {
00207 it = a_children.end();
00208 }
00209 return it;
00210 }
00211
00212
00213 const s3_config_node& s3_config_node::get_parent() const
00214 {
00215 return *a_parent;
00216 }
00217
00218
00219 s3_config_node& s3_config_node::get_parent()
00220 {
00221 return *a_parent;
00222 }
00223
00224
00225 void s3_config_node::set_parent(s3_config_node& n_parent)
00226 {
00227 a_parent = &n_parent;
00228 }
00229
00230
00231 const std::string& s3_config_node::get_name() const
00232 {
00233 return a_name;
00234 }
00235
00236
00237 void s3_config_node::set_name(const std::string& n_name)
00238 {
00239 a_name = n_name;
00240 }
00241
00242
00243 const std::string& s3_config_node::get_value() const
00244 {
00245 return a_value;
00246 }
00247
00248
00249 void s3_config_node::set_value(const std::string& n_value)
00250 {
00251 a_value = n_value;
00252 }
00253
00254
00255 const std::map<std::string, std::string>& s3_config_node::get_attributes() const
00256 {
00257 return a_attributes;
00258 }
00259
00260
00261 std::map<std::string, std::string>& s3_config_node::get_attributes()
00262 {
00263 return a_attributes;
00264 }
00265
00266
00267 unsigned int s3_config_node::get_num_children() const
00268 {
00269 return a_children.size();
00270 }
00271
00272
00273 const s3_config_node& s3_config_node::get_child(unsigned int i) const
00274 {
00275 if (! (i < get_num_children()) )
00276 {
00277 throw s3_generic_exception("s3_config_node::get_child()",
00278 "Precondition violation: "
00279 "i < get_num_children()");
00280 }
00281 return a_children[i];
00282 }
00283
00284
00285 s3_config_node& s3_config_node::get_child(unsigned int i)
00286 {
00287 return const_cast<s3_config_node&>(
00288 const_cast<const s3_config_node*>(this)->get_child(i));
00289 }
00290
00291
00292 const std::vector<const s3_config_node*>
00293 s3_config_node::get_children(const std::string& name_filter) const
00294 {
00295 std::vector<const s3_config_node*> lst;
00296
00297 for (std::vector<s3_config_node>::const_iterator it = a_children.begin();
00298 it != a_children.end();
00299 ++it)
00300 {
00301 if ( (name_filter == "") || (it->get_name() == name_filter) )
00302 {
00303 lst.push_back(&(*it));
00304 }
00305 }
00306 return lst;
00307 }
00308
00309
00310 std::vector<s3_config_node*>
00311 s3_config_node::get_children(const std::string& name_filter)
00312 {
00313 std::vector<const s3_config_node*> lst =
00314 const_cast<const s3_config_node*>(this)->get_children(name_filter);
00315 return reinterpret_cast<std::vector<s3_config_node*>&>(lst);
00316 }
00317
00318
00319 bool s3_config_node::node_exists(const std::string& path) const
00320 {
00321 const s3_config_node* nptr = gna_helper(path);
00322 return (nptr != 0);
00323 }
00324
00325
00326 const s3_config_node&
00327 s3_config_node::get_node_at(const std::string& path) const
00328 {
00329 const s3_config_node* nptr = gna_helper(path);
00330 if (nptr == 0)
00331 {
00332 throw s3_generic_exception("s3_config_node::get_child()",
00333 "Precondition violation: "
00334 "i < get_num_children()");
00335 }
00336 return *nptr;
00337 }
00338
00339
00340 s3_config_node&
00341 s3_config_node::get_node_at(const std::string& path)
00342 {
00343 return const_cast<s3_config_node&>(
00344 const_cast<const s3_config_node*>(this)->get_node_at(path));
00345 }
00346
00347
00348 const s3_config_node* s3_config_node::gna_helper(const std::string& path) const
00349 {
00350 std::vector<std::string> vs;
00351
00352 size_t pos = 0;
00353
00354
00355 while (true)
00356 {
00357
00358 unsigned int strt_i = path.find_first_not_of(" \t\n\r:#", pos);
00359
00360 unsigned int end_i = path.find_first_of(":", strt_i);
00361 if (strt_i != std::string::npos)
00362 {
00363 vs.push_back(path.substr(strt_i, end_i - strt_i));
00364 pos = end_i;
00365 }
00366 else
00367 {
00368 break;
00369 }
00370 }
00371
00372 std::string name;
00373 unsigned int idx;
00374 const s3_config_node* node = this;
00375
00376
00377 std::vector<const s3_config_node*> child_list;
00378
00379
00380 for (std::vector<std::string>::const_iterator ptr = vs.begin();
00381 ptr != vs.end();
00382 ptr++)
00383 {
00384 unsigned int i_pos = ptr->find_first_of("#", 0);
00385 idx = 0;
00386 if (i_pos != std::string::npos)
00387 {
00388 name = ptr->substr(0, i_pos);
00389 if (i_pos < ptr->size() - 1)
00390 {
00391 idx=atoi((ptr->substr(i_pos + 1, ptr->size() - i_pos - 1)).c_str());
00392 }
00393 }
00394 else
00395 {
00396 name = *ptr;
00397 }
00398 child_list = node->get_children(name);
00399
00400 if (child_list.size() < (idx + 1))
00401 {
00402 node = 0;
00403 break;
00404 }
00405 node = child_list[idx];
00406 }
00407 return node;
00408 }
00409