diff --git a/src/contrib/attribute-default-iterator.cc b/src/contrib/attribute-default-iterator.cc new file mode 100644 index 000000000..ba2fb433c --- /dev/null +++ b/src/contrib/attribute-default-iterator.cc @@ -0,0 +1,88 @@ +#include "attribute-default-iterator.h" +#include "ns3/type-id.h" +#include "ns3/attribute.h" +#include "ns3/object-vector.h" +#include "ns3/pointer.h" +#include "ns3/global-value.h" +#include "ns3/string.h" + +namespace ns3 { + +AttributeDefaultIterator::~AttributeDefaultIterator () +{} +void +AttributeDefaultIterator::Iterate (void) +{ + for (uint32_t i = 0; i < TypeId::GetRegisteredN (); i++) + { + TypeId tid = TypeId::GetRegistered (i); + if (tid.MustHideFromDocumentation ()) + { + continue; + } + bool calledStart = false; + for (uint32_t j = 0; j < tid.GetAttributeN (); j++) + { + uint32_t flags = tid.GetAttributeFlags (j); + if (!(flags & TypeId::ATTR_CONSTRUCT)) + { + // we can't construct the attribute, so, there is no + // initial value for the attribute + continue; + } + Ptr accessor = tid.GetAttributeAccessor (j); + if (accessor == 0) + { + continue; + } + if (!accessor->HasSetter ()) + { + continue; + } + Ptr checker = tid.GetAttributeChecker (j); + if (checker == 0) + { + continue; + } + Ptr value = tid.GetAttributeInitialValue (j); + if (value == 0) + { + continue; + } + Ptr vector = DynamicCast (value); + if (vector != 0) + { + continue; + } + Ptr pointer = DynamicCast (value); + if (pointer != 0) + { + continue; + } + if (!calledStart) + { + StartVisitTypeId (tid.GetName ()); + } + VisitAttribute (tid.GetAttributeName (j), + value->SerializeToString (checker)); + calledStart = true; + } + if (calledStart) + { + EndVisitTypeId (); + } + } +} + +void +AttributeDefaultIterator::StartVisitTypeId (std::string name) +{} +void +AttributeDefaultIterator::EndVisitTypeId (void) +{} +void +AttributeDefaultIterator::VisitAttribute (std::string name, std::string defaultValue) +{} + + +} // namespace ns3 diff --git a/src/contrib/attribute-default-iterator.h b/src/contrib/attribute-default-iterator.h new file mode 100644 index 000000000..7747a9b03 --- /dev/null +++ b/src/contrib/attribute-default-iterator.h @@ -0,0 +1,21 @@ +#ifndef ATTRIBUTE_DEFAULT_ITERATOR_H +#define ATTRIBUTE_DEFAULT_ITERATOR_H + +#include + +namespace ns3 { + +class AttributeDefaultIterator +{ +public: + virtual ~AttributeDefaultIterator () = 0; + void Iterate (void); +private: + virtual void StartVisitTypeId (std::string name); + virtual void EndVisitTypeId (void); + virtual void VisitAttribute (std::string name, std::string defaultValue); +}; + +} // namespace ns3 + +#endif /* ATTRIBUTE_DEFAULT_ITERATOR_H */ diff --git a/src/contrib/attribute-iterator.cc b/src/contrib/attribute-iterator.cc index 8a6b02b3d..747184618 100644 --- a/src/contrib/attribute-iterator.cc +++ b/src/contrib/attribute-iterator.cc @@ -252,23 +252,5 @@ AttributeIterator::DoIterate (Ptr object) } } -TextFileAttributeIterator::TextFileAttributeIterator (std::ostream &os) - : m_os (os) -{} -void -TextFileAttributeIterator::DoVisitAttribute (Ptr object, std::string name) -{ - StringValue str; - object->GetAttribute (name, str); - m_os << GetCurrentPath () << " " << str.Get () << std::endl; -} - -void -TextFileAttributeIterator::Save (void) -{ - Iterate (); -} - - } // namespace ns3 diff --git a/src/contrib/attribute-iterator.h b/src/contrib/attribute-iterator.h index 3a1fdb883..c49805a9b 100644 --- a/src/contrib/attribute-iterator.h +++ b/src/contrib/attribute-iterator.h @@ -49,17 +49,6 @@ private: std::vector m_currentPath; }; -class TextFileAttributeIterator : public AttributeIterator -{ -public: - TextFileAttributeIterator (std::ostream &os); - void Save (void); -private: - virtual void DoVisitAttribute (Ptr object, std::string name); - std::ostream &m_os; -}; - - } // namespace ns3 #endif /* ATTRIBUTE_ITERATOR_H */ diff --git a/src/contrib/config-store.cc b/src/contrib/config-store.cc index d4250bb50..61d65c1ec 100644 --- a/src/contrib/config-store.cc +++ b/src/contrib/config-store.cc @@ -1,19 +1,27 @@ #include "config-store.h" -#include "attribute-iterator.h" +#include "raw-text-config.h" #include "ns3/string.h" #include "ns3/log.h" +#include "ns3/simulator.h" +#include "ns3/enum.h" #include "ns3/attribute-list.h" -#include "ns3/config.h" +#include "ns3/contrib-config.h" +#ifdef HAVE_LIBXML2 +#include "xml-config.h" +#endif + #include #include #include #include #include + NS_LOG_COMPONENT_DEFINE ("ConfigStore"); namespace ns3 { + NS_OBJECT_ENSURE_REGISTERED (ConfigStore); TypeId @@ -21,16 +29,24 @@ ConfigStore::GetTypeId (void) { static TypeId tid = TypeId ("ns3::ConfigStore") .SetParent () - .AddAttribute ("LoadFilename", - "The file where the configuration should be loaded from.", + .AddAttribute ("Mode", + "Configuration mode", + EnumValue (ConfigStore::NONE), + MakeEnumAccessor (&ConfigStore::SetMode), + MakeEnumChecker (ConfigStore::NONE, "None", + ConfigStore::LOAD, "Load", + ConfigStore::SAVE, "Save")) + .AddAttribute ("Filename", + "The file where the configuration should be saved to or loaded from.", StringValue (""), - MakeStringAccessor (&ConfigStore::m_loadFilename), - MakeStringChecker ()) - .AddAttribute ("StoreFilename", - "The file where the configuration should be stored to.", - StringValue (""), - MakeStringAccessor (&ConfigStore::m_storeFilename), + MakeStringAccessor (&ConfigStore::SetFilename), MakeStringChecker ()) + .AddAttribute ("FileFormat", + "Type of file format", + EnumValue (ConfigStore::RAW_TEXT), + MakeEnumAccessor (&ConfigStore::SetFileFormat), + MakeEnumChecker (ConfigStore::RAW_TEXT, "RawText", + ConfigStore::XML, "Xml")) ; return tid; } @@ -44,44 +60,76 @@ ConfigStore::GetInstanceTypeId (void) const ConfigStore::ConfigStore () { ObjectBase::ConstructSelf (AttributeList ()); + +#ifdef HAVE_LIBXML2 + if (m_fileFormat == ConfigStore::XML) + { + if (m_mode == ConfigStore::SAVE) + { + m_file = new XmlConfigSave (); + } + else if (m_mode == ConfigStore::LOAD) + { + m_file = new XmlConfigLoad (); + } + else + { + m_file = new NoneFileConfig (); + } + } + else +#endif /* HAVE_LIBXML2 */ + if (m_fileFormat == ConfigStore::RAW_TEXT) + { + if (m_mode == ConfigStore::SAVE) + { + m_file = new RawTextConfigSave (); + } + else if (m_mode == ConfigStore::LOAD) + { + m_file = new RawTextConfigLoad (); + } + else + { + m_file = new NoneFileConfig (); + } + } + m_file->SetFilename (m_filename); +} + +ConfigStore::~ConfigStore () +{ + delete m_file; + m_file = 0; } void -ConfigStore::LoadFrom (std::string filename) +ConfigStore::SetMode (enum Mode mode) { - 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, StringValue (value)); - } + m_mode = mode; } void -ConfigStore::StoreTo (std::string filename) +ConfigStore::SetFileFormat (enum FileFormat format) { - - std::ofstream os; - os.open (filename.c_str (), std::ios::out); - TextFileAttributeIterator iter = TextFileAttributeIterator (os); - iter.Save (); - os.close (); - exit (0); + m_fileFormat = format; +} +void +ConfigStore::SetFilename (std::string filename) +{ + m_filename = filename; } void -ConfigStore::Configure (void) +ConfigStore::ConfigureAttributes (void) { - if (m_loadFilename != "") - { - LoadFrom (m_loadFilename); - } - if (m_storeFilename != "") - { - StoreTo (m_storeFilename); - } + m_file->Attributes (); +} + +void +ConfigStore::ConfigureDefaults (void) +{ + m_file->Default (); + m_file->Global (); } } // namespace ns3 diff --git a/src/contrib/config-store.h b/src/contrib/config-store.h index 38b80f282..9ad53552b 100644 --- a/src/contrib/config-store.h +++ b/src/contrib/config-store.h @@ -2,6 +2,7 @@ #define CONFIG_STORE_H #include "ns3/object-base.h" +#include "file-config.h" namespace ns3 { @@ -26,24 +27,33 @@ namespace ns3 { class ConfigStore : public ObjectBase { public: + enum Mode { + LOAD, + SAVE, + NONE + }; + enum FileFormat { + XML, + RAW_TEXT + }; static TypeId GetTypeId (void); virtual TypeId GetInstanceTypeId (void) const; ConfigStore (); + ~ConfigStore (); - /** - * Depending on which attribute was set: - * - Store simulation configuration in file and exit - * - Load simulation configuration from file and proceed. - */ - void Configure (void); + void SetMode (enum Mode mode); + void SetFileFormat (enum FileFormat format); + void SetFilename (std::string filename); + + void ConfigureDefaults (void); + void ConfigureAttributes (void); private: - void LoadFrom (std::string filename); - void StoreTo (std::string filename); - - std::string m_loadFilename; - std::string m_storeFilename; + enum Mode m_mode; + enum FileFormat m_fileFormat; + std::string m_filename; + FileConfig *m_file; }; } // namespace ns3 diff --git a/src/contrib/file-config.cc b/src/contrib/file-config.cc new file mode 100644 index 000000000..64d43d60d --- /dev/null +++ b/src/contrib/file-config.cc @@ -0,0 +1,25 @@ +#include "file-config.h" + +namespace ns3 { + +FileConfig::~FileConfig () +{} + +NoneFileConfig::NoneFileConfig () +{} +NoneFileConfig::~NoneFileConfig () +{} +void +NoneFileConfig::SetFilename (std::string filename) +{} +void +NoneFileConfig::Default (void) +{} +void +NoneFileConfig::Global (void) +{} +void +NoneFileConfig::Attributes (void) +{} + +} // namespace ns3 diff --git a/src/contrib/file-config.h b/src/contrib/file-config.h new file mode 100644 index 000000000..589153f9c --- /dev/null +++ b/src/contrib/file-config.h @@ -0,0 +1,31 @@ +#ifndef FILE_CONFIG_H +#define FILE_CONFIG_H + +#include + +namespace ns3 { + +class FileConfig +{ +public: + virtual ~FileConfig (); + virtual void SetFilename (std::string filename) = 0; + virtual void Default (void) = 0; + virtual void Global (void) = 0; + virtual void Attributes (void) = 0; +}; + +class NoneFileConfig : public FileConfig +{ +public: + NoneFileConfig (); + virtual ~NoneFileConfig (); + virtual void SetFilename (std::string filename); + virtual void Default (void); + virtual void Global (void); + virtual void Attributes (void); +}; + +} // namespace ns3 + +#endif /* FILE_CONFIG_H */ diff --git a/src/contrib/gtk-config-store.cc b/src/contrib/gtk-config-store.cc index 996e08f88..3935ddce6 100644 --- a/src/contrib/gtk-config-store.cc +++ b/src/contrib/gtk-config-store.cc @@ -1,5 +1,6 @@ #include "gtk-config-store.h" #include "attribute-iterator.h" +#include "raw-text-config.h" #include "ns3/config.h" #include "ns3/string.h" #include "ns3/pointer.h" @@ -403,11 +404,9 @@ save_clicked (GtkButton *button, char *filename; filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); - std::ofstream os; - os.open (filename); - TextFileAttributeIterator file = TextFileAttributeIterator (os); - file.Save (); - os.close (); + RawTextConfigSave config; + config.SetFilename (filename); + config.Attributes (); g_free (filename); } @@ -433,15 +432,9 @@ load_clicked (GtkButton *button, char *filename; filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); - std::ifstream is; - is.open (filename, std::ios::in); - std::string path, value; - while (is.good()) - { - is >> path >> value; - Config::Set (path, StringValue (value)); - } - g_free (filename); + RawTextConfigLoad config; + config.SetFilename (filename); + config.Attributes (); } gtk_widget_destroy (dialog); @@ -486,7 +479,11 @@ GtkConfigStore::GtkConfigStore () {} void -GtkConfigStore::Configure (void) +GtkConfigStore::ConfigureDefaults (void) +{} + +void +GtkConfigStore::ConfigureAttributes (void) { GtkWidget *window; GtkWidget *view; diff --git a/src/contrib/gtk-config-store.h b/src/contrib/gtk-config-store.h index 9b7cf7bbf..78a21b2ab 100644 --- a/src/contrib/gtk-config-store.h +++ b/src/contrib/gtk-config-store.h @@ -11,7 +11,8 @@ class GtkConfigStore public: GtkConfigStore (); - void Configure (void); + void ConfigureDefaults (void); + void ConfigureAttributes (void); }; diff --git a/src/contrib/raw-text-config.cc b/src/contrib/raw-text-config.cc new file mode 100644 index 000000000..0c27bb301 --- /dev/null +++ b/src/contrib/raw-text-config.cc @@ -0,0 +1,166 @@ +#include "raw-text-config.h" +#include "attribute-iterator.h" +#include "attribute-default-iterator.h" +#include "ns3/global-value.h" +#include "ns3/string.h" +#include "ns3/log.h" +#include "ns3/config.h" + +NS_LOG_COMPONENT_DEFINE ("RawTextConfig"); + +namespace ns3 { + +RawTextConfigSave::RawTextConfigSave () + : m_os (0) +{} +RawTextConfigSave::~RawTextConfigSave () +{ + if (m_os != 0) + { + m_os->close (); + } + delete m_os; + m_os = 0; +} +void +RawTextConfigSave::SetFilename (std::string filename) +{ + m_os = new std::ofstream (); + m_os->open (filename.c_str (), std::ios::out); +} +void +RawTextConfigSave::Default (void) +{ + class RawTextDefaultIterator : public AttributeDefaultIterator + { + public: + RawTextDefaultIterator (std::ostream *os) { + m_os = os; + } + private: + virtual void StartVisitTypeId (std::string name) { + m_typeId = name; + } + virtual void VisitAttribute (std::string name, std::string defaultValue) { + *m_os << "default " << m_typeId << "::" << name << " \"" << defaultValue << "\"" << std::endl; + } + std::string m_typeId; + std::ostream *m_os; + }; + + RawTextDefaultIterator iterator = RawTextDefaultIterator (m_os); + iterator.Iterate (); +} +void +RawTextConfigSave::Global (void) +{ + for (GlobalValue::Iterator i = GlobalValue::Begin (); i != GlobalValue::End (); ++i) + { + StringValue value; + (*i)->GetValue (value); + *m_os << "global " << (*i)->GetName () << " \"" << value.Get () << "\"" << std::endl; + } +} +void +RawTextConfigSave::Attributes (void) +{ + class RawTextAttributeIterator : public AttributeIterator + { + public: + RawTextAttributeIterator (std::ostream *os) + : m_os (os) {} + private: + virtual void DoVisitAttribute (Ptr object, std::string name) { + StringValue str; + object->GetAttribute (name, str); + *m_os << "value " << GetCurrentPath () << " \"" << str.Get () << "\"" << std::endl; + } + std::ostream *m_os; + }; + + RawTextAttributeIterator iter = RawTextAttributeIterator (m_os); + iter.Iterate (); +} + +RawTextConfigLoad::RawTextConfigLoad () + : m_is (0) +{} +RawTextConfigLoad::~RawTextConfigLoad () +{ + if (m_is != 0) + { + m_is->close (); + delete m_is; + m_is = 0; + } +} +void +RawTextConfigLoad::SetFilename (std::string filename) +{ + m_is = new std::ifstream (); + m_is->open (filename.c_str (), std::ios::in); +} +std::string +RawTextConfigLoad::Strip (std::string value) +{ + std::string::size_type start = value.find ("\""); + std::string::size_type end = value.find ("\"", 1); + NS_ASSERT (start == 0); + NS_ASSERT (end == value.size () - 1); + return value.substr (start+1, end-start-1); +} + +void +RawTextConfigLoad::Default (void) +{ + m_is->seekg (0); + std::string type, name, value; + *m_is >> type >> name >> value; + while (m_is->good()) + { + NS_LOG_DEBUG ("type=" << type << ", name=" << name << ", value=" << value); + value = Strip (value); + if (type == "global") + { + Config::SetDefault (name, StringValue (value)); + } + *m_is >> type >> name >> value; + } +} +void +RawTextConfigLoad::Global (void) +{ + m_is->seekg (0); + std::string type, name, value; + *m_is >> type >> name >> value; + while (m_is->good()) + { + NS_LOG_DEBUG ("type=" << type << ", name=" << name << ", value=" << value); + value = Strip (value); + if (type == "global") + { + Config::SetGlobal (name, StringValue (value)); + } + *m_is >> type >> name >> value; + } +} +void +RawTextConfigLoad::Attributes (void) +{ + m_is->seekg (0); + std::string type, path, value; + *m_is >> type >> path >> value; + while (m_is->good()) + { + NS_LOG_DEBUG ("type=" << type << ", path=" << path << ", value=" << value); + value = Strip (value); + if (type == "value") + { + Config::Set (path, StringValue (value)); + } + *m_is >> type >> path >> value; + } +} + + +} // namespace ns3 diff --git a/src/contrib/raw-text-config.h b/src/contrib/raw-text-config.h new file mode 100644 index 000000000..7244c7801 --- /dev/null +++ b/src/contrib/raw-text-config.h @@ -0,0 +1,39 @@ +#ifndef RAW_TEXT_CONFIG_H +#define RAW_TEXT_CONFIG_H + +#include +#include +#include "file-config.h" + +namespace ns3 { + +class RawTextConfigSave : public FileConfig +{ +public: + RawTextConfigSave (); + virtual ~RawTextConfigSave (); + virtual void SetFilename (std::string filename); + virtual void Default (void); + virtual void Global (void); + virtual void Attributes (void); +private: + std::ofstream *m_os; +}; + +class RawTextConfigLoad : public FileConfig +{ +public: + RawTextConfigLoad (); + virtual ~RawTextConfigLoad (); + virtual void SetFilename (std::string filename); + virtual void Default (void); + virtual void Global (void); + virtual void Attributes (void); +private: + std::string Strip (std::string value); + std::ifstream *m_is; +}; + +} // namespace ns3 + +#endif /* RAW_TEXT_CONFIG_H */ diff --git a/src/contrib/wscript b/src/contrib/wscript index 7324d8a56..64256bae5 100644 --- a/src/contrib/wscript +++ b/src/contrib/wscript @@ -1,14 +1,23 @@ ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- def configure(conf): - have_it = conf.pkg_check_modules('GTK_CONFIG_STORE', 'gtk+-2.0 >= 2.12', mandatory=False) - conf.env['ENABLE_GTK_CONFIG_STORE'] = have_it + have_gtk = conf.pkg_check_modules('GTK_CONFIG_STORE', 'gtk+-2.0 >= 2.12', mandatory=False) + conf.env['ENABLE_GTK_CONFIG_STORE'] = have_gtk conf.report_optional_feature("GtkConfigStore", "GtkConfigStore", conf.env['ENABLE_GTK_CONFIG_STORE'], "library 'gtk+-2.0 >= 2.12' not found") + have_libxml2 = conf.pkg_check_modules('LIBXML2', 'libxml-2.0 >= 2.6', mandatory=False) + if have_libxml2: + conf.define('HAVE_LIBXML2', 1) + conf.env['ENABLE_LIBXML2'] = have_libxml2 + conf.report_optional_feature("XmlIo", "XmlIo", + conf.env['ENABLE_LIBXML2'], + "library 'libxml-2.0 >= 2.7' not found") conf.sub_config('stats') + conf.write_config_header('ns3/contrib-config.h') + def build(bld): module = bld.create_ns3_module('contrib', ['simulator', 'common']) module.source = [ @@ -18,6 +27,9 @@ def build(bld): 'attribute-iterator.cc', 'config-store.cc', 'flow-id-tag.cc', + 'attribute-default-iterator.cc', + 'file-config.cc', + 'raw-text-config.cc', ] headers = bld.new_task_gen('ns3header') @@ -26,6 +38,7 @@ def build(bld): 'event-garbage-collector.h', 'gnuplot.h', 'delay-jitter-estimation.h', + 'file-config.h', 'config-store.h', 'flow-id-tag.h', ] @@ -34,3 +47,7 @@ def build(bld): headers.source.append ('gtk-config-store.h') module.source.append ('gtk-config-store.cc') module.uselib = 'GTK_CONFIG_STORE' + + if bld.env['ENABLE_LIBXML2']: + module.source.append ('xml-config.cc') + module.uselib = module.uselib + ' LIBXML2' diff --git a/src/contrib/xml-config.cc b/src/contrib/xml-config.cc new file mode 100644 index 000000000..0b57a2556 --- /dev/null +++ b/src/contrib/xml-config.cc @@ -0,0 +1,335 @@ +#include "xml-config.h" +#include "attribute-default-iterator.h" +#include "attribute-iterator.h" +#include "ns3/fatal-error.h" +#include "ns3/log.h" +#include "ns3/global-value.h" +#include "ns3/string.h" +#include "ns3/config.h" +#include +#include + +NS_LOG_COMPONENT_DEFINE ("XmlConfig"); + +namespace ns3 { + +XmlConfigSave::XmlConfigSave () + : m_writer (0) +{ + NS_LOG_FUNCTION (this); +} +void +XmlConfigSave::SetFilename (std::string filename) +{ + NS_LOG_FUNCTION (filename); + if (filename == "") + { + return; + } + int rc; + + /* Create a new XmlWriter for uri, with no compression. */ + m_writer = xmlNewTextWriterFilename(filename.c_str (), 0); + if (m_writer == NULL) + { + NS_FATAL_ERROR ("Error creating the xml writer"); + } + rc = xmlTextWriterSetIndent (m_writer, 1); + if (rc < 0) + { + NS_FATAL_ERROR ("Error at xmlTextWriterSetIndent"); + } + /* Start the document with the xml default for the version, + * encoding utf-8 and the default for the standalone + * declaration. */ + rc = xmlTextWriterStartDocument(m_writer, NULL, "utf-8", NULL); + if (rc < 0) + { + NS_FATAL_ERROR ("Error at xmlTextWriterStartDocument"); + } + + /* Start an element named "ns3". Since thist is the first + * element, this will be the root element of the document. */ + rc = xmlTextWriterStartElement(m_writer, BAD_CAST "ns3"); + if (rc < 0) + { + NS_FATAL_ERROR ("Error at xmlTextWriterStartElement\n"); + } +} +XmlConfigSave::~XmlConfigSave () +{ + NS_LOG_FUNCTION (this); + if (m_writer == 0) + { + return; + } + int rc; + /* Here we could close the remaining elements using the + * function xmlTextWriterEndElement, but since we do not want to + * write any other elements, we simply call xmlTextWriterEndDocument, + * which will do all the work. */ + rc = xmlTextWriterEndDocument(m_writer); + if (rc < 0) + { + NS_FATAL_ERROR ("Error at xmlTextWriterEndDocument\n"); + } + + xmlFreeTextWriter(m_writer); + m_writer = 0; +} +void +XmlConfigSave::Default (void) +{ + class XmlDefaultIterator : public AttributeDefaultIterator + { + public: + XmlDefaultIterator (xmlTextWriterPtr writer) { + m_writer = writer; + } + private: + virtual void StartVisitTypeId (std::string name) { + m_typeid = name; + } + virtual void VisitAttribute (std::string name, std::string defaultValue) { + int rc; + rc = xmlTextWriterStartElement(m_writer, BAD_CAST "default"); + if (rc < 0) + { + NS_FATAL_ERROR ("Error at xmlTextWriterStartElement"); + } + std::string fullname = m_typeid + "::" + name; + rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "name", + BAD_CAST fullname.c_str ()); + if (rc < 0) + { + NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute"); + } + rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "value", + BAD_CAST defaultValue.c_str ()); + if (rc < 0) + { + NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute"); + } + rc = xmlTextWriterEndElement(m_writer); + if (rc < 0) + { + NS_FATAL_ERROR ("Error at xmlTextWriterEndElement"); + } + } + xmlTextWriterPtr m_writer; + std::string m_typeid; + }; + XmlDefaultIterator iterator = XmlDefaultIterator (m_writer); + iterator.Iterate (); +} + +void +XmlConfigSave::Attributes (void) +{ + class XmlTextAttributeIterator : public AttributeIterator + { + public: + XmlTextAttributeIterator (xmlTextWriterPtr writer) + : m_writer (writer) {} + private: + virtual void DoVisitAttribute (Ptr object, std::string name) { + StringValue str; + object->GetAttribute (name, str); + int rc; + rc = xmlTextWriterStartElement(m_writer, BAD_CAST "value"); + if (rc < 0) + { + NS_FATAL_ERROR ("Error at xmlTextWriterStartElement"); + } + rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "path", + BAD_CAST GetCurrentPath ().c_str ()); + if (rc < 0) + { + NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute"); + } + rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "value", + BAD_CAST str.Get ().c_str ()); + if (rc < 0) + { + NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute"); + } + rc = xmlTextWriterEndElement(m_writer); + if (rc < 0) + { + NS_FATAL_ERROR ("Error at xmlTextWriterEndElement"); + } + } + xmlTextWriterPtr m_writer; + }; + + XmlTextAttributeIterator iter = XmlTextAttributeIterator (m_writer); + iter.Iterate (); +} + +void +XmlConfigSave::Global (void) +{ + int rc; + for (GlobalValue::Iterator i = GlobalValue::Begin (); i != GlobalValue::End (); ++i) + { + StringValue value; + (*i)->GetValue (value); + + rc = xmlTextWriterStartElement(m_writer, BAD_CAST "global"); + if (rc < 0) + { + NS_FATAL_ERROR ("Error at xmlTextWriterStartElement"); + } + rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "name", + BAD_CAST (*i)->GetName ().c_str ()); + if (rc < 0) + { + NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute"); + } + rc = xmlTextWriterWriteAttribute(m_writer, BAD_CAST "value", + BAD_CAST value.Get ().c_str ()); + if (rc < 0) + { + NS_FATAL_ERROR ("Error at xmlTextWriterWriteAttribute"); + } + rc = xmlTextWriterEndElement(m_writer); + if (rc < 0) + { + NS_FATAL_ERROR ("Error at xmlTextWriterEndElement"); + } + } +} + +XmlConfigLoad::XmlConfigLoad () +{ + NS_LOG_FUNCTION (this); +} +XmlConfigLoad::~XmlConfigLoad () +{ + NS_LOG_FUNCTION (this); +} + +void +XmlConfigLoad::SetFilename (std::string filename) +{ + NS_LOG_FUNCTION (filename); + m_filename = filename; +} +void +XmlConfigLoad::Default (void) +{ + xmlTextReaderPtr reader = xmlNewTextReaderFilename(m_filename.c_str ()); + if (reader == NULL) + { + NS_FATAL_ERROR ("Error at xmlReaderForFile"); + } + int rc; + rc = xmlTextReaderRead (reader); + while (rc > 0) + { + const xmlChar *type = xmlTextReaderConstName(reader); + if (type == 0) + { + NS_FATAL_ERROR ("Invalid value"); + } + if (std::string ((char*)type) == "default") + { + xmlChar *name = xmlTextReaderGetAttribute (reader, BAD_CAST "name"); + if (name == 0) + { + NS_FATAL_ERROR ("Error getting attribute 'name'"); + } + xmlChar *value = xmlTextReaderGetAttribute (reader, BAD_CAST "value"); + if (value == 0) + { + NS_FATAL_ERROR ("Error getting attribute 'value'"); + } + NS_LOG_DEBUG ("default="<<(char*)name<<", value=" < 0) + { + const xmlChar *type = xmlTextReaderConstName(reader); + if (type == 0) + { + NS_FATAL_ERROR ("Invalid value"); + } + if (std::string ((char*)type) == "global") + { + xmlChar *name = xmlTextReaderGetAttribute (reader, BAD_CAST "name"); + if (name == 0) + { + NS_FATAL_ERROR ("Error getting attribute 'name'"); + } + xmlChar *value = xmlTextReaderGetAttribute (reader, BAD_CAST "value"); + if (value == 0) + { + NS_FATAL_ERROR ("Error getting attribute 'value'"); + } + NS_LOG_DEBUG ("global="<<(char*)name<<", value=" < 0) + { + const xmlChar *type = xmlTextReaderConstName(reader); + if (type == 0) + { + NS_FATAL_ERROR ("Invalid value"); + } + if (std::string ((char*)type) == "value") + { + xmlChar *path = xmlTextReaderGetAttribute (reader, BAD_CAST "path"); + if (path == 0) + { + NS_FATAL_ERROR ("Error getting attribute 'path'"); + } + xmlChar *value = xmlTextReaderGetAttribute (reader, BAD_CAST "value"); + if (value == 0) + { + NS_FATAL_ERROR ("Error getting attribute 'value'"); + } + NS_LOG_DEBUG ("path="<<(char*)path << ", value=" << (char*)value); + Config::Set ((char*)path, StringValue ((char*)value)); + xmlFree (path); + xmlFree (value); + } + rc = xmlTextReaderRead (reader); + } + xmlFreeTextReader (reader); +} + + + +} // namespace ns3 diff --git a/src/contrib/xml-config.h b/src/contrib/xml-config.h new file mode 100644 index 000000000..2a05deaf4 --- /dev/null +++ b/src/contrib/xml-config.h @@ -0,0 +1,41 @@ +#ifndef XML_CONFIG_STORE_H +#define XML_CONFIG_STORE_H + +#include +#include +#include +#include "file-config.h" + +namespace ns3 { + +class XmlConfigSave : public FileConfig +{ +public: + XmlConfigSave (); + virtual ~XmlConfigSave (); + + virtual void SetFilename (std::string filename); + virtual void Default (void); + virtual void Global (void); + virtual void Attributes (void); +private: + xmlTextWriterPtr m_writer; +}; + +class XmlConfigLoad : public FileConfig +{ +public: + XmlConfigLoad (); + virtual ~XmlConfigLoad (); + + virtual void SetFilename (std::string filename); + virtual void Default (void); + virtual void Global (void); + virtual void Attributes (void); +private: + std::string m_filename; +}; + +} // namespace ns3 + +#endif /* XML_CONFIG_STORE_H */