Semi-working (Full|Diff)State -> XML and back conversions
diff --git a/model/sync-diff-state.cc b/model/sync-diff-state.cc
index d0b6f6c..5a53e81 100644
--- a/model/sync-diff-state.cc
+++ b/model/sync-diff-state.cc
@@ -24,6 +24,8 @@
 #include "sync-diff-leaf.h"
 
 #include <boost/make_shared.hpp>
+#include <boost/foreach.hpp>
+#include <boost/assert.hpp>
 
 using namespace boost;
 
@@ -77,5 +79,32 @@
   m_leaves.insert (leaf);
 }
 
+#ifdef _DEBUG
+#define DEBUG_ENDL os << "\n";
+#else
+#define DEBUG_ENDL
+#endif
+
+std::ostream &
+operator << (std::ostream &os, const DiffState &state)
+{
+  os << "<state type=\"diff\">"; DEBUG_ENDL;
+  
+  BOOST_FOREACH (shared_ptr<const Leaf> _leaf, state.getLeaves ())
+    {
+      shared_ptr<const DiffLeaf> leaf = dynamic_pointer_cast<const DiffLeaf> (_leaf);
+      BOOST_ASSERT (leaf != 0);
+
+      os << "<item action=\"" << leaf->getOperation () << "\">"; DEBUG_ENDL;
+      os << "<name>" << leaf->getInfo () << "</name>"; DEBUG_ENDL;
+      if (leaf->getOperation () == UPDATE)
+        {
+          os << "<seq>" << leaf->getSeq () << "</seq>"; DEBUG_ENDL;
+        }
+      os << "</item>"; DEBUG_ENDL;
+    }
+  os << "</state>";
+}
+
 
 } // ns3
diff --git a/model/sync-diff-state.h b/model/sync-diff-state.h
index 4a46969..053be84 100644
--- a/model/sync-diff-state.h
+++ b/model/sync-diff-state.h
@@ -24,6 +24,7 @@
 #define SYNC_DIFF_STATE_H
 
 #include "sync-state.h"
+#include <iostream>
 
 namespace Sync {
 
@@ -96,6 +97,15 @@
   DigestConstPtr m_digest;
 };
 
+/**
+ * @brief Formats an XML representation of the diff state
+ * @param os output stream
+ * @param state state
+ * @returns output stream
+ */
+std::ostream &
+operator << (std::ostream &os, const DiffState &state);
+
 } // Sync
 
 #endif // SYNC_DIFF_STATE_H
diff --git a/model/sync-full-state.cc b/model/sync-full-state.cc
index b30d2d4..f53de39 100644
--- a/model/sync-full-state.cc
+++ b/model/sync-full-state.cc
@@ -117,5 +117,25 @@
   m_leaves.erase (*info);
 }
 
+#ifdef _DEBUG
+#define DEBUG_ENDL os << "\n";
+#else
+#define DEBUG_ENDL
+#endif
+
+std::ostream &
+operator << (std::ostream &os, const FullState &state)
+{
+  os << "<state type=\"full\">"; DEBUG_ENDL;
+  
+  BOOST_FOREACH (shared_ptr<const Leaf> leaf, state.getLeaves ())
+    {
+      os << "<item>"; DEBUG_ENDL;
+      os << "<name>" << leaf->getInfo () << "</name>"; DEBUG_ENDL;
+      os << "<seq>" << leaf->getSeq () << "</seq>"; DEBUG_ENDL;
+      os << "</item>"; DEBUG_ENDL;
+    }
+  os << "</state>";
+}
 
 } // Sync
diff --git a/model/sync-full-state.h b/model/sync-full-state.h
index 7ec703c..96597d0 100644
--- a/model/sync-full-state.h
+++ b/model/sync-full-state.h
@@ -78,6 +78,15 @@
   DigestPtr m_digest;
 };
 
+/**
+ * @brief Formats an XML representation of the full state
+ * @param os output stream
+ * @param state state
+ * @returns output stream
+ */
+std::ostream &
+operator << (std::ostream &os, const FullState &state);
+
 
 } // Sync
 
