Merge XML config-store
authorRaj Bhattacharjea <raj.b@gatech.edu>
Thu, 19 Mar 2009 13:39:15 -0400
changeset 4278 0ffffb0b92c2
parent 4272 b40ce56e0247 (current diff)
parent 4277 196e20a32b50 (diff)
child 4279 7cb2938928d4
Merge XML config-store
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/attribute-default-iterator.cc	Thu Mar 19 13:39:15 2009 -0400
@@ -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<const AttributeAccessor> accessor = tid.GetAttributeAccessor (j);
+	  if (accessor == 0)
+	    {
+	      continue;
+	    }
+	  if (!accessor->HasSetter ())
+	    {
+	      continue;
+	    }
+	  Ptr<const AttributeChecker> checker = tid.GetAttributeChecker (j);
+	  if (checker == 0)
+	    {
+	      continue;
+	    }
+	  Ptr<const AttributeValue> value = tid.GetAttributeInitialValue (j);
+	  if (value == 0)
+	    {
+	      continue;
+	    }
+	  Ptr<const ObjectVectorValue> vector = DynamicCast<const ObjectVectorValue> (value);
+	  if (vector != 0)
+	    {
+	      continue;
+	    }
+	  Ptr<const PointerValue> pointer = DynamicCast<const PointerValue> (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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/attribute-default-iterator.h	Thu Mar 19 13:39:15 2009 -0400
@@ -0,0 +1,21 @@
+#ifndef ATTRIBUTE_DEFAULT_ITERATOR_H
+#define ATTRIBUTE_DEFAULT_ITERATOR_H
+
+#include <string>
+
+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 */
--- a/src/contrib/attribute-iterator.cc	Wed Mar 18 23:36:37 2009 -0700
+++ b/src/contrib/attribute-iterator.cc	Thu Mar 19 13:39:15 2009 -0400
@@ -252,23 +252,5 @@
     }
 }
 
-TextFileAttributeIterator::TextFileAttributeIterator (std::ostream &os)
-  : m_os (os)
-{}
-void 
-TextFileAttributeIterator::DoVisitAttribute (Ptr<Object> object, std::string name)
-{
-  StringValue str;
-  object->GetAttribute (name, str);
-  m_os << GetCurrentPath () << " " << str.Get () << std::endl;
-}
-
-void 
-TextFileAttributeIterator::Save (void)
-{
-  Iterate ();
-}
-
-
 
 } // namespace ns3
--- a/src/contrib/attribute-iterator.h	Wed Mar 18 23:36:37 2009 -0700
+++ b/src/contrib/attribute-iterator.h	Thu Mar 19 13:39:15 2009 -0400
@@ -49,17 +49,6 @@
   std::vector<std::string> m_currentPath;
 };
 
-class TextFileAttributeIterator : public AttributeIterator
-{
-public:
-  TextFileAttributeIterator (std::ostream &os);
-  void Save (void);
-private:
-  virtual void DoVisitAttribute (Ptr<Object> object, std::string name);
-  std::ostream &m_os;
-};
-
-
 } // namespace ns3
 
 #endif /* ATTRIBUTE_ITERATOR_H */
--- a/src/contrib/config-store.cc	Wed Mar 18 23:36:37 2009 -0700
+++ b/src/contrib/config-store.cc	Thu Mar 19 13:39:15 2009 -0400
@@ -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 <string>
 #include <fstream>
 #include <iostream>
 #include <unistd.h>
 #include <stdlib.h>
 
+
 NS_LOG_COMPONENT_DEFINE ("ConfigStore");
 
 namespace ns3 {
 
+
 NS_OBJECT_ENSURE_REGISTERED (ConfigStore);
 
 TypeId 
@@ -21,16 +29,24 @@
 {
   static TypeId tid = TypeId ("ns3::ConfigStore")
     .SetParent<ObjectBase> ()
-    .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),
+		   MakeStringAccessor (&ConfigStore::SetFilename),
 		   MakeStringChecker ())
