BDE 4.14.0 Production release
Loading...
Searching...
No Matches
baljsn_printutil.h
Go to the documentation of this file.
1/// @file baljsn_printutil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// baljsn_printutil.h -*-C++-*-
8#ifndef INCLUDED_BALJSN_PRINTUTIL
9#define INCLUDED_BALJSN_PRINTUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup baljsn_printutil baljsn_printutil
15/// @brief Provide a utility for encoding simple types in the JSON format.
16/// @addtogroup bal
17/// @{
18/// @addtogroup baljsn
19/// @{
20/// @addtogroup baljsn_printutil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#baljsn_printutil-purpose"> Purpose</a>
25/// * <a href="#baljsn_printutil-classes"> Classes </a>
26/// * <a href="#baljsn_printutil-description"> Description </a>
27/// * <a href="#baljsn_printutil-usage"> Usage </a>
28/// * <a href="#baljsn_printutil-example-1-encoding-a-simple-struct-into-json"> Example 1: Encoding a Simple struct into JSON </a>
29///
30/// # Purpose {#baljsn_printutil-purpose}
31/// Provide a utility for encoding simple types in the JSON format.
32///
33/// # Classes {#baljsn_printutil-classes}
34///
35/// - baljsn::PrintUtil: utility for printing simple types in JSON
36///
37/// @see baljsn_encoder, baljsn_parserutil
38///
39/// # Description {#baljsn_printutil-description}
40/// This component provides a `struct` of utility functions,
41/// `baljsn::PrintUtil`, for encoding a `bdeat` Simple type in the JSON format.
42/// The primary method is `printValue`, which encodes a specified object and is
43/// overloaded for all `bdeat` Simple types. The following table describes the
44/// format in which various Simple types are encoded.
45///
46/// Refer to the details of the JSON encoding format supported by this utility
47/// in the package documentation file (doc/baljsn.txt).
48///
49/// ## Usage {#baljsn_printutil-usage}
50///
51///
52/// This section illustrates intended use of this component.
53///
54/// ## Example 1: Encoding a Simple struct into JSON {#baljsn_printutil-example-1-encoding-a-simple-struct-into-json}
55///
56///
57/// Suppose we want to serialize some data into JSON.
58///
59/// First, we define a struct, `Employee`, to contain the data:
60/// @code
61/// struct Employee {
62/// const char *d_firstName;
63/// const char *d_lastName;
64/// int d_age;
65/// };
66/// @endcode
67/// Then, we create an `Employee` object and populate it with data:
68/// @code
69/// Employee john;
70/// john.d_firstName = "John";
71/// john.d_lastName = "Doe";
72/// john.d_age = 20;
73/// @endcode
74/// Now, we create an output stream and manually construct the JSON string
75/// using `baljsn::PrintUtil`:
76/// @code
77/// bsl::ostringstream oss;
78/// oss << '{' << '\n';
79/// baljsn::PrintUtil::printValue(oss, "firstName");
80/// oss << ':';
81/// baljsn::PrintUtil::printValue(oss, john.d_firstName);
82/// oss << ',' << '\n';
83/// baljsn::PrintUtil::printValue(oss, "lastName");
84/// oss << ':';
85/// baljsn::PrintUtil::printValue(oss, john.d_lastName);
86/// oss << ',' << '\n';
87/// baljsn::PrintUtil::printValue(oss, "age");
88/// oss << ':';
89/// baljsn::PrintUtil::printValue(oss, john.d_age);
90/// oss << '\n' << '}';
91/// @endcode
92/// Finally, we print out the JSON string:
93/// @code
94/// if (verbose) {
95/// bsl::cout << oss.str();
96/// }
97/// @endcode
98/// The output should look like:
99/// @code
100/// {
101/// "firstName":"John",
102/// "lastName":"Doe",
103/// "age":20
104/// }
105/// @endcode
106/// @}
107/** @} */
108/** @} */
109
110/** @addtogroup bal
111 * @{
112 */
113/** @addtogroup baljsn
114 * @{
115 */
116/** @addtogroup baljsn_printutil
117 * @{
118 */
119
120#include <balscm_version.h>
121
123
124#include <bdlb_float.h>
125#include <bdlb_variant.h>
126
127#include <bdldfp_decimal.h>
129#include <bdldfp_decimalutil.h>
130#include <bdljsn_stringutil.h>
132#include <bdlt_iso8601util.h>
133
135
136#include <bsls_platform.h>
137#include <bsls_types.h>
138
139#include <bsl_c_stdio.h>
140#include <bsl_cmath.h>
141#include <bsl_iomanip.h>
142#include <bsl_ios.h>
143#include <bsl_limits.h>
144#include <bsl_ostream.h>
145#include <bsl_string.h>
146#include <bsl_string_view.h>
147
148
149namespace baljsn {
150
151 // ===============
152 // class PrintUtil
153 // ===============
154
155/// This `struct` provides functions for printing objects to output streams
156/// in JSON format.
157struct PrintUtil {
158
159 private:
160 // PRIVATE CLASS METHODS
161
162 /// If the specified `options` is 0, return 0, otherwise return either
163 /// `options->maxFloatPrecision()` if the template parameter `TYPE` is
164 /// `float`, and `options->maxDoublePrecision()` is `double`. The
165 /// supplied `TYPE` must be either `float` or `double`.
166 template <class TYPE>
167 static int maxStreamPrecision(const baljsn::EncoderOptions *options);
168
169 public:
170 // TYPES
171
172 /// `DateOrDateTz` is a convenient alias for
173 /// `bdlb::Variant2<Date, DateTz>`.
175
176 /// `TimeOrTimeTz` is a convenient alias for
177 /// `bdlb::Variant2<Time, TimeTz>`.
179
180 /// `DatetimeOrDatetimeTz` is a convenient alias for
181 /// `bdlb::Variant2<Datetime, DatetimeTz>`.
184
185 // CLASS METHODS
186
187 /// Encode the specified `value` into JSON using ISO 8601 format and output
188 /// the result to the specified `stream` using the specified `options`.
189 template <class TYPE>
190 static int printDateAndTime(bsl::ostream& stream,
191 const TYPE& value,
192 const EncoderOptions *options);
193
194 /// Encode the specified floating point `value` into JSON and output the
195 /// result to the specified `stream`. Use the optionally-specified
196 /// `options` to decide how `value` is encoded.
197 template <class TYPE>
198 static int printFloatingPoint(bsl::ostream& stream,
199 TYPE value,
200 const EncoderOptions *options);
201
202 /// Encode the specified string `value` into JSON format and output the
203 /// result to the specified `stream`.
204 static int printString(bsl::ostream& stream,
205 const bsl::string_view& value);
206
207 static int printValue(bsl::ostream& stream,
208 bool value,
209 const EncoderOptions *options = 0);
210 static int printValue(bsl::ostream& stream,
211 char value,
212 const EncoderOptions *options = 0);
213 static int printValue(bsl::ostream& stream,
214 signed char value,
215 const EncoderOptions *options = 0);
216 static int printValue(bsl::ostream& stream,
217 unsigned char value,
218 const EncoderOptions *options = 0);
219 static int printValue(bsl::ostream& stream,
220 short value,
221 const EncoderOptions *options = 0);
222 static int printValue(bsl::ostream& stream,
223 unsigned short value,
224 const EncoderOptions *options = 0);
225 static int printValue(bsl::ostream& stream,
226 int value,
227 const EncoderOptions *options = 0);
228 static int printValue(bsl::ostream& stream,
229 unsigned int value,
230 const EncoderOptions *options = 0);
231 static int printValue(bsl::ostream& stream,
232 bsls::Types::Int64 value,
233 const EncoderOptions *options = 0);
234 static int printValue(bsl::ostream& stream,
236 const EncoderOptions *options = 0);
237 static int printValue(bsl::ostream& stream,
238 float value,
239 const EncoderOptions *options = 0);
240 static int printValue(bsl::ostream& stream,
241 double value,
242 const EncoderOptions *options = 0);
243 static int printValue(bsl::ostream& stream,
244 bdldfp::Decimal64 value,
245 const EncoderOptions *options = 0);
246 static int printValue(bsl::ostream& stream,
247 const char *value,
248 const EncoderOptions *options = 0);
249 static int printValue(bsl::ostream& stream,
250 const bsl::string_view& value,
251 const EncoderOptions *options = 0);
252 static int printValue(bsl::ostream& stream,
253 const bdlt::Time& value,
254 const EncoderOptions *options = 0);
255 static int printValue(bsl::ostream& stream,
256 const bdlt::Date& value,
257 const EncoderOptions *options = 0);
258 static int printValue(bsl::ostream& stream,
259 const bdlt::Datetime& value,
260 const EncoderOptions *options = 0);
261 static int printValue(bsl::ostream& stream,
262 const bdlt::DatetimeInterval& value,
263 const EncoderOptions *options = 0);
264 static int printValue(bsl::ostream& stream,
265 const bdlt::TimeTz& value,
266 const EncoderOptions *options = 0);
267 static int printValue(bsl::ostream& stream,
268 const bdlt::DateTz& value,
269 const EncoderOptions *options = 0);
270 static int printValue(bsl::ostream& stream,
271 const bdlt::DatetimeTz& value,
272 const EncoderOptions *options = 0);
273 static int printValue(bsl::ostream& stream,
274 const TimeOrTimeTz& value,
275 const EncoderOptions *options = 0);
276 static int printValue(bsl::ostream& stream,
277 const DateOrDateTz& value,
278 const EncoderOptions *options = 0);
279 /// Encode the specified `value` into JSON format and output the result
280 /// to the specified `stream` using the optionally specified `options`.
281 /// Return 0 on success and a non-zero value otherwise.
282 static int printValue(bsl::ostream& stream,
283 const DatetimeOrDatetimeTz& value,
284 const EncoderOptions *options = 0);
285};
286
287// ============================================================================
288// INLINE DEFINITIONS
289// ============================================================================
290
291 // ----------------
292 // struct PrintUtil
293 // ----------------
294
295// PRIVATE CLASS METHODS
296template <>
297inline
298int
299PrintUtil::maxStreamPrecision<float>(const baljsn::EncoderOptions *options)
300{
301 return options ? options->maxFloatPrecision() : 0;
302}
303
304template <>
305inline
306int
307PrintUtil::maxStreamPrecision<double>(const baljsn::EncoderOptions *options)
308{
309 return options ? options->maxDoublePrecision() : 0;
310}
311
312// CLASS METHODS
313template <class TYPE>
314inline
315int PrintUtil::printDateAndTime(bsl::ostream& stream,
316 const TYPE& value,
317 const EncoderOptions *options)
318{
319 char buffer[bdlt::Iso8601Util::k_MAX_STRLEN + 1];
321
322 if (options) {
325 }
326 else {
328 }
329
330 bdlt::Iso8601Util::generate(buffer, sizeof buffer, value, config);
331 return printValue(stream, buffer);
332}
333
334template <class TYPE>
335int PrintUtil::printFloatingPoint(bsl::ostream& stream,
336 TYPE value,
337 const baljsn::EncoderOptions *options)
338{
339 switch (bdlb::Float::classifyFine(value)) {
341 if (options && options->encodeInfAndNaNAsStrings()) {
342 stream << "\"+inf\"";
343 }
344 else {
345 return -1; // RETURN
346 }
347 } break;
349 if (options && options->encodeInfAndNaNAsStrings()) {
350 stream << "\"-inf\"";
351 }
352 else {
353 return -1; // RETURN
354 }
355 } break;
356 case bdlb::Float::k_QNAN: // FALL-THROUGH
357 case bdlb::Float::k_SNAN: {
358 if (options && options->encodeInfAndNaNAsStrings()) {
359 stream << "\"nan\"";
360 }
361 else {
362 return -1; // RETURN
363 }
364 } break;
365 default: {
366 const int precision = maxStreamPrecision<TYPE>(options);
367
368 if (0 == precision) {
369 typedef bslalg::NumericFormatterUtil NumFmt;
370 char buffer[NumFmt::ToCharsMaxLength<TYPE>::k_VALUE];
371
372 const char * const endPtr = NumFmt::toChars(buffer,
373 buffer + sizeof buffer,
374 value);
375 BSLS_ASSERT(0 != endPtr);
376
377 const size_t len = endPtr - buffer;
378
379 stream.write(buffer, len);
380 }
381 else {
382 const int k_SIZE = 32;
383 char buffer[k_SIZE];
384#if defined(BSLS_PLATFORM_CMP_MSVC)
385#define snprintf _snprintf
386#endif
387 const int len = snprintf(buffer,
388 k_SIZE,
389 "%-1.*g",
390 precision,
391 value);
392#if defined(BSLS_PLATFORM_CMP_MSVC)
393#undef snprintf
394#endif
395 stream.write(buffer, len);
396 }
397 }
398 }
399 return 0;
400}
401
402inline
403int PrintUtil::printString(bsl::ostream& stream,
404 const bsl::string_view& value)
405{
406 return bdljsn::StringUtil::writeString(stream, value);
407}
408
409inline
410int PrintUtil::printValue(bsl::ostream& stream,
411 bool value,
412 const EncoderOptions *)
413{
414 stream << (value ? "true" : "false");
415 return 0;
416}
417
418inline
419int PrintUtil::printValue(bsl::ostream& stream,
420 short value,
421 const EncoderOptions *)
422{
423 stream << value;
424 return 0;
425}
426
427inline
428int PrintUtil::printValue(bsl::ostream& stream,
429 int value,
430 const EncoderOptions *)
431{
432 stream << value;
433 return 0;
434}
435
436inline
437int PrintUtil::printValue(bsl::ostream& stream,
438 bsls::Types::Int64 value,
439 const EncoderOptions *)
440{
441 stream << value;
442 return 0;
443}
444
445inline
446int PrintUtil::printValue(bsl::ostream& stream,
447 unsigned char value,
448 const EncoderOptions *)
449{
450 stream << static_cast<int>(value);
451 return 0;
452}
453
454inline
455int PrintUtil::printValue(bsl::ostream& stream,
456 unsigned short value,
457 const EncoderOptions *)
458{
459 stream << value;
460 return 0;
461}
462
463inline
464int PrintUtil::printValue(bsl::ostream& stream,
465 unsigned int value,
466 const EncoderOptions *)
467{
468 stream << value;
469 return 0;
470}
471
472inline
473int PrintUtil::printValue(bsl::ostream& stream,
475 const EncoderOptions *)
476{
477 stream << value;
478 return 0;
479}
480
481inline
482int PrintUtil::printValue(bsl::ostream& stream,
483 float value,
484 const EncoderOptions *options)
485{
486 return printFloatingPoint(stream, value, options);
487}
488
489inline
490int PrintUtil::printValue(bsl::ostream& stream,
491 double value,
492 const EncoderOptions *options)
493{
494 return printFloatingPoint(stream, value, options);
495}
496
497inline
498int PrintUtil::printValue(bsl::ostream& stream,
499 const char *value,
500 const EncoderOptions *)
501{
502 return bdljsn::StringUtil::writeString(stream, value);
503}
504
505inline
506int PrintUtil::printValue(bsl::ostream& stream,
507 char value,
508 const EncoderOptions *)
509{
510 signed char tmp(value); // Note that 'char' is unsigned on IBM.
511
512 stream << static_cast<int>(tmp);
513 return 0;
514}
515
516inline
517int PrintUtil::printValue(bsl::ostream& stream,
518 signed char value,
519 const EncoderOptions *)
520{
521 stream << static_cast<int>(value);
522 return 0;
523}
524
525inline
526int PrintUtil::printValue(bsl::ostream& stream,
527 const bsl::string_view& value,
528 const EncoderOptions *)
529{
530 return bdljsn::StringUtil::writeString(stream, value);
531}
532
533inline
534int PrintUtil::printValue(bsl::ostream& stream,
535 const bdlt::Time& value,
536 const EncoderOptions *options)
537{
538 return printDateAndTime(stream, value, options);
539}
540
541inline
542int PrintUtil::printValue(bsl::ostream& stream,
543 const bdlt::Date& value,
544 const EncoderOptions *options)
545{
546 return printDateAndTime(stream, value, options);
547}
548
549inline
550int PrintUtil::printValue(bsl::ostream& stream,
551 const bdlt::Datetime& value,
552 const EncoderOptions *options)
553{
554 return printDateAndTime(stream, value, options);
555}
556
557inline
558int PrintUtil::printValue(bsl::ostream& stream,
559 const bdlt::DatetimeInterval& value,
560 const EncoderOptions *)
561{
562 stream << '"' << value << '"';
563 return 0;
564}
565
566inline
567int PrintUtil::printValue(bsl::ostream& stream,
568 const bdlt::TimeTz& value,
569 const EncoderOptions *options)
570{
571 return printDateAndTime(stream, value, options);
572}
573
574inline
575int PrintUtil::printValue(bsl::ostream& stream,
576 const bdlt::DateTz& value,
577 const EncoderOptions *options)
578{
579 return printDateAndTime(stream, value, options);
580}
581
582inline
583int PrintUtil::printValue(bsl::ostream& stream,
584 const bdlt::DatetimeTz& value,
585 const EncoderOptions *options)
586{
587 return printDateAndTime(stream, value, options);
588}
589
590inline
591int PrintUtil::printValue(bsl::ostream& stream,
592 const TimeOrTimeTz& value,
593 const EncoderOptions *options)
594{
595 return printDateAndTime(stream, value, options);
596}
597
598inline
599int PrintUtil::printValue(bsl::ostream& stream,
600 const DateOrDateTz& value,
601 const EncoderOptions *options)
602{
603 return printDateAndTime(stream, value, options);
604}
605
606inline
607int PrintUtil::printValue(bsl::ostream& stream,
608 const DatetimeOrDatetimeTz& value,
609 const EncoderOptions *options)
610{
611 return printDateAndTime(stream, value, options);
612}
613
614} // close package namespace
615
616
617
618#endif
619
620// ----------------------------------------------------------------------------
621// Copyright 2015 Bloomberg Finance L.P.
622//
623// Licensed under the Apache License, Version 2.0 (the "License");
624// you may not use this file except in compliance with the License.
625// You may obtain a copy of the License at
626//
627// http://www.apache.org/licenses/LICENSE-2.0
628//
629// Unless required by applicable law or agreed to in writing, software
630// distributed under the License is distributed on an "AS IS" BASIS,
631// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
632// See the License for the specific language governing permissions and
633// limitations under the License.
634// ----------------------------- END-OF-FILE ----------------------------------
635
636/** @} */
637/** @} */
638/** @} */
Definition baljsn_encoderoptions.h:262
bool encodeInfAndNaNAsStrings() const
Definition baljsn_encoderoptions.h:947
int maxFloatPrecision() const
Definition baljsn_encoderoptions.h:959
int maxDoublePrecision() const
Definition baljsn_encoderoptions.h:965
int datetimeFractionalSecondPrecision() const
Definition baljsn_encoderoptions.h:953
Definition bdlb_variant.h:2514
Definition bdldfp_decimal.h:1834
Definition bdlt_datetz.h:162
Definition bdlt_date.h:294
Definition bdlt_datetimeinterval.h:201
Definition bdlt_datetimetz.h:308
Definition bdlt_datetime.h:331
Definition bdlt_iso8601utilconfiguration.h:225
void setFractionalSecondPrecision(int value)
Definition bdlt_timetz.h:190
Definition bdlt_time.h:196
Definition bslstl_stringview.h:441
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition baljsn_datumdecoderoptions.h:113
Definition baljsn_printutil.h:157
bdlb::Variant2< bdlt::Time, bdlt::TimeTz > TimeOrTimeTz
Definition baljsn_printutil.h:178
static int printDateAndTime(bsl::ostream &stream, const TYPE &value, const EncoderOptions *options)
Definition baljsn_printutil.h:315
bdlb::Variant2< bdlt::Datetime, bdlt::DatetimeTz > DatetimeOrDatetimeTz
Definition baljsn_printutil.h:183
static int printValue(bsl::ostream &stream, bdldfp::Decimal64 value, const EncoderOptions *options=0)
static int printFloatingPoint(bsl::ostream &stream, TYPE value, const EncoderOptions *options)
Definition baljsn_printutil.h:335
static int printValue(bsl::ostream &stream, const DatetimeOrDatetimeTz &value, const EncoderOptions *options=0)
bdlb::Variant2< bdlt::Date, bdlt::DateTz > DateOrDateTz
Definition baljsn_printutil.h:174
static int printString(bsl::ostream &stream, const bsl::string_view &value)
Definition baljsn_printutil.h:403
static int printValue(bsl::ostream &stream, bool value, const EncoderOptions *options=0)
Definition baljsn_printutil.h:410
static int printValue(bsl::ostream &stream, const DateOrDateTz &value, const EncoderOptions *options=0)
static FineClassification classifyFine(float number)
@ k_SNAN
Definition bdlb_float.h:249
@ k_NEGATIVE_INFINITY
Definition bdlb_float.h:247
@ k_QNAN
Definition bdlb_float.h:248
@ k_POSITIVE_INFINITY
Definition bdlb_float.h:246
static int writeString(bsl::ostream &stream, const bsl::string_view &string)
@ k_MAX_STRLEN
Definition bdlt_iso8601util.h:761
static int generate(char *buffer, ssize_t bufferLength, const bsls::TimeInterval &object)
Definition bdlt_iso8601util.h:1967
Namespace struct for free functions supporting to_chars.
Definition bslalg_numericformatterutil.h:385
unsigned long long Uint64
Definition bsls_types.h:137
long long Int64
Definition bsls_types.h:132