BDE 4.14.0 Production release
Loading...
Searching...
No Matches
baljsn_simpleformatter.h
Go to the documentation of this file.
1/// @file baljsn_simpleformatter.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// baljsn_simpleformatter.h -*-C++-*-
8#ifndef INCLUDED_BALJSN_SIMPLEFORMATTER
9#define INCLUDED_BALJSN_SIMPLEFORMATTER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup baljsn_simpleformatter baljsn_simpleformatter
15/// @brief Provide a simple formatter for encoding data in the JSON format.
16/// @addtogroup bal
17/// @{
18/// @addtogroup baljsn
19/// @{
20/// @addtogroup baljsn_simpleformatter
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#baljsn_simpleformatter-purpose"> Purpose</a>
25/// * <a href="#baljsn_simpleformatter-classes"> Classes </a>
26/// * <a href="#baljsn_simpleformatter-description"> Description </a>
27/// * <a href="#baljsn_simpleformatter-comparison-to-baljsn-formatter"> Comparison to baljsn::Formatter </a>
28/// * <a href="#baljsn_simpleformatter-api-comparison"> API Comparison </a>
29/// * <a href="#baljsn_simpleformatter-json-format"> JSON Format </a>
30/// * <a href="#baljsn_simpleformatter-usage"> Usage </a>
31/// * <a href="#baljsn_simpleformatter-example-1-encoding-a-stock-portfolio-in-json"> Example 1: Encoding a Stock Portfolio in JSON </a>
32/// * <a href="#baljsn_simpleformatter-example-2-encoding-an-array"> Example 2: Encoding an array </a>
33///
34/// # Purpose {#baljsn_simpleformatter-purpose}
35/// Provide a simple formatter for encoding data in the JSON format.
36///
37/// # Classes {#baljsn_simpleformatter-classes}
38///
39/// - baljsn::SimpleFormatter: a mechanism to encode data into JSON
40///
41/// @see baljsn_encoder, baljsn_formatter, baljsn_printutil
42///
43/// # Description {#baljsn_simpleformatter-description}
44/// This component provides a class, `baljsn::SimpleFormatter`, for
45/// rendering JSON conforming text for objects, arrays, and various scalar
46/// types.
47///
48/// This component provides an interface that is easier to use, and renders more
49/// readable "pretty" JSON, than `baljsn::Formatter`. Clients are encouraged to
50/// use `baljsn::SimpleFormatter` instead of `baljsn::Formatter` (see
51/// {Comparison to `baljsn::Formatter`}).
52///
53/// The `SimpleFormatter` `class` also provides the ability to specify
54/// formatting options at construction. The options that can be provided
55/// include the encoding style (compact or pretty), the initial indentation
56/// level and spaces per level if encoding in the pretty format.
57///
58/// ## Comparison to baljsn::Formatter {#baljsn_simpleformatter-comparison-to-baljsn-formatter}
59///
60///
61///
62/// ### API Comparison {#baljsn_simpleformatter-api-comparison}
63///
64///
65/// Here is the side-by-side sequence of calls to create the following JSON
66/// using both components, assuming an existing stream `os`:
67/// @code
68/// {
69/// "Object" : {
70/// "Field 1" : 1,
71/// "Field 2" : null
72/// },
73/// "Array" : [
74/// 1,
75/// "string",
76/// [],
77/// [
78/// [
79/// {
80/// }
81/// ]
82/// ]
83/// ],
84/// "True" : true
85/// }
86/// @endcode
87/// Some extra indentation has been added in these examples to show the various
88/// `open`/`close` call nesting levels.
89/// @code
90/// Formatter | SimpleFormatter
91/// -----------------------------------+----------------------------------------
92/// baljsn::Formatter f(os); | baljsn::SimpleFormatter sf(os);
93/// |
94/// f.openObject(); | sf.openObject();
95/// |
96/// f.openMember("Object"); | sf.openObject("Object");
97/// f.openObject(); | sf.addValue("Field 1", 1);
98/// f.openMember("Field 1"); | sf.addNullValue("Field 2");
99/// f.putValue(1); | sf.closeObject();
100/// f.closeMember(); |
101/// f.openMember("Field 2"); | sf.openArray("Array");
102/// f.putNullValue(); | sf.addValue(1); // No name
103/// // Must remember NOT to call | sf.addValue("string"); // No name
104/// // closeMember here! | sf.openArray(e_EMPTY_ARRAY_FORMAT);
105/// f.closeObject(); | sf.closeArray(e_EMPTY_ARRAY_FORMAT);
106/// f.closeMember(); | sf.openArray();
107/// | sf.openArray();
108/// f.openMember("Array"); | sf.openObject();
109/// f.openArray(); | sf.closeObject();
110/// f.putValue(1); | sf.closeArray();
111/// f.addArrayElementSeparator(); | sf.closeArray();
112/// f.putValue("string"); | sf.closeArray();
113/// f.addArrayElementSeparator(); |
114/// f.openArray(true); | sf.addValue("True", true);
115/// f.closeArray(true); | sf.closeObject();
116/// f.addArrayElementSeparator(); |
117/// f.openArray(); |
118/// f.openArray(); |
119/// f.openObject(); |
120/// f.closeObject(); |
121/// f.closeArray(); |
122/// f.closeArray(); |
123/// |
124/// // Must remember NOT to call |
125/// // addArrayElementSeparator |
126/// // here! |
127/// f.closeArray(); |
128/// f.closeMember(); |
129/// |
130/// f.openMember("True"); |
131/// f.putValue(true); |
132/// // Must remember NOT to call |
133/// // closeMember here! |
134/// |
135/// f.closeObject(); |
136/// -----------------------------------+----------------------------------------
137///
138/// @endcode
139///
140/// ## JSON Format {#baljsn_simpleformatter-json-format}
141///
142///
143/// The JSON encoding format (see http://json.org or ECMA-404 standard for more
144/// information) specifies a self-describing and simple syntax that is built on
145/// two structures:
146///
147/// * Objects: JSON objects are represented as collections of name value
148/// pairs. The `SimpleFormatter` `class` allows encoding objects by
149/// providing the `openObject` and `closeObject` methods to open and close an
150/// object and overloads for `openObject`, `openArray`, `addValue` and
151/// `addNullValue` which take a `name` to specify the named fields in the
152/// object, or the use of the `addMemberName` manipulator followed by the
153/// overloads of `openObject`, `openArray`, `addValue`, and `addNullValue`
154/// which do not take a name.
155/// * Arrays: JSON arrays are specified as an ordered list of values. The
156/// `SimpleFormatter` `class` provides the `openArray` and `closeArray`
157/// method to open and close an array, as well as overloads for `openObject`,
158/// `openArray`, `addValue` and `addNullValue` which do not take a `name` for
159/// array elements.
160///
161/// The `SimpleFormatter` `class` provides the ability to specify formatting
162/// options at construction. The options that can be provided include the
163/// encoding style (compact or pretty), the initial indentation level and spaces
164/// per level if encoding in the pretty format.
165///
166/// ## Usage {#baljsn_simpleformatter-usage}
167///
168///
169/// This section illustrates intended use of this component.
170///
171/// ### Example 1: Encoding a Stock Portfolio in JSON {#baljsn_simpleformatter-example-1-encoding-a-stock-portfolio-in-json}
172///
173///
174/// Let us suppose we have to encode a JSON document containing information
175/// about a small portfolio of stocks. The eventual data we want to encode is
176/// represented by the following JSON string (which is the expected output of
177/// the encoding process):
178///
179/// First, we specify the result that we are expecting to get:
180/// @code
181/// {
182/// const bsl::string EXPECTED =
183/// "{\n"
184/// " \"Stocks\" : [\n"
185/// " {\n"
186/// " \"Name\" : \"International Business Machines Corp\",\n"
187/// " \"Ticker\" : \"IBM US Equity\",\n"
188/// " \"Last Price\" : 149.3,\n"
189/// " \"Dividend Yield\" : 3.95\n"
190/// " },\n"
191/// " {\n"
192/// " \"Name\" : \"Apple Inc\",\n"
193/// " \"Ticker\" : \"AAPL US Equity\",\n"
194/// " \"Last Price\" : 205.8,\n"
195/// " \"Dividend Yield\" : 1.4\n"
196/// " }\n"
197/// " ]\n"
198/// "}";
199/// @endcode
200/// Then, to encode this JSON document we create a `baljsn::SimpleFormatter`
201/// object. Since we want the document to be written in a pretty, easy to
202/// understand format we will specify `true` for the `usePrettyStyle` option and
203/// provide an appropriate initial indent level and spaces per level values:
204/// @code
205/// bsl::ostringstream os;
206/// baljsn::EncoderOptions encoderOptions;
207///
208/// encoderOptions.setEncodingStyle(baljsn::EncoderOptions::e_PRETTY);
209/// encoderOptions.setSpacesPerLevel(2);
210///
211/// baljsn::SimpleFormatter formatter(os, encoderOptions);
212/// @endcode
213/// Next, we encode the start of the top level object, and open the first member
214/// "Stocks" (which holds an array of stock information):
215/// @code
216/// formatter.openObject();
217/// formatter.openArray("Stocks");
218/// @endcode
219/// Next, we render each element within the array of "Stocks" as an object that
220/// contains information for an individual stock:
221/// @code
222/// formatter.openObject();
223/// @endcode
224/// We now encode the other elements in the stock object.
225/// @code
226/// formatter.addValue("Name", "International Business Machines Corp");
227/// formatter.addValue("Ticker", "IBM US Equity");
228/// formatter.addValue("Last Price", 149.3);
229/// formatter.addValue("Dividend Yield", 3.95);
230/// @endcode
231/// Then, close the first stock object.
232/// @code
233/// formatter.closeObject();
234/// @endcode
235/// Next, we add another stock object.
236/// @code
237/// formatter.openObject();
238///
239/// formatter.addValue("Name", "Apple Inc");
240/// formatter.addValue("Ticker", "AAPL US Equity");
241/// formatter.addValue("Last Price", 205.8);
242/// formatter.addValue("Dividend Yield", 1.4);
243///
244/// formatter.closeObject();
245/// @endcode
246/// Similarly, we can continue to format the rest of the document. For the
247/// purpose of this usage example we will complete this document.
248/// @code
249/// formatter.closeArray();
250/// formatter.closeObject();
251/// @endcode
252/// Once the formatting is complete the written data can be viewed from the
253/// stream passed to the formatter at construction.
254/// @code
255/// if (verbose)
256/// bsl::cout << os.str() << bsl::endl;
257/// @endcode
258/// Finally, verify the received result:
259/// @code
260/// assert(EXPECTED == os.str());
261/// }
262/// @endcode
263///
264/// ### Example 2: Encoding an array {#baljsn_simpleformatter-example-2-encoding-an-array}
265///
266///
267/// Let us say we want to encode an array of various values.
268///
269/// First, we create our `formatter` as we did above:
270/// @code
271/// {
272/// bsl::ostringstream os;
273/// baljsn::EncoderOptions encoderOptions;
274///
275/// encoderOptions.setEncodingStyle(baljsn::EncoderOptions::e_PRETTY);
276/// encoderOptions.setSpacesPerLevel(2);
277///
278/// baljsn::SimpleFormatter formatter(os, encoderOptions);
279/// @endcode
280/// Then we open our array.
281/// @code
282/// formatter.openArray();
283/// @endcode
284/// Next, we populate the array with a series of unnamed values. Named values
285/// are only used in objects, not arrays.
286/// @code
287/// formatter.addValue("First value");
288/// formatter.addValue(2);
289/// formatter.addValue(3);
290/// @endcode
291/// Then, we demonstrate that arrays can be nested, opening another level of
292/// array, populating it, and closing it:
293/// @code
294/// formatter.openArray();
295/// formatter.addValue("First value of inner array");
296/// formatter.addValue(3.14159);
297/// formatter.closeArray();
298/// @endcode
299/// Arrays can also contain (unnamed) objects:
300/// @code
301/// formatter.openObject();
302/// @endcode
303/// Next, we add (named) values to our object:
304/// @code
305/// formatter.addValue("Greeting", "Hello from the first inner object");
306/// formatter.addValue("PI approximation", 3.14);
307/// // We could, similarly, add nested named objects and/or named arrays
308/// @endcode
309/// Then we close the nested object:
310/// @code
311/// formatter.closeObject();
312/// @endcode
313/// Finally, we close the outer array:
314/// @code
315/// formatter.closeArray();
316/// }
317/// @endcode
318/// @}
319/** @} */
320/** @} */
321
322/** @addtogroup bal
323 * @{
324 */
325/** @addtogroup baljsn
326 * @{
327 */
328/** @addtogroup baljsn_simpleformatter
329 * @{
330 */
331
332#include <balscm_version.h>
333
335#include <baljsn_printutil.h>
336
337#include <bdlb_print.h>
338
339#include <bdlc_bitarray.h>
340
341#include <bsl_ostream.h>
342
343#include <bslma_allocator.h>
345
347
348#include <bsls_assert.h>
349#include <bsls_review.h>
350
351#include <bsl_string_view.h>
352
353
354namespace baljsn {
355
356class EncoderOptions;
357
358 // =====================
359 // class SimpleFormatter
360 // =====================
361
362/// This class implements a formatter providing operations for rendering
363/// JSON text elements to an output stream (supplied at construction)
364/// according to a set of formatting options (also supplied at
365/// construction).
366///
367/// This class has an interface that's easier to use than that of
368/// `baljsn::Formatter`, and generates more correctly-formatted `pretty`
369/// output.
370///
371/// See @ref baljsn_simpleformatter
373
374 public:
375 // TYPES
377 // This 'enum' lists all possible array formatting styles.
380 };
381
382 private:
383 // DATA
384 bsl::ostream& d_outputStream; // stream for output (held, not
385 // owned)
386
387 bool d_useComma; // whether next start item
388 // ('add*', 'open*') needs a
389 // preceding comma
390
391 bool d_started; // whether we've formatted at
392 // least one element
393
394 bool d_memberNameSupplied; // whether the previous output
395 // operation was 'addMemberName'
396
397 bdlc::BitArray d_callSequence; // array specifying the sequence
398 // in which the 'openObject' and
399 // 'openArray' methods were
400 // called. An 'openObject' call
401 // is represented by 'false' and
402 // an 'openArray' call by 'true'.
403
404 EncoderOptions d_encoderOptions; // formatting and encoding
405 // options
406
407 int d_indentLevel; // current indent level
408
409 // PRIVATE MANIPULATORS
410
411 /// Unconditionally print onto the stream supplied at construction the
412 /// sequence of whitespace characters for the proper indentation of an
413 /// element at the current indentation level. Note that this method
414 /// does not check that `usePrettyStyle()` is `true` before indenting.
415 void indent();
416
417 /// If `d_useComma` is `true`, print a comma. If `usePrettyStyle()` is
418 /// also `true`, also print a newline. This also sets
419 /// `d_memberNameSupplied` to `false`.
420 void printComma();
421
422 /// Set `d_useComma` to the value of the specified `flag`, indicating
423 /// whether the next `printComma()` call should actually print a comma.
424 void followWithComma(bool flag);
425
426 /// Print onto the stream supplied at construction the specified `name`,
427 /// followed by a `:`. The `:` is surrounded by a space on each side if
428 /// `usePrettyStyle()` is `true`. It is the caller's responsibility to
429 /// call `printComma()` - this routine does not handle commas, but does
430 /// call `indent()` if necessary.
431 void printName(const bsl::string_view& name);
432
433 // PRIVATE ACCESSORS
434
435 /// Return `true` if `e_PRETTY == d_encoderOptions.encodingStyle()`.
436 bool usePrettyStyle() const;
437
438 /// Return `d_encoderOptions.spacesPerLevel()`.
439 int spacesPerLevel() const;
440
441 public:
442 // TRAITS
445
446 // CREATORS
447
448 explicit SimpleFormatter(bsl::ostream& stream,
449 bslma::Allocator *basicAllocator = 0);
450 /// Create a `SimpleFormatter` object using the specified `stream`.
451 /// Optionally specify `encoderOptions` to configure the output options
452 /// - if `encoderOptions` is not supplied, a default-constructed
453 /// `EncoderOptions` object will be used. Note that the
454 /// `encodeEmptyArrays` attribute in the `encoderOptions` is ignored.
455 /// Optionally specify a `basicAllocator` used to supply memory. If
456 /// `basicAllocator` is 0, the currently installed default allocator is
457 /// used.
458 explicit SimpleFormatter(bsl::ostream& stream,
459 const EncoderOptions& encoderOptions,
460 bslma::Allocator *basicAllocator = 0);
461
462 /// Create a `SimpleFormatter` object having the same value as the
463 /// specified `original` object. Optionally specify a `basicAllocator`
464 /// used to supply memory. If `basicAllocator` is 0, the currently
465 /// installed default allocator is used.
467 bslma::Allocator *basicAllocator);
468
469 /// Destroy this object. Note that correct JSON has been generated if
470 /// the `isCompleteJSON()` call returns `true`.
472
473 // MANIPULATORS
474
475 /// Print onto the stream supplied at construction the sequence of
476 /// characters designating the start of an object (referred to as an
477 /// "object" in JSON), preceded, if necessary, by a comma. The behavior
478 /// is undefined unless `isNameNeeded()` is `false`.
480
481 /// Print onto the stream supplied at construction the sequence of
482 /// characters designating the start of an object (referred to as an
483 /// "object" in JSON) with the specified `name` , preceded, if
484 /// necessary, by a comma. The behavior is undefined unless
485 /// `isNameNeeded()` is `true`.
486 void openObject(const bsl::string_view& name);
487
488 /// Print onto the stream supplied at construction the specified `name`
489 /// in double-quotes, preceded, if necessary, by a comma, and followed
490 /// by a `:`. The behavior is undefined unless `isNameNeeded()` is
491 /// `true`. After this operation, `isNameNeeded()` will be `false`, and
492 /// an immediately subsequent attempt to add a value (or open an object
493 /// or array) should not provide a name.
494 void addMemberName(const bsl::string_view& name);
495
496 /// Print onto the stream supplied at construction the sequence of
497 /// characters designating the end of an object (referred to as an
498 /// "object" in JSON). The behavior is undefined unless
499 /// `isNameNeeded()` is `true`.
501
502 /// Print onto the stream supplied at construction the sequence of
503 /// characters designating the start of an array (referred to as an
504 /// "array" in JSON), preceded, if necessary, by a comma. Optionally
505 /// specify `formattingStyle` denoting if the array being opened should
506 /// be formatted as an empty array. If `formattingStyle` is not
507 /// specified then the array being opened is formatted as a regular
508 /// array having elements. The behavior is undefined unless
509 /// `isNameNeeded()` is `false`. Note that the formatting (and as a
510 /// consequence the `formattingStyle`) is relevant only if this
511 /// formatter encodes in the pretty style and is ignored otherwise.
514
515 /// Print onto the stream supplied at construction the sequence of
516 /// characters designating the start of an array (referred to as an
517 /// "array" in JSON) with the specified `name`, preceded, if necessary,
518 /// by a comma. Optionally specify `formattingStyle` denoting if the
519 /// array being opened should be formatted as an empty array. If
520 /// `formattingStyle` is not specified then the array being opened is
521 /// formatted as a regular array having elements. The behavior is
522 /// undefined unless `isNameNeeded()` is `true`. Note that the
523 /// formatting (and as a consequence the `formattingStyle`) is relevant
524 /// only if this formatter encodes in the pretty style and is ignored
525 /// otherwise.
527 const bsl::string_view& name,
529
530 /// Print onto the stream supplied at construction the sequence of
531 /// characters designating the end of an array (referred to as an
532 /// "array" in JSON). Optionally specify `formattingStyle` denoting if
533 /// the array being closed should be formatted as an empty array. If
534 /// `formattingStyle` is not specified then the array being closed is
535 /// formatted as a regular array having elements. The behavior is
536 /// undefined if `isFormattingArray()` is `false`. Note that the
537 /// formatting (and as a consequence the `formattingStyle`) is relevant
538 /// only if this formatter encodes in the pretty style and is ignored
539 /// otherwise.
542
543 /// Print onto the stream supplied at construction the value
544 /// corresponding to a null element, preceded, if necessary, by a comma.
545 /// The behavior is undefined unless `isNameNeeded()` is `false`.
546 void addNullValue();
547
548 /// Print onto the stream supplied at construction the value
549 /// corresponding to a null element with the specified `name`, preceded,
550 /// if necessary, by a comma. The behavior is undefined unless
551 /// `isNameNeeded()` is `true`.
552 void addNullValue(const bsl::string_view& name);
553
554 /// Print onto the stream supplied at construction the specified
555 /// `value`, preceded, if necessary, by a comma, passing the optionally
556 /// specified `options` through to the rendering routines. Return 0 on
557 /// success and a non-zero value otherwise. The behavior is undefined
558 /// unless `isNameNeeded()` is `false`.
559 template <class TYPE>
560 int addValue(const TYPE& value);
561
562 /// Print onto the stream supplied at construction the specified `name`
563 /// and the specified `value`, preceded, if necessary, by a comma,
564 /// passing the optionally specified `options` through to the rendering
565 /// routines. Return 0 on success and a non-zero value otherwise. The
566 /// behavior is undefined unless `isNameNeeded()` is `true`.
567 template <class TYPE>
568 int addValue(const bsl::string_view& name, const TYPE& value);
569
570 // ACCESSORS
571
572 /// Return `true` if this `SimpleFormatter` has formatted a complete
573 /// JSON object, where all `open*` calls have been balanced by their
574 /// corresponding `close*` calls. Note that a default-constructed
575 /// `SimpleFormatter` will return `false` - an empty string is not valid
576 /// JSON.
577 bool isCompleteJSON() const;
578
579 /// Return `true` if this `SimpleFormatter` is currently formatting an
580 /// array and `false` otherwise. It is formatting an array if the last
581 /// `open*` method overload (`openArray` or `openObject`) called on this
582 /// `SimpleFormatter` for which the corresponding `close*` method
583 /// (respectively, `closeArray` or `closeObject`) was `openArray`. If
584 /// `isFormattingArray()` is `true`, then `isFormattingObject()` is
585 /// `false`. Note that both can be `false`, at the `top-level` initial
586 /// scope before anything is added/opened or after the first `open*`
587 /// call has been closed'
588 bool isFormattingArray() const;
589
590 /// Return `true` if this `SimpleFormatter` is currently formatting an
591 /// object scope and `false` otherwise. It is formatting an object
592 /// scope if the last `open*` method overload (`openArray` or
593 /// `openObject`) called on this `SimpleFormatter` for which the
594 /// corresponding `close*` method (respectively, `closeArray` or
595 /// `closeObject`) was `openObject`. If `isFormattingObject()` is
596 /// `true`, then `isFormattingArray()` is `false`. Note that both can
597 /// be `false`, at the `top-level` initial scope before anything is
598 /// added/opened or after the first `open*` call has been closed'
599 /// JSON.
600 bool isFormattingObject() const;
601
602 /// Return `true` if a subsequent attempt to add a value must supply a
603 /// `name`, and `false` otherwise. This will be `true` if
604 /// `isFormattingObject()` is `true`, and `addMemberName()` was not the
605 /// most recently called manipulator. That is, a name is needed if this
606 /// formatter is currently in the context of formatting the members of a
607 /// JSON object, and `addMemberName` has not been called to explicitly
608 /// provide a name for the next member.
609 bool isNameNeeded() const;
610
611 // Aspects
612
613 /// Return the allocator used by this object to supply memory. Note
614 /// that if no allocator was supplied at construction the currently
615 /// installed default allocator is used.
617};
618
619// ============================================================================
620// INLINE DEFINITIONS
621// ============================================================================
622
623 // ---------------
624 // class SimpleFormatter
625 // ---------------
626
627// PRIVATE MANIPULATORS
628inline
629void SimpleFormatter::followWithComma(bool flag)
630{
631 d_useComma = flag;
632}
633
634inline
635void SimpleFormatter::indent()
636{
637 bdlb::Print::indent(d_outputStream, d_indentLevel, spacesPerLevel());
638}
639
640inline
641void SimpleFormatter::printComma()
642{
643 d_started = true;
644
645 if (d_useComma) {
646 d_outputStream << ',';
647
648 if (usePrettyStyle()) {
649 d_outputStream << '\n';
650 }
651 }
652
653 d_memberNameSupplied = false;
654}
655
656inline
657void SimpleFormatter::printName(const bsl::string_view& name)
658{
659 if (usePrettyStyle()) {
660 indent();
661 }
662
663 const int rc = PrintUtil::printValue(d_outputStream, name);
664 if (rc) {
665 return; // RETURN
666 }
667
668 d_outputStream << (usePrettyStyle() ? " : " : ":");
669}
670
671// PRIVATE ACCESSORS
672inline
673int SimpleFormatter::spacesPerLevel() const
674{
675 return d_encoderOptions.spacesPerLevel();
676}
677
678inline
679bool SimpleFormatter::usePrettyStyle() const
680{
681 return EncoderOptions::e_PRETTY == d_encoderOptions.encodingStyle();
682}
683
684// MANIPULATORS
685inline
687{
689
690 printComma();
691 followWithComma(false);
692
693 printName(name);
694
695 d_memberNameSupplied = true;
696}
697
698inline
700{
702
703 bool needIndent = usePrettyStyle() && !d_memberNameSupplied;
704
705 printComma();
706 followWithComma(true);
707
708 if (needIndent) {
709 indent();
710 }
711
712 d_outputStream << "null";
713}
714
715inline
717{
719
720 printComma();
721 followWithComma(true);
722
723 printName(name);
724
725 d_outputStream << "null";
726}
727
728template <class TYPE>
729int SimpleFormatter::addValue(const TYPE& value)
730{
732
733 bool needIndent = usePrettyStyle() && !d_memberNameSupplied;
734
735 printComma();
736 followWithComma(true);
737
738 if (needIndent) {
739 indent();
740 }
741
743 d_outputStream, value, &d_encoderOptions);
744}
745
746template <class TYPE>
747int SimpleFormatter::addValue(const bsl::string_view& name, const TYPE& value)
748{
750
751 printComma();
752 followWithComma(true);
753
754 printName(name);
755
757 d_outputStream, value, &d_encoderOptions);
758}
759
760// ACCESSORS
761inline
763{
764 return d_started && (1 == d_callSequence.length());
765}
766
767inline
769{
770 BSLS_ASSERT(d_callSequence.length() >= 1);
771
772 return d_callSequence.length() > 1 &&
773 d_callSequence[d_callSequence.length() - 1];
774}
775
776inline
778{
779 BSLS_ASSERT(d_callSequence.length() >= 1);
780
781 return d_callSequence.length() > 1 &&
782 !d_callSequence[d_callSequence.length() - 1];
783}
784
785inline
787{
788 return isFormattingObject() && !d_memberNameSupplied;
789}
790
791 // Aspects
792
793inline
795{
796 return d_callSequence.allocator();
797}
798
799} // close package namespace
800
801
802
803#endif
804
805// ----------------------------------------------------------------------------
806// Copyright 2019 Bloomberg Finance L.P.
807//
808// Licensed under the Apache License, Version 2.0 (the "License");
809// you may not use this file except in compliance with the License.
810// You may obtain a copy of the License at
811//
812// http://www.apache.org/licenses/LICENSE-2.0
813//
814// Unless required by applicable law or agreed to in writing, software
815// distributed under the License is distributed on an "AS IS" BASIS,
816// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
817// See the License for the specific language governing permissions and
818// limitations under the License.
819// ----------------------------- END-OF-FILE ----------------------------------
820
821/** @} */
822/** @} */
823/** @} */
Definition baljsn_encoderoptions.h:262
@ e_PRETTY
Definition baljsn_encoderoptions.h:316
baljsn::EncoderOptions::EncodingStyle encodingStyle() const
Definition baljsn_encoderoptions.h:929
int spacesPerLevel() const
Definition baljsn_encoderoptions.h:923
Definition baljsn_simpleformatter.h:372
void openArray(ArrayFormattingStyle formattingStyle=e_REGULAR_ARRAY_FORMAT)
void closeArray(ArrayFormattingStyle formattingStyle=e_REGULAR_ARRAY_FORMAT)
void openArray(const bsl::string_view &name, ArrayFormattingStyle formattingStyle=e_REGULAR_ARRAY_FORMAT)
void addMemberName(const bsl::string_view &name)
Definition baljsn_simpleformatter.h:686
SimpleFormatter(const SimpleFormatter &original, bslma::Allocator *basicAllocator)
SimpleFormatter(bsl::ostream &stream, bslma::Allocator *basicAllocator=0)
bool isFormattingArray() const
Definition baljsn_simpleformatter.h:768
bool isFormattingObject() const
Definition baljsn_simpleformatter.h:777
ArrayFormattingStyle
Definition baljsn_simpleformatter.h:376
@ e_EMPTY_ARRAY_FORMAT
Definition baljsn_simpleformatter.h:379
@ e_REGULAR_ARRAY_FORMAT
Definition baljsn_simpleformatter.h:378
SimpleFormatter(bsl::ostream &stream, const EncoderOptions &encoderOptions, bslma::Allocator *basicAllocator=0)
bslma::Allocator * allocator() const
Definition baljsn_simpleformatter.h:794
void addNullValue()
Definition baljsn_simpleformatter.h:699
void openObject(const bsl::string_view &name)
bool isCompleteJSON() const
Definition baljsn_simpleformatter.h:762
bool isNameNeeded() const
Definition baljsn_simpleformatter.h:786
int addValue(const TYPE &value)
Definition baljsn_simpleformatter.h:729
BSLMF_NESTED_TRAIT_DECLARATION(SimpleFormatter, bslma::UsesBslmaAllocator)
Definition bdlc_bitarray.h:521
bsl::size_t length() const
Return the number of bits in this array.
Definition bdlc_bitarray.h:1815
bslma::Allocator * allocator() const
Return the allocator used by this object to supply memory.
Definition bdlc_bitarray.h:1847
Definition bslstl_stringview.h:441
Definition bslma_allocator.h:457
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition baljsn_datumdecoderoptions.h:113
static int printValue(bsl::ostream &stream, bool value, const EncoderOptions *options=0)
Definition baljsn_printutil.h:410
static bsl::ostream & indent(bsl::ostream &stream, int level, int spacesPerLevel=4)
Definition bslma_usesbslmaallocator.h:343