MySQL 9.1.0
Source Code Documentation
serializer_impl.hpp
Go to the documentation of this file.
1// Copyright (c) 2023, 2024, Oracle and/or its affiliates.
2//
3// This program is free software; you can redistribute it and/or modify
4// it under the terms of the GNU General Public License, version 2.0,
5// as published by the Free Software Foundation.
6//
7// This program is designed to work with certain software (including
8// but not limited to OpenSSL) that is licensed under separate terms,
9// as designated in a particular file or component or in included license
10// documentation. The authors of MySQL hereby grant you an additional
11// permission to link the program and your derivative works with the
12// separately licensed software that they have either included with
13// the program or referenced in the documentation.
14//
15// This program is distributed in the hope that it will be useful,
16// but WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License, version 2.0, for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with this program; if not, write to the Free Software
22// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23
24/// @file
25/// Experimental API header
26
27#include <iostream>
28
29namespace mysql::serialization {
30
31template <class Serializer_derived_type, class Archive_type>
32template <class Field_type, Field_size field_size_defined>
36 get_derived()->encode(level, field_id, field_definition);
37}
38
39template <class Serializer_derived_type, class Archive_type>
40template <class Field_type, Field_size field_size_defined>
42 Level_type level, Field_id_type field_id, std::size_t serializable_end_pos,
44 get_derived()->decode(level, field_id, serializable_end_pos,
45 field_definition);
46}
47
48template <class Serializer_derived_type, class Archive_type>
49template <class Field_type, Field_size field_size_defined>
50std::size_t
54 return Serializer_derived_type::template get_size_field_def(field_id,
55 field_definition);
56}
57
58template <class Serializer_derived_type, class Archive_type>
59template <class Serializable_concrete_type>
60std::size_t
62 Field_id_type field_id, const Serializable_concrete_type &serializable,
63 bool skip_id) {
64 return Serializer_derived_type::template get_size_serializable(
65 field_id, serializable, skip_id);
66}
67
68template <class Serializer_derived_type, class Archive_type>
69template <typename T>
71 const T &arg) {
72 return get_size_serializable(0, arg, false);
73}
74
75template <class Serializer_derived_type, class Archive_type>
76template <typename T>
80 encode_serializable(m_level, field_id, arg, false);
81 return *this;
82}
83
84template <class Serializer_derived_type, class Archive_type>
85template <typename T>
86Serializer<Serializer_derived_type, Archive_type>
89 // passing 0 as serializable_end_pos
90 decode_serializable(m_level, field_id, 0, arg, false);
91 return *this;
92}
93
94template <class Serializer_derived_type, class Archive_type>
96 return m_archive;
98
99template <class Serializer_derived_type, class Archive_type>
100template <class Serializable_type>
102 encode_serializable_fields(const Serializable_type &serializable,
103 Level_type level) {
104 auto process_serializable =
105 [ this, level ](const auto &field, auto field_id) -> auto{
106 this->encode_serializable(level, field_id, field, false);
107 };
108 auto process_field =
109 [ this, level ](const auto &field, auto field_id) -> auto{
110 this->encode_field(level, field_id, field);
111 ++field_id;
112 };
113 serializable.do_for_each_field(process_serializable, process_field);
114}
115
116template <class Serializer_derived_type, class Archive_type>
117template <class Serializable_type>
120 const Serializable_type &serializable, bool skip_id) {
121 if (is_good()) {
122 get_derived()->encode_serializable_metadata(level, field_id, serializable,
123 skip_id);
124 if (is_error()) {
125 return;
126 }
127 // restart numbering below for nested type
128 // separate enumeration is needed to keep forward compatibility of
129 // serialized types, this way if a field is added inside a nested type,
130 // it does not affect rest of the class fields ids (they keep the same
131 // numbering). Before restarting, serializable must save it's own id
132 encode_serializable_fields(serializable, level + 1);
133 }
134}
136template <class Serializer_derived_type, class Archive_type>
137template <class Serializable_type>
139 decode_serializable_fields(Serializable_type &serializable,
140 Level_type level,
141 std::size_t serializable_end_pos) {
142 auto process_serializable =
143 [ this, level, serializable_end_pos ](auto &field, auto field_id) -> auto{
144 this->decode_serializable(level, field_id, serializable_end_pos, field,
145 false);
146 };
147 auto process_field =
148 [ this, level, serializable_end_pos ](auto &field, auto field_id) -> auto{
149 this->decode_field(level, field_id, serializable_end_pos, field);
151 ++field_id;
152 };
153 serializable.do_for_each_field(process_serializable, process_field);
154}
155
156template <class Serializer_derived_type, class Archive_type>
157template <class Serializable_type>
159 Level_type level, Field_id_type field_id, std::size_t serializable_end_pos,
160 Serializable_type &serializable, bool skip_id) {
161 // serializable_end_pos = 0 is a marker for serializers that don't check end
162 // position and for the top-level serializable field (no parent serializable
163 // with end position defined)
164 if (skip_id == false && serializable_end_pos != 0 &&
165 m_archive.get_read_pos() == serializable_end_pos) { // reached the end
166 // missing field handling here
167 // must run field missing functors for all serializable fields recursively
168 auto run_field_missing_functor = [](auto &field, auto) {
169 field.run_field_missing();
170 };
171 auto serializable_field_missing_functor = [](auto &, auto) {};
172 serializable.do_for_each_field(serializable_field_missing_functor,
173 run_field_missing_functor);
174 return;
175 }
176
177 if (is_good()) {
178 auto curr_pos = m_archive.get_read_pos();
179 auto encoded_size_read = get_derived()->decode_serializable_metadata(
180 level, field_id, serializable, skip_id);
181 if (is_error()) {
182 return;
183 }
184 // restart numbering below for nested type
185 // separate enumeration is needed to keep forward compatibility of
186 // serialized types, this way if a field is added inside a nested type,
187 // it does not affect rest of the class fields ids (they keep the same
188 // numbering). Before restarting, serializable must save it's own id
189 decode_serializable_fields(serializable, level + 1,
190 curr_pos + encoded_size_read);
191
192 auto next_pos = m_archive.get_read_pos();
193 auto expected_pos = curr_pos + encoded_size_read;
194 if (expected_pos > next_pos && is_good()) {
195 m_archive.seek_to(expected_pos - next_pos);
196 }
197 }
198}
199
200} // namespace mysql::serialization
Field definition provided by classes implementing Serializable interface.
Definition: field_definition.h:45
Interface for serializer.
Definition: serializer.h:62
void encode_serializable(Level_type level, Field_id_type field_id, const Serializable_type &serializable, bool skip_id)
Function used to encode serializable field, this function saves serializable metadata and calls seria...
Definition: serializer_impl.hpp:118
void encode_field(Level_type level, Field_id_type field_id, const Field_definition< Field_type, field_size_defined > &field_definition)
Function used to encode one field.
Definition: serializer_impl.hpp:33
void encode_serializable_fields(const Serializable_type &serializable, Level_type level)
Function used to encode fields of specializations of Serializable class, iterates over constant field...
Definition: serializer_impl.hpp:102
static std::size_t get_size(const T &arg)
Definition: serializer_impl.hpp:70
void decode_serializable(Level_type level, Field_id_type field_id, std::size_t serializable_end_pos, Serializable_type &serializable, bool skip_id)
Function used to decode serializable field, this function loads serializable metadata and calls seria...
Definition: serializer_impl.hpp:158
void decode_field(Level_type level, Field_id_type field_id, std::size_t serializable_end_pos, Field_definition< Field_type, field_size_defined > &field_definition)
Function used to decode one field.
Definition: serializer_impl.hpp:41
void decode_serializable_fields(Serializable_type &serializable, Level_type level, std::size_t serializable_end_pos)
Function used to decode fields of specializations of Serializable class, iterates over non constant f...
Definition: serializer_impl.hpp:139
static std::size_t get_size_serializable(Field_id_type field_id, const Serializable_concrete_type &serializable, bool skip_id=false)
Function returns size of serializable object written to an archive.
Definition: serializer_impl.hpp:61
Serializer_current_type & operator>>(T &arg)
Function for the API user to serialize data.
Serializer_current_type & operator<<(const T &arg)
Function for the API user to serialize data.
static std::size_t get_size_field_def(Field_id_type field_id, const Field_definition< Field_type, field_size_defined > &field_definition)
Function returns size of field object written to an archive.
Definition: serializer_impl.hpp:51
Archive_type & get_archive()
Function for the API user to access reference of the archive.
Definition: serializer_impl.hpp:95
Definition: archive.h:37
std::size_t Level_type
Type of the "level" used to indicate on which level of the nested message internal fields are defined...
Definition: serialization_types.h:40
uint64_t Field_id_type
Type for field_id assigned to each field in the.
Definition: serialization_types.h:42
static constexpr uint8_t serialization_format_version
Definition: serialization_format_version.h:35
static const LEX_CSTRING field_id
Definition: sql_show_processlist.cc:49