mirror of
				https://git.wownero.com/wownero/wownero.git
				synced 2024-08-15 01:03:23 +00:00 
			
		
		
		
	Merge pull request #9158
33e3f72 serialization: fix infinite loops and clean up dispatching (jeffro256)
			
			
This commit is contained in:
		
						commit
						68e40ea2a7
					
				
					 9 changed files with 88 additions and 153 deletions
				
			
		| 
						 | 
				
			
			@ -52,7 +52,7 @@ namespace cryptonote
 | 
			
		|||
 | 
			
		||||
    // load
 | 
			
		||||
    template <template <bool> class Archive>
 | 
			
		||||
    bool do_serialize(Archive<false>& ar)
 | 
			
		||||
    bool member_do_serialize(Archive<false>& ar)
 | 
			
		||||
    {
 | 
			
		||||
      // size - 1 - because of variant tag
 | 
			
		||||
      for (size = 1; size <= TX_EXTRA_PADDING_MAX_COUNT; ++size)
 | 
			
		||||
| 
						 | 
				
			
			@ -73,7 +73,7 @@ namespace cryptonote
 | 
			
		|||
 | 
			
		||||
    // store
 | 
			
		||||
    template <template <bool> class Archive>
 | 
			
		||||
    bool do_serialize(Archive<true>& ar)
 | 
			
		||||
    bool member_do_serialize(Archive<true>& ar)
 | 
			
		||||
    {
 | 
			
		||||
      if(TX_EXTRA_PADDING_MAX_COUNT < size)
 | 
			
		||||
        return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -129,7 +129,7 @@ namespace cryptonote
 | 
			
		|||
 | 
			
		||||
    // load
 | 
			
		||||
    template <template <bool> class Archive>
 | 
			
		||||
    bool do_serialize(Archive<false>& ar)
 | 
			
		||||
    bool member_do_serialize(Archive<false>& ar)
 | 
			
		||||
    {
 | 
			
		||||
      std::string field;
 | 
			
		||||
      if(!::do_serialize(ar, field))
 | 
			
		||||
| 
						 | 
				
			
			@ -142,7 +142,7 @@ namespace cryptonote
 | 
			
		|||
 | 
			
		||||
    // store
 | 
			
		||||
    template <template <bool> class Archive>
 | 
			
		||||
    bool do_serialize(Archive<true>& ar)
 | 
			
		||||
    bool member_do_serialize(Archive<true>& ar)
 | 
			
		||||
    {
 | 
			
		||||
      std::ostringstream oss;
 | 
			
		||||
      binary_archive<true> oar(oss);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,7 +42,7 @@ namespace serialization
 | 
			
		|||
    typename std::enable_if<!use_container_varint<T>(), bool>::type
 | 
			
		||||
    serialize_container_element(Archive& ar, T& e)
 | 
			
		||||
    {
 | 
			
		||||
      return ::do_serialize(ar, e);
 | 
			
		||||
      return do_serialize(ar, e);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename Archive, typename T>
 | 
			
		||||
| 
						 | 
				
			
			@ -52,7 +52,7 @@ namespace serialization
 | 
			
		|||
      static constexpr const bool previously_varint = std::is_same<uint64_t, T>() || std::is_same<uint32_t, T>();
 | 
			
		||||
 | 
			
		||||
      if (!previously_varint && ar.varint_bug_backward_compatibility_enabled() && !typename Archive::is_saving())
 | 
			
		||||
        return ::do_serialize(ar, e);
 | 
			
		||||
        return do_serialize(ar, e);
 | 
			
		||||
      ar.serialize_varint(e);
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,14 +42,12 @@ struct debug_archive : public json_archive<W> {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
struct serializer<debug_archive<true>, T>
 | 
			
		||||
static inline bool do_serialize(debug_archive<true> &ar, T &v)
 | 
			
		||||
{
 | 
			
		||||
  static void serialize(debug_archive<true> &ar, T &v)
 | 
			
		||||
  {
 | 
			
		||||
    ar.begin_object();
 | 
			
		||||
    ar.tag(variant_serialization_traits<debug_archive<true>, T>::get_tag());
 | 
			
		||||
    serializer<json_archive<true>, T>::serialize(ar, v);
 | 
			
		||||
    do_serialize(static_cast<json_archive<true>&>(ar), v);
 | 
			
		||||
    ar.end_object();
 | 
			
		||||
    ar.stream() << std::endl;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,8 +31,6 @@
 | 
			
		|||
#include "cryptonote_basic/difficulty.h"
 | 
			
		||||
#include "serialization.h"
 | 
			
		||||
 | 
			
		||||
template<> struct is_basic_type<cryptonote::difficulty_type> { typedef boost::true_type type; };
 | 
			
		||||
 | 
			
		||||
template <template <bool> class Archive>
 | 
			
		||||
inline bool do_serialize(Archive<false>& ar, cryptonote::difficulty_type &diff)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -47,7 +47,7 @@ namespace serialization
 | 
			
		|||
    typename std::enable_if<!use_pair_varint<T>(), bool>::type
 | 
			
		||||
    serialize_pair_element(Archive& ar, T& e)
 | 
			
		||||
    {
 | 
			
		||||
      return ::do_serialize(ar, e);
 | 
			
		||||
      return do_serialize(ar, e);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<typename Archive, typename T>
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +57,7 @@ namespace serialization
 | 
			
		|||
      static constexpr const bool previously_varint = std::is_same<uint64_t, T>();
 | 
			
		||||
 | 
			
		||||
      if (!previously_varint && ar.varint_bug_backward_compatibility_enabled() && !typename Archive::is_saving())
 | 
			
		||||
        return ::do_serialize(ar, e);
 | 
			
		||||
        return do_serialize(ar, e);
 | 
			
		||||
      ar.serialize_varint(e);
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -57,73 +57,30 @@
 | 
			
		|||
template <class T>
 | 
			
		||||
struct is_blob_type { typedef boost::false_type type; };
 | 
			
		||||
 | 
			
		||||
/*! \struct has_free_serializer
 | 
			
		||||
 *
 | 
			
		||||
 * \brief a descriptor for dispatching serialize
 | 
			
		||||
 */
 | 
			
		||||
template <class T>
 | 
			
		||||
struct has_free_serializer { typedef boost::true_type type; };
 | 
			
		||||
 | 
			
		||||
/*! \struct is_basic_type
 | 
			
		||||
 *
 | 
			
		||||
 * \brief a descriptor for dispatching serialize
 | 
			
		||||
 */
 | 
			
		||||
template <class T>
 | 
			
		||||
struct is_basic_type { typedef boost::false_type type; };
 | 
			
		||||
 | 
			
		||||
template<typename F, typename S>
 | 
			
		||||
struct is_basic_type<std::pair<F,S>> { typedef boost::true_type type; };
 | 
			
		||||
template<>
 | 
			
		||||
struct is_basic_type<std::string> { typedef boost::true_type type; };
 | 
			
		||||
 | 
			
		||||
/*! \struct serializer
 | 
			
		||||
 *
 | 
			
		||||
 * \brief ... wouldn't a class be better?
 | 
			
		||||
 * 
 | 
			
		||||
 * \detailed The logic behind serializing data. Places the archive
 | 
			
		||||
 * data into the supplied parameter. This dispatches based on the
 | 
			
		||||
 * supplied \a T template parameter's traits of is_blob_type or it is
 | 
			
		||||
 * an integral (as defined by the is_integral trait). Depends on the
 | 
			
		||||
 * \a Archive parameter to have overloaded the serialize_blob(T v,
 | 
			
		||||
 * size_t size) and serialize_int(T v) base on which trait it
 | 
			
		||||
 * applied. When the class has neither types, it falls to the
 | 
			
		||||
 * overloaded method do_serialize(Archive ar) in T to do the work.
 | 
			
		||||
 */
 | 
			
		||||
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(), typename is_basic_type<T>::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;
 | 
			
		||||
  }
 | 
			
		||||
  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, 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) {
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/*! \fn do_serialize(Archive &ar, T &v)
 | 
			
		||||
 *
 | 
			
		||||
 * \brief just calls the serialize function defined for ar and v...
 | 
			
		||||
 * \brief main function for dispatching serialization for a given pair of archive and value types
 | 
			
		||||
 * 
 | 
			
		||||
 * Types marked true with is_blob_type<T> will be serialized as a blob, integral types will be
 | 
			
		||||
 * serialized as integers, and types who have a `member_do_serialize` method will be serialized
 | 
			
		||||
 * using that method. Booleans are serialized like blobs.
 | 
			
		||||
 */
 | 
			
		||||
template <class Archive, class T>
 | 
			
		||||
inline bool do_serialize(Archive &ar, T &v)
 | 
			
		||||
inline std::enable_if_t<is_blob_type<T>::type::value, bool> do_serialize(Archive &ar, T &v)
 | 
			
		||||
{
 | 
			
		||||
  return ::serializer<Archive, T>::serialize(ar, v);
 | 
			
		||||
  ar.serialize_blob(&v, sizeof(v));
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
template <class Archive, class T>
 | 
			
		||||
inline std::enable_if_t<boost::is_integral<T>::value, bool> do_serialize(Archive &ar, T &v)
 | 
			
		||||
{
 | 
			
		||||
  ar.serialize_int(v);
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
template <class Archive, class T>
 | 
			
		||||
inline auto do_serialize(Archive &ar, T &v) -> decltype(v.member_do_serialize(ar), true)
 | 
			
		||||
{
 | 
			
		||||
  return v.member_do_serialize(ar);
 | 
			
		||||
}
 | 
			
		||||
template <class Archive>
 | 
			
		||||
inline bool do_serialize(Archive &ar, bool &v)
 | 
			
		||||
| 
						 | 
				
			
			@ -144,16 +101,6 @@ inline bool do_serialize(Archive &ar, bool &v)
 | 
			
		|||
    typedef boost::true_type type;					\
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
/*! \macro FREE_SERIALIZER
 | 
			
		||||
 *
 | 
			
		||||
 * \brief adds the has_free_serializer to the type
 | 
			
		||||
 */
 | 
			
		||||
#define FREE_SERIALIZER(T)						\
 | 
			
		||||
  template<>								\
 | 
			
		||||
  struct has_free_serializer<T> {					\
 | 
			
		||||
    typedef boost::true_type type;					\
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
/*! \macro VARIANT_TAG
 | 
			
		||||
 *
 | 
			
		||||
 * \brief Adds the tag \tag to the \a Archive of \a Type
 | 
			
		||||
| 
						 | 
				
			
			@ -174,7 +121,7 @@ inline bool do_serialize(Archive &ar, bool &v)
 | 
			
		|||
 */
 | 
			
		||||
#define BEGIN_SERIALIZE()						\
 | 
			
		||||
  template <bool W, template <bool> class Archive>			\
 | 
			
		||||
  bool do_serialize(Archive<W> &ar) {
 | 
			
		||||
  bool member_do_serialize(Archive<W> &ar) {
 | 
			
		||||
 | 
			
		||||
/*! \macro BEGIN_SERIALIZE_OBJECT
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			@ -183,7 +130,7 @@ inline bool do_serialize(Archive &ar, bool &v)
 | 
			
		|||
 */
 | 
			
		||||
#define BEGIN_SERIALIZE_OBJECT()					\
 | 
			
		||||
  template <bool W, template <bool> class Archive>			\
 | 
			
		||||
  bool do_serialize(Archive<W> &ar) {					\
 | 
			
		||||
  bool member_do_serialize(Archive<W> &ar) {					\
 | 
			
		||||
    ar.begin_object();							\
 | 
			
		||||
    bool r = do_serialize_object(ar);					\
 | 
			
		||||
    ar.end_object();							\
 | 
			
		||||
| 
						 | 
				
			
			@ -197,11 +144,6 @@ inline bool do_serialize(Archive &ar, bool &v)
 | 
			
		|||
#define PREPARE_CUSTOM_VECTOR_SERIALIZATION(size, vec)			\
 | 
			
		||||
  ::serialization::detail::prepare_custom_vector_serialization(size, vec, typename Archive<W>::is_saving())
 | 
			
		||||
 | 
			
		||||
/*! \macro PREPARE_CUSTOM_DEQUE_SERIALIZATION
 | 
			
		||||
 */
 | 
			
		||||
#define PREPARE_CUSTOM_DEQUE_SERIALIZATION(size, vec)			\
 | 
			
		||||
  ::serialization::detail::prepare_custom_deque_serialization(size, vec, typename Archive<W>::is_saving())
 | 
			
		||||
 | 
			
		||||
/*! \macro END_SERIALIZE
 | 
			
		||||
 * \brief self-explanatory
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -209,16 +151,6 @@ inline bool do_serialize(Archive &ar, bool &v)
 | 
			
		|||
  return ar.good();				\
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
/*! \macro VALUE(f)
 | 
			
		||||
 * \brief the same as FIELD(f)
 | 
			
		||||
 */
 | 
			
		||||
#define VALUE(f)					\
 | 
			
		||||
  do {							\
 | 
			
		||||
    ar.tag(#f);						\
 | 
			
		||||
    bool r = ::do_serialize(ar, f);			\
 | 
			
		||||
    if (!r || !ar.good()) return false;			\
 | 
			
		||||
  } while(0);
 | 
			
		||||
 | 
			
		||||
/*! \macro FIELD_N(t,f)
 | 
			
		||||
 *
 | 
			
		||||
 * \brief serializes a field \a f tagged \a t  
 | 
			
		||||
| 
						 | 
				
			
			@ -226,7 +158,7 @@ inline bool do_serialize(Archive &ar, bool &v)
 | 
			
		|||
#define FIELD_N(t, f)					\
 | 
			
		||||
  do {							\
 | 
			
		||||
    ar.tag(t);						\
 | 
			
		||||
    bool r = ::do_serialize(ar, f);			\
 | 
			
		||||
    bool r = do_serialize(ar, f);			\
 | 
			
		||||
    if (!r || !ar.good()) return false;			\
 | 
			
		||||
  } while(0);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -237,7 +169,7 @@ inline bool do_serialize(Archive &ar, bool &v)
 | 
			
		|||
#define FIELD(f)					\
 | 
			
		||||
  do {							\
 | 
			
		||||
    ar.tag(#f);						\
 | 
			
		||||
    bool r = ::do_serialize(ar, f);			\
 | 
			
		||||
    bool r = do_serialize(ar, f);			\
 | 
			
		||||
    if (!r || !ar.good()) return false;			\
 | 
			
		||||
  } while(0);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -247,7 +179,7 @@ inline bool do_serialize(Archive &ar, bool &v)
 | 
			
		|||
 */
 | 
			
		||||
#define FIELDS(f)							\
 | 
			
		||||
  do {									\
 | 
			
		||||
    bool r = ::do_serialize(ar, f);					\
 | 
			
		||||
    bool r = do_serialize(ar, f);					\
 | 
			
		||||
    if (!r || !ar.good()) return false;					\
 | 
			
		||||
  } while(0);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -317,17 +249,6 @@ namespace serialization {
 | 
			
		|||
      vec.resize(size);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    void prepare_custom_deque_serialization(size_t size, std::deque<T>& vec, const boost::mpl::bool_<true>& /*is_saving*/)
 | 
			
		||||
    {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename T>
 | 
			
		||||
    void prepare_custom_deque_serialization(size_t size, std::deque<T>& vec, const boost::mpl::bool_<false>& /*is_saving*/)
 | 
			
		||||
    {
 | 
			
		||||
      vec.resize(size);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /*! \fn do_check_stream_state
 | 
			
		||||
     *
 | 
			
		||||
     * \brief self explanatory
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,7 +39,7 @@ namespace serialization
 | 
			
		|||
    template <typename Archive, class T>
 | 
			
		||||
    bool serialize_tuple_element(Archive& ar, T& e)
 | 
			
		||||
    {
 | 
			
		||||
      return ::do_serialize(ar, e);
 | 
			
		||||
      return do_serialize(ar, e);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <typename Archive>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,7 +72,7 @@ struct variant_reader
 | 
			
		|||
  {
 | 
			
		||||
    if(variant_serialization_traits<Archive, current_type>::get_tag() == t) {
 | 
			
		||||
      current_type x;
 | 
			
		||||
      if(!::do_serialize(ar, x))
 | 
			
		||||
      if(!do_serialize(ar, x))
 | 
			
		||||
      {
 | 
			
		||||
        ar.set_fail();
 | 
			
		||||
        return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -100,19 +100,13 @@ struct variant_reader<Archive, Variant, TBegin, TBegin>
 | 
			
		|||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
template <template <bool> class Archive, BOOST_VARIANT_ENUM_PARAMS(typename T)>
 | 
			
		||||
struct serializer<Archive<false>, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>
 | 
			
		||||
{
 | 
			
		||||
  typedef boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> variant_type;
 | 
			
		||||
  typedef typename Archive<false>::variant_tag_type variant_tag_type;
 | 
			
		||||
  typedef typename variant_type::types types;
 | 
			
		||||
 | 
			
		||||
  static bool serialize(Archive<false> &ar, variant_type &v) {
 | 
			
		||||
    variant_tag_type t;
 | 
			
		||||
template <template <bool> class Archive, typename... T>
 | 
			
		||||
static bool do_serialize(Archive<false> &ar, boost::variant<T...> &v) {
 | 
			
		||||
    using types = typename boost::variant<T...>::types;
 | 
			
		||||
    typename Archive<false>::variant_tag_type t;
 | 
			
		||||
    ar.begin_variant();
 | 
			
		||||
    ar.read_variant_tag(t);
 | 
			
		||||
    if(!variant_reader<Archive<false>, variant_type,
 | 
			
		||||
    if(!variant_reader<Archive<false>, boost::variant<T...>,
 | 
			
		||||
       typename boost::mpl::begin<types>::type,
 | 
			
		||||
       typename boost::mpl::end<types>::type>::read(ar, v, t))
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -121,27 +115,21 @@ struct serializer<Archive<false>, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>
 | 
			
		|||
    }
 | 
			
		||||
    ar.end_variant();
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <template <bool> class Archive, BOOST_VARIANT_ENUM_PARAMS(typename T)>
 | 
			
		||||
struct serializer<Archive<true>, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>
 | 
			
		||||
template <template <bool> class Archive>
 | 
			
		||||
struct variant_write_visitor : public boost::static_visitor<bool>
 | 
			
		||||
{
 | 
			
		||||
  typedef boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> variant_type;
 | 
			
		||||
  //typedef typename Archive<true>::variant_tag_type variant_tag_type;
 | 
			
		||||
 | 
			
		||||
  struct visitor : public boost::static_visitor<bool>
 | 
			
		||||
  {
 | 
			
		||||
    Archive<true> &ar;
 | 
			
		||||
 | 
			
		||||
    visitor(Archive<true> &a) : ar(a) { }
 | 
			
		||||
    variant_write_visitor(Archive<true> &a) : ar(a) { }
 | 
			
		||||
 | 
			
		||||
    template <class T>
 | 
			
		||||
    bool operator ()(T &rv) const
 | 
			
		||||
    {
 | 
			
		||||
      ar.begin_variant();
 | 
			
		||||
      ar.write_variant_tag(variant_serialization_traits<Archive<true>, T>::get_tag());
 | 
			
		||||
      if(!::do_serialize(ar, rv))
 | 
			
		||||
      if(!do_serialize(ar, rv))
 | 
			
		||||
      {
 | 
			
		||||
        ar.set_fail();
 | 
			
		||||
        return false;
 | 
			
		||||
| 
						 | 
				
			
			@ -149,9 +137,10 @@ struct serializer<Archive<true>, boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)>>
 | 
			
		|||
      ar.end_variant();
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  static bool serialize(Archive<true> &ar, variant_type &v) {
 | 
			
		||||
    return boost::apply_visitor(visitor(ar), v);
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
template <template <bool> class Archive, typename... T>
 | 
			
		||||
static bool do_serialize(Archive<true> &ar, boost::variant<T...> &v)
 | 
			
		||||
{
 | 
			
		||||
  return boost::apply_visitor(variant_write_visitor<Archive>(ar), v);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,9 +59,7 @@ struct Struct
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
template <class Archive>
 | 
			
		||||
struct serializer<Archive, Struct>
 | 
			
		||||
{
 | 
			
		||||
  static bool serialize(Archive &ar, Struct &s) {
 | 
			
		||||
static bool do_serialize(Archive &ar, Struct &s) {
 | 
			
		||||
    ar.begin_object();
 | 
			
		||||
    ar.tag("a");
 | 
			
		||||
    ar.serialize_int(s.a);
 | 
			
		||||
| 
						 | 
				
			
			@ -71,8 +69,7 @@ struct serializer<Archive, Struct>
 | 
			
		|||
    ar.serialize_blob(s.blob, sizeof(s.blob));
 | 
			
		||||
    ar.end_object();
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct Struct1
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -122,6 +119,23 @@ bool try_parse(const string &blob)
 | 
			
		|||
  return serialization::parse_binary(blob, s1);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace example_namespace
 | 
			
		||||
{
 | 
			
		||||
  struct ADLExampleStruct
 | 
			
		||||
  {
 | 
			
		||||
    std::string msg;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  template <class Archive>
 | 
			
		||||
  static bool do_serialize(Archive &ar, ADLExampleStruct &aes)
 | 
			
		||||
  {
 | 
			
		||||
    ar.begin_object();
 | 
			
		||||
    FIELD_N("custom_fieldname", aes.msg);
 | 
			
		||||
    ar.end_object();
 | 
			
		||||
    return ar.good();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(Serialization, BinaryArchiveInts) {
 | 
			
		||||
  uint64_t x = 0xff00000000, x1;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1178,3 +1192,18 @@ TEST(Serialization, difficulty_type)
 | 
			
		|||
 | 
			
		||||
  ASSERT_EQ(v_original, v_unserialized);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(Serialization, adl_free_function)
 | 
			
		||||
{
 | 
			
		||||
  std::stringstream ss;
 | 
			
		||||
  json_archive<true> ar(ss);
 | 
			
		||||
 | 
			
		||||
  const std::string msg = "Howdy, World!";
 | 
			
		||||
  example_namespace::ADLExampleStruct aes{msg};
 | 
			
		||||
 | 
			
		||||
  ASSERT_TRUE(serialization::serialize(ar, aes));
 | 
			
		||||
 | 
			
		||||
  //                                                       VVVVVVVVVVVVVVVVVVVVVVVVVV weird string serialization artifact
 | 
			
		||||
  const std::string expected = "{\"custom_fieldname\": " + std::to_string(msg.size()) + '"' + epee::string_tools::buff_to_hex_nodelimer(msg) + "\"}";
 | 
			
		||||
  EXPECT_EQ(expected, ss.str());
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue