aboutsummaryrefslogtreecommitdiff
path: root/src/serialization/container.h
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2021-01-12 18:24:55 +0000
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2021-03-05 23:41:19 +0000
commit4a9ae3eb8b9a6d7a2e64f360fda2d5790c8e3321 (patch)
tree3638949b17e8fff7ccd64020f8b75b35ecaded7e /src/serialization/container.h
parentMerge pull request #7295 (diff)
downloadmonero-4a9ae3eb8b9a6d7a2e64f360fda2d5790c8e3321.tar.xz
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.
Diffstat (limited to 'src/serialization/container.h')
-rw-r--r--src/serialization/container.h23
1 files changed, 14 insertions, 9 deletions
diff --git a/src/serialization/container.h b/src/serialization/container.h
index d5e75bb4f..a4997c8ae 100644
--- a/src/serialization/container.h
+++ b/src/serialization/container.h
@@ -32,22 +32,27 @@ namespace serialization
{
namespace detail
{
- template <typename Archive, class T>
- bool serialize_container_element(Archive& ar, T& e)
+ template<typename T>
+ inline constexpr bool use_container_varint() noexcept
{
- return ::do_serialize(ar, e);
+ return std::is_integral<T>::value && std::is_unsigned<T>::value && sizeof(T) > 1;
}
- template <typename Archive>
- bool serialize_container_element(Archive& ar, uint32_t& e)
+ template <typename Archive, class T>
+ typename std::enable_if<!use_container_varint<T>(), bool>::type
+ serialize_container_element(Archive& ar, T& e)
{
- ar.serialize_varint(e);
- return true;
+ return ::do_serialize(ar, e);
}
- template <typename Archive>
- bool serialize_container_element(Archive& ar, uint64_t& e)
+ template<typename Archive, typename T>
+ typename std::enable_if<use_container_varint<T>(), bool>::type
+ serialize_container_element(Archive& ar, T& e)
{
+ 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);
ar.serialize_varint(e);
return true;
}