BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdljsn_jsonutil.h
Go to the documentation of this file.
1/// @file bdljsn_jsonutil.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdljsn_jsonutil.h -*-C++-*-
8#ifndef INCLUDED_BDLJSN_JSONUTIL
9#define INCLUDED_BDLJSN_JSONUTIL
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdljsn_jsonutil bdljsn_jsonutil
15/// @brief Provide common non-primitive operations on `Json` objects.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdljsn
19/// @{
20/// @addtogroup bdljsn_jsonutil
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdljsn_jsonutil-purpose"> Purpose</a>
25/// * <a href="#bdljsn_jsonutil-classes"> Classes </a>
26/// * <a href="#bdljsn_jsonutil-description"> Description </a>
27/// * <a href="#bdljsn_jsonutil-configuring-the-output-format"> Configuring the Output Format </a>
28/// * <a href="#bdljsn_jsonutil-handling-of-duplicate-keys"> Handling of Duplicate Keys </a>
29/// * <a href="#bdljsn_jsonutil-allowing-trailing-text"> Allowing Trailing Text </a>
30/// * <a href="#bdljsn_jsonutil-usage"> Usage </a>
31/// * <a href="#bdljsn_jsonutil-example-1-reading-and-writing-json-data"> Example 1: Reading and Writing JSON Data </a>
32/// * <a href="#bdljsn_jsonutil-example-2-the-effect-of-options-on-write"> Example 2: The Effect of options on write </a>
33/// * <a href="#bdljsn_jsonutil-sortmembers"> sortMembers </a>
34/// * <a href="#bdljsn_jsonutil-style-and-style-related-options"> style And style-related options </a>
35///
36/// # Purpose {#bdljsn_jsonutil-purpose}
37/// Provide common non-primitive operations on `Json` objects.
38///
39/// # Classes {#bdljsn_jsonutil-classes}
40///
41/// - bdljsn::JsonUtil: namespace for non-primitive operations on `Json` objects
42///
43/// # Description {#bdljsn_jsonutil-description}
44/// This component provides a namespace `bdljsn::JsonUtil`
45/// containing utility functions that operate on `Json` objects.
46///
47/// The following methods are provided by `JsonUtil`:
48/// * `read` populate a `Json` object from a JSON text document.
49/// * `write` populate a JSON text document from a `Json` object.
50///
51/// ## Configuring the Output Format {#bdljsn_jsonutil-configuring-the-output-format}
52///
53///
54/// There are a number of options to configure the output format produced by
55/// `write`:
56/// * `escapeForwardSlash`: determines whether any `/` characters are output
57/// escaped (as `\/`) or not (as `/`) in names or strings.
58/// * `sortMembers`: sort the members of any Object elements in the output JSON
59/// (default: `false`)
60/// * `style`: the style of the resulting output
61/// - `e_COMPACT` (default): render with no added white space
62/// - `e_ONELINE`: render a human readable single-line format (e.g., for
63/// logging)
64/// - `e_PRETTY`: render a multi-line human readable format
65/// * `spacesPerLevel`: for the `e_PRETTY` style, the number of spaces added
66/// for each additional nesting level (default 4)
67/// * `initialIndentationLevel`: for the `e_PRETTY` style, the number of sets
68/// of `spacesPerLevel` spaces added to every line of the output, including
69/// the first and last lines (default 0)
70///
71/// The example below shows the various write styles:
72/// @code
73/// Compact:
74/// {"a":1,"b":[]}
75///
76/// One-line:
77/// {"a": 1, "b": []}
78///
79/// Pretty:
80/// {
81/// "a": 1,
82/// "b": []
83/// }
84/// @endcode
85/// For more information, see the @ref bdljsn_writeoptions and @ref bdljsn_writestyle
86/// components.
87///
88/// ## Handling of Duplicate Keys {#bdljsn_jsonutil-handling-of-duplicate-keys}
89///
90///
91/// `bdljsn::JsonObject` represents a JSON Object having unique keys. If an
92/// Object with duplicate keys is found in a JSON document, `read` will preserve
93/// the value associated with the FIRST instance of that key.
94///
95/// Per the JSON RFC (https://www.rfc-editor.org/rfc/rfc8259#section-4):
96/// @code
97/// "The names within an object SHOULD be unique."
98/// @endcode
99/// That is, the expectation is that a JSON document should have unique keys,
100/// and JSON documents with duplicate keys are not an interoperable
101/// representation. JSON parsing implementations vary on how duplicate keys are
102/// handled (though many represent the object in-memory with unique keys). Note
103/// that preserving the value of the first key is consistent with the behavior
104/// of the existing `baljsn::DatumUtil` component.
105///
106/// ## Allowing Trailing Text {#bdljsn_jsonutil-allowing-trailing-text}
107///
108///
109/// By default, `bdljsn::JsonUtil::read` will report an error for input where a
110/// valid JSON document is followed by additional text unless the trailing text
111/// consists solely of white space characters. This behavior is configured by
112/// the `bdljsn::ReadOptions` attribute, "allowTrailingText" (which defaults to
113/// `false`).
114///
115/// If "allowTrailingText" is `true`, then `bdljsn::JsonUtil::read` will return
116/// success where a valid JSON document is followed by additional text as long
117/// as that text is separated from the valid JSON by a delimiter character
118/// (i.e., either the JSON text ends in a delimiter, or the text that follows
119/// starts with a delimiter). Here, delimiters are white-space characters,
120/// `[`, `]`, `{`, `}`, `,`, or double-quotes. Per RFC 8259, white space
121/// characters are Space (0x20), Horizontal tab (0x09), New Line (0x0A), and
122/// Carriage Return (0x0D).
123///
124/// The table below shows some examples:
125/// @code
126/// * "ATT" = "allowTrailingText"
127/// * Document is only valid where the result is SUCCESS
128///
129/// +-----------+------------------------+-------------+-----------+
130/// | Input | ATT = false (default) | ATT = true | Document |
131/// +===========+========================+=============+===========+
132/// | '[]' | SUCCESS | SUCCESS | [] |
133/// | '[] ' | SUCCESS | SUCCESS | [] |
134/// | '[],' | ERROR | SUCCESS | [] |
135/// | '[]a' | ERROR | SUCCESS | [] |
136/// | 'false ' | SUCCESS | SUCCESS | false |
137/// | 'false,' | ERROR | SUCCESS | false |
138/// | 'falsea' | ERROR | ERROR | |
139/// | '"a"x' | ERROR | SUCCESS | "a" |
140/// +-----------+------------------------+-------------+-----------+
141/// @endcode
142///
143/// ## Usage {#bdljsn_jsonutil-usage}
144///
145///
146/// This section illustrates the intended use of this component.
147///
148/// ### Example 1: Reading and Writing JSON Data {#bdljsn_jsonutil-example-1-reading-and-writing-json-data}
149///
150///
151/// This component provides methods for reading and writing JSON data to/from
152/// `Json` objects.
153///
154/// First, we define the JSON data we plan to read:
155/// @code
156/// const char *INPUT_JSON = R"JSON({
157/// "a boolean": true,
158/// "a date": "1970-01-01",
159/// "a number": 2.1,
160/// "an integer": 10,
161/// "array of values": [
162/// -1,
163/// 0,
164/// 2.718281828459045,
165/// 3.1415926535979,
166/// "abc",
167/// true
168/// ],
169/// "event": {
170/// "date": "1969-07-16",
171/// "description": "Apollo 11 Moon Landing",
172/// "passengers": [
173/// "Neil Armstrong",
174/// "Buzz Aldrin"
175/// ],
176/// "success": true,
177/// "target": "/luna/sea-of-tranquility"
178/// }
179/// }})JSON";
180/// @endcode
181/// Next, we read the JSON data into a `Json` object:
182/// @code
183/// bdljsn::Json result;
184/// bdljsn::Error error;
185///
186/// int rc = bdljsn::JsonUtil::read(&result, &error, INPUT_JSON);
187///
188/// assert(0 == rc);
189///
190/// if (0 != rc) {
191/// bsl::cout << "Error message: \"" << error.message() << "\""
192/// << bsl::endl;
193/// }
194/// @endcode
195/// Then, we check the values of a few selected fields:
196/// @code
197/// assert(result.type() == JsonType::e_OBJECT);
198/// assert(result["array of values"][2].theNumber().asDouble()
199/// == 2.718281828459045);
200/// assert(result["event"]["date"].theString() == "1969-07-16");
201/// assert(result["event"]["passengers"][1].theString() == "Buzz Aldrin");
202/// @endcode
203/// Finally, we'll `write` the `result` back into another string and make sure
204/// we got the same value back, by using the correct `WriteOptions` to match
205/// the input format:
206/// @code
207/// bsl::string resultString;
208///
209/// // Set the `WriteOptions` to match the `INPUT_JSON` format:
210/// WriteOptions writeOptions;
211/// writeOptions.setEscapeForwardSlash(false);
212/// writeOptions.setStyle(bdljsn::WriteStyle::e_PRETTY);
213/// writeOptions.setInitialIndentLevel(0);
214/// writeOptions.setSpacesPerLevel(2);
215/// writeOptions.setSortMembers(true);
216///
217/// bdljsn::JsonUtil::write(&resultString, result, writeOptions);
218///
219/// assert(resultString == INPUT_JSON);
220///
221/// // Set the `WriteOptions` to escape forward slashes (for example, to avoid
222/// // XSS issues in HTML contexts):
223/// writeOptions.setEscapeForwardSlash(true);
224///
225/// bdljsn::JsonUtil::write(&resultString, result, writeOptions);
226/// assert(bsl::string::npos !=
227/// resultString.find("\"\\/moon\\/sea-of-tranquility\""));
228/// assert(bsl::string::npos ==
229/// resultString.find("\"/moon/sea-of-tranquility\""));
230/// @endcode
231///
232/// ### Example 2: The Effect of options on write {#bdljsn_jsonutil-example-2-the-effect-of-options-on-write}
233///
234///
235/// By populating a `WriteOptions` object and passing it to `write`, the format
236/// of the resulting JSON can be controlled.
237///
238/// First, let's populate a `Json` object named `json` from an input string
239/// using `read`, and create an empty `options` (see `bdljsn::WriteOptions`):
240/// @code
241/// const bsl::string JSON = R"JSON(
242/// {
243/// "a" : 1,
244/// "b" : []
245/// }
246/// )JSON";
247///
248/// bdljsn::Json json;
249/// bdljsn::WriteOptions options;
250///
251/// int rc = bdljsn::JsonUtil::read(&json, JSON);
252///
253/// assert(0 == rc);
254/// @endcode
255/// There are 4 options, which can be broken down into 2 unrelated sets.
256///
257/// The first set consists of the `sortMembers` option, which controls whether
258/// members of objects are printed in lexicographical order.
259///
260/// The second set consists of the `style`, `initialIndentLevel`, and
261/// `spacesPerLevel` options - `style` controls the format used to render a
262/// `Json`, and, if `bdljsn::WriteStyle::e_PRETTY == options.style()`, the
263/// `spacesPerLevel` and `initialIndentLevel` options are used to control the
264/// indentation of the output. For any other value of `options.style()`, the
265/// `spacesPerLevel` and `initialIndentLevel` options have no effect.
266///
267/// #### sortMembers {#bdljsn_jsonutil-sortmembers}
268///
269///
270/// If `sortMembers` is true, then the members of an object output by `write`
271/// will be in sorted order. Otherwise, the elements are written in an
272/// (implementation defined) order (that may change).
273///
274/// The `sortMembers` option defaults to `false` for performance reasons, but
275/// applications that rely on stable output text should set `sortMembers` to
276/// `true` (e.g., in a test where the resulting JSON text is compared for
277/// equality) .
278///
279/// Here, we set `sortMembers` to `true`, and verify the resulting JSON text
280/// matches the expected text:
281/// @code
282/// options.setSortMembers(true);
283/// bsl::string output;
284///
285/// rc = bdljsn::JsonUtil::write(&output, json, options);
286///
287/// assert(0 == rc);
288/// assert(R"JSON({"a":1,"b":[]})JSON" == output);
289/// @endcode
290/// Had we not specified `setSortMembers(true)`, the order of the "a" and "b"
291/// members in the `output` string would be unpredictable.
292///
293/// #### style And style-related options {#bdljsn_jsonutil-style-and-style-related-options}
294///
295///
296/// There are 3 options for `style` (see `bdljsn::WriteStyle`):
297/// * bdljsn::WriteStyle::e_COMPACT
298/// * bdljsn::WriteStyle::e_ONELINE
299/// * bdljsn::WriteStyle::e_PRETTY
300///
301/// Next, we write `json` using the style `e_COMPACT` (the default), a single
302/// line presentation with no added spaces after `:` and `,` elements.
303/// @code
304/// rc = bdljsn::JsonUtil::write(&output, json, options);
305///
306/// assert(0 == rc);
307///
308/// // Using 'e_COMPACT' style:
309/// assert(R"JSON({"a":1,"b":[]})JSON" == output);
310/// @endcode
311/// Next, we write `json` using the `e_ONELINE` style, another single line
312/// format, which adds single ` ` characters after `:` and `,` elements for
313/// readability.
314/// @code
315/// options.setStyle(bdljsn::WriteStyle::e_ONELINE);
316/// rc = bdljsn::JsonUtil::write(&output, json, options);
317///
318/// assert(0 == rc);
319///
320/// // Using 'e_ONELINE' style:
321/// assert(R"JSON({"a": 1, "b": []})JSON" == output);
322/// @endcode
323/// Next, we write `json` using the `e_PRETTY` style, a multiline format where
324/// newlines are introduced after each (non-terminal) `{`, `[`, `,`, `]`, and
325/// `}` character. Furthermore, the indentation of JSON rendered in the
326/// `e_PRETTY` style is controlled by the other 2 attributes, `spacesPerLevel`
327/// and `initialIndentLevel`.
328///
329/// `e_PRETTY` styling does not add a newline to the end of the output.
330///
331/// `spacesPerLevel` controls the number of spaces added for each successive
332/// indentation level - e.g., if `spacesPerLevel` is 2, then each nesting level
333/// of the rendered JSON is indented 2 spaces.
334///
335/// `initialIndentLevel` controls how much the entire JSON output is indented.
336/// It defaults to 0 - if it's a positive value, then the entire JSON is
337/// indented by `initialIndentLevel * spacesPerLevel` spaces.
338/// @code
339/// options.setStyle(bdljsn::WriteStyle::e_PRETTY);
340/// options.setSpacesPerLevel(4); // the default
341/// options.setInitialIndentLevel(0); // the default
342///
343/// rc = bdljsn::JsonUtil::write(&output, json, options);
344///
345/// assert(0 == rc);
346///
347/// // Using 'e_PRETTY' style:
348/// assert(R"JSON({
349/// "a": 1,
350/// "b": []
351/// })JSON" == output);
352/// @endcode
353/// Finally, if we set `initialIndentLevel` to 1, then an extra set of 4 spaces
354/// is prepended to each line, where 4 is the value of `spacesPerLevel`:
355/// @code
356/// options.setInitialIndentLevel(1);
357///
358/// rc = bdljsn::JsonUtil::write(&output, json, options);
359///
360/// assert(0 == rc);
361///
362/// // Using 'e_PRETTY' style (with 'initialIndentLevel' as 1):
363/// assert(R"JSON({
364/// "a": 1,
365/// "b": []
366/// })JSON" == output);
367/// @endcode
368/// @}
369/** @} */
370/** @} */
371
372/** @addtogroup bdl
373 * @{
374 */
375/** @addtogroup bdljsn
376 * @{
377 */
378/** @addtogroup bdljsn_jsonutil
379 * @{
380 */
381
382#include <bdlscm_version.h>
383
384#include <bdljsn_error.h>
385#include <bdljsn_json.h>
386#include <bdljsn_readoptions.h>
387#include <bdljsn_writeoptions.h>
388
390
391#include <bslmf_movableref.h>
392
393#include <bsls_libraryfeatures.h>
394
395#include <bsl_cstdint.h>
396#include <bsl_iosfwd.h>
397#include <bsl_sstream.h>
398#include <bsl_string.h>
399#include <bsl_string_view.h>
400
401
402namespace bdljsn {
403
404 // ===============
405 // struct JsonUtil
406 // ===============
407
408/// This `struct` provides a namespace for utility functions that provide
409/// `read` and `write` operations to/from `Json` objects.
410///
411/// See @ref bdljsn_jsonutil
412struct JsonUtil {
413
414 // TYPES
416
417 // CLASS METHODS
418
419 /// Load to the specified `result` a value-semantic representation of
420 /// the JSON text in the specified `input`. Optionally specify an
421 /// `errorDescription` that, if an error occurs, is loaded with a
422 /// description of the error. Optionally specify `options` which allow
423 /// altering the maximum nesting depth. Return 0 on success, and a
424 /// non-zero value if `input` does not consist of valid JSON text or an
425 /// error occurs when reading from `input`. If
426 /// `options.allowTrailingText()` is `false` (the default), then an
427 /// error will be reported if a valid JSON text is followed by any text
428 /// that does not consist solely of white-space characters. If
429 /// `options.allowTrailingText()` is `true`, then this function will
430 /// return success where a valid JSON document is followed by additional
431 /// text as long as that text is separated from the valid JSON by a
432 /// delimiter character (i.e., either the JSON text ends in a delimiter,
433 /// or the text that follows starts with a delimiter). Here, delimiters
434 /// are white-space characters, `[`,`]`,`{`,`}`,`,`, or `"`.
435 static int read(Json *result,
436 bsl::istream& input);
437 static int read(Json *result,
438 bsl::istream& input,
439 const ReadOptions& options);
440 static int read(Json *result,
441 bsl::streambuf *input);
442 static int read(Json *result,
443 bsl::streambuf *input,
444 const ReadOptions& options);
445 static int read(Json *result,
446 const bsl::string_view& input);
447 static int read(Json *result,
448 const bsl::string_view& input,
449 const ReadOptions& options);
450 static int read(Json *result,
451 Error *errorDescription,
452 bsl::istream& input);
453 static int read(Json *result,
454 Error *errorDescription,
455 bsl::istream& input,
456 const ReadOptions& options);
457 static int read(Json *result,
458 Error *errorDescription,
459 bsl::streambuf *input);
460 static int read(Json *result,
461 Error *errorDescription,
462 bsl::streambuf *input,
463 const ReadOptions& options);
464 static int read(Json *result,
465 Error *errorDescription,
466 const bsl::string_view& input);
467 static int read(Json *result,
468 Error *errorDescription,
469 const bsl::string_view& input,
470 const ReadOptions& options);
471
472 /// Print, to the specified `stream`, a description of the specified
473 /// `error`, containing the line and column in the specified `input`
474 /// where the `error` occurred. Return a reference to the modifiable
475 /// `stream`. If `error.location()` does not refer to a valid location
476 /// in `input` an unspecified error description will be written to `stream`.
477 ///
478 /// \note Note that the caller should ensure `input` refers to the
479 /// same input position as when `input` was supplied to `read` (or
480 /// whatever operation created `error`).
481 static bsl::ostream& printError(bsl::ostream& stream,
482 bsl::istream& input,
483 const Error& error);
484 static bsl::ostream& printError(bsl::ostream& stream,
485 bsl::streambuf *input,
486 const Error& error);
487 static bsl::ostream& printError(bsl::ostream& stream,
488 const bsl::string_view& input,
489 const Error& error);
490
491 static int write(bsl::ostream& output,
492 const Json& json);
493 static int write(bsl::ostream& output,
494 const Json& json,
495 const WriteOptions& options);
496 static int write(bsl::streambuf *output,
497 const Json& json);
498 static int write(bsl::streambuf *output,
499 const Json& json,
500 const WriteOptions& options);
501 static int write(bsl::string *output,
502 const Json& json);
503 static int write(bsl::string *output,
504 const Json& json,
505 const WriteOptions& options);
506#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
507 static int write(std::pmr::string *output,
508 const Json& json);
509 static int write(std::pmr::string *output,
510 const Json& json,
511 const WriteOptions& options);
512#endif
513 /// Write to the specified `output` a JSON text representation of the
514 /// specified `json` document, using the optionally specified `options`
515 /// for formatting the resulting text. Return 0 on success, and a non-zero value otherwise.
516 ///
517 /// \note Note that this operation will report an
518 /// error only if there is an error writing to `output`.
519 static int write(std::string *output,
520 const Json& json);
521 static int write(std::string *output,
522 const Json& json,
523 const WriteOptions& options);
524};
525
526// ============================================================================
527// INLINE DEFINITIONS
528// ============================================================================
529
530 // --------------
531 // class JsonUtil
532 // --------------
533// CLASS METHODS
534inline
536 bsl::istream& input,
537 const ReadOptions& options)
538{
539 Error tmp;
540 return read(result, &tmp, input, options);
541}
542
543inline
545 bsl::istream& input)
546{
547 ReadOptions options;
548 return read(result, input, options);
549}
550
551inline
553 bsl::streambuf *input,
554 const ReadOptions& options)
555{
556 Error tmp;
557 return read(result, &tmp, input, options);
558}
559
560inline
562 bsl::streambuf *input)
563{
564 ReadOptions options;
565 return read(result, input, options);
566}
567
568inline
570 const bsl::string_view& input,
571 const ReadOptions& options)
572{
573 Error tmp;
574 return read(result, &tmp, input, options);
575}
576
577inline
579 const bsl::string_view& input)
580{
581 ReadOptions options;
582 return read(result, input, options);
583}
584
585inline
587 Error *errorDescription,
588 bsl::istream& input,
589 const ReadOptions& options)
590{
591
592 return read(result, errorDescription, input.rdbuf(), options);
593}
594
595inline
597 Error *errorDescription,
598 bsl::istream& input)
599{
600 ReadOptions options;
601
602 return read(result, errorDescription, input, options);
603}
604
605inline
607 Error *errorDescription,
608 bsl::streambuf *input)
609{
610 ReadOptions options;
611
612 return read(result, errorDescription, input, options);
613}
614
615inline
617 Error *errorDescription,
618 const bsl::string_view& input,
619 const ReadOptions& options)
620{
621 bdlsb::FixedMemInStreamBuf inputBuf(input.data(), input.size());
622 return read(result, errorDescription, &inputBuf, options);
623}
624
625inline
627 Error *errorDescription,
628 const bsl::string_view& input)
629{
630 ReadOptions options;
631 return read(result, errorDescription, input, options);
632}
633
634inline
635bsl::ostream& JsonUtil::printError(bsl::ostream& stream,
636 bsl::istream& input,
637 const Error& error)
638{
639 return printError(stream, input.rdbuf(), error);
640}
641
642inline
643bsl::ostream& JsonUtil::printError(bsl::ostream& stream,
644 const bsl::string_view& input,
645 const Error& error)
646{
647 bdlsb::FixedMemInStreamBuf inputBuf(input.data(), input.size());
648 return printError(stream, &inputBuf, error);
649}
650
651inline
652int JsonUtil::write(bsl::streambuf *output,
653 const Json& json,
654 const WriteOptions& options)
655{
656 bsl::ostream outputStream(output);
657 return write(outputStream, json, options);
658}
659
660inline
661int JsonUtil::write(bsl::streambuf *output,
662 const Json& json)
663{
664 WriteOptions options;
665 return write(output, json, options);
666}
667
668inline
670 const Json& json,
671 const WriteOptions& options)
672{
673 bsl::ostringstream stream(output->get_allocator());
674
675 int rc = write(stream, json, options);
676 if (0 == rc) {
677#ifdef BSLS_PLATFORM_CMP_SUN
678 const bsl::string &tmpOutput = stream.str();
679#else
680 bsl::string tmpOutput = stream.str(output->get_allocator());
681#endif
682 *output = bslmf::MovableRefUtil::move(tmpOutput);
683 }
684 return rc;
685}
686
687inline
689 const Json& json)
690{
691 WriteOptions options;
692
693 return write(output, json, options);
694}
695
696#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
697inline
698int JsonUtil::write(std::pmr::string *output,
699 const Json& json,
700 const WriteOptions& options)
701{
702#if defined (BSLS_LIBRARYFEATURES_HAS_CPP20_BASELINE_LIBRARY)
703 typedef std::basic_ostringstream<char,
704 std::char_traits<char>,
705 std::pmr::polymorphic_allocator<char> >
706 PmrOstringStream;
707
708 PmrOstringStream stream(std::ios_base::out, output->get_allocator());
709 int rc = write(stream, json, options);
710 if (0 == rc) {
711 std::pmr::string tmpOutput = stream.str(output->get_allocator());
712 *output = bslmf::MovableRefUtil::move(tmpOutput);
713 }
714 return rc;
715#else
716 std::ostringstream stream;
717 int rc = write(stream, json, options);
718 if (0 == rc) {
719 const bsl::string &tmpOutput = stream.str();
720 *output = bslmf::MovableRefUtil::move(tmpOutput);
721 }
722 return rc;
723#endif
724}
725#endif // defined(BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING)
726
727#ifdef BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING
728inline
729int JsonUtil::write(std::pmr::string *output,
730 const Json& json)
731{
732 WriteOptions options;
733
734 return write(output, json, options);
735}
736#endif // defined(BSLS_LIBRARYFEATURES_HAS_CPP17_PMR_STRING)
737
738inline
739int JsonUtil::write(std::string *output,
740 const Json& json,
741 const WriteOptions& options)
742{
743 std::ostringstream stream;
744
745 int rc = write(stream, json, options);
746 if (0 == rc) {
747 std::string tmpOutput(stream.str());
748 *output = bslmf::MovableRefUtil::move(tmpOutput);
749 }
750 return rc;
751}
752
753inline
754int JsonUtil::write(std::string *output,
755 const Json& json)
756{
757 WriteOptions options;
758
759 return write(output, json, options);
760}
761
762inline
763int JsonUtil::write(bsl::ostream& output, const Json& json)
764{
765 WriteOptions options;
766 return write(output, json, options);
767}
768
769} // close package namespace
770
771
772#endif // INCLUDED_BDLJSN_JSONUTIL
773
774// ----------------------------------------------------------------------------
775// Copyright 2022 Bloomberg Finance L.P.
776//
777// Licensed under the Apache License, Version 2.0 (the "License");
778// you may not use this file except in compliance with the License.
779// You may obtain a copy of the License at
780//
781// http://www.apache.org/licenses/LICENSE-2.0
782//
783// Unless required by applicable law or agreed to in writing, software
784// distributed under the License is distributed on an "AS IS" BASIS,
785// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
786// See the License for the specific language governing permissions and
787// limitations under the License.
788// ----------------------------- END-OF-FILE ----------------------------------
789
790/** @} */
791/** @} */
792/** @} */
Definition bdljsn_error.h:155
Definition bdljsn_json.h:1461
Definition bdljsn_readoptions.h:128
Definition bdljsn_writeoptions.h:138
Definition bdlsb_fixedmeminstreambuf.h:187
Definition bslstl_stringview.h:471
BSLS_KEYWORD_CONSTEXPR const_pointer data() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_stringview.h:1988
BSLS_KEYWORD_CONSTEXPR size_type size() const BSLS_KEYWORD_NOEXCEPT
Return the length of this view.
Definition bslstl_stringview.h:1904
Definition bslstl_string.h:1252
allocator_type get_allocator() const BSLS_KEYWORD_NOEXCEPT
Return the allocator used by this string to supply memory.
Definition bslstl_string.h:7423
Definition bslstl_pair.h:1280
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdljsn_error.h:142
basic_ostringstream< char, char_traits< char >, allocator< char > > ostringstream
Definition bslstl_iosfwd.h:97
Definition bdljsn_jsonutil.h:412
static int write(bsl::ostream &output, const Json &json, const WriteOptions &options)
static int write(bsl::ostream &output, const Json &json)
Definition bdljsn_jsonutil.h:763
static bsl::ostream & printError(bsl::ostream &stream, bsl::istream &input, const Error &error)
Definition bdljsn_jsonutil.h:635
static bsl::ostream & printError(bsl::ostream &stream, bsl::streambuf *input, const Error &error)
bsl::pair< bsl::uint64_t, bsl::uint64_t > LineAndColumnNumber
Definition bdljsn_jsonutil.h:415
static int read(Json *result, bsl::istream &input)
Definition bdljsn_jsonutil.h:544
static int read(Json *result, Error *errorDescription, bsl::streambuf *input, const ReadOptions &options)
static MovableRef< t_TYPE > move(t_TYPE &reference) BSLS_KEYWORD_NOEXCEPT
Definition bslmf_movableref.h:1067