Search:

SENF Extensible Network Framework

  • Home
  • Download
  • Wiki
  • BerliOS
  • ChangeLog
  • Browse SVN
  • Bug Tracker
  • Overview
  • Examples
  • HowTos
  • Glossary
  • PPI
  • Packets
  • Scheduler
  • Socket
  • Utils
  • Console
  • Daemon
  • Logger
  • Termlib
  • Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

Node.cc

Go to the documentation of this file.
00001 // $Id: Node.cc 1772 2011-03-10 12:45:21Z tho $
00002 //
00003 // Copyright (C) 2008
00004 // Fraunhofer (FOKUS)
00005 // Competence Center NETwork research (NET), St. Augustin, GERMANY
00006 //     Stefan Bund <g0dil@berlios.de>
00007 //
00008 // This program is free software; you can redistribute it and/or modify
00009 // it under the terms of the GNU General Public License as published by
00010 // the Free Software Foundation; either version 2 of the License, or
00011 // (at your option) any later version.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the
00020 // Free Software Foundation, Inc.,
00021 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00022 
00026 #include "Node.hh"
00027 #include "Node.ih"
00028 
00029 // Custom includes
00030 #include <senf/Utils/Range.hh>
00031 
00032 //#include "Node.mpp"
00033 #define prefix_
00034 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00035 
00036 prefix_ senf::console::DirectoryNode & senf::console::root()
00037 {
00038     static DirectoryNode::ptr rootNode (new DirectoryNode());
00039     return *rootNode;
00040 }
00041 
00042 namespace {
00043     void dodump(std::ostream & output, unsigned level, senf::console::DirectoryNode & node)
00044     {
00045         std::string pad (2*level, ' ');
00046         senf::console::DirectoryNode::child_iterator i (node.children().begin());
00047         senf::console::DirectoryNode::child_iterator const i_end (node.children().end());
00048         for (; i != i_end; ++i) {
00049             output << pad << i->first;
00050             if (i->second->isDirectory()) {
00051                 output << "/\n";
00052                 dodump(output, level+1,static_cast<senf::console::DirectoryNode&>(*i->second));
00053             }
00054             else if (i->second->isLink())
00055                 output << "@ -> " << i->second->followLink().path() << '\n';
00056             else
00057                 output << '\n';
00058         }
00059     }
00060 }
00061 
00062 prefix_ void senf::console::dump(std::ostream & os, DirectoryNode & dir)
00063 {
00064     dodump(os,0,dir);
00065 }
00066 
00067 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00068 // senf::console::GenericNode
00069 
00070 prefix_ std::string senf::console::GenericNode::path()
00071     const
00072 {
00073     std::string path (name());
00074     ptr node (parent());
00075     while (node) {
00076         path = node->name() + "/" + path;
00077         node = node->parent();
00078     }
00079     return path.empty() ? "/" : path;
00080 }
00081 
00082 prefix_ std::string senf::console::GenericNode::path(DirectoryNode const & root)
00083     const
00084 {
00085     std::string path;
00086     cptr node (thisptr());
00087     while (node && node != root.thisptr()) {
00088         if (! path.empty())
00089             path = node->name() + "/" + path;
00090         else
00091             path = node->name();
00092         node = node->parent();
00093     }
00094     if (path.empty() || path[0] != '/')
00095         path = "/" + path;
00096     return path;
00097 }
00098 
00099 prefix_ bool senf::console::GenericNode::active()
00100     const
00101 {
00102     cptr node (thisptr());
00103     while (node->parent())
00104         node = node->parent();
00105     return node == root().thisptr();
00106 }
00107 
00108 prefix_ bool senf::console::GenericNode::isChildOf(DirectoryNode & parent)
00109     const
00110 {
00111     cptr node (thisptr());
00112     while (node && node != parent.thisptr())
00113         node = node->parent();
00114     return node;
00115 }
00116 
00117 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00118 // senf::console::LinkNode
00119 
00120 prefix_ void senf::console::LinkNode::v_help(std::ostream & os)
00121     const
00122 {
00123     follow().help(os);
00124 }
00125 
00126 prefix_ std::string senf::console::LinkNode::v_shorthelp()
00127     const
00128 {
00129     return follow().shorthelp();
00130 }
00131 
00132 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00133 //senf::console::DirectoryNode
00134 
00135 prefix_ senf::console::DirectoryNode::~DirectoryNode()
00136 {
00137     ChildMap::iterator i (children_.begin());
00138     ChildMap::iterator const i_end (children_.end());
00139     for (; i != i_end; ++i)
00140         i->second->parent_ = 0;
00141 }
00142 
00143 prefix_ senf::console::GenericNode::ptr
00144 senf::console::DirectoryNode::remove(std::string const & name)
00145 {
00146     ChildMap::iterator i (children_.find(name));
00147     if (i == children_.end())
00148         throw UnknownNodeNameException() << ": '" << name << "'";
00149     GenericNode::ptr node (i->second);
00150     children_.erase(i);
00151     node->parent_ = 0;
00152     node->name_.clear();
00153     return node;
00154 }
00155 
00156 prefix_ void senf::console::DirectoryNode::add(GenericNode::ptr node)
00157 {
00158     BOOST_ASSERT( ! node->parent() );
00159     if (node->name().empty()) {
00160         node->name("unnamed");
00161         SENF_LOG((senf::log::MESSAGE)("Adding 'unnamed' node"));
00162     }
00163     if (children_.find(node->name()) != children_.end()) {
00164         unsigned suffix (0);
00165         std::string newName;
00166         do {
00167             ++suffix;
00168             newName = node->name() + "-" + boost::lexical_cast<std::string>(suffix);
00169         } while (children_.find(newName) != children_.end());
00170         SENF_LOG((senf::log::MESSAGE)("Uniquifying node '" << node->name() << "' to '"
00171                                       << newName << "'"));
00172         node->name(newName);
00173     }
00174     children_.insert(std::make_pair(node->name(),node));
00175     node->parent_ = this;
00176 }
00177 
00178 prefix_ senf::console::GenericNode &
00179 senf::console::DirectoryNode::getLink(std::string const & name)
00180     const
00181 {
00182     ChildMap::const_iterator i (children_.find(name));
00183     if (i == children_.end())
00184         throw UnknownNodeNameException() << ": '" << name << "'";
00185     return *(i->second);
00186 }
00187 
00188 prefix_ void senf::console::DirectoryNode::v_help(std::ostream & output)
00189     const
00190 {
00191     output << doc_ << "\n";
00192 }
00193 
00194 prefix_ std::string senf::console::DirectoryNode::v_shorthelp()
00195     const
00196 {
00197     if (! shortdoc_.empty())
00198         return shortdoc_;
00199     return doc_.substr(0,doc_.find('\n'));
00200 }
00201 
00202 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00203 // senf::console::detail::NodeTraverser
00204 #ifndef DOXYGEN
00205 
00206 prefix_ void senf::console::detail::NodeTraverser::operator()(std::string const & name)
00207 {
00208     if (! init_) {
00209         init_ = true;
00210         if (name == std::string("")) {
00211             dir_ = root_.thisptr();
00212             return;
00213         }
00214     }
00215     if (! elt_.empty()) {
00216         if (elt_ == "..") {
00217             dir_ = dir_->parent();
00218             if (! dir_ || ! dir_->isChildOf(root_))
00219                 dir_ = root_.thisptr();
00220         }
00221         else if (elt_ != "" && elt_ != ".") {
00222             if (! dir_->hasChild(elt_) && autocomplete_) {
00223                 DirectoryNode::ChildrenRange completions (dir_->completions(elt_));
00224                 if (has_one_elt(completions))
00225                     elt_ = completions.begin()->first;
00226             }
00227             // Why does g++ give an error on this line ???? :
00228             // dir = dynamic_cast<DirectoryNode&>( dir->get(name) ).thisptr();
00229             DirectoryNode & d (dynamic_cast<DirectoryNode&>( dir_->get(elt_) ));
00230             dir_ = d.thisptr();
00231         }
00232     }
00233     elt_ = name;
00234 }
00235 
00236 prefix_ senf::console::GenericNode & senf::console::detail::NodeTraverser::node()
00237 {
00238     if (elt_ != "" && elt_ != ".") {
00239         if (! dir_->hasChild(elt_) && autocomplete_) {
00240             DirectoryNode::ChildrenRange completions (dir_->completions(elt_));
00241             if (has_one_elt(completions))
00242                 elt_ = completions.begin()->first;
00243         }
00244         return dir_->get(elt_);
00245     }
00246     else
00247         return * dir_;
00248 }
00249 #endif
00250 
00251 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00252 // senf::console::SimpleCommandNode
00253 
00254 prefix_ void senf::console::SimpleCommandNode::v_help(std::ostream & output)
00255     const
00256 {
00257     output << doc_ << "\n";
00258 }
00259 
00260 prefix_ std::string senf::console::SimpleCommandNode::v_shorthelp()
00261     const
00262 {
00263     if (! shortdoc_.empty())
00264         return shortdoc_;
00265     return doc_.substr(0,doc_.find('\n'));
00266 }
00267 
00268 prefix_ void senf::console::SimpleCommandNode::v_execute(boost::any & rv, std::ostream & os,
00269                                                          ParseCommandInfo const & command)
00270     const
00271 {
00272     fn_(os, command);
00273 }
00274 
00275 //-/////////////////////////////////////////////////////////////////////////////////////////////////
00276 #undef prefix_
00277 //#include "Node.mpp"
00278 
00279 
00280 // Local Variables:
00281 // mode: c++
00282 // fill-column: 100
00283 // comment-column: 40
00284 // c-file-style: "senf"
00285 // indent-tabs-mode: nil
00286 // ispell-local-dictionary: "american"
00287 // compile-command: "scons -u test"
00288 // End:

Contact: senf-dev@lists.berlios.de | © 2006-2010 Fraunhofer Institute for Open Communication Systems, Network Research