Modifying exception throwing in Sync::Digest

Now there are more diagnostic information attached to each exception
diff --git a/doc/doxygen_boost_dummy.h b/doc/doxygen_boost_dummy.h
index ffcc1b0..bfa0592 100644
--- a/doc/doxygen_boost_dummy.h
+++ b/doc/doxygen_boost_dummy.h
@@ -1,3 +1,6 @@
-namespace boost { template<class T> class shared_ptr { T *dummy; }; }
+namespace boost { 
+	template<class T> class shared_ptr { T *dummy; }; 
+	template<class T> class weak_ptr { T *dummy; }; 
+}
 
 namespace Sync { class DiffStateContainer { boost::shared_ptr<DiffState> dummy; }; }
diff --git a/model/sync-diff-leaf.cc b/model/sync-diff-leaf.cc
index 59e0fc1..0790ec7 100644
--- a/model/sync-diff-leaf.cc
+++ b/model/sync-diff-leaf.cc
@@ -21,6 +21,8 @@
  */
 
 #include "sync-diff-leaf.h"
+#include <boost/throw_exception.hpp>
+typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info; 
 
 namespace Sync {
 
@@ -36,4 +38,35 @@
 {
 }
 
+std::ostream &
+operator << (std::ostream &os, Operation op)
+{
+  switch (op)
+    {
+    case UPDATE:
+      os << "update";
+      break;
+    case REMOVE:
+      os << "remove";
+      break;
+    }
+  return os;
+}
+
+std::istream &
+operator >> (std::istream &is, Operation &op)
+{
+  std::string operation;
+  is >> operation;
+  if (operation == "update")
+    op = UPDATE;
+  else if (operation == "remove")
+    op = REMOVE;
+  else
+    BOOST_THROW_EXCEPTION (SyncDiffLeafOperationParseError () << errmsg_info (operation));
+
+  return is;
+}
+
+
 }
diff --git a/model/sync-diff-leaf.h b/model/sync-diff-leaf.h
index 084b5fc..a4b6538 100644
--- a/model/sync-diff-leaf.h
+++ b/model/sync-diff-leaf.h
@@ -24,6 +24,7 @@
 #define SYNC_DIFF_LEAF_H
 
 #include "sync-leaf.h"
+#include <boost/exception/all.hpp>
 
 namespace Sync {
 
@@ -74,6 +75,14 @@
 
 typedef boost::shared_ptr<DiffLeaf> DiffLeafPtr;
 
+std::ostream &
+operator << (std::ostream &os, Operation op);
+
+std::istream &
+operator >> (std::istream &is, Operation &op);
+
+struct SyncDiffLeafOperationParseError : virtual boost::exception, virtual std::exception { };
+
 } // Sync
 
 #endif // SYNC_DIFF_LEAF_H
diff --git a/model/sync-digest.cc b/model/sync-digest.cc
index 621b52b..d8dda5c 100644
--- a/model/sync-digest.cc
+++ b/model/sync-digest.cc
@@ -24,7 +24,9 @@
 #include <string.h>
 
 #include <boost/assert.hpp>
-#include <boost/exception/errinfo_at_line.hpp>
+#include <boost/throw_exception.hpp>
+typedef boost::error_info<struct tag_errmsg, std::string> errmsg_info_str; 
+typedef boost::error_info<struct tag_errmsg, int> errmsg_info_int; 
 
 // for printing, may be disabled in optimized build
 
@@ -86,7 +88,7 @@
     if ((unsigned)ch < 128)
       value = lookup_table [(unsigned)ch];
     if (value == -1)
-      throw Sync::DigestCalculationError () << errinfo_at_line (__LINE__);
+      BOOST_THROW_EXCEPTION (Sync::DigestCalculationError () << errmsg_info_int ((int)ch));
     
     return value;
   }
@@ -137,7 +139,9 @@
 
   int ok = EVP_DigestInit_ex (m_context, HASH_FUNCTION (), 0);
   if (!ok)
-    throw DigestCalculationError () << errinfo_at_line (__LINE__);
+    BOOST_THROW_EXCEPTION (DigestCalculationError ()
+                           << errmsg_info_str ("EVP_DigestInit_ex returned error")
+                           << errmsg_info_int (ok));
 }
 
 
@@ -151,7 +155,9 @@
   int ok = EVP_DigestFinal_ex (m_context,
 			       m_buffer, &m_hashLength);
   if (!ok)
-    throw DigestCalculationError () << errinfo_at_line (__LINE__);
+    BOOST_THROW_EXCEPTION (DigestCalculationError ()
+                           << errmsg_info_str ("EVP_DigestFinal_ex returned error")
+                           << errmsg_info_int (ok));
 }
   
 std::size_t
@@ -161,7 +167,9 @@
     finalize ();
 
   if (sizeof (std::size_t) > m_hashLength)
