Modifying exception throwing in Sync::Digest
Now there are more diagnostic information attached to each exception
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;