MySQL 9.1.0
Source Code Documentation
primitive_type_codec.h
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#ifndef MYSQL_SERIALIZATION_PRIMITIVE_TYPE_CODEC_H
25#define MYSQL_SERIALIZATION_PRIMITIVE_TYPE_CODEC_H
26
27/// @file
28/// Experimental API header
29
31
32#include "my_byteorder.h"
33
36
37#include <bitset>
38#include <iostream>
39#include <limits>
40
41/// @addtogroup GroupLibsMysqlSerialization
42/// @{
43
44namespace mysql::serialization {
45
46template <class Type>
48
49template <Field_size field_size>
51
52/// @brief Specialization of Byte_count_helper for 0 field_size. 0 means
53/// default. Default choice for integer is variable-length encoding (1-9 bytes).
54/// Default choice for a string is unlimited size (un-bounded string)
55template <>
57 /// @brief Calculates bytes needed to encode the field, enabled for integer
58 /// @tparam Type of the field, as represented in the code
59 /// @param arg Variable we need to encode
60 /// @return Bytes needed to encode the "arg" field
61 template <class Type, typename Enabler = std::enable_if_t<
62 std::is_integral<std::decay_t<Type>>::value>>
63 static size_t count_write_bytes(const Type &arg) {
64 return detail::get_size_integer_varlen<Type>(arg);
65 }
66
67 /// @brief Calculates bytes needed to encode the field, enabled for
68 /// non-integer types (float/double)
69 /// @tparam Type of the field, as represented in the code
70 /// @return Bytes needed to encode the "arg" field
71 template <class Type, typename Enabler = std::enable_if_t<
72 std::is_floating_point<std::decay_t<Type>>::value>>
73 static size_t count_write_bytes(const Type &, int = 0) {
74 return sizeof(Type);
75 }
76
77 /// @brief Calculates bytes needed to encode the unbounded string
78 /// @param arg String argument needed to be encoded
79 /// @return Bytes needed to encode the "arg" field
80 static size_t count_write_bytes(const std::string &arg) {
81 return Byte_count_helper<0>::count_write_bytes(arg.length()) + arg.length();
82 }
83};
84
85/// @brief Structure that contains methods to count the number of bytes needed
86/// to encode a specific field
87/// @tparam field_size The number of bytes requested by the user. 0 means
88/// "default". For string, field_size is the boundary length of the string
89template <Field_size field_size>
91 /// Calculates bytes needed to encode the field
92 /// @tparam Type of the field, as represented in the code
93 /// @return Bytes needed to encode the field
94 template <class Type, typename Enabler = std::enable_if_t<
95 std::is_integral<std::decay_t<Type>>::value>>
96 static size_t count_write_bytes(const Type &) {
97 return field_size;
98 }
99
100 /// Calculates bytes needed to encode the bounded string field (specialization
101 /// of count_write_bytes for string type)
102 /// @param arg String argument needed to be encoded
103 /// @return Bytes needed to encode the arg
104 static size_t count_write_bytes(const std::string &arg) {
105 return Byte_count_helper<0>::count_write_bytes(arg.length()) + arg.length();
106 }
107};
108
109/// @brief This class is to provide functionality to encode/decode the primitive
110/// types into/out of defined stream, without boundary check
111/// @tparam Type Type of the field being read / written
112template <class Type>
114 /// @brief Writes field_size bytes stored in data into stream
115 /// @tparam field_size Number of bytes stored into the stream
116 /// @param[in,out] stream Output stream
117 /// @param[in] data Value to write
118 /// @return Number of bytes written
119 template <Field_size field_size>
120 static size_t write_bytes(unsigned char *stream, const Type &data);
121
122 /// @brief Reads field_size bytes stored in the stream into data
123 /// @tparam field_size Number of bytes stored in the stream
124 /// @param[in] stream Input stream
125 /// @param[in] stream_bytes Number of bytes in the stream
126 /// @param[in,out] data Output value
127 /// @return Number of bytes read or 0 on error
128 template <Field_size field_size>
129 static size_t read_bytes(const unsigned char *stream,
130 std::size_t stream_bytes, Type &data);
131
132 /// @brief Returns number of bytes required to hold information
133 /// Returns field_size or size of bytes required to write variable length data
134 /// @tparam field_size Number of bytes stored in the stream
135 /// @param[in] data Count bytes for this variable
136 /// @return Number of bytes that will be read
137 template <Field_size field_size>
138 static size_t count_write_bytes(const Type &data) {
140 }
141};
142
143template <>
144template <Field_size field_size>
146 const std::string &data) {
147 if (data.length() > field_size && field_size != 0) {
148 return 0;
149 }
150 std::size_t bytes_written = detail::write_varlen_bytes(stream, data.length());
151 if (data.length() == 0) {
152 return bytes_written;
153 }
154 memcpy(stream + bytes_written, data.c_str(), data.length());
155 return data.length() + bytes_written;
156}
157
158template <>
159template <Field_size field_size>
161 const unsigned char *stream, std::size_t stream_bytes, std::string &data) {
162 uint64_t string_length = 0;
163 std::size_t bytes_read =
164 detail::read_varlen_bytes(stream, stream_bytes, string_length);
165 if (bytes_read == 0 || (string_length > field_size && field_size != 0) ||
166 stream_bytes < bytes_read + string_length) {
167 return 0;
168 }
169 try {
170 data.resize(string_length);
171 } catch (std::bad_alloc &) {
172 return 0;
173 }
174 memcpy(data.data(), stream + bytes_read, data.length());
175 return data.length() + bytes_read;
176}
177
178} // namespace mysql::serialization
179
180/// @}
181
182#endif // MYSQL_SERIALIZATION_PRIMITIVE_TYPE_CODEC_H
Experimental API header Conversions between different number representations.
Functions for reading and storing in machine-independent format.
size_t write_varlen_bytes(unsigned char *stream, const std::unsigned_integral auto &data)
Writes variable-length integer to the stream.
Definition: variable_length_integers.h:123
size_t read_varlen_bytes(const unsigned char *stream, std::size_t stream_bytes, std::unsigned_integral auto &data)
Reads variable-length integer from the stream.
Definition: variable_length_integers.h:195
Definition: archive.h:37
Type
Definition: resource_group_basic_types.h:33
Experimental API header.
static size_t count_write_bytes(const Type &, int=0)
Calculates bytes needed to encode the field, enabled for non-integer types (float/double)
Definition: primitive_type_codec.h:73
static size_t count_write_bytes(const std::string &arg)
Calculates bytes needed to encode the unbounded string.
Definition: primitive_type_codec.h:80
static size_t count_write_bytes(const Type &arg)
Calculates bytes needed to encode the field, enabled for integer.
Definition: primitive_type_codec.h:63
Structure that contains methods to count the number of bytes needed to encode a specific field.
Definition: primitive_type_codec.h:90
static size_t count_write_bytes(const Type &)
Calculates bytes needed to encode the field.
Definition: primitive_type_codec.h:96
static size_t count_write_bytes(const std::string &arg)
Calculates bytes needed to encode the bounded string field (specialization of count_write_bytes for s...
Definition: primitive_type_codec.h:104
This class is to provide functionality to encode/decode the primitive types into/out of defined strea...
Definition: primitive_type_codec.h:113
static size_t write_bytes(unsigned char *stream, const Type &data)
Writes field_size bytes stored in data into stream.
static size_t count_write_bytes(const Type &data)
Returns number of bytes required to hold information Returns field_size or size of bytes required to ...
Definition: primitive_type_codec.h:138
static size_t read_bytes(const unsigned char *stream, std::size_t stream_bytes, Type &data)
Reads field_size bytes stored in the stream into data.
Experimental API header.