userver
C++ Async Framework
Loading...
Searching...
No Matches
operations.hpp
Go to the documentation of this file.
1
#
pragma
once
2
3
/// @file userver/dump/operations.hpp
4
/// @brief Binary dump Reader and Writer interfaces
5
6
#
include
<
stdexcept
>
7
#
include
<
string
>
8
#
include
<
string_view
>
9
#
include
<
type_traits
>
10
11
#
include
<
userver
/
dump
/
fwd
.
hpp
>
12
#
include
<
userver
/
dump
/
meta
.
hpp
>
13
14
USERVER_NAMESPACE_BEGIN
15
16
namespace
dump
{
17
18
/// Indicates a failure reading or writing a dump. No further operations
19
/// should be performed with a failed dump.
20
class
Error
final
:
public
std::runtime_error {
21
public
:
22
explicit
Error(std::string message) : std::runtime_error(std::move(message)) {}
23
};
24
25
/// A general interface for binary data output
26
class
Writer
{
27
public
:
28
virtual
~Writer() =
default
;
29
30
/// @brief Writes binary data
31
/// @details Calls ADL-found `Write(writer, data)`
32
/// @throws `Error` and any user-thrown `std::exception`
33
template
<
typename
T>
34
void
Write
(
const
T& data);
35
36
/// @brief Must be called once all data has been written
37
/// @warning This method must not be called from within `Write`/`Read`
38
/// @throws `Error` on write operation failure
39
virtual
void
Finish
() = 0;
40
41
protected
:
42
/// @brief Writes binary data
43
/// @details Unlike `Write`, doesn't write the size of `data`
44
/// @throws `Error` on write operation failure
45
virtual
void
WriteRaw
(std::string_view data) = 0;
46
47
friend
void
WriteStringViewUnsafe
(
Writer
& writer, std::string_view value);
48
};
49
50
/// A general interface for binary data input
51
class
Reader
{
52
public
:
53
virtual
~Reader() =
default
;
54
55
/// @brief Reads binary data
56
/// @details Calls ADL-found `Read(reader, To<T>)`
57
/// @throws `Error` and any user-thrown `std::exception`
58
template
<
typename
T>
59
T
Read
();
60
61
/// @brief Must be called once all data has been read
62
/// @warning This method must not be called from within `Write`/`Read`
63
/// @throws `Error` on read operation failure or if there is leftover data
64
virtual
void
Finish
() = 0;
65
66
protected
:
67
/// @brief Reads binary data
68
/// @note Invalidates the memory returned by the previous call of `ReadRaw`
69
/// @note Normally, exactly `max_size` bytes is returned. On end-of-file,
70
/// the amount of bytes returned can be less than `max_size`.
71
/// @throws `Error` on read operation failure
72
virtual
std::string_view
ReadRaw
(std::size_t max_size) = 0;
73
74
/// @brief Moves the internal cursor back by `size` bytes
75
/// so that the next call to @ref ReadRaw returns the same data again
76
/// @note If there has been no previous call to @ref ReadRaw,
77
/// or `size` is greater than the number of bytes returned from that call,
78
/// the behavior is undefined.
79
virtual
void
BackUp
(std::size_t size);
80
81
friend
std::string_view
ReadUnsafeAtMost
(
Reader
& reader, std::size_t size);
82
friend
void
BackUpReadUnsafe
(
Reader
& reader, std::size_t size);
83
};
84
85
namespace
impl {
86
87
template
<
typename
T>
88
void
CallWrite(
Writer
& writer,
const
T& data) {
89
Write(writer, data);
90
}
91
92
template
<
typename
T>
93
// NOLINTNEXTLINE(readability-const-return-type)
94
T CallRead(
Reader
& reader,
To
<T> to) {
95
return
Read(reader, to);
96
}
97
98
}
// namespace impl
99
100
template
<
typename
T>
101
void
Writer
::
Write
(
const
T& data) {
102
if
constexpr
(kIsWritable<T>) {
103
impl::CallWrite(*
this
, data);
104
}
else
if
constexpr
(std::is_aggregate_v<T>) {
105
static_assert
(
106
!
sizeof
(T),
107
"Serialization is not implemented for this type. You "
108
"either forgot to specialize IsDumpedAggregate for your type "
109
"(see <userver/dump/aggregates.hpp>)"
110
"or you've got a non-standard data type and need to implement "
111
"`void Write(dump::Writer& writer, const T& data);` and put it "
112
"in the namespace of `T` or in `dump`."
113
);
114
}
else
{
115
static_assert
(
116
!
sizeof
(T),
117
"You either forgot to `#include <userver/dump/common_containers.hpp>`, "
118
"or you've got a non-standard data type and need to implement "
119
"`void Write(dump::Writer& writer, const T& data);` and put it "
120
"in the namespace of `T` or in `dump`."
121
);
122
}
123
}
124
125
template
<
typename
T>
126
// NOLINTNEXTLINE(readability-const-return-type)
127
T
Reader
::
Read
() {
128
if
constexpr
(kIsReadable<T>) {
129
return
impl::CallRead(*
this
,
To
<T>{});
130
}
else
if
constexpr
(std::is_aggregate_v<T>) {
131
static_assert
(
132
!
sizeof
(T),
133
"Serialization is not implemented for this type. You "
134
"either forgot to specialize IsDumpedAggregate for your type"
135
"(see <userver/dump/aggregates.hpp>) "
136
"or you've got a non-standard data type and need to implement "
137
"`T Read(dump::Reader& reader, dump::To<T>);` and put it "
138
"in the namespace of `T` or in `dump`."
139
);
140
}
else
{
141
static_assert
(
142
!
sizeof
(T),
143
"You either forgot to `#include <userver/dump/common_containers.hpp>`, "
144
"or you've got a non-standard data type and need to implement"
145
"`T Read(dump::Reader& reader, dump::To<T>);` and put it "
146
"in the namespace of `T` or in `dump`."
147
);
148
return
T{};
149
}
150
}
151
152
}
// namespace dump
153
154
USERVER_NAMESPACE_END
userver
dump
operations.hpp
Generated on Thu May 21 2026 16:16:13 for userver by
Doxygen
1.13.2