456 lines
20 KiB
C++
456 lines
20 KiB
C++
/* -*- 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 "ptr.h"
|
|
#include "object.h"
|
|
|
|
namespace ns3 {
|
|
|
|
/**
|
|
* \brief A directory of name and Ptr<Object> 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<Object> 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> 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> 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<Object> context, std::string name, Ptr<Object> object);
|
|
*/
|
|
static void Add (std::string path, std::string name, Ptr<Object> 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 available, 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> 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> 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<Object> context, std::string name, Ptr<Object> 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<Object> 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 available, 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> 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<Object> 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 smart 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> 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 smart 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> 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 <typename T>
|
|
static Ptr<T> 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 <typename T>
|
|
static Ptr<T> 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 available, 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 <typename T>
|
|
static Ptr<T> Find (Ptr<Object> context, std::string name);
|
|
|
|
private:
|
|
/**
|
|
* \brief Non-templated internal version of Names::Find
|
|
*
|
|
* \param path A string containing the path of the object to look for.
|
|
*
|
|
* \returns a smart pointer to the named object.
|
|
*/
|
|
static Ptr<Object> FindInternal (std::string path);
|
|
|
|
/**
|
|
* \brief Non-templated internal version of Names::Find
|
|
*
|
|
* \param path 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<Object> FindInternal (std::string path, std::string name);
|
|
|
|
/**
|
|
* \brief Non-templated internal version of Names::Find
|
|
*
|
|
* \param context A smart 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<Object> FindInternal (Ptr<Object> context, std::string name);
|
|
};
|
|
|
|
/**
|
|
* \brief Template definition of corresponding template declaration found in class Names.
|
|
*/
|
|
template <typename T>
|
|
Ptr<T>
|
|
Names::Find (std::string name)
|
|
{
|
|
Ptr<Object> obj = FindInternal (name);
|
|
if (obj)
|
|
{
|
|
return obj->GetObject<T> ();
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Template definition of corresponding template declaration found in class Names.
|
|
*/
|
|
template <typename T>
|
|
Ptr<T>
|
|
Names::Find (std::string path, std::string name)
|
|
{
|
|
Ptr<Object> obj = FindInternal (path, name);
|
|
if (obj)
|
|
{
|
|
return obj->GetObject<T> ();
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* \brief Template definition of corresponding template declaration found in class Names.
|
|
*/
|
|
template <typename T>
|
|
Ptr<T>
|
|
Names::Find (Ptr<Object> context, std::string name)
|
|
{
|
|
Ptr<Object> obj = FindInternal (context, name);
|
|
if (obj)
|
|
{
|
|
return obj->GetObject<T> ();
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
} // namespace ns3
|
|
|
|
#endif /* OBJECT_NAMES_H */
|