-    throw DigestCalculationError () << errinfo_at_line (__LINE__);
+    BOOST_THROW_EXCEPTION (DigestCalculationError ()
+                           << errmsg_info_str ("Hash length is less than size_t")
+                           << errmsg_info_int (m_hashLength));
   
   // just getting first sizeof(std::size_t) bytes
   // not ideal, but should work pretty well
@@ -171,10 +179,19 @@
 bool
 Digest::operator == (const Digest &digest) const
 {
-  if (m_buffer == 0 || digest.m_buffer == 0)
-    throw DigestCalculationError () << errinfo_at_line (__LINE__);
-  
-  BOOST_ASSERT (m_hashLength == digest.m_hashLength);
+  if (m_buffer == 0)
+    BOOST_THROW_EXCEPTION (DigestCalculationError ()
+                           << errmsg_info_str ("Digest1 is empty"));
+
+  if (digest.m_buffer == 0)
+    BOOST_THROW_EXCEPTION (DigestCalculationError ()
+                           << errmsg_info_str ("Digest2 is empty"));
+
+  if (m_hashLength != digest.m_hashLength)
+    BOOST_THROW_EXCEPTION (DigestCalculationError ()
+                           << errmsg_info_str ("Digest lengths are not the same")
+                           << errmsg_info_int (m_hashLength)
+                           << errmsg_info_int (digest.m_hashLength));
 
   return memcmp (m_buffer, digest.m_buffer, m_hashLength) == 0;
 }
@@ -187,11 +204,14 @@
   
   // cannot update Digest when it has been finalized
   if (m_buffer != 0)
-    throw DigestCalculationError () << errinfo_at_line (__LINE__);
+    BOOST_THROW_EXCEPTION (DigestCalculationError ()
+                           << errmsg_info_str ("Digest has been already finalized"));
 
   bool ok = EVP_DigestUpdate (m_context, buffer, size);
   if (!ok)
-    throw DigestCalculationError () << errinfo_at_line (__LINE__);
+    BOOST_THROW_EXCEPTION (DigestCalculationError ()
+                           << errmsg_info_str ("EVP_DigestUpdate returned error")
+                           << errmsg_info_int (ok));
 }
 
 
@@ -199,7 +219,8 @@
 Digest::operator << (const Digest &src)
 {
   if (src.m_buffer == 0) 
-    throw DigestCalculationError () << errinfo_at_line (__LINE__);
+    BOOST_THROW_EXCEPTION (DigestCalculationError ()
+                           << errmsg_info_str ("Digest has not been yet finalized"));
 
   update (src.m_buffer, src.m_hashLength);
 
@@ -227,14 +248,16 @@
   is >> str; // read string first
 
   if (str.size () == 0)
-    throw DigestCalculationError () << errinfo_at_line (__LINE__);
+    BOOST_THROW_EXCEPTION (DigestCalculationError ()
+                           << errmsg_info_str ("Input is empty"));
   
   // uint8_t padding = (3 - str.size () % 3) % 3;
   // for (uint8_t i = 0; i < padding; i++) str.push_back ('=');
 
   // only empty digest object can be used for reading
   if (digest.m_buffer != 0)
-    throw DigestCalculationError () << errinfo_at_line (__LINE__);
+    BOOST_THROW_EXCEPTION (DigestCalculationError ()
+                           << errmsg_info_str ("Digest has been already finalized"));
 
   digest.m_buffer = new uint8_t [EVP_MAX_MD_SIZE];
   uint8_t *end = copy (string_to_binary (str.begin ()),
diff --git a/model/sync-digest.h b/model/sync-digest.h
index 52072d2..04e6d13 100644
--- a/model/sync-digest.h
+++ b/model/sync-digest.h
@@ -130,7 +130,7 @@
   uint32_t m_hashLength;
 };
 
-struct DigestCalculationError : virtual boost::exception { };
+struct DigestCalculationError : virtual boost::exception, virtual std::exception { };
 
 typedef boost::shared_ptr<Digest> DigestPtr;
 typedef boost::shared_ptr<const Digest> DigestConstPtr;
diff --git a/wscript b/wscript
index 7f4f1b3..443bf49 100644
--- a/wscript
+++ b/wscript
@@ -4,6 +4,7 @@
 APPNAME='sync'
 
 def options(opt):
+    opt.add_option('--no-debug',action='store_true',default=False,dest='no_debug',help='''Make an optimized build of the library (remove debugging code)''')
     opt.load('compiler_c')
     opt.load('compiler_cxx')
     opt.load('boost')
@@ -25,7 +26,8 @@
     conf.check_tinyxml (path=conf.options.ccnx_dir)
 
     conf.define ('STANDALONE', 1)
-    # conf.define ('DIGEST_BASE64', 1) # base64 is not working and probably will not work at all
+    if not conf.options.no_debug:
+        conf.define ('_DEBUG', 1)
 	
 def build (bld):
     bld.shlib (target=APPNAME,