diff --git a/src/contrib/config-store.cc b/src/contrib/config-store.cc new file mode 100644 index 000000000..911aff3f7 --- /dev/null +++ b/src/contrib/config-store.cc @@ -0,0 +1,201 @@ +#include "config-store.h" +#include "ns3/string.h" +#include "ns3/config.h" +#include "ns3/object-vector.h" +#include "ns3/pointer.h" +#include "ns3/log.h" +#include +#include +#include +#include + +NS_LOG_COMPONENT_DEFINE ("ConfigStore"); + +namespace ns3 { + +NS_OBJECT_ENSURE_REGISTERED (ConfigStore); + +TypeId +ConfigStore::GetTypeId (void) +{ + static TypeId tid = TypeId ("ns3::ConfigStore") + .SetParent () + .AddAttribute ("LoadFilename", + "The file where the configuration should be loaded from.", + String (""), + MakeStringAccessor (&ConfigStore::m_loadFilename), + MakeStringChecker ()) + .AddAttribute ("StoreFilename", + "The file where the configuration should be stored to.", + String (""), + MakeStringAccessor (&ConfigStore::m_storeFilename), + MakeStringChecker ()) + ; + return tid; +} +TypeId +ConfigStore::GetInstanceTypeId (void) const +{ + return GetTypeId (); +} + + +ConfigStore::ConfigStore () +{ + ObjectBase::ConstructSelf (AttributeList ()); +} + +void +ConfigStore::LoadFrom (std::string filename) +{ + std::ifstream is; + is.open (filename.c_str (), std::ios::in); + std::string path, value; + while (is.good()) + { + is >> path >> value; + NS_LOG_DEBUG (path << "=" << value); + Config::Set (path, String (value)); + } +} +void +ConfigStore::StoreTo (std::string filename) +{ + std::ofstream os; + os.open (filename.c_str (), std::ios::out); + for (uint32_t i = 0; i < Config::GetRootNamespaceObjectN (); ++i) + { + Ptr object = Config::GetRootNamespaceObject (i); + Store (os, object); + } + os.close (); + NS_ASSERT (m_currentPath.empty ()); + NS_ASSERT (m_examined.empty ()); + exit (0); +} + +bool +ConfigStore::IsExamined (Ptr object) +{ + for (uint32_t i = 0; i < m_examined.size (); ++i) + { + if (object == m_examined[i]) + { + return true; + } + } + return false; +} + +std::string +ConfigStore::GetCurrentPath (std::string attr) const +{ + std::ostringstream oss; + for (uint32_t i = 0; i < m_currentPath.size (); ++i) + { + oss << "/" << m_currentPath[i]; + } + oss << "/" << attr; + return oss.str (); +} + +void +ConfigStore::Store (std::ostream &os, Ptr object) +{ + if (IsExamined (object)) + { + return; + } + TypeId tid = object->GetInstanceTypeId (); + m_currentPath.push_back ("$" + tid.GetName ()); + NS_LOG_DEBUG ("store " << tid.GetName ()); + for (uint32_t i = 0; i < tid.GetAttributeN (); ++i) + { + Ptr checker = tid.GetAttributeChecker (i); + const PointerChecker *ptrChecker = dynamic_cast (PeekPointer (checker)); + if (ptrChecker != 0) + { + NS_LOG_DEBUG ("pointer attribute " << tid.GetAttributeName (i)); + Ptr tmp = Pointer (object->GetAttribute (tid.GetAttributeName (i))); + if (tmp != 0) + { + m_currentPath.push_back (tid.GetAttributeName (i)); + m_examined.push_back (object); + Store (os, tmp); + m_examined.pop_back (); + m_currentPath.pop_back (); + } + continue; + } + // attempt to cast to an object vector. + const ObjectVectorChecker *vectorChecker = dynamic_cast (PeekPointer (checker)); + if (vectorChecker != 0) + { + NS_LOG_DEBUG ("vector attribute " << tid.GetAttributeName (i)); + ObjectVector vector = object->GetAttribute (tid.GetAttributeName (i)); + for (uint32_t j = 0; j < vector.GetN (); ++j) + { + NS_LOG_DEBUG ("vector attribute item " << j); + Ptr tmp = vector.Get (j); + std::ostringstream oss; + oss << tid.GetAttributeName (i) << "/" << j; + m_currentPath.push_back (oss.str ()); + m_examined.push_back (object); + Store (os, tmp); + m_examined.pop_back (); + m_currentPath.pop_back (); + } + continue; + } + uint32_t flags = tid.GetAttributeFlags (i); + Ptr accessor = tid.GetAttributeAccessor (i); + if ((flags & TypeId::ATTR_GET) && accessor->HasGetter () && + (flags & TypeId::ATTR_SET) && accessor->HasSetter ()) + { + std::string value = object->GetAttributeAsString (tid.GetAttributeName (i)); + os << GetCurrentPath (tid.GetAttributeName (i)) << " " << value << std::endl; + } + else + { + NS_LOG_DEBUG ("could not store " << tid.GetAttributeName (i)); + } + } + Object::AggregateIterator iter = object->GetAggregateIterator (); + bool recursiveAggregate = false; + while (iter.HasNext ()) + { + Ptr tmp = iter.Next (); + if (IsExamined (tmp)) + { + recursiveAggregate = true; + } + } + if (!recursiveAggregate) + { + iter = object->GetAggregateIterator (); + while (iter.HasNext ()) + { + Ptr tmp = iter.Next (); + m_examined.push_back (object); + Store (os, tmp); + m_examined.pop_back (); + } + } + m_currentPath.pop_back (); +} + + +void +ConfigStore::Configure (void) +{ + if (m_loadFilename != "") + { + LoadFrom (m_loadFilename); + } + if (m_storeFilename != "") + { + StoreTo (m_storeFilename); + } +} + +} // namespace ns3 diff --git a/src/contrib/config-store.h b/src/contrib/config-store.h new file mode 100644 index 000000000..27639e255 --- /dev/null +++ b/src/contrib/config-store.h @@ -0,0 +1,35 @@ +#ifndef CONFIG_STORE_H +#define CONFIG_STORE_H + +#include "ns3/object-base.h" +#include "ns3/object.h" +#include + +namespace ns3 { + +class ConfigStore : public ObjectBase +{ +public: + static TypeId GetTypeId (void); + virtual TypeId GetInstanceTypeId (void) const; + + ConfigStore (); + + void Configure (void); + +private: + void LoadFrom (std::string filename); + void StoreTo (std::string filename); + void Store (std::ostream &os, Ptr object); + bool IsExamined (Ptr object); + std::string GetCurrentPath (std::string attr) const; + + std::string m_loadFilename; + std::string m_storeFilename; + std::vector > m_examined; + std::vector m_currentPath; +}; + +} // namespace ns3 + +#endif /* CONFIG_STORE_H */ diff --git a/src/contrib/wscript b/src/contrib/wscript index 223077d38..557242867 100644 --- a/src/contrib/wscript +++ b/src/contrib/wscript @@ -6,6 +6,7 @@ def build(bld): 'event-garbage-collector.cc', 'gnuplot.cc', 'delay-jitter-estimation.cc', + 'config-store.cc', ] headers = bld.create_obj('ns3header') @@ -14,4 +15,5 @@ def build(bld): 'event-garbage-collector.h', 'gnuplot.h', 'delay-jitter-estimation.h', + 'config-store.h', ]