1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3 * Copyright (c) 2009 University of Washington
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation;
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19 #ifndef OBJECT_NAMES_H
20 #define OBJECT_NAMES_H
21
22 #include "ptr.h"
23 #include "object.h"
24
25 /**
26 * \file
27 * \ingroup config
28 * Declaration of class ns3::Names.
29 */
30
31 namespace ns3 {
32
33 /**
34 * \ingroup config
35 * \brief A directory of name and Ptr<Object> associations that allows
36 * us to give any ns3 Object a name.
37 */
38 class Names
39 {
40 public:
41
42 /**
43 * \brief Add the association between the string "name" and the
44 * Ptr<Object> obj.
45 *
46 * The name may begin either with "/Names" to explicitly call out
47 * the fact that the name provided is installed under the root of
48 * the name space, or it may begin with the name of the first object
49 * in the path. For example, Names::Add ("/Names/client", obj) and
50 * Names::Add ("client", obj) accomplish exactly the same thing. A
51 * name at a given level in the name space path must be unique. In
52 * the case of the example above, it would be illegal to try and
53 * associate a different object with the same name: "client" at the
54 * same level ("/Names") in the path.
55 *
56 * As well as specifying a name at the root of the "/Names"
57 * namespace, the name parameter can contain a path that fully
58 * qualifies the name to be added. For example, if you previously
59 * have named an object "client" in the root namespace as above, you
60 * could name an object "under" that name by making a call like
61 * Names::Add ("/Names/client/eth0", obj). This will define the
62 * name "eth0" and make it reachable using the path specified. Note
63 * that Names::Add ("client/eth0", obj) would accomplish exactly the
64 * same thing.
65 *
66 * Duplicate names are not allowed at the same level in a path,
67 * however you may associate similar names with different paths.
68 * For example, if you define "/Names/Client", you may not define
69 * another "/Names/Client" just as you may not have two files with
70 * the same name in a classical filesystem. However, you may have
71 * "/Names/Client/eth0" and "/Names/Server/eth0" defined at the same
72 * time just as you might have different files of the same name
73 * under different directories.
74 *
75 * \param [in] name The name of the object you want to associate; which may be
76 * prepended with a path to that object.
77 * \param [in] object A smart pointer to the object itself.
78 */
79 static void Add (std::string name, Ptr<Object> object);
80
81 /**
82 * \brief An intermediate form of Names::Add allowing you to provide
83 * a path to the parent object (under which you want this name to be
84 * defined) in the form of a name path string.
85 *
86 * In some cases, it is desirable to break up the path used to
87 * describe an item in the names namespace into a path and a name.
88 * This is analogous to a file system operation in which you provide
89 * a directory name and a file name.
90 *
91 * For example, consider a situation where you have previously named
92 * an object "/Names/server". If you further want to create an
93 * association for between a Ptr<Object> object that you want to
94 * live "under" the server in the name space -- perhaps "eth0" --
95 * you could do this in two ways, depending on which was more
96 * convenient: Names::Add ("/Names/server/eth0", object) or, using
97 * the split path and name approach, Names::Add ("/Names/server",
98 * "eth0", object).
99 *
100 * Duplicate names are not allowed at the same level in a path,
101 * however you may associate similar names with different paths.
102 * For example, if you define "/Names/Client", you may not define
103 * another "/Names/Client" just as you may not have two files with
104 * the same name in a classical filesystem. However, you may have
105 * "/Names/Client/eth0" and "/Names/Server/eth0" defined at the same
106 * time just as you might have different files of the same name
107 * under different directories.
108 *
109 * \param [in] path A path name describing a previously named object
110 * under which you want this new name to be defined.
111 * \param [in] name The name of the object you want to associate.
112 * \param [in] object A smart pointer to the object itself.
113 *
114 * \see Names::Add (Ptr<Object>,std::string,Ptr<Object>);
115 */
116 static void Add (std::string path, std::string name, Ptr<Object> object);
117
118 /**
119 * \brief A low-level form of Names::Add allowing you to specify the
120 * path to the parent object (under which you want this name to be
121 * defined) in the form of a previously named object.
122 *
123 * In some use cases, it is desirable to break up the path in the
124 * names name space into a path and a name. This is analogous to a
125 * file system operation in which you provide a directory name and a
126 * file name. Recall that the path string actually refers to a
127 * previously named object, "under" which you want to accomplish
128 * some naming action.
129 *
130 * However, the path is sometimes not available, and you only have
131 * the object that is represented by the path in the names name
132 * space. To support this use-case in a reasonably high-performance
133 * way, the path string is can be replaced by the object pointer to
134 * which that path would refer. In the spirit of the Config code
135 * where this use-case is most prominent, we refer to this object as
136 * the "context" for the names operation.
137 *
138 * You can think of the context roughly as the inode number of a
139 * directory file in Unix. The inode number can be used to look up
140 * the directory file which contains the list of file names defined
141 * at that directory level. Similarly the context is used to look
142 * up an internal name service entry which contains the names
143 * defined for that context.
144 *
145 * For example, consider a situation where you have previously named
146 * an object "/Names/server". If you further want to create an
147 * association for between a Ptr<Object> object that you want to
148 * live "under" the server in the name space -- perhaps "eth0" --
149 * you could do this by providing a complete path to the new name:
150 * Names::Add ("/Names/server/eth0", object). If, however,
151 * somewhere in your code you only had a pointer to the server, say
152 * Ptr<Node> node, and not a handy path string, you could also
153 * accomplish this by Names::Add (node, "eth0", object).
154 *
155 * Duplicate names are not allowed at the same level in a path. In
156 * the case of this method, the context object gives the same
157 * information as a path string. You may associate similar names
158 * with different paths. For example, if you define"/Names/Client",
159 * you may not define another "/Names/Client" just as you may not
160 * have two files with the same name in a classical filesystem.
161 * However, you may have "/Names/Client/eth0" and
162 * "/Names/Server/eth0" defined at the same time just as you might
163 * have different files of the same name under different
164 * directories.
165 *
166 * \param [in] context A smart pointer to an object that is used
167 * in place of the path under which you want this new
168 * name to be defined.
169 * \param [in] name The name of the object you want to associate.
170 * \param [in] object A smart pointer to the object itself.
171 */
172 static void Add (Ptr<Object> context, std::string name, Ptr<Object> object);
173
174 /**
175 * \brief Rename a previously associated name.
176 *
177 * The name may begin either with "/Names" to explicitly call out
178 * the fact that the name provided is installed under the root of
179 * the name space, or it may begin with the name of the first object
180 * in the path. For example, Names::Rename ("/Names/client",
181 * "server") and Names::Rename ("client", "server") accomplish
182 * exactly the same thing. Names at a given level in the name space
183 * path must be unique. In the case of the example above, it would
184 * be illegal to try and rename a different object to the same name:
185 * "server" at the same level ("/Names") in the path.
186 *
187 * As well as specifying a name at the root of the "/Names"
188 * namespace, the name parameter can contain a path that fully
189 * qualifies the name to be changed. For example, if you previously
190 * have (re)named an object "server" in the root namespace as above,
191 * you could then rename an object "under" that name by making a
192 * call like Names::Rename ("/Names/server/csma", "eth0"). This
193 * will rename the object previously associated with
194 * "/Names/server/csma" to "eth0" and make leave it reachable using
195 * the path "/Names/server/eth0". Note that Names::Rename
196 * ("server/csma", "eth0") would accomplish exactly the same thing.
197 *
198 * \param [in] oldpath The current path name to the object you want
199 * to change.
200 * \param [in] newname The new name of the object you want to change.
201 *
202 * \see Names::Add (std::string name, Ptr<Object> obj)
203 */
204 static void Rename (std::string oldpath, std::string newname);
205
206 /**
207 * \brief An intermediate form of Names::Rename allowing you to
208 * provide a path to the parent object (under which you want this
209 * name to be changed) in the form of a name path string.
210 *
211 * In some cases, it is desirable to break up the path used to
212 * describe an item in the names namespace into a path and a name.
213 * This is analogous to a file system operation in which you provide
214 * a directory name and a file name.
215 *
216 * For example, consider a situation where you have previously named
217 * an object "/Names/server/csma". If you want to change the name
218 * "csma" to "eth0", you could do this in two ways, depending on
219 * which was more convenient: Names::Rename ("/Names/server/csma",
220 * "eth0") or, using the split path and name approach, Names::Rename
221 * ("/Names/server", "csma", "eth0").
222 *
223 * \param [in] path A path name describing a previously named object
224 * under which you want this name change to occur
225 * (cf. directory).
226 * \param [in] oldname The currently defined name of the object.
227 * \param [in] newname The new name you want the object to have.
228 */
229 static void Rename (std::string path, std::string oldname, std::string newname);
230
231 /**
232 * \brief A low-level form of Names::Rename allowing you to specify
233 * the path to the parent object (under which you want this name to
234 * be changed) in the form of a previously named object.
235 *
236 * In some use cases, it is desirable to break up the path in the
237 * names name space into a path and a name. This is analogous to a
238 * file system operation in which you provide a directory name and a
239 * file name. Recall that the path string actually refers to a
240 * previously named object, "under" which you want to accomplish
241 * some naming action.
242 *
243 * However, the path is sometimes not available, and you only have
244 * the object that is represented by the path in the names name
245 * space. To support this use-case in a reasonably high-performance
246 * way, the path string is can be replaced by the object pointer to
247 * which that path would refer. In the spirit of the Config code
248 * where this use-case is most prominent, we refer to this object as
249 * the "context" for the names operation.
250 *
251 * You can think of the context roughly as the inode number of a
252 * directory file in Unix. The inode number can be used to look up
253 * the directory file which contains the list of file names defined
254 * at that directory level. Similarly the context is used to look
255 * up an internal name service entry which contains the names
256 * defined for that context.
257 *
258 * For example, consider a situation where you have previously named
259 * an object "/Names/server/csma". If you later decide to rename
260 * the csma object to say "eth0" -- you could do this by providing a
261 * complete path as in Names::Rename ("/Names/server/csma", "eth0").
262 * If, however, somewhere in your code you only had a pointer to the
263 * server, and not a handy path string, say Ptr<Node> node, you
264 * could also accomplish this by Names::Rename (node, "csma",
265 * "eth0").
266 *
267 * \param [in] context A smart pointer to an object that is used
268 * in place of the path under which you want this
269 * new name to be defined.
270 * \param [in] oldname The current shortname of the object you want
271 * to change.
272 * \param [in] newname The new shortname of the object you want
273 * to change.
274 */
275 static void Rename (Ptr<Object> context, std::string oldname, std::string newname);
276
277 /**
278 * \brief Given a pointer to an object, look to see if that object
279 * has a name associated with it and, if so, return the name of the
280 * object otherwise return an empty string.
281 *
282 * An object can be referred to in two ways. Either you can talk
283 * about it using its fully qualified path name, for example,
284 * "/Names/client/eth0" or you can refer to it by its name, in this
285 * case "eth0".
286 *
287 * This method returns the name of the object, e.g., "eth0".
288 *
289 * \param [in] object A smart pointer to an object for which you want
290 * to find its name.
291 *
292 * \returns A string containing the name of the object if found,
293 * otherwise the empty string.
294 */
295 static std::string FindName (Ptr<Object> object);
296
297 /**
298 * \brief Given a pointer to an object, look to see if that object
299 * has a name associated with it and return the fully qualified name
300 * path of the object otherwise return an empty string.
301 *
302 * An object can be referred to in two ways. Either you can talk
303 * about it using its fully qualified path name, for example,
304 * "/Names/client/eth0" or you can refer to it by its name, in this
305 * case "eth0".
306 *
307 * This method returns the name path of the object, e.g.,
308 * "Names/client/eth0".
309 *
310 * \param [in] object A smart pointer to an object for which you
311 * want to find its fullname.
312 *
313 * \returns A string containing the name path of the object,
314 * otherwise the empty string.
315 */
316 static std::string FindPath (Ptr<Object> object);
317
318 /**
319 * \brief Clear the list of objects associated with names.
320 */
321
322 static void Clear (void);
323
324 /**
325 * \brief Given a name path string, look to see if there's an object
326 * in the system with that associated to it. If there is, do a
327 * GetObject on the resulting object to convert it to the requested
328 * typename and return it.
329 *
330 * An object can be referred to in two ways. Either you can talk
331 * about it using its fully qualified path name, for example,
332 * "/Names/client/eth0" or you can refer to it by its name, in this
333 * case "eth0".
334 *
335 * This method requires that the name path of the object be
336 * provided, e.g., "Names/client/eth0".
337 *
338 * \param [in] path A string containing a name space path used
339 * to locate the object.
340 *
341 * \returns A smart pointer to the named object converted to
342 * the requested type.
343 */
344 template <typename T>
345 static Ptr<T> Find (std::string path);
346
347 /**
348 * \brief Given a path to an object and an object name, look through
349 * the names defined under the path to see if there's an object
350 * there with the given name.
351 *
352 * In some cases, it is desirable to break up the path used to
353 * describe an item in the names namespace into a path and a name.
354 * This is analogous to a file system operation in which you provide
355 * a directory name and a file name.
356 *
357 * For example, consider a situation where you have previously named
358 * an object "/Names/server/eth0". If you want to discover the
359 * object which you associated with this path, you could do this in
360 * two ways, depending on which was more convenient: Names::Find
361 * ("/Names/server/eth0") or, using the split path and name
362 * approach, Names::Find ("/Names/server", "eth0").
363 *
364 * \param [in] path A path name describing a previously named object
365 * under which you want to look for the specified name.
366 * \param [in] name A string containing a name to search for.
367 *
368 * \returns A smart pointer to the named object converted to
369 * the requested type.
370 */
371 template <typename T>
372 static Ptr<T> Find (std::string path, std::string name);
373
374 /**
375 * \brief Given a path to an object and an object name, look through
376 * the names defined under the path to see if there's an object
377 * there with the given name.
378 *
379 * In some cases, it is desirable to break up the path used to
380 * describe an item in the names namespace into a path and a name.
381 * This is analogous to a file system operation in which you provide
382 * a directory name and a file name.
383 *
384 * For example, consider a situation where you have previously named
385 * an object "/Names/server/eth0". If you want to discover the
386 * object which you associated with this path, you could do this in
387 * two ways, depending on which was more convenient: Names::Find
388 * ("/Names/server/eth0") or, using the split path and name
389 * approach, Names::Find ("/Names/server", "eth0").
390 *
391 * However, the path is sometimes not available, and you only have
392 * the object that is represented by the path in the names name
393 * space. To support this use-case in a reasonably high-performance
394 * way, the path string is can be replaced by the object pointer to
395 * which that path would refer. In the spirit of the Config code
396 * where this use-case is most prominent, we refer to this object as
397 * the "context" for the names operation.
398 *
399 * You can think of the context roughly as the inode number of a
400 * directory file in Unix. The inode number can be used to look up
401 * the directory file which contains the list of file names defined
402 * at that directory level. Similarly the context is used to look
403 * up an internal name service entry which contains the names
404 * defined for that context.
405 *
406 * \param [in] context A smart pointer to an object that is used
407 * in place of the path under which you want this
408 * new name to be defined.
409 * \param [in] name A string containing a name to search for.
410 *
411 * \returns A smart pointer to the named object converted to
412 * the requested type.
413 */
414 template <typename T>
415 static Ptr<T> Find (Ptr<Object> context, std::string name);
416
417 private:
418 /**
419 * \brief Non-templated internal version of Names::Find
420 *
421 * \param [in] path A string containing the path of the object
422 * to look for.
423 *
424 * \returns A smart pointer to the named object.
425 */
426 static Ptr<Object> FindInternal (std::string path);
427
428 /**
429 * \brief Non-templated internal version of Names::Find
430 *
431 * \param [in] path A string containing the path to search
432 * for the object in.
433 * \param [in] name A string containing the name of the object
434 * to look for.
435 *
436 * \returns A smart pointer to the named object.
437 */
438 static Ptr<Object> FindInternal (std::string path, std::string name);
439
440 /**
441 * \brief Non-templated internal version of Names::Find
442 *
443 * \param [in] context A smart pointer to an object under which
444 * you want to look for the provided name.
445 * \param [in] name A string containing the name to look for.
446 *
447 * \returns A smart pointer to the named object.
448 */
449 static Ptr<Object> FindInternal (Ptr<Object> context, std::string name);
450 };
451
452
453 template <typename T>
454 /* static */
455 Ptr<T>
Find(std::string path)456 Names::Find (std::string path)
457 {
458 Ptr<Object> obj = FindInternal (path);
459 if (obj)
460 {
461 return obj->GetObject<T> ();
462 }
463 else
464 {
465 return 0;
466 }
467 }
468
469 template <typename T>
470 /* static */
471 Ptr<T>
Find(std::string path,std::string name)472 Names::Find (std::string path, std::string name)
473 {
474 Ptr<Object> obj = FindInternal (path, name);
475 if (obj)
476 {
477 return obj->GetObject<T> ();
478 }
479 else
480 {
481 return 0;
482 }
483 }
484
485 template <typename T>
486 /* static */
487 Ptr<T>
Find(Ptr<Object> context,std::string name)488 Names::Find (Ptr<Object> context, std::string name)
489 {
490 Ptr<Object> obj = FindInternal (context, name);
491 if (obj)
492 {
493 return obj->GetObject<T> ();
494 }
495 else
496 {
497 return 0;
498 }
499 }
500
501 } // namespace ns3
502
503 #endif /* OBJECT_NAMES_H */
504