S3FC project page S3FC home page

Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

s3_config_node.cc

Go to the documentation of this file.
00001 /*
00002  * Stone Three Foundation Class (s3fc) provides a number of utility classes.
00003  * Copyright (C) 2001 by Stone Three Signal Processing (Pty) Ltd.
00004  *
00005  * Authored by Stone Three Signal Processing (Pty) Ltd.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public
00009  * License as published by the Free Software Foundation; either
00010  * version 2.1 of the License, or (at your option) any later version.
00011  * 
00012  * This library is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Lesser General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this library; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  * 
00021  * Please see the file 'COPYING' in the source root directory.
00022  */
00023 
00030 #include <s3fc/s3_config_node.h>
00031 #include <cstdlib>   // atoi
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 // init ctor - init from supplied values and update parent
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 // copy ctor - deep copy and update parent
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 // copy assign - recursive deep, but dont change parent
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 // true if this == &empty_node
00107 bool s3_config_node::empty() const
00108 {
00109    return (this == &empty_node);
00110 }
00111 
00112 // true is parent 0
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    // add child at end
00154    if (&before == &at_end)
00155    {
00156       a_children.push_back(child);
00157       rv = &(a_children.back());
00158    }
00159    // add child somewhere else
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       // insert before before
00170       it = a_children.insert(it, child);
00171       // set parent
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 // const parent return
00213 const s3_config_node& s3_config_node::get_parent() const
00214 {
00215    return *a_parent;
00216 }
00217 
00218 // parent return
00219 s3_config_node& s3_config_node::get_parent()
00220 {
00221    return *a_parent;
00222 }
00223 
00224 // set parent
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 // const attribute return
00255 const std::map<std::string, std::string>& s3_config_node::get_attributes() const
00256 {
00257    return a_attributes;
00258 }
00259 
00260 // attribute return
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 // return child node by ref
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 // child node by ref
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 // return const list of children matching name
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 // return list of children matching name
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 // const return specified node
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 // return specified node
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    // current position - at start
00352    size_t pos = 0;
00353 
00354    // First split path into a vector of child names.
00355    while (true)
00356    {
00357       // find first token starting at pos
00358       unsigned int strt_i = path.find_first_not_of(" \t\n\r:#", pos);
00359       // find ws after token
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    // Next, traverse down the tree.
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       // invalid path - leave
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 

Send comments to: s3fc@stonethree.com SourceForge Logo