Monero
Toggle main menu visibility
Loading...
Searching...
No Matches
src
serialization
container.h
Go to the documentation of this file.
1
// Copyright (c) 2014-2022, The Monero Project
2
//
3
// All rights reserved.
4
//
5
// Redistribution and use in source and binary forms, with or without modification, are
6
// permitted provided that the following conditions are met:
7
//
8
// 1. Redistributions of source code must retain the above copyright notice, this list of
9
// conditions and the following disclaimer.
10
//
11
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
12
// of conditions and the following disclaimer in the documentation and/or other
13
// materials provided with the distribution.
14
//
15
// 3. Neither the name of the copyright holder nor the names of its contributors may be
16
// used to endorse or promote products derived from this software without specific
17
// prior written permission.
18
//
19
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
//
29
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
30
31
#include <algorithm>
32
#include <cstdint>
33
#include <cstddef>
34
#include <limits>
35
#include <type_traits>
36
37
namespace
serialization
38
{
39
namespace
detail
40
{
41
template
<
typename
T>
42
inline
constexpr
bool
use_container_varint
() noexcept
43
{
44
return
std::is_integral<T>::value && std::is_unsigned<T>::value &&
sizeof
(
T
) > 1;
45
}
46
47
template
<
typename
Archive,
class
T>
48
typename
std::enable_if<!use_container_varint<T>(),
bool
>::type
49
serialize_container_element
(Archive&
ar
,
T
& e)
50
{
51
return
do_serialize
(
ar
, e);
52
}
53
54
template
<
typename
Archive,
typename
T>
55
typename
std::enable_if<use_container_varint<T>(),
bool
>::type
56
serialize_container_element
(Archive&
ar
,
T
& e)
57
{
58
static
constexpr
const
bool
previously_varint = std::is_same<uint64_t, T>() || std::is_same<uint32_t, T>();
59
60
if
(!previously_varint &&
ar
.varint_bug_backward_compatibility_enabled() && !
typename
Archive::is_saving())
61
return
do_serialize
(
ar
, e);
62
ar
.serialize_varint(e);
63
return
true
;
64
}
65
67
template
<
typename
... C>
68
void
do_reserve
(
const
C&...) {}
69
template
<
typename
C>
70
auto
do_reserve
(C &c, std::size_t N, std::size_t B) ->
decltype
(c.reserve(N))
71
{
72
using
T
=
typename
C::value_type;
73
74
static
constexpr
std::size_t max_compression_ratio =
75
is_blob_type<T>::type::value
? 1 :
76
use_container_varint<T>
() ?
sizeof
(
T
) :
77
(std::is_same<T, char>::value || std::is_same<T, unsigned char>::value) ? 1:
78
4;
// default
79
80
// max compression ratio for upfront memory usage
81
B /=
sizeof
(
T
);
82
B = std::max(std::size_t(1), B);
83
if
(std::numeric_limits<std::size_t>::max() / max_compression_ratio <= B)
84
B = std::numeric_limits<std::size_t>::max();
85
else
86
B *= max_compression_ratio;
87
88
return
c.reserve(std::min(N, B));
89
}
90
}
91
}
92
93
template
<
template
<
bool
>
class
Archive,
typename
C>
94
bool
do_serialize_container
(Archive<false> &
ar
, C &v)
95
{
96
size_t
cnt;
97
ar
.begin_array(cnt);
98
if
(!
ar
.good())
99
return
false
;
100
v.clear();
101
102
// very basic sanity check
103
if
(
ar
.remaining_bytes() < cnt) {
104
ar
.set_fail();
105
return
false
;
106
}
107
108
::serialization::detail::do_reserve
(v, cnt,
ar
.remaining_bytes());
109
110
for
(
size_t
i = 0; i < cnt; i++) {
111
if
(i > 0)
112
ar
.delimit_array();
113
typename
C::value_type e;
114
if
(!
::serialization::detail::serialize_container_element
(
ar
, e))
115
return
false
;
116
::serialization::detail::do_add
(v, std::move(e));
117
if
(!
ar
.good())
118
return
false
;
119
}
120
ar
.end_array();
121
return
true
;
122
}
123
124
template
<
template
<
bool
>
class
Archive,
typename
C>
125
bool
do_serialize_container
(Archive<true> &
ar
, C &v)
126
{
127
size_t
cnt = v.size();
128
ar
.begin_array(cnt);
129
for
(
auto
i = v.begin(); i != v.end(); ++i)
130
{
131
if
(!
ar
.good())
132
return
false
;
133
if
(i != v.begin())
134
ar
.delimit_array();
135
if
(!
::serialization::detail::serialize_container_element
(
ar
, (
typename
C::value_type&)*i))
136
return
false
;
137
if
(!
ar
.good())
138
return
false
;
139
}
140
ar
.end_array();
141
return
true
;
142
}
ar
binary_archive< false > ar
Definition
cold-outputs.cpp:54
do_serialize_container
bool do_serialize_container(Archive< false > &ar, C &v)
Definition
container.h:94
do_serialize
bool do_serialize(Archive< false > &ar, std::vector< T > &v)
Definition
containers.h:108
detail
declaration and default definition for the functions used the API
Definition
expect.cpp:34
serialization::detail::do_add
void do_add(std::vector< T > &c, T &&e)
Definition
containers.h:90
serialization::detail::do_reserve
void do_reserve(const C &...)
Reserve space for N elements if applicable for container.
Definition
container.h:68
serialization::detail::use_container_varint
constexpr bool use_container_varint() noexcept
Definition
container.h:42
serialization::detail::serialize_container_element
std::enable_if<!use_container_varint< T >(), bool >::type serialize_container_element(Archive &ar, T &e)
Definition
container.h:49
serialization
Definition
binary_utils.h:36
is_blob_type
a descriptor for dispatching serialize
Definition
serialization.h:58
T
#define T(x)
Generated on
for Monero by
1.17.0