diff --git a/model/sync-global-function.cc b/model/sync-global-function.cc
index 8c38083..c01b682 100644
--- a/model/sync-global-function.cc
+++ b/model/sync-global-function.cc
@@ -38,7 +38,7 @@
     doc.Parse(DataBuffer.c_str());
     for (TiXmlElement *iterator = doc.RootElement(); iterator != NULL; iterator = iterator->NextSiblingElement())
     {
-      if (strcmp(iterator->Attribute("action"), "UPDATE") == 0)
+      if (strcmp(iterator->Attribute("action"), "update") == 0)
       {
 	TiXmlElement *name = iterator->FirstChildElement();
 	TiXmlElement *session = name->NextSiblingElement();
@@ -58,4 +58,4 @@
 
     return DataBuffer;
   }
-}
\ No newline at end of file
+}
diff --git a/model/sync-seq-no.h b/model/sync-seq-no.h
index ae7f355..93013a5 100644
--- a/model/sync-seq-no.h
+++ b/model/sync-seq-no.h
@@ -142,7 +142,7 @@
 inline std::ostream &
 operator << (std::ostream &os, const SeqNo &seqno)
 {
-  os << seqno.getSession () << ":" << seqno.getSeq ();
+  os << "<session>" << seqno.getSession () << "</session><seqno>" << seqno.getSeq () << "</seqno>";
   return os;
 }
 
diff --git a/model/sync-state.h b/model/sync-state.h
index 03d4ec4..71e65c1 100644
--- a/model/sync-state.h
+++ b/model/sync-state.h
@@ -68,6 +68,8 @@
   LeafContainer m_leaves;
 };
 
+std::string & operator >> (std::string &DataBuffer, State &state);
+
 } // Sync
 
 #endif // SYNC_STATE_H
diff --git a/test/test_state.cc b/test/test_state.cc
index ff0a8a1..e1a5e81 100644
--- a/test/test_state.cc
+++ b/test/test_state.cc
@@ -135,4 +135,64 @@
   BOOST_CHECK (*digest5 == *digest3);
 }
 
+BOOST_AUTO_TEST_CASE (FullStateXml)
+{
+  FullState state;
+
+  NameInfoConstPtr name3 = StdNameInfo::FindOrCreate ("3");
+  NameInfoConstPtr name2 = StdNameInfo::FindOrCreate ("2");
+  NameInfoConstPtr name1 = StdNameInfo::FindOrCreate ("1");
+
+  state.update (name1, SeqNo (10));
+  state.update (name2, SeqNo (12));
+  state.update (name3, SeqNo (8));  
+
+  {
+  ostringstream os;
+  os << state;
+  string s = os.str ();
+  erase_all (s, "\n");
+  BOOST_CHECK_EQUAL (s, "<state type=\"full\"><item><name>3</name><seq><session>0</session><seqno>8</seqno></seq></item><item><name>2</name><seq><session>0</session><seqno>12</seqno></seq></item><item><name>1</name><seq><session>0</session><seqno>10</seqno></seq></item></state>");
+  }
+  
+  state.remove (name2);
+  {
+  ostringstream os;
+  os << state;
+  string s = os.str ();
+  erase_all (s, "\n");
+  BOOST_CHECK_EQUAL (s, "<state type=\"full\"><item><name>3</name><seq><session>0</session><seqno>8</seqno></seq></item><item><name>1</name><seq><session>0</session><seqno>10</seqno></seq></item></state>");
+  }
+}
+
+BOOST_AUTO_TEST_CASE (DiffStateXml)
+{
+  DiffState state;
+
+  NameInfoConstPtr name3 = StdNameInfo::FindOrCreate ("3");
+  NameInfoConstPtr name2 = StdNameInfo::FindOrCreate ("2");
+  NameInfoConstPtr name1 = StdNameInfo::FindOrCreate ("1");
+
+  state.update (name1, SeqNo (10));
+  state.update (name2, SeqNo (12));
+  state.update (name3, SeqNo (8));  
+
+  {
+  ostringstream os;
+  os << state;
+  string s = os.str ();
+  erase_all (s, "\n");
+  BOOST_CHECK_EQUAL (s, "<state type=\"diff\"><item action=\"update\"><name>3</name><seq><session>0</session><seqno>8</seqno></seq></item><item action=\"update\"><name>2</name><seq><session>0</session><seqno>12</seqno></seq></item><item action=\"update\"><name>1</name><seq><session>0</session><seqno>10</seqno></seq></item></state>");
+  }
+  
+  state.remove (name2);
+  {
+  ostringstream os;
+  os << state;
+  string s = os.str ();
+  erase_all (s, "\n");
+  BOOST_CHECK_EQUAL (s, "<state type=\"diff\"><item action=\"update\"><name>3</name><seq><session>0</session><seqno>8</seqno></seq></item><item action=\"remove\"><name>2</name></item><item action=\"update\"><name>1</name><seq><session>0</session><seqno>10</seqno></seq></item></state>");
+  }
+}
+
 BOOST_AUTO_TEST_SUITE_END()