-    .AddAttribute ("StoreFilename", 
-		   "The file where the configuration should be stored to.",
-		   StringValue (""),
-		   MakeStringAccessor (&ConfigStore::m_storeFilename),
-		   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::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
--- a/src/contrib/config-store.h	Wed Mar 18 23:36:37 2009 -0700
+++ b/src/contrib/config-store.h	Thu Mar 19 13:39:15 2009 -0400
@@ -2,6 +2,7 @@
 #define CONFIG_STORE_H
 
 #include "ns3/object-base.h"
+#include "file-config.h"
 
 namespace ns3 {
 
@@ -26,24 +27,33 @@
 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/file-config.cc	Thu Mar 19 13:39:15 2009 -0400
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/file-config.h	Thu Mar 19 13:39:15 2009 -0400
@@ -0,0 +1,31 @@
+#ifndef FILE_CONFIG_H
+#define FILE_CONFIG_H
+
+#include <string>
+
+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 */
--- a/src/contrib/gtk-config-store.cc	Wed Mar 18 23:36:37 2009 -0700
+++ b/src/contrib/gtk-config-store.cc	Thu Mar 19 13:39:15 2009 -0400
@@ -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 @@
       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 @@
       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 @@
 {}
 
 void 
-GtkConfigStore::Configure (void)
+GtkConfigStore::ConfigureDefaults (void)
+{}
+
+void 
+GtkConfigStore::ConfigureAttributes (void)
 {
   GtkWidget *window;
   GtkWidget *view;
--- a/src/contrib/gtk-config-store.h	Wed Mar 18 23:36:37 2009 -0700
+++ b/src/contrib/gtk-config-store.h	Thu Mar 19 13:39:15 2009 -0400
@@ -11,7 +11,8 @@
 public:
   GtkConfigStore ();
 
-  void Configure (void);
+  void ConfigureDefaults (void);
+  void ConfigureAttributes (void);
 };
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/raw-text-config.cc	Thu Mar 19 13:39:15 2009 -0400
@@ -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> 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/raw-text-config.h	Thu Mar 19 13:39:15 2009 -0400
@@ -0,0 +1,39 @@
+#ifndef RAW_TEXT_CONFIG_H
+#define RAW_TEXT_CONFIG_H
+
+#include <string>
+#include <fstream>
+#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 */
--- a/src/contrib/wscript	Wed Mar 18 23:36:37 2009 -0700
+++ b/src/contrib/wscript	Thu Mar 19 13:39:15 2009 -0400
@@ -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 @@
         '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 @@
         'event-garbage-collector.h',
         'gnuplot.h',
         'delay-jitter-estimation.h',
+        'file-config.h',
         'config-store.h',
         'flow-id-tag.h',
         ]
@@ -34,3 +47,7 @@
         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'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/xml-config.cc	Thu Mar 19 13:39:15 2009 -0400
@@ -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 <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+
+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> 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=" <<value);
+	  Config::SetDefault ((char*)name, StringValue ((char*)value));
+	  xmlFree (name);
+	  xmlFree (value);
+	}
+      rc = xmlTextReaderRead (reader);
+    }
+  xmlFreeTextReader (reader);
+}
+void 
+XmlConfigLoad::Global (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) == "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=" <<value);
+	  Config::SetGlobal ((char*)name, StringValue ((char*)value));
+	  xmlFree (name);
+	  xmlFree (value);
+	}
+      rc = xmlTextReaderRead (reader);
+    }
+  xmlFreeTextReader (reader);
+}
+void 
+XmlConfigLoad::Attributes (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) == "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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/contrib/xml-config.h	Thu Mar 19 13:39:15 2009 -0400
@@ -0,0 +1,41 @@
+#ifndef XML_CONFIG_STORE_H
+#define XML_CONFIG_STORE_H
+
+#include <string>
+#include <libxml/xmlwriter.h>
+#include <libxml/xmlreader.h>
+#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 */