diff options
-rw-r--r-- | src/serialization/list.h | 100 | ||||
-rw-r--r-- | src/serialization/pair.h | 96 | ||||
-rw-r--r-- | src/serialization/serialization.h | 27 |
3 files changed, 219 insertions, 4 deletions
diff --git a/src/serialization/list.h b/src/serialization/list.h new file mode 100644 index 000000000..d0fb72163 --- /dev/null +++ b/src/serialization/list.h @@ -0,0 +1,100 @@ +// Copyright (c) 2014-2015, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers + +#pragma once + +#include "serialization.h" + +namespace serialization +{ + namespace detail + { + template <typename Archive, class T> + bool serialize_list_element(Archive& ar, T& e) + { + return ::do_serialize(ar, e); + } + + template <typename Archive> + bool serialize_list_element(Archive& ar, uint64_t& e) + { + ar.serialize_varint(e); + return true; + } + } +} + +template <template <bool> class Archive, class T> +bool do_serialize(Archive<false> &ar, std::list<T> &l) +{ + size_t cnt; + ar.begin_array(cnt); + if (!ar.stream().good()) + return false; + l.clear(); + + // very basic sanity check + if (ar.remaining_bytes() < cnt) { + ar.stream().setstate(std::ios::failbit); + return false; + } + + for (size_t i = 0; i < cnt; i++) { + if (i > 0) + ar.delimit_array(); + l.push_back(T()); + T &t = l.back(); + if (!::serialization::detail::serialize_list_element(ar, t)) + return false; + if (!ar.stream().good()) + return false; + } + ar.end_array(); + return true; +} + +template <template <bool> class Archive, class T> +bool do_serialize(Archive<true> &ar, std::list<T> &l) +{ + size_t cnt = l.size(); + ar.begin_array(cnt); + for (typename std::list<T>::iterator i = l.begin(); i != l.end(); ++i) { + if (!ar.stream().good()) + return false; + if (i != l.begin()) + ar.delimit_array(); + if(!::serialization::detail::serialize_list_element(ar, *i)) + return false; + if (!ar.stream().good()) + return false; + } + ar.end_array(); + return true; +} diff --git a/src/serialization/pair.h b/src/serialization/pair.h new file mode 100644 index 000000000..4913a74d6 --- /dev/null +++ b/src/serialization/pair.h @@ -0,0 +1,96 @@ +// Copyright (c) 2014-2015, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers + +#pragma once +#include <memory> +#include "serialization.h" + +namespace serialization +{ + namespace detail + { + template <typename Archive, class T> + bool serialize_pair_element(Archive& ar, T& e) + { + return ::do_serialize(ar, e); + } + + template <typename Archive> + bool serialize_pair_element(Archive& ar, uint64_t& e) + { + ar.serialize_varint(e); + return true; + } + } +} + +template <template <bool> class Archive, class F, class S> +inline bool do_serialize(Archive<false>& ar, std::pair<F,S>& p) +{ + size_t cnt; + ar.begin_array(cnt); + if (!ar.stream().good()) + return false; + if (cnt != 2) + return false; + + if (!::serialization::detail::serialize_pair_element(ar, p.first)) + return false; + if (!ar.stream().good()) + return false; + ar.delimit_array(); + if (!::serialization::detail::serialize_pair_element(ar, p.second)) + return false; + if (!ar.stream().good()) + return false; + + ar.end_array(); + return true; +} + +template <template <bool> class Archive, class F, class S> +inline bool do_serialize(Archive<true>& ar, std::pair<F,S>& p) +{ + ar.begin_array(2); + if (!ar.stream().good()) + return false; + if(!::serialization::detail::serialize_pair_element(ar, p.first)) + return false; + if (!ar.stream().good()) + return false; + ar.delimit_array(); + if(!::serialization::detail::serialize_pair_element(ar, p.second)) + return false; + if (!ar.stream().good()) + return false; + ar.end_array(); + return true; +} + diff --git a/src/serialization/serialization.h b/src/serialization/serialization.h index 177cdf33a..dac43720b 100644 --- a/src/serialization/serialization.h +++ b/src/serialization/serialization.h @@ -41,6 +41,7 @@ #pragma once #include <vector> +#include <list> #include <string> #include <boost/type_traits/is_integral.hpp> #include <boost/type_traits/integral_constant.hpp> @@ -59,6 +60,16 @@ struct is_blob_type { typedef boost::false_type type; }; template <class T> struct has_free_serializer { typedef boost::true_type type; }; +/*! \struct is_pair_type + * + * \brief a descriptor for dispatching serialize + */ +template <class T> +struct is_pair_type { typedef boost::false_type type; }; + +template<typename F, typename S> +struct is_pair_type<std::pair<F,S>> { typedef boost::true_type type; }; + /*! \struct serializer * * \brief ... wouldn't a class be better? @@ -75,20 +86,26 @@ struct has_free_serializer { typedef boost::true_type type; }; template <class Archive, class T> struct serializer{ static bool serialize(Archive &ar, T &v) { - return serialize(ar, v, typename boost::is_integral<T>::type(), typename is_blob_type<T>::type()); + return serialize(ar, v, typename boost::is_integral<T>::type(), typename is_blob_type<T>::type(), typename is_pair_type<T>::type()); } - static bool serialize(Archive &ar, T &v, boost::false_type, boost::true_type) { + template<typename A> + static bool serialize(Archive &ar, T &v, boost::false_type, boost::true_type, A a) { ar.serialize_blob(&v, sizeof(v)); return true; } - static bool serialize(Archive &ar, T &v, boost::true_type, boost::false_type) { + template<typename A> + static bool serialize(Archive &ar, T &v, boost::true_type, boost::false_type, A a) { ar.serialize_int(v); return true; } - static bool serialize(Archive &ar, T &v, boost::false_type, boost::false_type) { + static bool serialize(Archive &ar, T &v, boost::false_type, boost::false_type, boost::false_type) { //serialize_custom(ar, v, typename has_free_serializer<T>::type()); return v.do_serialize(ar); } + static bool serialize(Archive &ar, T &v, boost::false_type, boost::false_type, boost::true_type) { + //serialize_custom(ar, v, typename has_free_serializer<T>::type()); + return do_serialize(ar, v); + } static void serialize_custom(Archive &ar, T &v, boost::true_type) { } }; @@ -328,3 +345,5 @@ namespace serialization { #include "string.h" #include "vector.h" +#include "list.h" +#include "pair.h" |