Node.cc
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
17 #include "Node.hh"
18 
19 // Custom includes
20 #include <senf/Utils/Range.hh>
21 
22 //#include "Node.mpp"
23 #define prefix_
24 //-/////////////////////////////////////////////////////////////////////////////////////////////////
25 
27 {
28  static DirectoryNode::ptr rootNode (new DirectoryNode());
29  return *rootNode;
30 }
31 
32 namespace {
33  void dodump(std::ostream & output, unsigned level, senf::console::DirectoryNode & node)
34  {
35  std::string pad (2*level, ' ');
37  senf::console::DirectoryNode::child_iterator const i_end (node.children().end());
38  for (; i != i_end; ++i) {
39  output << pad << i->first;
40  if (i->second->isDirectory()) {
41  output << "/\n";
42  dodump(output, level+1,static_cast<senf::console::DirectoryNode&>(*i->second));
43  }
44  else if (i->second->isLink())
45  output << "@ -> " << i->second->followLink().path() << '\n';
46  else
47  output << '\n';
48  }
49  }
50 }
51 
52 prefix_ void senf::console::dump(std::ostream & os, DirectoryNode & dir)
53 {
54  dodump(os,0,dir);
55 }
56 
58 {
59  DirectoryNode::child_iterator child (from.children().begin());
60  while (child != from.children().end()) {
61  std::string name (child->first);
62  ++child;
63  to.add(name, from.remove(name));
64  }
65 }
66 
67 //-/////////////////////////////////////////////////////////////////////////////////////////////////
68 // senf::console::GenericNode
69 
71  const
72 {
73  std::string path (name());
74  ptr node (parent());
75  while (node) {
76  path = node->name() + "/" + path;
77  node = node->parent();
78  }
79  return path.empty() ? "/" : path;
80 }
81 
83  const
84 {
85  std::string path;
86  cptr node (thisptr());
87  while (node && node != root.thisptr()) {
88  if (! path.empty())
89  path = node->name() + "/" + path;
90  else
91  path = node->name();
92  node = node->parent();
93  }
94  if (path.empty() || path[0] != '/')
95  path = "/" + path;
96  return path;
97 }
98 
100  const
101 {
102  cptr node (thisptr());
103  while (node->parent())
104  node = node->parent();
105  return node == root().thisptr();
106 }
107 
109  const
110 {
111  cptr node (thisptr());
112  while (node && node != parent.thisptr())
113  node = node->parent();
114  return node.get() != 0;
115 }
116 
117 prefix_ void senf::console::GenericNode::rename(std::string const & newName)
118 {
119  DirectoryNode::ptr myParent (parent());
120  if (myParent)
121  myParent->add( newName, unlink());
122 }
123 
124 //-/////////////////////////////////////////////////////////////////////////////////////////////////
125 // senf::console::LinkNode
126 
127 prefix_ void senf::console::LinkNode::v_help(std::ostream & os)
128  const
129 {
130  follow().help(os);
131 }
132 
133 prefix_ std::string senf::console::LinkNode::v_shorthelp()
134  const
135 {
136  return follow().shorthelp();
137 }
138 
139 //-/////////////////////////////////////////////////////////////////////////////////////////////////
140 //senf::console::DirectoryNode
141 
143 {
144  ChildMap::iterator i (children_.begin());
145  ChildMap::iterator const i_end (children_.end());
146  for (; i != i_end; ++i)
147  i->second->parent_ = 0;
148 }
149 
152 {
153  try {
154  return remove( name);
155  } catch (UnknownNodeNameException &) {}
156  return ptr();
157 }
158 
161 {
162  ChildMap::iterator i (children_.find(name));
163  if (i == children_.end())
164  throw UnknownNodeNameException() << ": '" << name << "'";
165  GenericNode::ptr node (i->second);
166  children_.erase(i);
167  node->parent_ = 0;
168  node->name_.clear();
169  return node;
170 }
171 
173 {
174  BOOST_ASSERT( ! node->parent() );
175  if (node->name().empty()) {
176  node->name("unnamed");
177  SENF_LOG((senf::log::MESSAGE)("Adding 'unnamed' node"));
178  }
179  if (children_.find(node->name()) != children_.end()) {
180  unsigned suffix (0);
181  std::string newName;
182  do {
183  ++suffix;
184  newName = node->name() + "-" + boost::lexical_cast<std::string>(suffix);
185  } while (children_.find(newName) != children_.end());
186  SENF_LOG((senf::log::MESSAGE)("Uniquifying node '" << node->name() << "' to '"
187  << newName << "'"));
188  node->name(newName);
189  }
190  children_.insert(std::make_pair(node->name(),node));
191  node->parent_ = this;
192 }
193 
196  const
197 {
198  ChildMap::const_iterator i (children_.find(name));
199  if (i == children_.end())
200  throw UnknownNodeNameException() << ": '" << name << "'";
201  return *(i->second);
202 }
203 
204 prefix_ void senf::console::DirectoryNode::v_help(std::ostream & output)
205  const
206 {
207  output << doc_ << "\n";
208 }
209 
210 prefix_ std::string senf::console::DirectoryNode::v_shorthelp()
211  const
212 {
213  if (! shortdoc_.empty())
214  return shortdoc_;
215  return doc_.substr(0,doc_.find('\n'));
216 }
217 
218 //-/////////////////////////////////////////////////////////////////////////////////////////////////
219 // senf::console::SimpleCommandNode
220 
221 prefix_ void senf::console::SimpleCommandNode::v_help(std::ostream & output)
222  const
223 {
224  output << doc_ << "\n";
225 }
226 
227 prefix_ std::string senf::console::SimpleCommandNode::v_shorthelp()
228  const
229 {
230  if (! shortdoc_.empty())
231  return shortdoc_;
232  return doc_.substr(0,doc_.find('\n'));
233 }
234 
235 prefix_ void senf::console::SimpleCommandNode::v_execute(boost::any & rv, std::ostream & os,
236  ParseCommandInfo const & command)
237  const
238 {
239  fn_(os, command);
240 }
241 
242 //-/////////////////////////////////////////////////////////////////////////////////////////////////
243 #undef prefix_
244 //#include "Node.mpp"
245 
246 
247 // Local Variables:
248 // mode: c++
249 // fill-column: 100
250 // comment-column: 40
251 // c-file-style: "senf"
252 // indent-tabs-mode: nil
253 // ispell-local-dictionary: "american"
254 // compile-command: "scons -u test"
255 // End:
ptr thisptr()
Get smart pointer to node.
boost::shared_ptr< DirectoryNode > ptr
Definition: Node.hh:414
#define prefix_
Definition: Node.cc:23
Config/console tree directory node.
Definition: Node.hh:406
bool active() const
true, if node is attached to the root() node
Definition: Node.cc:99
Node public header.
Single parsed console command.
Definition: Parse.hh:363
void dump(std::ostream &os, DirectoryNode &dir=root())
Dump console directory structure.
Definition: Node.cc:52
std::string const & name() const
Node name.
NodeType & add(std::string const &name, boost::shared_ptr< NodeType > node)
Add node to tree.
boost::shared_ptr< GenericNode const > cptr
Definition: Node.hh:259
GenericNode & getLink(std::string const &name) const
Get child node without dereferencing links.
Definition: Node.cc:195
void rename(std::string const &newName)
Rename node name in it&#39;s parent directory.
Definition: Node.cc:117
ChildMap::const_iterator child_iterator
Definition: Node.hh:419
void moveChildren(DirectoryNode &from, DirectoryNode &to)
Definition: Node.cc:57
DirectoryNode & root()
Get console root node.
Definition: Node.cc:26
NoThrow_t
boost::shared_ptr< DirectoryNode > parent() const
Parent node.
ChildrenRange children() const
Return iterator range over all children.
unspecified_keyword_type name
Argument name.
Config/console node tree base-class.
Definition: Node.hh:250
GenericNode::ptr remove(std::string const &name)
Remove node name from the tree.
Definition: Node.cc:160
#define SENF_LOG(args)
boost::shared_ptr< GenericNode > ptr
Definition: Node.hh:253
Exception: Unknown node name.
Definition: Node.hh:548
ptr unlink()
Remove node from it&#39;s parent directory.
std::string path() const
Node path.
Definition: Node.cc:70
bool isChildOf(DirectoryNode &parent) const
true, if node is a child of parent
Definition: Node.cc:108