]> Git Repo - VerusCoin.git/commitdiff
Add serialization for primitive boost::optional<T>.
authorSean Bowe <[email protected]>
Mon, 28 Mar 2016 06:16:22 +0000 (00:16 -0600)
committerSean Bowe <[email protected]>
Thu, 28 Apr 2016 22:07:52 +0000 (16:07 -0600)
src/serialize.h
src/test/serialize_tests.cpp

index 8db53ecfd3144455934fda3ab43a51c6f4a6bea4..0644a852eee700213695fa793d0f365c57c7bb9e 100644 (file)
@@ -21,6 +21,7 @@
 #include <vector>
 
 #include <boost/array.hpp>
+#include <boost/optional.hpp>
 
 class CScript;
 
@@ -508,6 +509,13 @@ extern inline unsigned int GetSerializeSize(const CScript& v, int nType, int nVe
 template<typename Stream> void Serialize(Stream& os, const CScript& v, int nType, int nVersion);
 template<typename Stream> void Unserialize(Stream& is, CScript& v, int nType, int nVersion);
 
+/**
+ * optional
+ */
+template<typename T> unsigned int GetSerializeSize(const boost::optional<T> &item, int nType, int nVersion);
+template<typename Stream, typename T> void Serialize(Stream& os, const boost::optional<T>& item, int nType, int nVersion);
+template<typename Stream, typename T> void Unserialize(Stream& is, boost::optional<T>& item, int nType, int nVersion);
+
 /**
  * array
  */
@@ -707,6 +715,52 @@ void Unserialize(Stream& is, CScript& v, int nType, int nVersion)
 }
 
 
+
+/**
+ * optional
+ */
+template<typename T>
+unsigned int GetSerializeSize(const boost::optional<T> &item, int nType, int nVersion)
+{
+    if (item) {
+        return 1 + GetSerializeSize(*item, nType, nVersion);
+    } else {
+        return 1;
+    }
+}
+
+template<typename Stream, typename T>
+void Serialize(Stream& os, const boost::optional<T>& item, int nType, int nVersion)
+{
+    // If the value is there, put 0x01 and then serialize the value.
+    // If it's not, put 0x00.
+    if (item) {
+        unsigned char discriminant = 0x01;
+        Serialize(os, discriminant, nType, nVersion);
+        Serialize(os, *item, nType, nVersion);
+    } else {
+        unsigned char discriminant = 0x00;
+        Serialize(os, discriminant, nType, nVersion);
+    }
+}
+
+template<typename Stream, typename T>
+void Unserialize(Stream& is, boost::optional<T>& item, int nType, int nVersion)
+{
+    unsigned char discriminant = 0x00;
+    Unserialize(is, discriminant, nType, nVersion);
+
+    if (discriminant == 0x00) {
+        item = boost::none;
+    } else {
+        T object;
+        Unserialize(is, object, nType, nVersion);
+        item = object;
+    }
+}
+
+
+
 /**
  * array
  */
index 56c9db2fdb2908eb1161dd11a8a856a845d67f7a..f7240e4e3742455101c02b821909d5ca7f392ecd 100644 (file)
 #include <stdint.h>
 
 #include <boost/test/unit_test.hpp>
+#include <boost/optional.hpp>
 
 using namespace std;
 
+
+template<typename T>
+void check_ser_rep(T thing, std::vector<unsigned char> expected)
+{
+    CDataStream ss(SER_DISK, 0);
+    ss << thing;
+
+    BOOST_CHECK(GetSerializeSize(thing, 0, 0) == ss.size());
+
+    std::vector<unsigned char> serialized_representation(ss.begin(), ss.end());
+
+    BOOST_CHECK(serialized_representation == expected);
+
+    T thing_deserialized;
+    ss >> thing_deserialized;
+
+    BOOST_CHECK(thing_deserialized == thing);
+}
+
 BOOST_FIXTURE_TEST_SUITE(serialize_tests, BasicTestingSetup)
 
+BOOST_AUTO_TEST_CASE(boost_optional)
+{
+    check_ser_rep<boost::optional<unsigned char>>(0xff, {0x01, 0xff});
+    check_ser_rep<boost::optional<unsigned char>>(boost::none, {0x00});
+    check_ser_rep<boost::optional<std::string>>(std::string("Test"), {0x01, 0x04, 'T', 'e', 's', 't'});
+}
+
 BOOST_AUTO_TEST_CASE(boost_arrays)
 {
     boost::array<std::string, 2> test_case = {string("zub"), string("baz")};
This page took 0.0308850000000001 seconds and 4 git commands to generate.