/* -*- Mode: C++; c-file-style: "gnu"; indent-tabs-mode:nil; -*- */ /* * Copyright (c) 2009 University of Washington * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation; * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef OBJECT_NAMES_H #define OBJECT_NAMES_H #include "ns3/ptr.h" #include "ns3/object.h" namespace ns3 { /** * \brief A directory of name and Ptr associations that allows us to * give any ns3 Object a name. */ class Names { public: /** * \brief Add the association between the string "name" and the Ptr obj. * * The name may begin either with "/Names" to explicitly call out the fact * that the name provided is installed under the root of the name space, * or it may begin with the name of the first object in the path. For example, * Names::Add ("/Names/client", obj) and Names::Add ("client", obj) accomplish * exactly the same thing. A name at a given level in the name space path must * be unique. In the case of the example above, it would be illegal to try and * associate a different object with the same name: "client" at the same level * ("/Names") in the path. * * As well as specifying a name at the root of the "/Names" namespace, the * name parameter can contain a path that fully qualifies the name to * be added. For example, if you previously have named an object "client" * in the root namespace as above, you could name an object "under" that * name by making a call like Names::Add ("/Names/client/eth0", obj). This * will define the name "eth0" and make it reachable using the path specified. * Note that Names::Add ("client/eth0", obj) would accomplish exactly the same * thing. * * Duplicate names are not allowed at the same level in a path, however you may * associate similar names with different paths. For example, if you define * "/Names/Client", you may not define another "/Names/Client" just as you may * not have two files with the same name in a classical filesystem. However, * you may have "/Names/Client/eth0" and "/Names/Server/eth0" defined at the * same time just as you might have different files of the same name under * different directories. * * \param name The name of the object you want to associate; which may be * prepended with a path to that object. * \param object A smart pointer to the object itself. */ static void Add (std::string name, Ptr object); /** * \brief An intermediate form of Names::Add allowing you to provide a path to * the parent object (under which you want this name to be defined) in the form * of a name path string. * * In some cases, it is desirable to break up the path used to describe an item * in the names namespace into a path and a name. This is analogous to a * file system operation in which you provide a directory name and a file name. * * For example, consider a situation where you have previously named an object * "/Names/server". If you further want to create an association for between a * Ptr object that you want to live "under" the server in the name space * -- perhaps "eth0" -- you could do this in two ways, depending on which was * more convenient: Names::Add ("/Names/server/eth0", object) or, using the split * path and name approach, Names::Add ("/Names/server", "eth0", object). * * Duplicate names are not allowed at the same level in a path, however you may * associate similar names with different paths. For example, if you define * "/Names/Client", you may not define another "/Names/Client" just as you may * not have two files with the same name in a classical filesystem. However, * you may have "/Names/Client/eth0" and "/Names/Server/eth0" defined at the * same time just as you might have different files of the same name under * different directories. * * \param path A path name describing a previously named object under which * you want this new name to be defined. * \param name The name of the object you want to associate. * \param object A smart pointer to the object itself. * * \see Names::Add (Ptr context, std::string name, Ptr object); */ static void Add (std::string path, std::string name, Ptr object); /** * \brief A low-level form of Names::Add allowing you to specify the path to * the parent object (under which you want this name to be defined) in the form * of a previously named object. * * In some use cases, it is desirable to break up the path in the names name * space into a path and a name. This is analogous to a file system operation * in which you provide a directory name and a file name. Recall that the path * string actually refers to a previously named object, "under" which you want * to accomplish some naming action. * * However, the path is sometimes not avialable, and you only have the object * that is represented by the path in the names name space. To support this * use-case in a reasonably high-performance way, the path string is can be * replaced by the object pointer to which that path would refer. In the spirit * of the Config code where this use-case is most prominent, we refer to this * object as the "context" for the names operation. * * You can think of the context roughly as the inode number of a directory file * in Unix. The inode number can be used to look up the directory file which * contains the list of file names defined at that directory level. Similarly * the context is used to look up an internal name service entry which contains * the names defined for that context. * * For example, consider a situation where you have previously named an object * "/Names/server". If you further want to create an association for between a * Ptr object that you want to live "under" the server in the name space * -- perhaps "eth0" -- you could do this by providing a complete path to the * new name: Names::Add ("/Names/server/eth0", object). If, however, somewhere * in your code you only had a pointer to the server, say Ptr node, and * not a handy path string, you could also accomplish this by * Names::Add (node, "eth0", object). * * Duplicate names are not allowed at the same level in a path. In the case * of this method, the context object gives the same information as a path * string. You may associate similar names with different paths. For example, * if you define"/Names/Client", you may not define another "/Names/Client" * just as you may not have two files with the same name in a classical filesystem. * However, you may have "/Names/Client/eth0" and "/Names/Server/eth0" defined at * the same time just as you might have different files of the same name under * different directories. * * \param context A smart pointer to an object that is used in place of the path * under which you want this new name to be defined. * \param name The name of the object you want to associate. * \param object A smart pointer to the object itself. */ static void Add (Ptr context, std::string name, Ptr object); /** * \brief Rename a previously associated name. * * The name may begin either with "/Names" to explicitly call out the fact * that the name provided is installed under the root of the name space, * or it may begin with the name of the first object in the path. For example, * Names::Rename ("/Names/client", "server") and Names::Rename ("client", "server") * accomplish exactly the same thing. Names at a given level in the name space * path must be unique. In the case of the example above, it would be illegal * to try and rename a different object to the same name: "server" at the same * level ("/Names") in the path. * * As well as specifying a name at the root of the "/Names" namespace, the * name parameter can contain a path that fully qualifies the name to * be changed. For example, if you previously have (re)named an object * "server" in the root namespace as above, you could then rename an object * "under" that name by making a call like Names::Rename ("/Names/server/csma", "eth0"). * This will rename the object previously associated with "/Names/server/csma" * to "eth0" and make leave it reachable using the path "/Names/server/eth0". * Note that Names::Rename ("server/csma", "eth0") would accomplish exactly the * same thing. * * \param oldpath The current path name to the object you want to change. * \param newname The new name of the object you want to change. * * \see Names::Add (std::string name, Ptr obj) */ static void Rename (std::string oldpath, std::string newname); /** * \brief An intermediate form of Names::Rename allowing you to provide a path to * the parent object (under which you want this name to be changed) in the form * of a name path string. * * In some cases, it is desirable to break up the path used to describe an item * in the names namespace into a path and a name. This is analogous to a * file system operation in which you provide a directory name and a file name. * * For example, consider a situation where you have previously named an object * "/Names/server/csma". If you want to change the name "csma" to "eth0", you * could do this in two ways, depending on which was more convenient: * Names::Rename ("/Names/server/csma", "eth0") or, using the split * path and name approach, Names::Rename ("/Names/server", "csma", "eth0"). * * \param path A path name describing a previously named object under which * you want this name change to occur (cf. directory). * \param oldname The currently defined name of the object. * \param newname The new name you want the object to have. */ static void Rename (std::string path, std::string oldname, std::string newname); /** * \brief A low-level form of Names::Rename allowing you to specify the path to * the parent object (under which you want this name to be changed) in the form * of a previously named object. * * In some use cases, it is desirable to break up the path in the names name * space into a path and a name. This is analogous to a file system operation * in which you provide a directory name and a file name. Recall that the path * string actually refers to a previously named object, "under" which you want * to accomplish some naming action. * * However, the path is sometimes not avialable, and you only have the object * that is represented by the path in the names name space. To support this * use-case in a reasonably high-performance way, the path string is can be * replaced by the object pointer to which that path would refer. In the spirit * of the Config code where this use-case is most prominent, we refer to this * object as the "context" for the names operation. * * You can think of the context roughly as the inode number of a directory file * in Unix. The inode number can be used to look up the directory file which * contains the list of file names defined at that directory level. Similarly * the context is used to look up an internal name service entry which contains * the names defined for that context. * * For example, consider a situation where you have previously named an object * "/Names/server/csma". If you later decide to rename the csma object to say * "eth0" -- you could do this by providing a complete path as in * Names::Rename ("/Names/server/csma", "eth0"). If, however, somewhere * in your code you only had a pointer to the server, and not a handy path * string, say Ptr node, you could also accomplish this by * Names::Rename (node, "csma", "eth0"). * * \param context A smart pointer to an object that is used in place of the path * under which you want this new name to be defined. * \param oldname The current shortname of the object you want to change. * \param newname The new shortname of the object you want to change. */ static void Rename (Ptr context, std::string oldname, std::string newname); /** * Given a pointer to an object, look to see if that object has a name * associated with it and, if so, return the name of the object otherwise * return an empty string. * * An object can be referred to in two ways. Either you can talk about it * using its fully qualified path name, for example, "/Names/client/eth0" * or you can refer to it by its name, in this case "eth0". * * This method returns the name of the object, e.g., "eth0". * * \param object A spart pointer to an object for which you want to find * its name. * * \returns a string containing the name of the object if found, otherwise * the empty string. */ static std::string FindName (Ptr object); /** * Given a pointer to an object, look to see if that object has a name * associated with it and return the fully qualified name path of the * object otherwise return an empty string. * * An object can be referred to in two ways. Either you can talk about it * using its fully qualified path name, for example, "/Names/client/eth0" * or you can refer to it by its name, in this case "eth0". * * This method returns the name path of the object, e.g., "Names/client/eth0". * * \param object A spart pointer to an object for which you want to find * its fullname. * * \returns a string containing the name path of the object, otherwise * the empty string. */ static std::string FindPath (Ptr object); /** * Clear the list of objects associated with names. */ static void Clear (void); /** * Given a name path string, look to see if there's an object in the system * with that associated to it. If there is, do a GetObject on the resulting * object to convert it to the requested typename and return it. * * An object can be referred to in two ways. Either you can talk about it * using its fully qualified path name, for example, "/Names/client/eth0" * or you can refer to it by its name, in this case "eth0". * * This method requires that the name path of the object be provided, e.g., * "Names/client/eth0". * * \param path A string containing a name space path used to locate the object. * * \returns a smart pointer to the named object converted to the requested * type. */ template static Ptr Find (std::string path); /** * Given a path to an object and an object name, look through the names defined * under the path to see if there's an object there with the given name. * * In some cases, it is desirable to break up the path used to describe an item * in the names namespace into a path and a name. This is analogous to a * file system operation in which you provide a directory name and a file name. * * For example, consider a situation where you have previously named an object * "/Names/server/eth0". If you want to discover the object which you associated * with this path, you could do this in two ways, depending on which was more * convenient: Names::Find ("/Names/server/eth0") or, using the split path and * name approach, Names::Find ("/Names/server", "eth0"). * * \param path A path name describing a previously named object under which * you want to look for the specified name. * \param name A string containing a name to search for. * * \returns a smart pointer to the named object converted to the requested * type. */ template static Ptr Find (std::string path, std::string name); /** * Given a path to an object and an object name, look through the names defined * under the path to see if there's an object there with the given name. * * In some cases, it is desirable to break up the path used to describe an item * in the names namespace into a path and a name. This is analogous to a * file system operation in which you provide a directory name and a file name. * * For example, consider a situation where you have previously named an object * "/Names/server/eth0". If you want to discover the object which you associated * with this path, you could do this in two ways, depending on which was more * convenient: Names::Find ("/Names/server/eth0") or, using the split path and * name approach, Names::Find ("/Names/server", "eth0"). * * However, the path is sometimes not avialable, and you only have the object * that is represented by the path in the names name space. To support this * use-case in a reasonably high-performance way, the path string is can be * replaced by the object pointer to which that path would refer. In the spirit * of the Config code where this use-case is most prominent, we refer to this * object as the "context" for the names operation. * * You can think of the context roughly as the inode number of a directory file * in Unix. The inode number can be used to look up the directory file which * contains the list of file names defined at that directory level. Similarly * the context is used to look up an internal name service entry which contains * the names defined for that context. * * \param context A smart pointer to an object that is used in place of the path * under which you want this new name to be defined. * \param name A string containing a name to search for. * * \returns a smart pointer to the named object converted to the requested * type. */ template static Ptr Find (Ptr context, std::string name); private: /** * \internal * * \brief Non-templated internal version of Names::Find * * \param name A string containing the path of the object to look for. * * \returns a smart pointer to the named object. */ static Ptr FindInternal (std::string path); /** * \internal * * \brief Non-templated internal version of Names::Find * * \param context A string containing the path to search for the object in. * \param name A string containing the name of the object to look for. * * \returns a smart pointer to the named object. */ static Ptr FindInternal (std::string path, std::string name); /** * \internal * * \brief Non-templated internal version of Names::Find * * \param context A spart pointer to an object under which you want to look * for the provided name. * \param name A string containing the name to look for. * * \returns a smart pointer to the named object. */ static Ptr FindInternal (Ptr context, std::string name); }; /** * \brief Template definition of corresponding template declaration found in class Names. */ template Ptr Names::Find (std::string name) { Ptr obj = FindInternal (name); if (obj) { return obj->GetObject (); } else { return 0; } } /** * \brief Template definition of corresponding template declaration found in class Names. */ template Ptr Names::Find (std::string path, std::string name) { Ptr obj = FindInternal (path, name); if (obj) { return obj->GetObject (); } else { return 0; } } /** * \brief Template definition of corresponding template declaration found in class Names. */ template Ptr Names::Find (Ptr context, std::string name) { Ptr obj = FindInternal (context, name); if (obj) { return obj->GetObject (); } else { return 0; } } }//namespace ns3 #endif /* OBJECT_NAMES_H */