BDE 4.39.x Production Release
Loading...
Searching...
No Matches
baljsn_jsonparserutil.h
Go to the documentation of this file.
1/// @file baljsn_jsonparserutil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// baljsn_jsonparserutil.h -*-C++-*-
8#ifndef INCLUDED_BALJSN_JSONPARSERUTIL
9#define INCLUDED_BALJSN_JSONPARSERUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup baljsn_jsonparserutil baljsn_jsonparserutil
15/// @brief Provide a utility to get simple types from `bdl::json` objects
16/// @addtogroup bal
17/// @{
18/// @addtogroup baljsn
19/// @{
20/// @addtogroup baljsn_jsonparserutil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#baljsn_jsonparserutil-purpose"> Purpose</a>
25/// * <a href="#baljsn_jsonparserutil-classes"> Classes </a>
26/// * <a href="#baljsn_jsonparserutil-description"> Description </a>
27/// * <a href="#baljsn_jsonparserutil-usage"> Usage </a>
28/// * <a href="#baljsn_jsonparserutil-example-1-decoding-into-a-simple-struct-from-bdljsn-json-objects"> Example 1: Decoding into a Simple struct from bdljsn::Json Objects </a>
29///
30/// # Purpose {#baljsn_jsonparserutil-purpose}
31/// Provide a utility to get simple types from `bdl::json` objects
32///
33/// # Classes {#baljsn_jsonparserutil-classes}
34///
35/// - baljsn::JsonParserUtil: utility to get simple types from `bdljsn::Json`s
36///
37/// @see baljsn_parserutil
38///
39/// # Description {#baljsn_jsonparserutil-description}
40/// This component provides a `struct` of utility functions,
41/// `baljsn::JsonParserUtil`, for extracting data from `bdljsn::Json` objects
42/// format into a `bdlat` Simple type. The primary method is `getValue` which
43/// is is overloaded for all `bdlat` Simple types.
44///
45/// ## Usage {#baljsn_jsonparserutil-usage}
46///
47///
48/// This section illustrates intended use of this component.
49///
50/// ## Example 1: Decoding into a Simple struct from bdljsn::Json Objects {#baljsn_jsonparserutil-example-1-decoding-into-a-simple-struct-from-bdljsn-json-objects}
51///
52///
53/// Suppose we want extract some data from `bdljsn::Json` objects.
54///
55/// First, we define a `struct`, `Employee`, to contain the data:
56/// @code
57/// struct Employee {
58/// bsl::string d_name;
59/// bdlt::Date d_date;
60/// int d_age;
61/// };
62/// @endcode
63/// Then, we create an `Employee` object:
64/// @code
65/// Employee employee;
66/// @endcode
67/// Next, we create `bdljsn::Json` objects of different (dynameic) types
68/// having the data of interest. Note that the string data does *not* have
69/// embedden double quote deliminters as required in JSON documents. Also note
70/// that the date information is represented in ISO 8601 format in a string.
71/// @code
72/// const char *nameStr = "John Smith"; // No double quotes *in* string.
73/// const char *dateStr = "1985-06-24"; // No double quotes *in* string.
74///
75/// bdljsn::Json name; name.makeString(nameStr);
76/// bdljsn::Json date; date.makeString(dateStr); // ISO 8601
77/// bdljsn::Json age; age .makeNumber(bdljsn::JsonNumber(21));
78/// @endcode
79/// Now, we use `bdljsn::Json` objects to populate the `employee` object:
80/// @code
81/// assert(0 == baljsn::JsonParserUtil::getValue(&employee.d_name, name));
82/// assert(0 == baljsn::JsonParserUtil::getValue(&employee.d_date, date));
83/// assert(0 == baljsn::JsonParserUtil::getValue(&employee.d_age, age ));
84/// @endcode
85/// Finally, we will verify that the values are as expected:
86/// @code
87/// assert("John Smith" == employee.d_name);
88/// assert(bdlt::Date(1985, 06, 24) == employee.d_date);
89/// assert(21 == employee.d_age);
90/// @endcode
91/// @}
92/** @} */
93/** @} */
94
95/** @addtogroup bal
96 * @{
97 */
98/** @addtogroup baljsn
99 * @{
100 */
101/** @addtogroup baljsn_jsonparserutil
102 * @{
103 */
104
105#include <balscm_version.h>
106
107#include <baljsn_parserutil.h>
108
109#include <bdljsn_json.h>
110
111#include <bdldfp_decimal.h>
112
113#include <bdlt_date.h>
114#include <bdlt_datetime.h>
115#include <bdlt_datetimetz.h>
116#include <bdlt_datetz.h>
117#include <bdlt_time.h>
118#include <bdlt_timetz.h>
119
120#include <bsla_unreachable.h>
121
122#include <bsls_assert.h>
123#include <bsls_libraryfeatures.h>
124#include <bsls_types.h>
125
126#include <bsl_limits.h>
127#include <bsl_cstring.h> // `bsl::strncmp`
128#include <bsl_string.h>
129#include <bsl_string_view.h>
130#include <bsl_vector.h>
131
132#include <string>
133
134
135namespace baljsn {
136
137 // =====================
138 // struct JsonParserUtil
139 // =====================
140
141///This class provides utility functions for decoding data in the JSON
142///format into a `bdeat` Simple type. The primary method is `getValue`,
143///which decodes into a specified object and is overloaded for all `bdeat`
144///Simple types.
145///
146/// See @ref baljsn_jsonparserutil
148
149 public:
150
151 /// Load into the specified `value` the characters read from the
152 /// specified `data`. Return 0 on success or a non-zero value on failure.
153 ///
154 /// \pre The behavior is undefined unless 'json.isBoolean())'
155 static int getValue(bool *value,
156 const bdljsn::Json& json);
157
158 /// Load into the specified `value` the characters read from the
159 /// specified `data`. Return 0 on success or a non-zero value on failure.
160 ///
161 /// \pre The behavior is undefined unless 'json.isNumber())'
162 static int getValue(char *value,
163 const bdljsn::Json& json);
164 static int getValue(unsigned char *value,
165 const bdljsn::Json& json);
166 static int getValue(signed char *value,
167 const bdljsn::Json& json);
168 static int getValue(short *value,
169 const bdljsn::Json& json);
170 static int getValue(unsigned short *value,
171 const bdljsn::Json& json);
172 static int getValue(int *value,
173 const bdljsn::Json& json);
174 static int getValue(unsigned int *value,
175 const bdljsn::Json& json);
176 static int getValue(bsls::Types::Int64 *value,
177 const bdljsn::Json& json);
178 static int getValue(bsls::Types::Uint64 *value,
179 const bdljsn::Json& json);
180
181 /// Load into the specified `value` the characters read from the
182 /// specified `data`. Return 0 on success or a non-zero value on failure.
183 ///
184 /// \pre The behavior is undefined unless 'json.isNumber())'
185 /// or 'json.isString()' if the value is INF, -INF, or NaN.
186 static int getValue(float *value,
187 const bdljsn::Json& json);
188 static int getValue(double *value,
189 const bdljsn::Json& json);
190 static int getValue(bdldfp::Decimal64 *value,
191 const bdljsn::Json& json);
192
193 /// Load into the specified `value` the characters read from the
194 /// specified `data`. Return 0 on success or a non-zero value on failure.
195 ///
196 /// \pre The behavior is undefined unless 'json.isString())'
197 static int getValue(bsl::string *value,
198 const bdljsn::Json& json);
199 static int getValue(std::string *value,
200 const bdljsn::Json& json);
201#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
202 static int getValue(std::pmr::string *value,
203 const bdljsn::Json& json);
204#endif
205 static int getValue(bdlt::Date *value,
206 const bdljsn::Json& json);
207 static int getValue(bdlt::Datetime *value,
208 const bdljsn::Json& json);
209 static int getValue(bdlt::DatetimeTz *value,
210 const bdljsn::Json& json);
211 static int getValue(bdlt::DateTz *value,
212 const bdljsn::Json& json);
213 static int getValue(bdlt::Time *value,
214 const bdljsn::Json& json);
215 static int getValue(bdlt::TimeTz *value,
216 const bdljsn::Json& json);
217
218 static int getValue(ParserUtil::DateOrDateTz *value,
219 const bdljsn::Json& json);
221 const bdljsn::Json& json);
223 const bdljsn::Json& json);
224
225 static int getValue(bsl::vector<char> *value,
226 const bdljsn::Json& data);
227};
228
229// ============================================================================
230// INLINE DEFINITIONS
231// ============================================================================
232
233 // ---------------------
234 // struct JsonParserUtil
235 // ---------------------
236
237inline
238int JsonParserUtil::getValue(bool *value, const bdljsn::Json& json)
239{
240 BSLS_ASSERT(value);
241 BSLS_ASSERT(json.isBoolean());
242
243 *value = json.theBoolean();
244
245 return 0;
246}
247
248inline
249int JsonParserUtil::getValue(char *value, const bdljsn::Json& json)
250{
251 BSLS_ASSERT(value);
252 BSLS_ASSERT(json.isNumber());
253
254 bsl::string_view data = json.theNumber().value();
255
256 return ParserUtil::getValue(value, data);
257}
258
259inline
260int JsonParserUtil::getValue(unsigned char *value, const bdljsn::Json& json)
261{
262 BSLS_ASSERT(value);
263 BSLS_ASSERT(json.isNumber());
264
265 bsl::string_view data = json.theNumber().value();
266
267 return ParserUtil::getValue(value, data);
268}
269
270inline
271int JsonParserUtil::getValue(signed char *value, const bdljsn::Json& json)
272{
273 BSLS_ASSERT(value);
274 BSLS_ASSERT(json.isNumber());
275
276 bsl::string_view data = json.theNumber().value();
277
278 return ParserUtil::getValue(value, data);
279}
280
281inline
282int JsonParserUtil::getValue(short *value, const bdljsn::Json& json)
283{
284 BSLS_ASSERT(value);
285 BSLS_ASSERT(json.isNumber());
286
287 bsl::string_view data = json.theNumber().value();
288
289 return ParserUtil::getValue(value, data);
290}
291
292inline
293int JsonParserUtil::getValue(unsigned short *value, const bdljsn::Json& json)
294{
295 BSLS_ASSERT(value);
296 BSLS_ASSERT(json.isNumber());
297
298 bsl::string_view data = json.theNumber().value();
299
300 return ParserUtil::getValue(value, data);
301}
302
303inline
304int JsonParserUtil::getValue(int *value, const bdljsn::Json& json)
305{
306 BSLS_ASSERT(value);
307 BSLS_ASSERT(json.isNumber());
308
309 bsl::string_view data = json.theNumber().value();
310
311 return ParserUtil::getValue(value, data);
312}
313
314inline
315int JsonParserUtil::getValue(unsigned int *value, const bdljsn::Json& json)
316{
317 BSLS_ASSERT(value);
318 BSLS_ASSERT(json.isNumber());
319
320 bsl::string_view data = json.theNumber().value();
321
322 return ParserUtil::getValue(value, data);
323}
324
325inline
327 const bdljsn::Json& json)
328{
329 BSLS_ASSERT(value);
330 BSLS_ASSERT(json.isNumber());
331
332 bsl::string_view data = json.theNumber().value();
333
334 return ParserUtil::getValue(value, data);
335}
336
337inline
339 const bdljsn::Json& json)
340{
341 BSLS_ASSERT(value);
342 BSLS_ASSERT(json.isNumber());
343
344 bsl::string_view data = json.theNumber().value();
345
346 return ParserUtil::getValue(value, data);
347
348}
349
350inline
351int JsonParserUtil::getValue(float *value, const bdljsn::Json& json)
352{
353 BSLS_ASSERT(value);
354 BSLS_ASSERT(json.isNumber() || json.isString());
355
356 double tmp;
357 const int rc = getValue(&tmp, json);
358 if (!rc) {
359 *value = static_cast<float>(tmp);
360 }
361 return rc;
362}
363
364inline
365int JsonParserUtil::getValue(double *value, const bdljsn::Json& json)
366{
367 BSLS_ASSERT(value);
368 BSLS_ASSERT(json.isNumber() || json.isString());
369
370 if (json.isNumber()) {
371 bsl::string_view data = json.theNumber().value();
372 return ParserUtil::getValue(value, data); // RETURN
373 } else if (json.isString()) {
374 if (0 == bsl::strncmp("+inf",
375 json.theString().data(),
376 json.theString().size())) {
377 *value = bsl::numeric_limits<double>::infinity();
378 return 0; // RETURN
379 } else if (0 == bsl::strncmp("-inf",
380 json.theString().data(),
381 json.theString().size())) {
382 *value = -bsl::numeric_limits<double>::infinity();
383 return 0; // RETURN
384 } else if (0 == bsl::strncmp("nan",
385 json.theString().data(),
386 json.theString().size())) {
387 *value = bsl::numeric_limits<double>::quiet_NaN();
388 return 0; // RETURN
389 } else {
390 return -1; // RETURN
391 }
392 }
393
395}
396
397inline
399 const bdljsn::Json& json)
400{
401 BSLS_ASSERT(value);
402 BSLS_ASSERT(json.isNumber() || json.isString());
403
404 bsl::string_view data = json. isNumber()
405 ? json.theNumber().value()
406 : json.theString();
407
408 return ParserUtil::getValue(value, data);
409}
410
411inline
413{
414 BSLS_ASSERT(value);
415 BSLS_ASSERT(json.isString());
416
417 value->assign(json.theString()); // Note: The 'Json' string already had
418 // delimiting double quotes stripped
419 // and special character sequences
420 // converted.
421 return 0;
422}
423
424inline
425int JsonParserUtil::getValue(std::string *value, const bdljsn::Json& json)
426{
427 BSLS_ASSERT(value);
428 BSLS_ASSERT(json.isString());
429
430 value->assign(json.theString());
431
432 return 0;
433}
434
435#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
436inline
437int JsonParserUtil::getValue(std::pmr::string *value, const bdljsn::Json& json)
438{
439 BSLS_ASSERT(value);
440 BSLS_ASSERT(json.isString());
441
442 value->assign(json.theString());
443
444 return 0;
445}
446#endif
447
448inline
450{
451 BSLS_ASSERT(value);
452 BSLS_ASSERT(json.isString());
453
454 bsl::string_view data = json.theString();
455
456 return bdlt::Iso8601Util::parse(value,
457 data.data(),
458 static_cast<int>(data.length()));
459}
460
461inline
463{
464 BSLS_ASSERT(value);
465 BSLS_ASSERT(json.isString());
466
467 bsl::string_view data = json.theString();
468
469 return bdlt::Iso8601Util::parse(value,
470 data.data(),
471 static_cast<int>(data.length()));
472}
473
474inline
476{
477 BSLS_ASSERT(value);
478 BSLS_ASSERT(json.isString());
479
480 bsl::string_view data = json.theString();
481
482 int rc = bdlt::Iso8601Util::parse(value,
483 data.data(),
484 static_cast<int>(data.length()));
485 return rc;
486}
487
488inline
490{
491 BSLS_ASSERT(value);
492 BSLS_ASSERT(json.isString());
493
494 bsl::string_view data = json.theString();
495
496 return bdlt::Iso8601Util::parse(value,
497 data.data(),
498 static_cast<int>(data.length()));
499}
500
501inline
503{
504 BSLS_ASSERT(value);
505 BSLS_ASSERT(json.isString());
506
507 bsl::string_view data = json.theString();
508
509 return bdlt::Iso8601Util::parse(value,
510 data.data(),
511 static_cast<int>(data.length()));
512}
513
514inline
516{
517 BSLS_ASSERT(value);
518 BSLS_ASSERT(json.isString());
519
520 bsl::string_view data = json.theString();
521
522 return bdlt::Iso8601Util::parse(value,
523 data.data(),
524 static_cast<int>(data.length()));
525}
526
527inline
529 const bdljsn::Json& json)
530{
531 BSLS_ASSERT(value);
532 BSLS_ASSERT(json.isString());
533
534 bsl::string_view data = json.theString();
535
536 return bdlt::Iso8601Util::parse(value,
537 data.data(),
538 static_cast<int>(data.length()));
539}
540
541inline
543 const bdljsn::Json& json)
544{
545 BSLS_ASSERT(value);
546 BSLS_ASSERT(json.isString());
547
548 bsl::string_view data = json.theString();
549
550 return bdlt::Iso8601Util::parse(value,
551 data.data(),
552 static_cast<int>(data.length()));
553}
554
555inline
557 const bdljsn::Json& json)
558{
559 BSLS_ASSERT(value);
560 BSLS_ASSERT(json.isString());
561
562 bsl::string_view data = json.theString();
563
564 return bdlt::Iso8601Util::parse(value,
565 data.data(),
566 static_cast<int>(data.length()));
567}
568
569} // close package namespace
570
571
572#endif
573
574// ----------------------------------------------------------------------------
575// Copyright 2025 Bloomberg Finance L.P.
576//
577// Licensed under the Apache License, Version 2.0 (the "License");
578// you may not use this file except in compliance with the License.
579// You may obtain a copy of the License at
580//
581// http://www.apache.org/licenses/LICENSE-2.0
582//
583// Unless required by applicable law or agreed to in writing, software
584// distributed under the License is distributed on an "AS IS" BASIS,
585// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
586// See the License for the specific language governing permissions and
587// limitations under the License.
588// ----------------------------- END-OF-FILE ----------------------------------
589
590/** @} */
591/** @} */
592/** @} */
Definition bdlb_variant.h:2592
Definition bdldfp_decimal.h:1890
const bsl::string & value() const
Return the textual representation of this JsonNumber.
Definition bdljsn_jsonnumber.h:1010
Definition bdljsn_json.h:1461
bool isBoolean() const
Definition bdljsn_json.h:5064
bool isNumber() const
Definition bdljsn_json.h:5076
bool isString() const
Definition bdljsn_json.h:5088
JsonNumber & theNumber()
Definition bdljsn_json.h:5112
bool & theBoolean()
Definition bdljsn_json.h:5100
const bsl::string & theString() const
Definition bdljsn_json.h:5320
Definition bdlt_datetz.h:161
Definition bdlt_date.h:294
Definition bdlt_datetimetz.h:308
Definition bdlt_datetime.h:330
Definition bdlt_timetz.h:190
Definition bdlt_time.h:195
Definition bslstl_stringview.h:471
Definition bslstl_string.h:1252
basic_string & assign(const basic_string &replacement)
Definition bslstl_string.h:6347
size_type size() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:7292
CHAR_TYPE * data() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:7177
Definition bslstl_vector.h:1120
#define BSLA_UNREACHABLE
Definition bsla_unreachable.h:159
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition baljsn_convertfromjsonoptions.h:112
Definition baljsn_jsonparserutil.h:147
static int getValue(ParserUtil::TimeOrTimeTz *value, const bdljsn::Json &json)
static int getValue(bool *value, const bdljsn::Json &json)
Definition baljsn_jsonparserutil.h:238
static int getValue(ParserUtil::DatetimeOrDatetimeTz *value, const bdljsn::Json &json)
static int getValue(bsl::vector< char > *value, const bdljsn::Json &data)
static int getValue(bool *value, const bsl::string_view &data)
bdlb::Variant2< bdlt::Datetime, bdlt::DatetimeTz > DatetimeOrDatetimeTz
Definition baljsn_parserutil.h:215
static int parse(bsls::TimeInterval *result, const char *string, ssize_t length)
unsigned long long Uint64
Definition bsls_types.h:139
long long Int64
Definition bsls_types.h:134