- Notifications
You must be signed in to change notification settings - Fork 255
/
Copy pathvalue.h
323 lines (254 loc) · 7.56 KB
/
value.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
/*
* Copyright (c) 2015, 2024, Oracle and/or its affiliates.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2.0, as
* published by the Free Software Foundation.
*
* This program is designed to work with certain software (including
* but not limited to OpenSSL) that is licensed under separate terms, as
* designated in a particular file or component or in included license
* documentation. The authors of MySQL hereby grant you an additional
* permission to link the program and your derivative works with the
* separately licensed software that they have either included with
* the program or referenced in the documentation.
*
* Without limiting anything contained in the foregoing, this file,
* which is part of Connector/C++, is also subject to the
* Universal FOSS Exception, version 1.0, a copy of which can be found at
* https://oss.oracle.com/licenses/universal-foss-exception.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License, version 2.0, for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef MYSQLX_COMMON_VALUE_H
#defineMYSQLX_COMMON_VALUE_H
#include"api.h"
#include"error.h"
#include"util.h"
PUSH_SYS_WARNINGS
#include<string>
POP_SYS_WARNINGS
namespacemysqlx {
MYSQLX_ABI_BEGIN(2,0)
namespacecommon {
classValue_conv;
/*
Class representing a polymorphic value of one of the supported types.
TODO: Extend it with array and document types (currently these are implemented
in derived mysqlx::Value class of DevAPI).
TODO: When storing raw bytes, currently they are copied inside the Value
object. Consider if this can be avoided.
*/
classPUBLIC_API Value
: public virtual Printable
{
public:
enum Type
{
VNULL, ///< Null value
UINT64, ///< Unsigned integer
INT64, ///< Signed integer
FLOAT, ///< Float number
DOUBLE, ///< Double number
BOOL, ///< Boolean
STRING, ///< String (utf8)
USTRING, ///< Wide string (utf16)
RAW, ///< Raw bytes
EXPR, ///< String to be interpreted as an expression
JSON, ///< JSON string
};
using string = std::string;
protected:
Type m_type;
// TODO: Use std::variant to save space
DLL_WARNINGS_PUSH
std::string m_str;
std::u16string m_ustr;
DLL_WARNINGS_POP
union {
double v_double = 0.0;
float v_float;
int64_t v_sint;
uint64_t v_uint;
bool v_bool;
} m_val;
voidprint(std::ostream&) constoverride;
template <typename T>
Value(Type type, T &&init)
: Value(std::forward<T>(init))
{
m_type = type;
}
public:
// Construct a NULL item
Value() : m_type(VNULL)
{}
// Construct an item from a string
Value(const std::string& str) : m_type(STRING), m_str(str)
{
m_val.v_bool = false;
}
Value(const std::u16string &str)
: m_type(USTRING), m_ustr(str)
{
m_val.v_bool = false;
}
// Construct an item from a signed 64-bit integer
Value(int64_t v) : m_type(INT64)
{ m_val.v_sint = v; }
// Construct an item from an unsigned 64-bit integer
Value(uint64_t v) : m_type(UINT64)
{ m_val.v_uint = v; }
// Construct an item from a float
Value(float v) : m_type(FLOAT)
{ m_val.v_float = v; }
// Construct an item from a double
Value(double v) : m_type(DOUBLE)
{ m_val.v_double = v; }
// Construct an item from a bool
Value(bool v) : m_type(BOOL)
{ m_val.v_bool = v; }
// Construct an item from bytes
Value(const byte *ptr, size_t len) : m_type(RAW)
{
// Note: bytes are copied to m_str member.
m_str.assign((constchar*)ptr, len);
}
// Other numeric conversions
template <
typename T,
typename std::enable_if<std::is_unsigned<T>::value>::type* = nullptr
>
Value(T val)
: Value(uint64_t(val))
{}
template <
typename T,
typename std::enable_if<!std::is_unsigned<T>::value>::type* = nullptr,
typename std::enable_if<std::is_integral<T>::value>::type* = nullptr
>
Value(T val)
: Value(int64_t(val))
{}
boolis_null() const
{
return VNULL == m_type;
}
boolget_bool() const
{
switch (m_type)
{
case BOOL: return m_val.v_bool;
case UINT64: return0 != m_val.v_uint;
case INT64: return0 != m_val.v_sint;
default:
throwError("Can not convert to Boolean value");
}
}
uint64_tget_uint() const
{
if (UINT64 != m_type && INT64 != m_type && BOOL != m_type)
throwError("Can not convert to integer value");
if (BOOL == m_type)
return m_val.v_bool ? 1 : 0;
if (INT64 == m_type && 0 > m_val.v_sint)
throwError("Converting negative integer to unsigned value");
uint64_t val = (UINT64 == m_type ? m_val.v_uint : (uint64_t)m_val.v_sint);
return val;
}
int64_tget_sint() const
{
if (INT64 == m_type)
return m_val.v_sint;
uint64_t val = get_uint();
if (!check_num_limits<int64_t>(val))
throwError("Value cannot be converted to signed integer number");
return val;
}
floatget_float() const
{
switch (m_type)
{
case INT64: return1.0F*m_val.v_sint;
case UINT64: return1.0F*m_val.v_uint;
case FLOAT: return m_val.v_float;
default:
throwError("Value cannot be converted to float number");
}
}
doubleget_double() const
{
switch (m_type)
{
case INT64: return1.0*m_val.v_sint;
case UINT64: return1.0*m_val.v_uint;
case FLOAT: return m_val.v_float;
case DOUBLE: return m_val.v_double;
default:
throwError("Value can not be converted to double number");
}
}
/*
Note: In general this method returns raw value representation as obtained
from the server, which is stored in m_str member. If a non-string value was
not obtained from the server, there is no raw representation for it and
error is thrown. String values always have raw representation which is
either utf8 or utf16 encoding. Strings obtained from the server use utf8 as
raw representation. For strings created by user code this might be either
utf8 or utf16, depending on how string was created.
*/
const byte* get_bytes(size_t *size) const
{
switch (m_type)
{
case USTRING:
if (!m_ustr.empty())
{
if (size)
*size = m_ustr.size() * sizeof(char16_t);
return (const byte*)m_ustr.data();
}
FALLTHROUGH;
default:
if (m_str.empty())
throwError("Value cannot be converted to raw bytes");
FALLTHROUGH;
case RAW:
case STRING:
if (size)
*size = m_str.length();
return (const byte*)m_str.data();
}
}
// Note: these methods perform utf8 conversions as necessary.
const std::string& get_string() const;
const std::u16string& get_ustring() const;
Type get_type() const
{
return m_type;
}
private:
/*
Note: Avoid implicit conversion from pointer types to bool.
Without this declaration, Value(bool) constructor is invoked
for pointer types. Here we declare and hide an explicit constructor
for pointer types which prevents compiler to pick Value(bool).
*/
template <typename T>
Value(const T*);
public:
friend Value_conv;
structAccess;
friend Access;
};
} // common
MYSQLX_ABI_END(2,0)
} // mysqlx
#endif