mirror of
https://github.com/monero-project/monero.git
synced 2025-07-31 08:08:41 -04:00
fix serialization being different on mac
On Mac, size_t is a distinct type from uint64_t, and some types (in wallet cache as well as cold/hot wallet transfer data) use pairs/containers with size_t as fields. Mac would save those as full size, while other platforms would save them as varints. Might apply to other platforms where the types are distinct. There's a nasty hack for backward compatibility, which can go after a couple forks.
This commit is contained in:
parent
b8f3e44a3f
commit
f9b5b521e8
9 changed files with 64 additions and 27 deletions
|
@ -98,7 +98,7 @@ template <>
|
|||
struct binary_archive<false> : public binary_archive_base<std::istream, false>
|
||||
{
|
||||
|
||||
explicit binary_archive(stream_type &s) : base_type(s) {
|
||||
explicit binary_archive(stream_type &s) : base_type(s), varint_bug_backward_compatibility_(false) {
|
||||
stream_type::pos_type pos = stream_.tellg();
|
||||
stream_.seekg(0, std::ios_base::end);
|
||||
eof_pos_ = stream_.tellg();
|
||||
|
@ -173,8 +173,13 @@ struct binary_archive<false> : public binary_archive_base<std::istream, false>
|
|||
assert(stream_.tellg() <= eof_pos_);
|
||||
return eof_pos_ - stream_.tellg();
|
||||
}
|
||||
|
||||
void enable_varint_bug_backward_compatibility() { varint_bug_backward_compatibility_ = true; }
|
||||
bool varint_bug_backward_compatibility_enabled() const { return varint_bug_backward_compatibility_; }
|
||||
|
||||
protected:
|
||||
std::streamoff eof_pos_;
|
||||
bool varint_bug_backward_compatibility_;
|
||||
};
|
||||
|
||||
template <>
|
||||
|
@ -227,6 +232,8 @@ struct binary_archive<true> : public binary_archive_base<std::ostream, true>
|
|||
void write_variant_tag(variant_tag_type t) {
|
||||
serialize_int(t);
|
||||
}
|
||||
|
||||
bool varint_bug_backward_compatibility_enabled() const { return false; }
|
||||
};
|
||||
|
||||
POP_WARNINGS
|
||||
|
|
|
@ -32,22 +32,27 @@ namespace serialization
|
|||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename T>
|
||||
inline constexpr bool use_container_varint() noexcept
|
||||
{
|
||||
return std::is_integral<T>::value && std::is_unsigned<T>::value && sizeof(T) > 1;
|
||||
}
|
||||
|
||||
template <typename Archive, class T>
|
||||
bool serialize_container_element(Archive& ar, T& e)
|
||||
typename std::enable_if<!use_container_varint<T>(), bool>::type
|
||||
serialize_container_element(Archive& ar, T& e)
|
||||
{
|
||||
return ::do_serialize(ar, e);
|
||||
}
|
||||
|
||||
template <typename Archive>
|
||||
bool serialize_container_element(Archive& ar, uint32_t& e)
|
||||
template<typename Archive, typename T>
|
||||
typename std::enable_if<use_container_varint<T>(), bool>::type
|
||||
serialize_container_element(Archive& ar, T& e)
|
||||
{
|
||||
ar.serialize_varint(e);
|
||||
return true;
|
||||
}
|
||||
static constexpr const bool previously_varint = std::is_same<uint64_t, T>() || std::is_same<uint32_t, T>();
|
||||
|
||||
template <typename Archive>
|
||||
bool serialize_container_element(Archive& ar, uint64_t& e)
|
||||
{
|
||||
if (!previously_varint && ar.varint_bug_backward_compatibility_enabled() && !typename Archive::is_saving())
|
||||
return ::do_serialize(ar, e);
|
||||
ar.serialize_varint(e);
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -84,6 +84,8 @@ struct json_archive_base
|
|||
void end_variant() { end_object(); }
|
||||
Stream &stream() { return stream_; }
|
||||
|
||||
bool varint_bug_backward_compatibility_enabled() const { return false; }
|
||||
|
||||
protected:
|
||||
void make_indent()
|
||||
{
|
||||
|
|
|
@ -30,21 +30,34 @@
|
|||
|
||||
#pragma once
|
||||
#include <memory>
|
||||
#include <boost/type_traits/make_unsigned.hpp>
|
||||
#include "serialization.h"
|
||||
|
||||
namespace serialization
|
||||
{
|
||||
namespace detail
|
||||
{
|
||||
template<typename T>
|
||||
inline constexpr bool use_pair_varint() noexcept
|
||||
{
|
||||
return std::is_integral<T>::value && std::is_unsigned<T>::value && sizeof(T) > 1;
|
||||
}
|
||||
|
||||
template <typename Archive, class T>
|
||||
bool serialize_pair_element(Archive& ar, T& e)
|
||||
typename std::enable_if<!use_pair_varint<T>(), bool>::type
|
||||
serialize_pair_element(Archive& ar, T& e)
|
||||
{
|
||||
return ::do_serialize(ar, e);
|
||||
}
|
||||
|
||||
template <typename Archive>
|
||||
bool serialize_pair_element(Archive& ar, uint64_t& e)
|
||||
template<typename Archive, typename T>
|
||||
typename std::enable_if<use_pair_varint<T>(), bool>::type
|
||||
serialize_pair_element(Archive& ar, T& e)
|
||||
{
|
||||
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);
|
||||
ar.serialize_varint(e);
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue