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