BDE 4.14.0 Production release
Loading...
Searching...
No Matches
baljsn_encoder.h
Go to the documentation of this file.
1/// @file baljsn_encoder.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// baljsn_encoder.h -*-C++-*-
8#ifndef INCLUDED_BALJSN_ENCODER
9#define INCLUDED_BALJSN_ENCODER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup baljsn_encoder baljsn_encoder
15/// @brief Provide a JSON encoder for `bdlat`-compatible types.
16/// @addtogroup bal
17/// @{
18/// @addtogroup baljsn
19/// @{
20/// @addtogroup baljsn_encoder
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#baljsn_encoder-purpose"> Purpose</a>
25/// * <a href="#baljsn_encoder-classes"> Classes </a>
26/// * <a href="#baljsn_encoder-description"> Description </a>
27/// * <a href="#baljsn_encoder-usage"> Usage </a>
28/// * <a href="#baljsn_encoder-example-1-encoding-a-bas_codegen-pl-generated-object-into-json"> Example 1: Encoding a bas_codegen.pl-Generated Object into JSON </a>
29///
30/// # Purpose {#baljsn_encoder-purpose}
31/// Provide a JSON encoder for `bdlat`-compatible types.
32///
33/// # Classes {#baljsn_encoder-classes}
34///
35/// - baljsn::Encoder: JSON decoder for `bdlat`-compliant types
36///
37/// @see baljsn_decoder, baljsn_printutil
38///
39/// # Description {#baljsn_encoder-description}
40/// This component provides a class, `baljsn::Encoder`, for
41/// encoding value-semantic objects in the JSON format. In particular, the
42/// `class` contains a parameterized `encode` function that encodes an object
43/// into a specified stream. There are two overloaded versions of this
44/// function:
45///
46/// * one that writes to a `bsl::streambuf`
47/// * one that writes to an `bsl::ostream`
48///
49/// This component can be used with types that support the `bdlat` framework
50/// (see the `bdlat` package for details), which is a compile-time interface for
51/// manipulating struct-like and union-like objects. In particular, types
52/// generated by the `bas_codegen.pl` tool, and other dynamic types, can be
53/// encoded using this `class`. The `encode` function can be invoked on any
54/// object that satisfies the requirements of a sequence, choice, or array
55/// object as defined in the @ref bdlat_sequencefunctions , @ref bdlat_choicefunctions ,
56/// and @ref bdlat_arrayfunctions components.
57///
58/// Although the JSON format is easy to read and write and is very useful for
59/// debugging, it is relatively expensive to encode and decode and relatively
60/// bulky to transmit. It is more efficient to use a binary encoding (such as
61/// BER) if the encoding format is under your control (see @ref balber_berencoder ).
62///
63/// Refer to the details of the JSON encoding format supported by this encoder
64/// in the package documentation file (doc/baljsn.txt).
65///
66/// ## Usage {#baljsn_encoder-usage}
67///
68///
69/// This section illustrates intended use of this component.
70///
71/// ## Example 1: Encoding a bas_codegen.pl-Generated Object into JSON {#baljsn_encoder-example-1-encoding-a-bas_codegen-pl-generated-object-into-json}
72///
73///
74/// Consider that we want to exchange an employee's information between two
75/// processes. To allow this information exchange we will define the XML schema
76/// representation for that class, use `bas_codegen.pl` to create the `Employee`
77/// `class` for storing that information, populate an `Employee` object, and
78/// encode that object using the `baljsn` encoder.
79///
80/// First, we will define the XML schema inside a file called `employee.xsd`:
81/// @code
82/// <?xml version='1.0' encoding='UTF-8'?>
83/// <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
84/// xmlns:test='http://bloomberg.com/schemas/test'
85/// targetNamespace='http://bloomberg.com/schemas/test'
86/// elementFormDefault='unqualified'>
87///
88/// <xs:complexType name='Address'>
89/// <xs:sequence>
90/// <xs:element name='street' type='xs:string'/>
91/// <xs:element name='city' type='xs:string'/>
92/// <xs:element name='state' type='xs:string'/>
93/// </xs:sequence>
94/// </xs:complexType>
95///
96/// <xs:complexType name='Employee'>
97/// <xs:sequence>
98/// <xs:element name='name' type='xs:string'/>
99/// <xs:element name='homeAddress' type='test:Address'/>
100/// <xs:element name='age' type='xs:int'/>
101/// </xs:sequence>
102/// </xs:complexType>
103///
104/// <xs:element name='Employee' type='test:Employee'/>
105///
106/// </xs:schema>
107/// @endcode
108/// Then, we will use the `bas_codegen.pl` tool, to generate the C++ classes for
109/// this schema. The following command will generate the header and
110/// implementation files for the all the classes in the @ref test_messages
111/// components in the current directory:
112/// @code
113/// $ bas_codegen.pl -m msg -p test xsdfile.xsd
114/// @endcode
115/// Next, we will populate a `test::Employee` object:
116/// @code
117/// test::Employee employee;
118/// employee.name() = "Bob";
119/// employee.homeAddress().street() = "Lexington Ave";
120/// employee.homeAddress().city() = "New York City";
121/// employee.homeAddress().state() = "New York";
122/// employee.age() = 21;
123/// @endcode
124/// Then, we will create a `baljsn::Encoder` object:
125/// @code
126/// baljsn::Encoder encoder;
127/// @endcode
128/// Now, we will output this object in the JSON format by invoking the `encode`
129/// method of the encoder. We will also create a `baljsn::EncoderOptions`
130/// object that allows us to specify that the encoding should be done in a
131/// pretty format, and what the initial indent level and spaces per level should
132/// be. We will then pass that object to the `encode` method:
133/// @code
134/// bsl::ostringstream os;
135///
136/// baljsn::EncoderOptions options;
137/// options.setEncodingStyle(baljsn::EncoderOptions::e_PRETTY);
138/// options.setInitialIndentLevel(1);
139/// options.setSpacesPerLevel(4);
140///
141/// const int rc = encoder.encode(os, employee, options);
142/// assert(!rc);
143/// assert(os);
144/// @endcode
145/// Finally, we will verify that the output is as expected:
146/// @code
147/// const char EXP_OUTPUT[] = " {\n"
148/// " \"name\" : \"Bob\",\n"
149/// " \"homeAddress\" : {\n"
150/// " \"street\" : \"Lexington Ave\",\n"
151/// " \"city\" : \"New York City\",\n"
152/// " \"state\" : \"New York\"\n"
153/// " },\n"
154/// " \"age\" : 21\n"
155/// " }\n";
156///
157/// assert(EXP_OUTPUT == os.str());
158/// @endcode
159/// @}
160/** @} */
161/** @} */
162
163/** @addtogroup bal
164 * @{
165 */
166/** @addtogroup baljsn
167 * @{
168 */
169/** @addtogroup baljsn_encoder
170 * @{
171 */
172
173#include <balscm_version.h>
174
176#include <baljsn_formatter.h>
177#include <baljsn_printutil.h>
178
179#include <bdlat_attributeinfo.h>
182#include <bdlat_enumfunctions.h>
183#include <bdlat_formattingmode.h>
185#include <bdlat_selectioninfo.h>
187#include <bdlat_typecategory.h>
189
190#include <bdlb_print.h>
191
193
194#include <bsla_maybeunused.h>
195#include <bsls_assert.h>
196#include <bsls_types.h>
197
198#include <bsl_cstddef.h>
199#include <bsl_iostream.h>
200#include <bsl_ostream.h>
201#include <bsl_sstream.h>
202#include <bsl_streambuf.h>
203#include <bsl_string.h>
204#include <bsl_string_view.h>
205#include <bsl_vector.h>
206
207
208namespace baljsn {
209
210 // =============
211 // class Encoder
212 // =============
213
214/// This class provides a mechanism for encoding value-semantic objects in
215/// the JSON format. The `encode` methods are function templates that will
216/// encode any object that meets the requirements of a sequence, choice, or
217/// array object as defined in the @ref bdlat_sequencefunctions ,
218/// @ref bdlat_choicefunctions , and @ref bdlat_choicefunctions components
219/// respectively. These generic frameworks provide a common compile-time
220/// interface for accessing struct-like and union-like objects. In
221/// particular, the types generated by `bas_codegen.pl` provide the
222/// necessary interface and can be encoded using this component.
223///
224/// See @ref baljsn_encoder
225class Encoder {
226
227 // DATA
228 bsl::ostringstream d_logStream; // stream used for logging
229
230 // NOT IMPLEMENTED
231 Encoder(const Encoder&);
232
233 // PRIVATE MANIPULATORS
234
235 /// Return the stream for logging.
236 bsl::ostream& logStream();
237
238 public:
239 // CREATORS
240
241 /// Create a encoder object. Optionally specify a `basicAllocator` used
242 /// to supply memory. If `basicAllocator` is 0, the currently installed
243 /// default allocator is used.
244 explicit Encoder(bslma::Allocator *basicAllocator = 0);
245
246 /// Destroy this object.
247 ~Encoder() = default;
248
249 // MANIPULATORS
250
251 /// Encode the specified `value`, of (template parameter) `TYPE`, in the
252 /// JSON format using the specified `options` and output it onto the
253 /// specified `streamBuf`. Specifying a nullptr `options` is equivalent
254 /// to passing a default-constructed DecoderOptions in `options`.
255 /// `TYPE` shall be a `bdlat`-compatible sequence, choice, or array
256 /// type, or a `bdlat`-compatible dynamic type referring to one of those
257 /// types. Return 0 on success, and a non-zero value otherwise.
258 template <class TYPE>
259 int encode(bsl::streambuf *streamBuf,
260 const TYPE& value,
261 const EncoderOptions& options);
262 template <class TYPE>
263 int encode(bsl::streambuf *streamBuf,
264 const TYPE& value,
265 const EncoderOptions *options);
266
267 /// Encode the specified `value`, of (template parameter) `TYPE`, in the
268 /// JSON format using the specified `options` and output it onto the
269 /// specified `stream`. Specifying a nullptr `options` is equivalent to
270 /// passing a default-constructed DecoderOptions in `options`. `TYPE`
271 /// shall be a `bdlat`-compatible choice, or array type, or a
272 /// `bdlat`-compatible dynamic type referring to one of those types.
273 /// Return 0 on success, and a non-zero value otherwise.
274 template <class TYPE>
275 int encode(bsl::ostream& stream,
276 const TYPE& value,
277 const EncoderOptions& options);
278 template <class TYPE>
279 int encode(bsl::ostream& stream,
280 const TYPE& value,
281 const EncoderOptions *options);
282
283 /// Encode the specified `value` of (template parameter) `TYPE` into the
284 /// specified `streamBuf`. Return 0 on success, and a non-zero value
285 /// otherwise.
286 ///
287 /// @deprecated Use @ref encode function passed a reference to a
288 /// non-modifiable `EncoderOptions` object instead.
289 template <class TYPE>
290 int encode(bsl::streambuf *streamBuf, const TYPE& value);
291
292 /// Encode the specified `value` of (template parameter) `TYPE` into the
293 /// specified `stream`. Return 0 on success, and a non-zero value
294 /// otherwise. Note that `stream` will be invalidated if the encoding
295 /// failed.
296 ///
297 /// @deprecated Use @ref encode function passed a reference to a
298 /// non-modifiable `EncoderOptions` object instead.
299 template <class TYPE>
300 int encode(bsl::ostream& stream, const TYPE& value);
301
302 // ACCESSORS
303
304 /// Return a string containing any error, warning, or trace messages
305 /// that were logged during the last call to the `encode` method. The
306 /// log is reset each time `encode` is called.
308};
309
310 // =============================
311 // struct Encoder_EncodeImplUtil
312 // =============================
313
314/// This component-private utility `struct` provides a suite of functions that
315/// encode `bdlat` types in the JSON format.
317
318 // TYPES
319
320 /// `ThisUtil` is a convenience alias for this utility `struct`.
322
323 /// `FormattingMode` is an alias to the type of an `int`-valued
324 /// `bdlat_FormattingMode` bit-field. A `FormattingMode` value is not
325 /// valid unless it is equal to an enumerator of `bdlat_FormattingMode` or
326 /// a valid bitwise-or of two or more such enumerators. See
327 /// @ref bdlat_formattingmode for a description of the set of valid
328 /// formatting-mode values.
329 typedef int FormattingMode;
330
331 // CLASS METHODS
332
333 // Document Encoding
334
335 /// Print the sequence of characters that designate the start of a JSON
336 /// document to the specified `outputStream` according to the specified
337 /// encoding `options`. See @ref baljsn_encoderoptions for a description of
338 /// the effects, if any, of each option in the `options` on the start of a
339 /// JSON document.
340 static void openDocument(bsl::ostream *outputStream,
341 const EncoderOptions& options);
342
343 /// Print the sequence of characters that designate the end of a JSON
344 /// document to the specified `outputStream` according to the specified
345 /// encoding `options`. See the @ref baljsn_encoderoptions for a description
346 /// of the effects, if any, of each option in the `options` on the end of a
347 /// JSON document.
348 static void closeDocument(bsl::ostream *outputStream,
349 const EncoderOptions& options);
350
351 // Value Encoding
352
353 /// Encode the JSON representation of the specified `value` to the
354 /// specified `jsonStream`. Optionally specify `options` to configure
355 /// aspects of the JSON representation of the `value`. If `options` is
356 /// not specified, the default `EncoderOptions` value is used. Return 0
357 /// on success, and a non-zero value otherwise. The behavior is
358 /// undefined unless the specified `TYPE` satisfies both the static and
359 /// dynamic requirements of one `bdlat` type-category concept. See
360 /// @ref baljsn_encoderoptions for a description of the effects, if any, of
361 /// each option in the `options` on the JSON representation of the `value`.
362 /// See the package-level documentation of `bdlat` for a description of the
363 /// available type-category concepts.
364 template <class TYPE>
365 static int encode(bsl::ostream *jsonStream,
366 const TYPE& value,
367 const EncoderOptions& options = EncoderOptions());
368
369 /// Encode the JSON representation of the specified `value` to the
370 /// specified `jsonStream`. If this operation is not successful, load
371 /// an unspecified, human-readable description of the error condition to
372 /// the specified `logStream`. Optionally specify `options` to
373 /// configure aspects of the JSON representation of the `value`. If
374 /// `options` is not specified, the default `EncoderOptions` value is
375 /// used. Return 0 on success, and a non-zero value otherwise. The
376 /// behavior is undefined unless the specified `TYPE` satisfies both the
377 /// static and dynamic requirements of one `bdlat` type-category
378 /// concept. See @ref baljsn_encoderoptions for a description of the effects,
379 /// if any, of each option in the `options` on the JSON representation of
380 /// the `value`. See the package-level documentation of `bdlat` for an
381 /// introduction to the requirements of `bdlat` type-category concepts.
382 template <class TYPE>
383 static int encode(bsl::ostream *logStream,
384 bsl::ostream *jsonStream,
385 const TYPE& value,
386 const EncoderOptions& options = EncoderOptions());
387
388 /// Encode the JSON representation of the specified `value` to the
389 /// specified JSON `formatter`, according to the specified
390 /// `formattingMode`. If the representation contains no text, load the
391 /// value `true` into `isValueEmpty` and the value `false` otherwise.
392 /// If the specified `isFirstMember` option is `true`, then the
393 /// representation of the value contains no leading sequence delimiter,
394 /// and does contain such a delimiter if the remaining representation is
395 /// non-empty otherwise. Use the specified `options` to configure
396 /// aspects of the JSON representation of the `value`. If this
397 /// operation is not successful, load an unspecified, human-readable
398 /// description of the error condition to the specified `logStream`.
399 /// Return 0 on success, and a non-zero value otherwise. The behavior
400 /// is undefined unless the specified `TYPE` satisfies both the static
401 /// and dynamic requirements of one of the `bdlat` type-category
402 /// concepts. See @ref baljsn_encoderoptions for a description of the
403 /// effects, if any, of each option in the `options` on the JSON
404 /// representation of the `value`. See the package-level documentation of
405 /// `bdlat` for an introduction to the requirements of `bdlat`
406 /// type-category concepts.
407 template <class TYPE>
408 static int encode(bool *isValueEmpty,
409 Formatter *formatter,
410 bsl::ostream *logStream,
411 const TYPE& value,
412 FormattingMode formattingMode,
413 const EncoderOptions& options,
414 bool isFirstMember);
415
416 // Validation
417
418 /// Determine if the specified `value` having the specified `bdlat`
419 /// `category` satisfies the requirements for encoding using this
420 /// component. If the `value` meets the encoding requirements, return 0,
421 /// otherwise load an unspecified, human-readable description of the
422 /// requirements that are not satisfied by the `value` and return a
423 /// non-zero value. For values satisfying the `bdlat` `Choice`
424 /// type-category concept, the value of the `selectionId` attribute must
425 /// not be undefined. For values satisfying the requirements of other
426 /// `bdlat` type-category concepts, there are no further requirements for
427 /// encoding using this component. See the package-level documentation of
428 /// `bdlat` for an introduction to the requirements of `bdlat`
429 /// type-category concepts.
430 template <class TYPE>
431 static int validate(bsl::ostream *logStream,
432 const TYPE& value,
434 template <class TYPE, class CATEGORY>
435 static int validate(bsl::ostream *logStream,
436 const TYPE& value,
437 CATEGORY category);
438
439 /// Determine if the specified `value` satisfies the requirements for
440 /// encoding using this component. If the `value` meets the encoding
441 /// requirements, return 0, otherwise load an unspecified, human-readable
442 /// description of the requirements that are not satisfied by the `value`
443 /// to the specified `logStream` and return a non-zero value. The `value`
444 /// is required to not have an undefined `selectionId`.
445 template <class TYPE>
446 static int validateChoice(bsl::ostream *logStream, const TYPE& value);
447
448 // Encoding Values That Have Specific Type Categories
449
450 /// Encode the JSON representation of the specified `value` to the
451 /// specified JSON `formatter`. Use the specified `options` to configure
452 /// aspects of the JSON representation of the `value`. Return 0 on
453 /// success, and a non-zero value otherwise.
454 static int encodeCharArray(Formatter *formatter,
455 const bsl::vector<char>& value,
456 const EncoderOptions& options);
457
458 /// Encode the JSON representation of the specified `value` to the
459 /// specified JSON `formatter`. Use the specified `options` to
460 /// configure aspects of the JSON representation of the `value`. Return
461 /// 0 on success, and a non-zero value otherwise. The behavior is
462 /// undefined unless the specified `TYPE` satisfies both the static and
463 /// dynamic requirements of the `Simple` `bdlat` type-category concept.
464 /// See @ref baljsn_encoderoptions for a description of the effects, if any,
465 /// of each option in the `options` on the JSON representation of the
466 /// `value`. See the package-level documentation of `bdlat` for an
467 /// introduction to the requirements of `bdlat` type-category concepts.
468 template <class TYPE>
469 static int encodeSimpleValue(Formatter *formatter,
470 const TYPE& value,
471 const EncoderOptions& options);
472
473 // Encoding Prefixes and Suffixes
474
475 /// If the specified `formattingMode` does not have the
476 /// `bdlat_FormattingMode::e_UNTAGGED` bit set, encode a "left brace"
477 /// JSON token to the specified `formatter`, and encoding nothing to the
478 /// `formatter` otherwise. If this operation encodes a token to the
479 /// formatter, load the value `false` to the specified `isPrefixEmpty`,
480 /// and the value `true` otherwise.
481 static void encodeObjectPrefix(bool *isPrefixEmpty,
482 Formatter *formatter,
483 FormattingMode formattingMode);
484
485 /// If the specified `formattingMode` does not have the
486 /// `bdlat_FormattingMode::e_UNTAGGED` bit set, encode a "right brace"
487 /// JSON token to the specified `formatter`, and encoding nothing to the
488 /// `formatter` otherwise. If this operation encodes a token to the
489 /// `formatter`, load the value `false` to the specified
490 /// `isSuffixEmpty`, and the value `true` otherwise.
491 static void encodeObjectSuffix(bool *isSuffixEmpty,
492 Formatter *formatter,
493 FormattingMode formattingMode);
494
495 // Encoding Arrays That Have Specific Shapes
496
497 /// Encode the representation of the empty-array JSON value to the
498 /// specified `formatter`.
499 static void encodeEmptyArray(Formatter *formatter);
500
501 /// Encode the JSON representation of the specified `value` to the
502 /// specified JSON `formatter`. Use the specified `options` to configure
503 /// aspects of the JSON representation of the `value`. If this operation
504 /// is not successful, load an unspecified, human-readable description of
505 /// the error condition to the specified `logStream`. Return 0 on success,
506 /// and a non-zero value otherwise. The behavior is undefined unless the
507 /// `value` is non-empty and the specified `TYPE` satisfies both the static
508 /// and dynamic requirements of the `Array` `bdlat` type-category concept.
509 /// See @ref baljsn_encoderoptions for a description of the effects, if any,
510 /// of each option in the `options` on the JSON representation of the
511 /// `selection`. See the package-level documentation of `bdlat` for an
512 /// introduction to the requirements of `bdlat` type-category concepts.
513 template <class TYPE>
514 static int encodeNonEmptyArray(Formatter *formatter,
515 bsl::ostream *logStream,
516 const TYPE& value,
517 const EncoderOptions& options);
518
519 // Encoding Generalized Members
520
521 /// Encode the JSON representation of the specified object `member`
522 /// having the specified `memberName` to the specified JSON `formatter`,
523 /// according to the specified `formattingMode`. If the representation
524 /// contains no text, load the value `true` to `isMemberEmpty` and the
525 /// value `false` otherwise. If the specified `isFirstMember` option is
526 /// `true`, then the representation of the member contains no leading
527 /// sequence delimiter, and does contain such a delimiter otherwise.
528 /// Use the specified `options` to configure aspects of the JSON
529 /// representation of the `member`. If this operation is not
530 /// successful, load an unspecified, human-readable description of the
531 /// error condition to the specified `logStream`. Return 0 on success,
532 /// and a non-zero value otherwise. The behavior is undefined unless
533 /// the specified `TYPE` satisfies both the static and dynamic
534 /// requirements of the specified `category` `bdlat` type-category
535 /// concept. See @ref baljsn_encoderoptions for a description of the effects,
536 /// if any, of each option in the `options` on the JSON representation of
537 /// the `selection`. See the package-level documentation of `bdlat` for
538 /// an introduction to the requirements of `bdlat` type-category concepts.
539 static int encodeMember(bool *isMemberEmpty,
540 Formatter *formatter,
541 bsl::ostream *logStream,
542 const bsl::string_view& memberName,
543 const bsl::vector<char>& member,
544 FormattingMode formattingMode,
545 const EncoderOptions& options,
546 bool isFirstMember,
548 template <class TYPE>
549 static int encodeMember(bool *isMemberEmpty,
550 Formatter *formatter,
551 bsl::ostream *logStream,
552 const bsl::string_view& memberName,
553 const TYPE& member,
554 FormattingMode formattingMode,
555 const EncoderOptions& options,
556 bool isFirstMember,
558 template <class TYPE, class OTHER_CATEGORY>
559 static int encodeMember(bool *isMemberEmpty,
560 Formatter *formatter,
561 bsl::ostream *logStream,
562 const bsl::string_view& memberName,
563 const TYPE& member,
564 FormattingMode formattingMode,
565 const EncoderOptions& options,
566 bool isFirstMember,
567 OTHER_CATEGORY category);
568
569 static int encodeMemberPrefix(Formatter *formatter,
570 bsl::ostream *logStream,
571 const bsl::string_view& memberName,
572 bool isFirstMember);
573 static int encodeMemberPrefix(Formatter *formatter,
574 bsl::ostream *logStream,
575 const bsl::string_view& memberName,
576 FormattingMode formattingMode,
577 bool isFirstMember);
578 /// If the specified `isFirstMember` flag is `false`, encode a "comma"
579 /// JSON token to the specified `formatter`, and do not encode a "comma"
580 /// JSON token otherwise. If the specified `formattingMode` does not
581 /// have the `bdlat_FormattingMode::e_UNTAGGED` bit set, encode a JSON
582 /// "string" token having the specified `memberName` contents, and
583 /// encode a JSON "colon" token after the string, and do not encode
584 /// these tokens otherwise. If this operation is not successful, load
585 /// an unspecified, human-readable description of the error condition to
586 /// the specified `logStream`. Optionally specify `isPrefixEmpty`. If
587 /// this operation encodes a token to the formatter, load the value
588 /// `false` to `isPrefixEmpty` if specified, and the value `true`
589 /// otherwise. Return 0 on success, and a non-zero value otherwise.
590 static int encodeMemberPrefix(bool *isPrefixEmpty,
591 Formatter *formatter,
592 bsl::ostream *logStream,
593 const bsl::string_view& memberName,
594 FormattingMode formattingMode,
595 bool isFirstMember);
596};
597
598 // ==============================
599 // struct Encoder_ValueDispatcher
600 // ==============================
601
602/// this component-private class provides a function object used to encode
603/// values that satisfy one of the `bdlat` type-category concepts.
604///
605/// This class's constructor closes over the `formatter`, `logStream`, and
606/// `options` parameters that are shared between all encoding operations
607/// provided in this component. The function-call operator of this class
608/// provides an overload set that accepts an object that satisfies one of
609/// the `bdlat` type-category concepts, and a `bdlat_TypeCategory` tag type
610/// that corresponds to the object's `bdlat` type category. Each
611/// function-call-operator overload encodes a JSON representation of the
612/// specified value to the `formatter` supplied on construction.
613///
614/// See @ref baljsn_encoder
616
617 public:
618 // TYPES
619
620 /// `FormattingMode` is an alias to the type of an `int`-valued
621 /// `bdlat_FormattingMode` bit-field. A `FormattingMode` value is not
622 /// valid unless it is equal to an enumerator of `bdlat_FormattingMode`
623 /// or a valid bitwise-or of two or more such enumerators. See the
624 /// component-level documentation of @ref bdlat_formattingmode for a
625 /// description of the set of valid formatting-mode values.
626 typedef int FormattingMode;
627
628 private:
629 // DATA
630
631 // wrapper around the output stream that determines the whitespace to
632 // emit around each JSON token
633 Formatter *d_formatter_p;
634
635 // human-readable descriptions of all encountered error conditions
636 bsl::ostream *d_logStream_p;
637
638 // options set by the caller of the encoding operation that controls
639 // some aspects of the token sequence to emit
640 const EncoderOptions *d_options_p;
641
642 // formatting mode of the value
643 FormattingMode d_formattingMode;
644
645 // if `false` then emit a leading sequence delimiter before the
646 // representation of the value, otherwise do not emit a leading
647 // sequence delimiter
648 bool d_isNextObjectFirst;
649
650 public:
651 // CREATORS
652
653 /// Construct an `Encoder_ValueDispatcher` object having the specified
654 /// `formatter`, `logStream`, `formattingMode`, `isNextObjectFirst`, and
655 /// `options` attributes.
657 bsl::ostream *logStream,
658 FormattingMode formattingMode,
660 const EncoderOptions& options);
661
662 // MANIPULATORS
663
664 /// Encode the JSON representation of the specified `value` to the JSON
665 /// `formatter` attribute of this object, according to the `formattingMode`
666 /// attribute of this object. If the representation contains no text and
667 /// the `isFirstSubObject` attribute of this object is `true`, set the
668 /// `isNextObjectFirst` attribute of this object to `true`, and the value
669 /// `false` otherwise. If `isFirstSubObject` is `true`, then the
670 /// representation of the value contains no leading sequence delimiter, and
671 /// does contain such a delimiter otherwise. The `options` attribute of
672 /// this object configures aspects of the JSON representation of the
673 /// `value`. If this operation is not successful, load an unspecified,
674 /// human-readable description of the error condition to the `logStream`
675 /// attribute of this object. Return 0 on success, and a non-zero value
676 /// otherwise. The behavior is undefined unless the specified `TYPE`
677 /// satisfies both the static and dynamic requirements of the specified
678 /// `category` `bdlat` type-category concept. See @ref baljsn_encoderoptions
679 /// for a description of the effects, if any, of each option in the
680 /// `options` on the JSON representation of the `value`. See the
681 /// package-level documentation of `bdlat` for an introduction to the
682 /// requirements of `bdlat` type-category concepts.
683 int operator()(const bsl::vector<char>& value,
685 template <class TYPE>
686 int operator()(const TYPE& value, bdlat_TypeCategory::Array category);
687 template <class TYPE>
688 int operator()(const TYPE& value, bdlat_TypeCategory::Choice category);
689 template <class TYPE>
690 int operator()(const TYPE& value,
692 template <class TYPE>
693 int operator()(const TYPE& value,
695 template <class TYPE>
696 int operator()(const TYPE& value,
698 template <class TYPE>
699 int operator()(const TYPE& value,
701 template <class TYPE>
702 int operator()(const TYPE& value, bdlat_TypeCategory::Sequence category);
703 template <class TYPE>
704 int operator()(const TYPE& value, bdlat_TypeCategory::Simple category);
705
706 /// The behavior of this function is undefined.
707 template <class TYPE>
708 int operator()(const TYPE&, bslmf::Nil);
709
710 // ACCESSORS
711
712 /// Return the value of the `isNextObjectFirst` attribute of this
713 /// object.
714 bool isNextObjectFirst() const;
715};
716
717 // ============================
718 // class Encoder_ElementVisitor
719 // ============================
720
721/// This component-private class provides a function object that closes over
722/// the `formatter`, `logStream`, and `options` parameters that are shared
723/// between all encoding operations provided in this component. The
724/// function-call operator of this class provides an overload set that
725/// accepts an "element" object that satisfies one of the `bdlat`
726/// type-category concepts.
727///
728/// See @ref baljsn_encoder
730
731 // DATA
732
733 // wrapper around the output stream that determines the whitespace to
734 // emit around each JSON token
735 Formatter *d_formatter_p;
736
737 // human-readable descriptions of all encountered error conditions
738 bsl::ostream *d_logStream_p;
739
740 // options set by the caller of the encoding operation that controls
741 // some aspects of the token sequence to emit
742 const EncoderOptions *d_options_p;
743
744 // if `false` then emit a leading sequence delimiter before the
745 // representation of the value, otherwise do not emit a leading
746 // sequence delimiter
747 bool d_isNextElementFirst;
748
749 public:
750 // CREATORS
751
752 /// Construct an `Encoder_ElementVisitor` object having the specified
753 /// `formatter`, `logStream`, `isNextElementFirst`, and `options`
754 /// attributes.
756 bsl::ostream *logStream,
758 const EncoderOptions& options);
759
760 // MANIPULATORS
761
762 /// Encode the JSON representation of the specified `value` to the JSON
763 /// `formatter` attribute of this object, according to the
764 /// `formattingMode` attribute of this object. If the
765 /// `isNextElementFirst` attribute of this object is `true`, then the
766 /// representation of the value contains no leading sequence delimiter,
767 /// and does contain such a delimiter otherwise. The `options`
768 /// attribute of this object configures aspects of the JSON
769 /// representation of the `value`. If this operation is not successful,
770 /// load an unspecified, human-readable description of the error
771 /// condition to the `logStream` attribute of this object. Return 0 on
772 /// success, and a non-zero value otherwise. The behavior is undefined
773 /// unless the specified `TYPE` satisfies both the static and dynamic
774 /// requirements of the specified `category` `bdlat` type-category
775 /// concept. See the component-level documentation of
776 /// @ref baljsn_encoderoptions for a description of the effects, if any,
777 /// of each option in the `options` on the JSON representation of the
778 /// `value`. See the package-level documentation of {`bdlat`} for an
779 /// introduction to the requirements of `bdlat` type-category concepts.
780 template <class TYPE>
781 int operator()(const TYPE& element);
782
783 // ACCESSORS
784
785 /// Return the value of the `isNextElementFirst` attribute of this
786 /// object.
787 bool isNextElementFirst() const;
788};
789
790 // ===============================
791 // class Encoder_ElementDispatcher
792 // ===============================
793
794/// This component-private class provides a function object that closes over
795/// the `formatter`, `logStream`, and `options` parameters that are shared
796/// between all encoding operations provided in this component. The
797/// function-call operator of this class provides an overload set that
798/// accepts an "element" object that satisfies one of the `bdlat`
799/// type-category concepts, and an optional `bdlat_TypeCategory` tag type
800/// that corresponds to the element's `bdlat` type category. Each
801/// function-call-operator overload encodes a JSON representation of the
802/// specified selection to the `formatter` supplied on construction.
803///
804/// See @ref baljsn_encoder
806
807 // DATA
808
809 // wrapper around the output stream that determines the whitespace to
810 // emit around each JSON token
811 Formatter *d_formatter_p;
812
813 // human-readable descriptions of all encountered error conditions
814 bsl::ostream *d_logStream_p;
815
816 // options set by the caller of the encoding operation that controls
817 // some aspects of the token sequence to emit
818 const EncoderOptions *d_options_p;
819
820 // if `false` then emit a leading sequence delimiter before the
821 // representation of the value, otherwise do not emit a leading
822 // sequence delimiter
823 bool d_isNextElementFirst;
824
825 public:
826 // CREATORS
827
828 /// Construct an `Encoder_ElementDispatcher` object having the specified
829 /// `formatter`, `logStream`, `isNextElementFirst`, and `options`
830 /// attributes.
832 bsl::ostream *logStream,
834 const EncoderOptions& options);
835
836 // MANIPULATORS
837
838 /// Encode the JSON representation of the specified `value` to the JSON
839 /// `formatter` attribute of this object, according to the specified
840 /// `formattingMode`. If the representation contains no text and the
841 /// specified `isFirstElement` is `true`, load the value `true` into the
842 /// specified `isNextElementFirst`, and the value `false` otherwise. If
843 /// `isFirstElement` is `true`, then the representation of the value
844 /// contains no leading sequence delimiter, and does contain such a
845 /// delimiter otherwise. The `options` attribute of this object
846 /// configures aspects of the JSON representation of the `value`. If
847 /// this operation is not successful, load an unspecified,
848 /// human-readable description of the error condition to the `logStream`
849 /// attribute of this object. Return 0 on success, and a non-zero value
850 /// otherwise. The behavior is undefined unless the specified `TYPE`
851 /// satisfies both the static and dynamic requirements of the specified
852 /// `category` `bdlat` type-category concept. See @ref baljsn_encoderoptions
853 /// for a description of the effects, if any, of each option in the
854 /// `options` on the JSON representation of the `value`. See the
855 /// package-level documentation of `bdlat` for an introduction to the
856 /// requirements of `bdlat` type-category concepts.
857 int operator()(const bsl::vector<char>& element,
859 template <class TYPE>
860 int operator()(const TYPE& element, bdlat_TypeCategory::Array category);
861 template <class TYPE>
862 int operator()(const TYPE& element, bdlat_TypeCategory::Choice category);
863 template <class TYPE>
864 int operator()(const TYPE& element,
866 template <class TYPE>
867 int operator()(const TYPE& element,
869 template <class TYPE>
870 int operator()(const TYPE& element,
872 template <class TYPE>
873 int operator()(const TYPE& element,
875 template <class TYPE>
876 int operator()(const TYPE& element, bdlat_TypeCategory::Sequence category);
877 template <class TYPE>
878 int operator()(const TYPE& element, bdlat_TypeCategory::Simple category);
879
880 /// The behavior of this function is undefined.
881 template <class TYPE>
882 int operator()(const TYPE&, bslmf::Nil);
883
884 // ACCESSORS
885
886 /// Return the value of the `isNextElementFirst` attribute of this
887 /// object.
888 bool isNextElementFirst() const;
889};
890
891 // ==============================
892 // class Encoder_SelectionVisitor
893 // ==============================
894
895/// This component-private class provides a function object that closes over
896/// the `formatter`, `logStream`, and `options` parameters that are shared
897/// between all encoding operations provided in this component. The
898/// function-call operator of this class provides an overload set that
899/// accepts a "selection" object that satisfies one of the `bdlat`
900/// type-category concepts, and a "selection info" object that describes
901/// various metadata of the selection.
902///
903/// See @ref baljsn_encoder
905
906 public:
907 // TYPES
908
909 /// `FormattingMode` is an alias to the type of an `int`-valued
910 /// `bdlat_FormattingMode` bit-field. A `FormattingMode` value is not
911 /// valid unless it is equal to an enumerator of `bdlat_FormattingMode`
912 /// or a valid bitwise-or of two or more such enumerators. See the
913 /// component-level documentation of @ref bdlat_formattingmode for a
914 /// description of the set of valid formatting-mode values.
915 typedef int FormattingMode;
916
917 private:
918 // DATA
919
920 // wrapper around the output stream that determines the whitespace to
921 // emit around each JSON token
922 Formatter *d_formatter_p;
923
924 // human-readable descriptions of all encountered error conditions
925 bsl::ostream *d_logStream_p;
926
927 // if `false` then emit a leading sequence delimiter before the
928 // representation of the value, otherwise do not emit a leading
929 // sequence delimiter
930 bool d_isNextObjectFirst;
931
932 // options set by the caller of the encoding operation that controls
933 // some aspects of the token sequence to emit
934 const EncoderOptions *d_options_p;
935
936 public:
937 // CREATORS
938
939 /// Construct an `Encoder_SelectionVisitor` object having the specified
940 /// `formatter`, `logStream`, `isNextObjectFirst`, and `options`
941 /// attributes.
943 bsl::ostream *logStream,
945 const EncoderOptions& options);
946
947 // MANIPULATORS
948
949 /// Encode the JSON representation of the specified `selection`, having
950 /// the name equal to the `name` attribute of the specified
951 /// `selectionInfo` to the JSON `formatter` attribute of this object,
952 /// according to the specified `formattingMode`. If the
953 /// `isNextObjectFirst` attribute of this object is `true`, then the
954 /// representation of the selection contains no leading sequence
955 /// delimiter, and does contain such a delimiter otherwise. The
956 /// `options` attribute of this object configures aspects of the JSON
957 /// representation of the `selection`. If this operation is not
958 /// successful, load an unspecified, human-readable description of the
959 /// error condition to the `logStream` attribute of this object. Return
960 /// 0 on success, and a non-zero value otherwise. The behavior is
961 /// undefined unless the `selection` satisfies both the static and
962 /// dynamic requirements of the `bdlat` type-category concept
963 /// corresponding to the specified `category`. See the component-level
964 /// documentation of @ref baljsn_encoderoptions for a description of the
965 /// effects, if any, of each option in the `options` on the JSON
966 /// representation of the `selection`. See the package-level
967 /// documentation of {`bdlat`} for an introduction to the requirements
968 /// of `bdlat` type-category concepts.
969 template <class TYPE, class SELECTION_INFO>
970 int operator()(const TYPE& selection, const SELECTION_INFO& selectionInfo);
971
972 // ACCESSORS
973
974 /// Return the value of the `isNextObjectFirst` attribute of this
975 /// object.
976 bool isNextObjectFirst() const;
977};
978
979 // =================================
980 // class Encoder_SelectionDispatcher
981 // =================================
982
983/// This component-private class provides a function object that closes over
984/// the `formatter`, `logStream`, and `options` parameters that are shared
985/// between all encoding operations provided in this component. The
986/// function-call operator of this class provides an overload set that
987/// accepts a "selection" object that satisfies one of the `bdlat`
988/// type-category concepts, and an optional `bdlat_TypeCategory` tag type
989/// that corresponds to the selections's `bdlat` type category. Each
990/// function-call-operator overload encodes a JSON representation of the
991/// specified selection to the `formatter` supplied on construction.
992///
993/// See @ref baljsn_encoder
995
996 public:
997 // TYPES
998
999 /// `FormattingMode` is an alias to the type of an `int`-valued
1000 /// `bdlat_FormattingMode` bit-field. A `FormattingMode` value is not
1001 /// valid unless it is equal to an enumerator of `bdlat_FormattingMode`
1002 /// or a valid bitwise-or of two or more such enumerators. See the
1003 /// component-level documentation of @ref bdlat_formattingmode for a
1004 /// description of the set of valid formatting-mode values.
1005 typedef int FormattingMode;
1006
1007 private:
1008 // DATA
1009
1010 // wrapper around the output stream that determines the whitespace to
1011 // emit around each JSON token
1012 Formatter *d_formatter_p;
1013
1014 // human-readable descriptions of all encountered error conditions
1015 bsl::ostream *d_logStream_p;
1016
1017 // options set by the caller of the encoding operation that controls
1018 // some aspects of the token sequence to emit
1019 const EncoderOptions *d_options_p;
1020
1021 // name of the selection
1022 bsl::string_view d_selectionName;
1023
1024 // formatting mode of the selection
1025 FormattingMode d_formattingMode;
1026
1027 // if `false` then emit a leading sequence delimiter before the
1028 // representation of the value, otherwise do not emit a leading
1029 // sequence delimiter
1030 bool d_isNextObjectFirst;
1031
1032 public:
1033 // CREATORS
1034
1035 /// Construct an `Encoder_SelectionDispatcher` object having the
1036 /// specified `formatter`, `logStream`, and `options` attributes.
1038 bsl::ostream *logStream,
1039 const bsl::string_view& selectionName,
1040 FormattingMode formattingMode,
1041 bool isNextObjectFirst,
1042 const EncoderOptions& options);
1043
1044 // MANIPULATORS
1045
1046 /// Encode the JSON representation of the specified `selection`, having
1047 /// the name equal to the `name` attribute of the specified
1048 /// `selectionInfo` to the JSON `formatter` attribute of this object,
1049 /// according to the specified `formattingMode`. If the representation
1050 /// contains no text and `isFirstSubObject` is `true`, load the value
1051 /// `true` into the specified `isNextObjectFirst`, and the value `false`
1052 /// otherwise. If `isFirstSubObject` is `true`, then the representation
1053 /// of the selection contains no leading sequence delimiter, and does
1054 /// contain such a delimiter otherwise. The `options` attribute of this
1055 /// object configures aspects of the JSON representation of the
1056 /// `selection`. If this operation is not successful, load an
1057 /// unspecified, human-readable description of the error condition to
1058 /// the `logStream` attribute of this object. Return 0 on success, and
1059 /// a non-zero value otherwise. The behavior is undefined unless the
1060 /// `selection` satisfies both the static and dynamic requirements of
1061 /// the `bdlat` type-category concept corresponding to the specified
1062 /// `category`. See the component-level documentation of
1063 /// @ref baljsn_encoderoptions for a description of the effects, if any,
1064 /// of each option in the `options` on the JSON representation of the
1065 /// `selection`. See the package-level documentation of {`bdlat`} for
1066 /// an introduction to the requirements of `bdlat` type-category
1067 /// concepts.
1068 template <class TYPE>
1069 int operator()(const TYPE& selection,
1071 template <class TYPE>
1072 int operator()(const TYPE& selection,
1074 template <class TYPE, class CATEGORY>
1075 int operator()(const TYPE& selection, CATEGORY category);
1076
1077 /// The behavior of this function is undefined.
1078 template <class TYPE>
1079 int operator()(const TYPE&, bslmf::Nil);
1080
1081 // ACCESSORS
1082
1083 /// Return the value of the `isNextElementFirst` attribute of this
1084 /// object.
1085 bool isNextObjectFirst() const;
1086};
1087
1088 // ==============================
1089 // class Encoder_AttributeVisitor
1090 // ==============================
1091
1092/// This component-private class provides a function object that closes over
1093/// the `formatter`, `logStream`, and `options` parameters that are shared
1094/// between all encoding operations provided in this component. The
1095/// function-call operator of this class provides an overload set that
1096/// accepts an "attribute" object that satisfies one of the `bdlat`
1097/// type-category concepts, and an "attribute info" object that describes
1098/// various metadata of the attribute.
1099///
1100/// See @ref baljsn_encoder
1102
1103 public:
1104 // TYPES
1105
1106 /// `FormattingMode` is an alias to the type of an `int`-valued
1107 /// `bdlat_FormattingMode` bit-field. A `FormattingMode` value is not
1108 /// valid unless it is equal to an enumerator of `bdlat_FormattingMode`
1109 /// or a valid bitwise-or of two or more such enumerators. See the
1110 /// component-level documentation of @ref bdlat_formattingmode for a
1111 /// description of the set of valid formatting-mode values.
1112 typedef int FormattingMode;
1113
1114 private:
1115 // DATA
1116
1117 // wrapper around the output stream that determines the whitespace to
1118 // emit around each JSON token
1119 Formatter *d_formatter_p;
1120
1121 // human-readable descriptions of all encountered error conditions
1122 bsl::ostream *d_logStream_p;
1123
1124 // if `false` then emit a leading sequence delimiter before the
1125 // representation of the value, otherwise do not emit a leading
1126 // sequence delimiter
1127 bool d_isNextAttributeFirst;
1128
1129 // options set by the caller of the encoding operation that controls
1130 // some aspects of the token sequence to emit
1131 const EncoderOptions *d_options_p;
1132
1133 public:
1134 // CREATORS
1135
1136 /// Construct an `Encoder_AttributeVisitor` object having the specified
1137 /// `formatter`, `logStream`, `isNextAttributeFirst`, and `options`
1138 /// attributes.
1140 bsl::ostream *logStream,
1142 const EncoderOptions& options);
1143
1144 // MANIPULATORS
1145
1146 /// Encode the JSON representation of the specified `attribute`, having
1147 /// the name equal to the `name` of the specified `attributeInfo`, to
1148 /// the JSON `formatter` attribute of this object according to the
1149 /// `formattingMode` attribute of this object. If the
1150 /// `isNextAttributeFirst` attribute of this object is `true`, then the
1151 /// representation of the attribute contains no leading sequence
1152 /// delimiter, and does contain such a delimiter otherwise. The
1153 /// `options` attribute of this object configures aspects of the JSON
1154 /// representation of the `attribute`. If this operation is not
1155 /// successful, load an unspecified, human-readable description of the
1156 /// error condition to the `logStream` attribute of this object. Return
1157 /// 0 on success, and a non-zero value otherwise. The behavior is
1158 /// undefined unless the `attribute` satisfies both the static and
1159 /// dynamic requirements of the `bdlat` type-category concept
1160 /// corresponding to the specified `category`. See the component-level
1161 /// documentation of @ref baljsn_encoderoptions for a description of the
1162 /// effects, if any, of each option in the `options` on the JSON
1163 /// representation of the `attribute`. See the package-level
1164 /// documentation of {`bdlat`} for an introduction to the requirements
1165 /// of `bdlat` type-category concepts.
1166 template <class TYPE, class ATTRIBUTE_INFO>
1167 int operator()(const TYPE& attribute, const ATTRIBUTE_INFO& attributeInfo);
1168
1169 // ACCESSORS
1170
1171 /// Return the value of the `isNextAttributeFirst` attribute of this
1172 /// object.
1173 bool isNextAttributeFirst() const;
1174};
1175
1176 // =================================
1177 // class Encoder_AttributeDispatcher
1178 // =================================
1179
1180/// This component-private class provides a function object that closes over
1181/// the `formatter`, `logStream`, and `options` parameters that are shared
1182/// between all encoding operations provided in this component. The
1183/// function-call operator of this class provides an overload set that
1184/// accepts an "attribute" object that satisfies one of the `bdlat`
1185/// type-category concepts, and an optional `bdlat_TypeCategory` tag type
1186/// that corresponds to the attribute's `bdlat` type category. Each
1187/// function-call-operator overload encodes a JSON representation of the
1188/// specified attribute to the `formatter` supplied on construction.
1189///
1190/// See @ref baljsn_encoder
1192
1193 public:
1194 // TYPES
1195
1196 /// `FormattingMode` is an alias to the type of an `int`-valued
1197 /// `bdlat_FormattingMode` bit-field. A `FormattingMode` value is not
1198 /// valid unless it is equal to an enumerator of `bdlat_FormattingMode`
1199 /// or a valid bitwise-or of two or more such enumerators. See the
1200 /// component-level documentation of @ref bdlat_formattingmode for a
1201 /// description of the set of valid formatting-mode values.
1202 typedef int FormattingMode;
1203
1204 private:
1205 // DATA
1206
1207 // wrapper around the output stream that determines the whitespace to
1208 // emit around each JSON token
1209 Formatter *d_formatter_p;
1210
1211 // human-readable descriptions of all encountered error conditions
1212 bsl::ostream *d_logStream_p;
1213
1214 // options set by the caller of the encoding operation that controls
1215 // some aspects of the token sequence to emit
1216 const EncoderOptions *d_options_p;
1217
1218 // name of the attribute
1219 bsl::string_view d_attributeName;
1220
1221 // formatting mode of the attribute
1222 FormattingMode d_formattingMode;
1223
1224 // if `false` then emit a leading sequence delimiter before the
1225 // representation of the value, otherwise do not emit a leading
1226 // sequence delimiter
1227 bool d_isNextAttributeFirst;
1228
1229 public:
1230 // CREATORS
1231
1232 /// Construct an `Encoder_AttributeDispatcher` object having the
1233 /// specified `formatter`, `logStream`, `attributeName`,
1234 /// `formattingMode`, `isNextAttributeFirst`, and `options` attributes.
1236 bsl::ostream *logStream,
1237 const bsl::string_view& attributeName,
1238 FormattingMode formattingMode,
1240 const EncoderOptions& options);
1241
1242 // MANIPULATORS
1243
1244 /// Encode the JSON representation of the specified `attribute`, having
1245 /// the name equal to the `name` of the `attributeInfo` attribute of
1246 /// this object, to the JSON `formatter` attribute of this object
1247 /// according to the `formattingMode` attribute of this object. If the
1248 /// `isNextAttributeFirst` attribute of this object is `true`, then the
1249 /// representation of the attribute contains no leading sequence
1250 /// delimiter, and does contain such a delimiter otherwise. The
1251 /// `options` attribute of this object configures aspects of the JSON
1252 /// representation of the `attribute`. If this operation is not
1253 /// successful, load an unspecified, human-readable description of the
1254 /// error condition to the `logStream` attribute of this object. Return
1255 /// 0 on success, and a non-zero value otherwise. The behavior is
1256 /// undefined unless the `attribute` satisfies both the static and
1257 /// dynamic requirements of the `bdlat` type-category concept
1258 /// corresponding to the specified `category`. See the component-level
1259 /// documentation of @ref baljsn_encoderoptions for a description of the
1260 /// effects, if any, of each option in the `options` on the JSON
1261 /// representation of the `attribute`. See the package-level
1262 /// documentation of {`bdlat`} for an introduction to the requirements
1263 /// of `bdlat` type-category concepts.
1264 int operator()(const bsl::vector<char>& attribute,
1265 bdlat_TypeCategory::Array category);
1266 template <class TYPE>
1267 int operator()(const TYPE& attribute, bdlat_TypeCategory::Array category);
1268 template <class TYPE>
1269 int operator()(const TYPE& attribute,
1271 template <class TYPE>
1272 int operator()(const TYPE& attribute,
1274 template <class TYPE>
1275 int operator()(const TYPE& attribute,
1277 template <class TYPE, class CATEGORY>
1278 int operator()(const TYPE& attribute, CATEGORY category);
1279
1280 /// The behavior of this function is undefined.
1281 template <class TYPE>
1282 int operator()(const TYPE&, bslmf::Nil);
1283
1284 // ACCESSORS
1285
1286 /// Return the value of the `isNextAttributeFirst` attribute of this
1287 /// object.
1288 bool isNextAttributeFirst() const;
1289};
1290
1291// ============================================================================
1292// INLINE DEFINITIONS
1293// ============================================================================
1294
1295 // -------------
1296 // class Encoder
1297 // -------------
1298
1299// PRIVATE MANIPULATORS
1300inline
1301bsl::ostream& Encoder::logStream()
1302{
1303 return d_logStream;
1304}
1305
1306// CREATORS
1307inline
1308Encoder::Encoder(bslma::Allocator *basicAllocator)
1309: d_logStream(basicAllocator)
1310{
1311}
1312
1313// MANIPULATORS
1314template <class TYPE>
1315inline
1316int Encoder::encode(bsl::streambuf *streamBuf, const TYPE& value)
1317{
1318 const EncoderOptions options;
1319 return encode(streamBuf, value, options);
1320}
1321
1322template <class TYPE>
1323inline
1324int Encoder::encode(bsl::ostream& stream, const TYPE& value)
1325{
1326 const EncoderOptions options;
1327 return encode(stream, value, options);
1328}
1329
1330template <class TYPE>
1331int Encoder::encode(bsl::streambuf *streamBuf,
1332 const TYPE& value,
1333 const EncoderOptions& options)
1334{
1335 BSLS_ASSERT(streamBuf);
1336
1337 d_logStream.clear();
1338 d_logStream.str("");
1339
1340 bdlat_TypeCategory::Value category =
1345 logStream()
1346 << "Encoded object must be a Sequence, Choice, or Array type."
1347 << bsl::endl;
1348 return -1; // RETURN
1349 }
1350
1351 bsl::ostream outputStream(streamBuf);
1352 Encoder_EncodeImplUtil::openDocument(&outputStream, options);
1353
1354 const int rc = Encoder_EncodeImplUtil::encode(&d_logStream,
1355 &outputStream,
1356 value,
1357 options);
1358 if (0 != rc) {
1359 streamBuf->pubsync();
1360 return rc; // RETURN
1361 }
1362
1363 Encoder_EncodeImplUtil::closeDocument(&outputStream, options);
1364
1365 if (!outputStream) {
1366 logStream()
1367 << "An error occurred when writing to the supplied output stream"
1368 " or stream buffer."
1369 << bsl::endl;
1370 streamBuf->pubsync();
1371 return -1; // RETURN
1372 }
1373
1374 streamBuf->pubsync();
1375
1376 return 0;
1377}
1378
1379template <class TYPE>
1380int Encoder::encode(bsl::streambuf *streamBuf,
1381 const TYPE& value,
1382 const EncoderOptions *options)
1383{
1384 EncoderOptions localOpts;
1385 return encode(streamBuf, value, options ? *options : localOpts);
1386}
1387
1388template <class TYPE>
1389int Encoder::encode(bsl::ostream& stream,
1390 const TYPE& value,
1391 const EncoderOptions& options)
1392{
1393 if (!stream.good()) {
1394 logStream() << "Invalid stream." << bsl::endl;
1395 return -1; // RETURN
1396 }
1397
1398 const int rc = this->encode(stream.rdbuf(), value, options);
1399 if (rc) {
1400 stream.setstate(bsl::ios_base::failbit);
1401 return rc; // RETURN
1402 }
1403
1404 return 0;
1405}
1406
1407template <class TYPE>
1408inline
1409int Encoder::encode(bsl::ostream& stream,
1410 const TYPE& value,
1411 const EncoderOptions *options)
1412{
1413 EncoderOptions localOpts;
1414 return encode(stream, value, options ? *options : localOpts);
1415}
1416
1417// ACCESSORS
1418inline
1420{
1421 return d_logStream.str();
1422}
1423
1424 // -----------------------------
1425 // struct Encoder_EncodeImplUtil
1426 // -----------------------------
1427
1428// CLASS METHODS
1429
1430// Document Encoding Functions
1431
1432inline
1433void Encoder_EncodeImplUtil::openDocument(bsl::ostream *outputStream,
1434 const EncoderOptions& options)
1435{
1437 bdlb::Print::indent(*outputStream,
1438 options.initialIndentLevel(),
1439 options.spacesPerLevel());
1440 }
1441}
1442
1443inline
1445 bsl::ostream *outputStream,
1446 const baljsn::EncoderOptions& options)
1447{
1449 (*outputStream) << '\n';
1450 }
1451}
1452
1453// Value Encoding
1454
1455template <class TYPE>
1456inline
1457int Encoder_EncodeImplUtil::encode(bsl::ostream *jsonStream,
1458 const TYPE& value,
1459 const EncoderOptions& options)
1460{
1461 bdlsb::MemOutStreamBuf logStreamBuf;
1462 bsl::ostream logStream(&logStreamBuf);
1463
1464 return encode(&logStream, jsonStream, value, options);
1465}
1466
1467template <class TYPE>
1468inline
1469int Encoder_EncodeImplUtil::encode(bsl::ostream *logStream,
1470 bsl::ostream *jsonStream,
1471 const TYPE& value,
1472 const EncoderOptions& options)
1473{
1474 static const FormattingMode s_MODE = bdlat_FormattingMode::e_DEFAULT;
1475 static const bool s_FIRST_MEMBER_FLAG = false;
1476
1477 baljsn::Formatter formatter(
1478 *jsonStream,
1480 options.initialIndentLevel(),
1481 options.spacesPerLevel());
1482
1483 bool isValueEmpty = false;
1484
1485 int rc = encode(&isValueEmpty,
1486 &formatter,
1487 logStream,
1488 value,
1489 s_MODE,
1490 options,
1491 s_FIRST_MEMBER_FLAG);
1492
1493 if (0 != formatter.nestingDepth()) {
1494 *logStream << "Encoding failed leaving an unclosed element (rc = "
1495 << rc << ")\n";
1496 }
1497
1498 return rc;
1499}
1500
1501template <class TYPE>
1502int Encoder_EncodeImplUtil::encode(bool *isValueEmpty,
1503 Formatter *formatter,
1504 bsl::ostream *logStream,
1505 const TYPE& value,
1506 FormattingMode formattingMode,
1507 const EncoderOptions& options,
1508 bool isFirstMember)
1509{
1510 Encoder_ValueDispatcher visitor(formatter,
1511 logStream,
1512 formattingMode,
1513 isFirstMember,
1514 options);
1515
1516 typedef typename bdlat_TypeCategory::Select<TYPE>::Type Category;
1517 int rc = visitor(value, Category());
1518 if (0 != rc) {
1519 return rc; // RETURN
1520 }
1521
1522 *isValueEmpty = visitor.isNextObjectFirst();
1523 return 0;
1524}
1525
1526// Validation
1527
1528template <class TYPE>
1529int Encoder_EncodeImplUtil::validate(bsl::ostream *logStream,
1530 const TYPE& value,
1532{
1533 return validateChoice(logStream, value);
1534}
1535
1536template <class TYPE, class CATEGORY>
1537inline
1538int Encoder_EncodeImplUtil::validate(bsl::ostream *, const TYPE&, CATEGORY)
1539{
1540 return 0;
1541}
1542
1543template <class TYPE>
1544int Encoder_EncodeImplUtil::validateChoice(bsl::ostream *logStream,
1545 const TYPE& value)
1546{
1549 (*logStream) << "Undefined selection for Choice object" << bsl::endl;
1550 return -1; // RETURN
1551 }
1552
1553 return 0;
1554}
1555
1556// Encoding Values That Have Specific Type Categories
1557
1558template <class TYPE>
1559inline
1561 const TYPE& value,
1562 const EncoderOptions& options)
1563{
1564 return formatter->putValue(value, &options);
1565}
1566
1567// Encoding Value Prefixes and Suffixes
1568
1569inline
1571 Formatter *formatter,
1572 FormattingMode formattingMode)
1573{
1574 if (bdlat_FormattingMode::e_UNTAGGED & formattingMode) {
1575 *isPrefixEmpty = true;
1576 return; // RETURN
1577 }
1578
1579 formatter->openObject();
1580
1581 *isPrefixEmpty = false;
1582}
1583
1584inline
1586 Formatter *formatter,
1587 FormattingMode formattingMode)
1588{
1589 if (bdlat_FormattingMode::e_UNTAGGED & formattingMode) {
1590 *isSuffixEmpty = true;
1591 return; // RETURN
1592 }
1593
1594 formatter->closeObject();
1595
1596 *isSuffixEmpty = false;
1597}
1598
1599// Encoding Arrays That Have Specific Shapes
1600
1601inline
1603{
1604 formatter->openArray(true);
1605 formatter->closeArray(true);
1606}
1607
1608template <class TYPE>
1610 Formatter *formatter,
1611 bsl::ostream *logStream,
1612 const TYPE& value,
1613 const EncoderOptions& options)
1614{
1615 const int size = static_cast<int>(bdlat_ArrayFunctions::size(value));
1616 BSLS_ASSERT(0 < size);
1617
1618 formatter->openArray();
1619
1620 Encoder_ElementVisitor visitor(formatter, logStream, true, options);
1621
1622 for (int index = 0; index != size; ++index) {
1623 int rc = bdlat_ArrayFunctions::accessElement(value, visitor, index);
1624 if (0 != rc) {
1625 return rc; // RETURN
1626 }
1627 }
1628
1629 formatter->closeArray();
1630
1631 return 0;
1632}
1633
1634// Encoding Generalized Members
1635
1636template <class TYPE>
1637
1638/// ## Implementation Note
1639/// This function purposefully ignores the `EncodeEmptyArrays` option in the
1640/// specified `options` and always encodes the value of the specified
1641/// `member` array. The caller is responsible for checking the value of
1642/// this option and deciding whether to obey the option or not. Callers
1643/// that encode array-valued attributes of sequences must always obey the
1644/// option. Callers that encode array-valued selections of choices must
1645/// never obey the option, and must always encode the array value.
1647 bool *isMemberEmpty,
1648 Formatter *formatter,
1649 bsl::ostream *logStream,
1650 const bsl::string_view& memberName,
1651 const TYPE& member,
1652 FormattingMode formattingMode,
1653 const EncoderOptions& options,
1654 bool isFirstMember,
1656{
1657 int rc = ThisUtil::validate(logStream, member, category);
1658 if (0 != rc) {
1659 return rc; // RETURN
1660 }
1661
1662 rc = ThisUtil::encodeMemberPrefix(formatter,
1663 logStream,
1664 memberName,
1665 formattingMode,
1666 isFirstMember);
1667 if (0 != rc) {
1668 return rc; // RETURN
1669 }
1670
1671 if (bdlat_ArrayFunctions::size(member) == 0) {
1672 ThisUtil::encodeEmptyArray(formatter);
1673
1674 *isMemberEmpty = false;
1675 return 0; // RETURN
1676 }
1677
1678 rc = ThisUtil::encodeNonEmptyArray(formatter, logStream, member, options);
1679 if (0 != rc) {
1680 (*logStream) << "Unable to encode value of element "
1681 << "named: '" << memberName << "'." << bsl::endl;
1682 return rc; // RETURN
1683 }
1684
1685 *isMemberEmpty = false;
1686 return 0;
1687}
1688
1689template <class TYPE, class OTHER_CATEGORY>
1691 bool *isMemberEmpty,
1692 Formatter *formatter,
1693 bsl::ostream *logStream,
1694 const bsl::string_view& memberName,
1695 const TYPE& member,
1696 FormattingMode formattingMode,
1697 const EncoderOptions& options,
1698 bool isFirstMember,
1699 OTHER_CATEGORY category)
1700{
1701 int rc = ThisUtil::validate(logStream, member, category);
1702 if (0 != rc) {
1703 return rc; // RETURN
1704 }
1705
1706 bool isPrefixEmpty = false;
1707 rc = ThisUtil::encodeMemberPrefix(&isPrefixEmpty,
1708 formatter,
1709 logStream,
1710 memberName,
1711 formattingMode,
1712 isFirstMember);
1713 if (0 != rc) {
1714 return rc; // RETURN
1715 }
1716
1717 bool isValueEmpty = false;
1718 rc = ThisUtil::encode(&isValueEmpty,
1719 formatter,
1720 logStream,
1721 member,
1722 formattingMode,
1723 options,
1724 !isPrefixEmpty || isFirstMember);
1725 if (0 != rc) {
1726 (*logStream) << "Unable to encode value of element "
1727 << "named: '" << memberName << "'." << bsl::endl;
1728 return rc; // RETURN
1729 }
1730
1731 BSLS_ASSERT(!isValueEmpty || isPrefixEmpty);
1732 // If the value is empty then the prefix is empty. Otherwise, this
1733 // function would produce invalid JSON because it would emit a member name
1734 // token and a colon token, but no member value.
1735
1736 *isMemberEmpty = isFirstMember && isValueEmpty;
1737 return 0;
1738}
1739
1740inline
1742 Formatter *formatter,
1743 bsl::ostream *logStream,
1744 const bsl::string_view& memberName,
1745 bool isFirstMember)
1746{
1747 if (!isFirstMember) {
1748 formatter->closeMember();
1749 }
1750
1751 int rc = formatter->openMember(memberName);
1752 if (0 != rc) {
1753 (*logStream) << "Unable to encode element name: '" << memberName
1754 << "'." << bsl::endl;
1755 return rc; // RETURN
1756 }
1757
1758 return 0;
1759}
1760
1761inline
1763 Formatter *formatter,
1764 bsl::ostream *logStream,
1765 const bsl::string_view& memberName,
1766 FormattingMode formattingMode,
1767 bool isFirstMember)
1768{
1769 if (bdlat_FormattingMode::e_UNTAGGED & formattingMode) {
1770 return 0; // RETURN
1771 }
1772
1773 return ThisUtil::encodeMemberPrefix(formatter,
1774 logStream,
1775 memberName,
1776 isFirstMember);
1777}
1778
1779inline
1781 bool *isPrefixEmpty,
1782 Formatter *formatter,
1783 bsl::ostream *logStream,
1784 const bsl::string_view& memberName,
1785 FormattingMode formattingMode,
1786 bool isFirstMember)
1787{
1788 if (bdlat_FormattingMode::e_UNTAGGED & formattingMode) {
1789 *isPrefixEmpty = true;
1790 return 0; // RETURN
1791 }
1792
1793 int rc = ThisUtil::encodeMemberPrefix(formatter,
1794 logStream,
1795 memberName,
1796 isFirstMember);
1797 if (0 != rc) {
1798 return rc; // RETURN
1799 }
1800
1801 *isPrefixEmpty = false;
1802 return 0;
1803}
1804
1805 // ------------------------------
1806 // struct Encoder_ValueDispatcher
1807 // ------------------------------
1808
1809// CREATORS
1810inline
1812 Formatter *formatter,
1813 bsl::ostream *logStream,
1814 FormattingMode formattingMode,
1815 bool isNextObjectFirst,
1816 const EncoderOptions& options)
1817: d_formatter_p(formatter)
1818, d_logStream_p(logStream)
1819, d_options_p(&options)
1820, d_formattingMode(formattingMode)
1821, d_isNextObjectFirst(isNextObjectFirst)
1822{
1823}
1824
1825// ACCESSORS
1826inline
1829{
1830 d_isNextObjectFirst = false;
1831 return Encoder_EncodeImplUtil::encodeCharArray(d_formatter_p,
1832 value,
1833 *d_options_p);
1834}
1835
1836template <class TYPE>
1837inline
1840{
1841 const bool arrayIsEmpty = (0 == bdlat_ArrayFunctions::size(value));
1842
1843 if (arrayIsEmpty && !d_options_p->encodeEmptyArrays()) {
1844 d_isNextObjectFirst = true;
1845 return 0; // RETURN
1846 }
1847
1848 if (arrayIsEmpty && d_options_p->encodeEmptyArrays()) {
1850 d_isNextObjectFirst = false;
1851 return 0; // RETURN
1852 }
1853
1854 int rc = Encoder_EncodeImplUtil::encodeNonEmptyArray(d_formatter_p,
1855 d_logStream_p,
1856 value,
1857 *d_options_p);
1858 if (0 != rc) {
1859 return rc; // RETURN
1860 }
1861
1862 d_isNextObjectFirst = false;
1863 return 0;
1864}
1865
1866template <class TYPE>
1867inline
1870{
1871 int rc = Encoder_EncodeImplUtil::validateChoice(d_logStream_p, value);
1872 if (0 != rc) {
1873 return rc; // RETURN
1874 }
1875
1876 bool isPrefixEmpty = false;
1878 d_formatter_p,
1879 d_formattingMode);
1880
1881 Encoder_SelectionVisitor visitor(d_formatter_p,
1882 d_logStream_p,
1883 !isPrefixEmpty || d_isNextObjectFirst,
1884 *d_options_p);
1885 rc = bdlat_ChoiceFunctions::accessSelection(value, visitor);
1886 if (0 != rc) {
1887 return rc; // RETURN
1888 }
1889
1890 const bool isSelectionEmpty = visitor.isNextObjectFirst();
1891
1892 bool isSuffixEmpty = false;
1894 d_formatter_p,
1895 d_formattingMode);
1896
1897 d_isNextObjectFirst = isPrefixEmpty && isSelectionEmpty && isSuffixEmpty;
1898 return 0;
1899}
1900
1901template <class TYPE>
1902inline
1904 const TYPE& value,
1906{
1908 &d_isNextObjectFirst,
1909 d_formatter_p,
1910 d_logStream_p,
1912 d_formattingMode,
1913 *d_options_p,
1914 d_isNextObjectFirst);
1915}
1916
1917template <class TYPE>
1918inline
1924
1925template <class TYPE>
1926inline
1929{
1930 bsl::string valueString;
1931 bdlat_EnumFunctions::toString(&valueString, value);
1932
1933 d_isNextObjectFirst = false;
1934 return Encoder_EncodeImplUtil::encodeSimpleValue(d_formatter_p,
1935 valueString,
1936 *d_options_p);
1937}
1938
1939template <class TYPE>
1940inline
1942 const TYPE& value,
1944{
1946 d_formatter_p->putNullValue();
1947 d_isNextObjectFirst = false;
1948 return 0; // RETURN
1949 }
1950
1951 Encoder_ValueDispatcher visitor(d_formatter_p,
1952 d_logStream_p,
1953 d_formattingMode,
1954 d_isNextObjectFirst,
1955 *d_options_p);
1956
1957 int rc = bdlat::NullableValueUtil::accessValueByCategory(value, visitor);
1958 if (0 != rc) {
1959 return rc; // RETURN
1960 }
1961
1962 d_isNextObjectFirst = visitor.isNextObjectFirst();
1963 return 0;
1964}
1965
1966template <class TYPE>
1967inline
1970{
1971 bool isPrefixEmpty = false;
1973 d_formatter_p,
1974 d_formattingMode);
1975
1976 Encoder_AttributeVisitor visitor(d_formatter_p,
1977 d_logStream_p,
1978 !isPrefixEmpty || d_isNextObjectFirst,
1979 *d_options_p);
1980
1981 int rc = bdlat_SequenceFunctions::accessAttributes(value, visitor);
1982 if (0 != rc) {
1983 return rc; // RETURN
1984 }
1985
1986 const bool isAttributeEmpty = visitor.isNextAttributeFirst();
1987
1988 bool isSuffixEmpty = false;
1990 d_formatter_p,
1991 d_formattingMode);
1992
1993 d_isNextObjectFirst = isPrefixEmpty && isAttributeEmpty && isSuffixEmpty;
1994 return 0;
1995}
1996
1997template <class TYPE>
1998inline
2001{
2002 d_isNextObjectFirst = false;
2003 return Encoder_EncodeImplUtil::encodeSimpleValue(d_formatter_p,
2004 value,
2005 *d_options_p);
2006}
2007
2008template <class TYPE>
2009inline
2011{
2012 BSLS_ASSERT_OPT(0 == "Unreachable");
2013 return -1;
2014}
2015
2016// ACCESSORS
2017inline
2019{
2020 return d_isNextObjectFirst;
2021}
2022
2023 // ----------------------------
2024 // class Encoder_ElementVisitor
2025 // ----------------------------
2026
2027// CREATORS
2028inline
2030 Formatter *formatter,
2031 bsl::ostream *logStream,
2032 bool isNextElementFirst,
2033 const EncoderOptions& options)
2034: d_formatter_p(formatter)
2035, d_logStream_p(logStream)
2036, d_options_p(&options)
2037, d_isNextElementFirst(isNextElementFirst)
2038{
2039}
2040
2041// MANIPULATORS
2042template <class TYPE>
2043inline
2045{
2046 Encoder_ElementDispatcher dispatcher(d_formatter_p,
2047 d_logStream_p,
2048 d_isNextElementFirst,
2049 *d_options_p);
2050
2051 typedef typename bdlat_TypeCategory::Select<TYPE>::Type Category;
2052 int rc = dispatcher(element, Category());
2053 if (0 != rc) {
2054 return rc; // RETURN
2055 }
2056
2057 d_isNextElementFirst = dispatcher.isNextElementFirst();
2058 return 0;
2059}
2060
2061// ACCESSORS
2062inline
2064{
2065 return d_isNextElementFirst;
2066}
2067
2068 // -------------------------------
2069 // class Encoder_ElementDispatcher
2070 // -------------------------------
2071
2072// CREATORS
2073inline
2075 Formatter *formatter,
2076 bsl::ostream *logStream,
2077 bool isNextElementFirst,
2078 const EncoderOptions& options)
2079: d_formatter_p(formatter)
2080, d_logStream_p(logStream)
2081, d_options_p(&options)
2082, d_isNextElementFirst(isNextElementFirst)
2083{
2084}
2085
2086// MANIPULATORS
2087inline
2090{
2091 if (!d_isNextElementFirst) {
2092 d_formatter_p->addArrayElementSeparator();
2093 }
2094
2095 int rc = Encoder_EncodeImplUtil::encodeCharArray(d_formatter_p,
2096 element,
2097 *d_options_p);
2098 if (0 != rc) {
2099 return rc; // RETURN
2100 }
2101
2102 d_isNextElementFirst = false;
2103 return 0;
2104}
2105
2106template <class TYPE>
2109{
2110 const bool arrayIsEmpty = (0 == bdlat_ArrayFunctions::size(element));
2111
2112 if (arrayIsEmpty && !d_options_p->encodeEmptyArrays()) {
2113 return 0; // RETURN
2114 }
2115
2116 if (!d_isNextElementFirst) {
2117 d_formatter_p->addArrayElementSeparator();
2118 }
2119
2120 if (arrayIsEmpty && d_options_p->encodeEmptyArrays()) {
2122 d_isNextElementFirst = false;
2123 return 0; // RETURN
2124 }
2125
2126 int rc = Encoder_EncodeImplUtil::encodeNonEmptyArray(d_formatter_p,
2127 d_logStream_p,
2128 element,
2129 *d_options_p);
2130 if (0 != rc) {
2131 return rc; // RETURN
2132 }
2133
2134 d_isNextElementFirst = false;
2135 return 0;
2136}
2137
2138template <class TYPE>
2141{
2142 int rc = Encoder_EncodeImplUtil::validateChoice(d_logStream_p, element);
2143 if (0 != rc) {
2144 return rc; // RETURN
2145 }
2146
2147 if (!d_isNextElementFirst) {
2148 d_formatter_p->addArrayElementSeparator();
2149 }
2150
2151 d_formatter_p->openObject();
2152
2153 Encoder_SelectionVisitor visitor(d_formatter_p,
2154 d_logStream_p,
2155 true,
2156 *d_options_p);
2157 rc = bdlat_ChoiceFunctions::accessSelection(element, visitor);
2158 if (0 != rc) {
2159 return rc; // RETURN
2160 }
2161
2162 d_formatter_p->closeObject();
2163
2164 d_isNextElementFirst = false;
2165 return 0;
2166}
2167
2168template <class TYPE>
2177
2178template <class TYPE>
2180 const TYPE& element,
2182{
2183 return bdlat_TypeCategoryUtil::accessByCategory(element, *this);
2184}
2185
2186template <class TYPE>
2188 const TYPE& element,
2190{
2191 if (!d_isNextElementFirst) {
2192 d_formatter_p->addArrayElementSeparator();
2193 }
2194
2195 bsl::string valueString;
2196 bdlat_EnumFunctions::toString(&valueString, element);
2197
2198 d_isNextElementFirst = false;
2199 return Encoder_EncodeImplUtil::encodeSimpleValue(d_formatter_p,
2200 valueString,
2201 *d_options_p);
2202}
2203
2204template <class TYPE>
2206 const TYPE& element,
2208{
2209 const bool elementIsNull = bdlat_NullableValueFunctions::isNull(element);
2210
2211 if (elementIsNull) {
2212 if (!d_isNextElementFirst) {
2213 d_formatter_p->addArrayElementSeparator();
2214 }
2215
2216 d_formatter_p->putNullValue();
2217 d_isNextElementFirst = false;
2218 return 0; // RETURN
2219 }
2220
2221 Encoder_ElementVisitor visitor(d_formatter_p,
2222 d_logStream_p,
2223 d_isNextElementFirst,
2224 *d_options_p);
2225
2226 int rc = bdlat_NullableValueFunctions::accessValue(element, visitor);
2227 if (0 != rc) {
2228 return rc; // RETURN
2229 }
2230
2231 d_isNextElementFirst = visitor.isNextElementFirst();
2232 return 0;
2233}
2234
2235template <class TYPE>
2238{
2239 if (!d_isNextElementFirst) {
2240 d_formatter_p->addArrayElementSeparator();
2241 }
2242
2243 d_formatter_p->openObject();
2244
2245 Encoder_AttributeVisitor visitor(d_formatter_p,
2246 d_logStream_p,
2247 true,
2248 *d_options_p);
2249
2250 int rc = bdlat_SequenceFunctions::accessAttributes(element, visitor);
2251 if (0 != rc) {
2252 return rc; // RETURN
2253 }
2254
2255 d_formatter_p->closeObject();
2256
2257 d_isNextElementFirst = false;
2258 return 0;
2259}
2260
2261template <class TYPE>
2264{
2265 if (!d_isNextElementFirst) {
2266 d_formatter_p->addArrayElementSeparator();
2267 }
2268
2269 d_isNextElementFirst = false;
2270 return Encoder_EncodeImplUtil::encodeSimpleValue(d_formatter_p,
2271 element,
2272 *d_options_p);
2273}
2274
2275template <class TYPE>
2277{
2278 BSLS_ASSERT_OPT(0 == "Unreachable");
2279 return -1;
2280}
2281
2282// ACCESSORS
2283inline
2285{
2286 return d_isNextElementFirst;
2287}
2288
2289 // ------------------------------
2290 // class Encoder_SelectionVisitor
2291 // ------------------------------
2292
2293// CREATORS
2294inline
2296 Formatter *formatter,
2297 bsl::ostream *logStream,
2298 bool isNextObjectFirst,
2299 const EncoderOptions& options)
2300: d_formatter_p(formatter)
2301, d_logStream_p(logStream)
2302, d_isNextObjectFirst(isNextObjectFirst)
2303, d_options_p(&options)
2304{
2305}
2306
2307// MANIPULATORS
2308template <class TYPE, class SELECTION_INFO>
2309inline
2311 const SELECTION_INFO& selectionInfo)
2312{
2313 Encoder_SelectionDispatcher dispatcher(d_formatter_p,
2314 d_logStream_p,
2315 selectionInfo.name(),
2316 selectionInfo.formattingMode(),
2317 d_isNextObjectFirst,
2318 *d_options_p);
2319
2320 typedef typename bdlat_TypeCategory::Select<TYPE>::Type Category;
2321 int rc = dispatcher(selection, Category());
2322 if (0 != rc) {
2323 return rc; // RETURN
2324 }
2325
2326 d_isNextObjectFirst = dispatcher.isNextObjectFirst();
2327
2328 return 0;
2329}
2330
2331// ACCESSORS
2332inline
2334{
2335 return d_isNextObjectFirst;
2336}
2337
2338 // ---------------------------------
2339 // class Encoder_SelectionDispatcher
2340 // ---------------------------------
2341
2342// CREATORS
2343inline
2345 Formatter *formatter,
2346 bsl::ostream *logStream,
2347 const bsl::string_view& selectionName,
2348 FormattingMode formattingMode,
2349 bool isNextObjectFirst,
2350 const EncoderOptions& options)
2351: d_formatter_p(formatter)
2352, d_logStream_p(logStream)
2353, d_options_p(&options)
2354, d_selectionName(selectionName)
2355, d_formattingMode(formattingMode)
2356, d_isNextObjectFirst(isNextObjectFirst)
2357{
2358}
2359
2360// MANIPULATORS
2361template <class TYPE>
2362inline
2371
2372template <class TYPE>
2373inline
2375 const TYPE& selection,
2377{
2378 return bdlat_TypeCategoryUtil::accessByCategory(selection, *this);
2379}
2380
2381template <class TYPE, class CATEGORY>
2382inline
2384 CATEGORY category)
2385{
2386 return Encoder_EncodeImplUtil::encodeMember(&d_isNextObjectFirst,
2387 d_formatter_p,
2388 d_logStream_p,
2389 d_selectionName.data(),
2390 selection,
2391 d_formattingMode,
2392 *d_options_p,
2393 d_isNextObjectFirst,
2394 category);
2395}
2396
2397template <class TYPE>
2398inline
2400{
2401 BSLS_ASSERT_OPT(0 == "Unreachable");
2402 return -1;
2403}
2404
2405// ACCESSORS
2406inline
2408{
2409 return d_isNextObjectFirst;
2410}
2411
2412 // ------------------------------
2413 // class Encoder_AttributeVisitor
2414 // ------------------------------
2415
2416// CREATORS
2417inline
2419 Formatter *formatter,
2420 bsl::ostream *logStream,
2421 bool isNextAttributeFirst,
2422 const EncoderOptions& options)
2423: d_formatter_p(formatter)
2424, d_logStream_p(logStream)
2425, d_isNextAttributeFirst(isNextAttributeFirst)
2426, d_options_p(&options)
2427{
2428}
2429
2430// MANIPULATORS
2431template <class TYPE, class ATTRIBUTE_INFO>
2433 const ATTRIBUTE_INFO& attributeInfo)
2434{
2435 Encoder_AttributeDispatcher dispatcher(d_formatter_p,
2436 d_logStream_p,
2437 attributeInfo.name(),
2438 attributeInfo.formattingMode(),
2439 d_isNextAttributeFirst,
2440 *d_options_p);
2441
2442 typedef typename bdlat_TypeCategory::Select<TYPE>::Type Category;
2443 int rc = dispatcher(attribute, Category());
2444 if (0 != rc) {
2445 return -rc; // RETURN
2446 }
2447
2448 d_isNextAttributeFirst = dispatcher.isNextAttributeFirst();
2449 return 0;
2450}
2451
2452// ACCESSORS
2453inline
2455{
2456 return d_isNextAttributeFirst;
2457}
2458
2459 // ---------------------------------
2460 // class Encoder_AttributeDispatcher
2461 // ---------------------------------
2462
2463// CREATORS
2464inline
2466 Formatter *formatter,
2467 bsl::ostream *logStream,
2468 const bsl::string_view& attributeName,
2469 FormattingMode formattingMode,
2470 bool isNextAttributeFirst,
2471 const EncoderOptions& options)
2472: d_formatter_p(formatter)
2473, d_logStream_p(logStream)
2474, d_options_p(&options)
2475, d_attributeName(attributeName)
2476, d_formattingMode(formattingMode)
2477, d_isNextAttributeFirst(isNextAttributeFirst)
2478{
2479}
2480
2481// MANIPULATORS
2482inline
2484 const bsl::vector<char>& attribute,
2486{
2487 return Encoder_EncodeImplUtil::encodeMember(&d_isNextAttributeFirst,
2488 d_formatter_p,
2489 d_logStream_p,
2490 d_attributeName.data(),
2491 attribute,
2492 d_formattingMode,
2493 *d_options_p,
2494 d_isNextAttributeFirst,
2495 category);
2496}
2497
2498template <class TYPE>
2499inline
2501 const TYPE& attribute,
2503{
2504 const bool isArrayEmpty = (0 == bdlat_ArrayFunctions::size(attribute));
2505
2506 if (!d_options_p->encodeEmptyArrays() && isArrayEmpty) {
2507 return 0; // RETURN
2508 }
2509
2510 return Encoder_EncodeImplUtil::encodeMember(&d_isNextAttributeFirst,
2511 d_formatter_p,
2512 d_logStream_p,
2513 d_attributeName.data(),
2514 attribute,
2515 d_formattingMode,
2516 *d_options_p,
2517 d_isNextAttributeFirst,
2518 category);
2519}
2520
2521template <class TYPE>
2522inline
2531
2532template <class TYPE>
2533inline
2535 const TYPE& attribute,
2537{
2538 return bdlat_TypeCategoryUtil::accessByCategory(attribute, *this);
2539}
2540
2541template <class TYPE>
2542inline
2544 const TYPE& attribute,
2546{
2547 if (bdlat_NullableValueFunctions::isNull(attribute) &&
2548 !d_options_p->encodeNullElements()) {
2549 return 0; // RETURN
2550 }
2551
2552 return Encoder_EncodeImplUtil::encodeMember(&d_isNextAttributeFirst,
2553 d_formatter_p,
2554 d_logStream_p,
2555 d_attributeName.data(),
2556 attribute,
2557 d_formattingMode,
2558 *d_options_p,
2559 d_isNextAttributeFirst,
2560 category);
2561}
2562
2563template <class TYPE, class CATEGORY>
2564inline
2566 CATEGORY category)
2567{
2568 return Encoder_EncodeImplUtil::encodeMember(&d_isNextAttributeFirst,
2569 d_formatter_p,
2570 d_logStream_p,
2571 d_attributeName.data(),
2572 attribute,
2573 d_formattingMode,
2574 *d_options_p,
2575 d_isNextAttributeFirst,
2576 category);
2577}
2578
2579template <class TYPE>
2580inline
2582{
2583 BSLS_ASSERT_OPT(0 == "Unreachable");
2584 return -1;
2585}
2586
2587// ACCESSORS
2588inline
2590{
2591 return d_isNextAttributeFirst;
2592}
2593
2594// The 'Encoder_Formatter' 'class' has been replaced by the 'baljsn::Formatter'
2595// 'class' in the @ref baljsn_formatter component. Clients should use that
2596// 'class' instead. The following 'class' definition is provided for
2597// backwards-compatibility for users that have written code using this
2598// component-private 'class'.
2599
2600 // =======================
2601 // class Encoder_Formatter
2602 // =======================
2603
2604/// This class implements a formatter providing operations for rending JSON
2605/// text elements to an output stream (supplied at construction) according
2606/// to a set of formatting options (also supplied at construction). This is
2607/// a component-private class and should not be used outside of this
2608/// component.
2609///
2610/// @deprecated Use @ref baljsn::Formatter instead.
2611///
2612/// See @ref baljsn_encoder
2614
2615 // DATA
2616 bsl::ostream& d_outputStream; // stream for output (held, not owned)
2617 bool d_usePrettyStyle; // encoding style
2618 int d_indentLevel; // initial indent level
2619 int d_spacesPerLevel; // spaces per level
2620 bool d_isArrayElement; // is current element part of an array
2621
2622 public:
2623 // CREATORS
2624
2625 /// Create a `Encoder_Formatter` object using the specified `stream` and
2626 /// `options`.
2627 Encoder_Formatter(bsl::ostream& stream, const EncoderOptions& options);
2628
2630 // Destroy this object.
2631
2632 // MANIPULATORS
2633
2634 /// Print onto the stream supplied at construction the sequence of
2635 /// characters designating the start of an object.
2637
2638 /// Print onto the stream supplied at construction the sequence of
2639 /// characters designating the end of an object.
2641
2642 /// Print onto the stream supplied at construction the sequence of
2643 /// characters designating the start of an array. Optionally specify
2644 /// `formatAsEmptyArrayFlag` denoting if the array being opened should
2645 /// be formatted as an empty array. If `formatAsEmptyArrayFlag` is not
2646 /// specified then the array being opened is formatted as an array
2647 /// having elements. Note that the formatting (and as a consequence the
2648 /// `formatAsEmptyArrayFlag`) is relevant only if this formatter encodes
2649 /// in the pretty style and is ignored otherwise.
2650 void openArray(bool formatAsEmptyArrayFlag = false);
2651
2652 /// Print onto the stream supplied at construction the sequence of
2653 /// characters designating the end of an array. Optionally specify
2654 /// `formatAsEmptyArrayFlag` denoting if the array being closed should
2655 /// be formatted as an empty array. If `formatAsEmptyArrayFlag` is not
2656 /// specified then the array being closed is formatted as an array
2657 /// having elements. Note that the formatting (and as a consequence the
2658 /// `formatAsEmptyArrayFlag`) is relevant only if this formatter encodes
2659 /// in the pretty style and is ignored otherwise.
2660 void closeArray(bool formatAsEmptyArrayFlag = false);
2661
2662 /// Print onto the stream supplied at construction the sequence of
2663 /// whitespace characters for the proper indentation of an element given
2664 /// the encoding options supplied at construction.
2665 void indent();
2666
2667 /// Print onto the stream supplied at construction the sequence of
2668 /// characters designating the start of an element having the specified
2669 /// `name`. Return 0 on success and a non-zero value otherwise.
2670 int openElement(const bsl::string& name);
2671
2672 /// Print onto the stream supplied at construction the sequence of
2673 /// characters designating the end of an element.
2675
2676 /// Print onto the stream supplied at construction the sequence of
2677 /// characters designating the start of the document.
2679
2680 /// Print onto the stream supplied at construction the sequence of
2681 /// characters designating the end of the document.
2683
2684 /// Set the flag denoting if the current element refers to an array
2685 /// element to the specified `isArrayElement`.
2687
2688 // ACCESSORS
2689
2690 /// Return the value of the flag denoting if the current element refers
2691 /// to an array element.
2692 bool isArrayElement() const;
2693};
2694
2695 // -----------------------
2696 // class Encoder_Formatter
2697 // -----------------------
2698
2699// MANIPULATORS
2700inline
2702{
2703 d_isArrayElement = isArrayElement;
2704}
2705
2706// ACCESSORS
2707inline
2709{
2710 return d_isArrayElement;
2711}
2712
2713} // close package namespace
2714
2715
2716#endif
2717
2718// ----------------------------------------------------------------------------
2719// Copyright 2015 Bloomberg Finance L.P.
2720//
2721// Licensed under the Apache License, Version 2.0 (the "License");
2722// you may not use this file except in compliance with the License.
2723// You may obtain a copy of the License at
2724//
2725// http://www.apache.org/licenses/LICENSE-2.0
2726//
2727// Unless required by applicable law or agreed to in writing, software
2728// distributed under the License is distributed on an "AS IS" BASIS,
2729// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2730// See the License for the specific language governing permissions and
2731// limitations under the License.
2732// ----------------------------- END-OF-FILE ----------------------------------
2733
2734/** @} */
2735/** @} */
2736/** @} */
Definition baljsn_encoderoptions.h:262
@ e_PRETTY
Definition baljsn_encoderoptions.h:316
bool encodeNullElements() const
Definition baljsn_encoderoptions.h:941
baljsn::EncoderOptions::EncodingStyle encodingStyle() const
Definition baljsn_encoderoptions.h:929
int initialIndentLevel() const
Definition baljsn_encoderoptions.h:917
int spacesPerLevel() const
Definition baljsn_encoderoptions.h:923
bool encodeEmptyArrays() const
Definition baljsn_encoderoptions.h:935
Definition baljsn_encoder.h:1191
int FormattingMode
Definition baljsn_encoder.h:1202
bool isNextAttributeFirst() const
Definition baljsn_encoder.h:2589
int operator()(const bsl::vector< char > &attribute, bdlat_TypeCategory::Array category)
Definition baljsn_encoder.h:2483
Encoder_AttributeDispatcher(Formatter *formatter, bsl::ostream *logStream, const bsl::string_view &attributeName, FormattingMode formattingMode, bool isNextAttributeFirst, const EncoderOptions &options)
Definition baljsn_encoder.h:2465
Definition baljsn_encoder.h:1101
int operator()(const TYPE &attribute, const ATTRIBUTE_INFO &attributeInfo)
Definition baljsn_encoder.h:2432
int FormattingMode
Definition baljsn_encoder.h:1112
Encoder_AttributeVisitor(Formatter *formatter, bsl::ostream *logStream, bool isNextAttributeFirst, const EncoderOptions &options)
Definition baljsn_encoder.h:2418
bool isNextAttributeFirst() const
Definition baljsn_encoder.h:2454
Definition baljsn_encoder.h:805
Encoder_ElementDispatcher(Formatter *formatter, bsl::ostream *logStream, bool isNextElementFirst, const EncoderOptions &options)
Definition baljsn_encoder.h:2074
int operator()(const bsl::vector< char > &element, bdlat_TypeCategory::Array category)
Definition baljsn_encoder.h:2088
bool isNextElementFirst() const
Definition baljsn_encoder.h:2284
Definition baljsn_encoder.h:729
bool isNextElementFirst() const
Definition baljsn_encoder.h:2063
Encoder_ElementVisitor(Formatter *formatter, bsl::ostream *logStream, bool isNextElementFirst, const EncoderOptions &options)
Definition baljsn_encoder.h:2029
int operator()(const TYPE &element)
Definition baljsn_encoder.h:2044
Definition baljsn_encoder.h:2613
void openArray(bool formatAsEmptyArrayFlag=false)
int openElement(const bsl::string &name)
void setIsArrayElement(bool isArrayElement)
Definition baljsn_encoder.h:2701
void closeArray(bool formatAsEmptyArrayFlag=false)
bool isArrayElement() const
Definition baljsn_encoder.h:2708
Encoder_Formatter(bsl::ostream &stream, const EncoderOptions &options)
Definition baljsn_encoder.h:994
int operator()(const TYPE &selection, bdlat_TypeCategory::CustomizedType category)
Definition baljsn_encoder.h:2363
Encoder_SelectionDispatcher(Formatter *formatter, bsl::ostream *logStream, const bsl::string_view &selectionName, FormattingMode formattingMode, bool isNextObjectFirst, const EncoderOptions &options)
Definition baljsn_encoder.h:2344
bool isNextObjectFirst() const
Definition baljsn_encoder.h:2407
int FormattingMode
Definition baljsn_encoder.h:1005
Definition baljsn_encoder.h:904
int FormattingMode
Definition baljsn_encoder.h:915
bool isNextObjectFirst() const
Definition baljsn_encoder.h:2333
int operator()(const TYPE &selection, const SELECTION_INFO &selectionInfo)
Definition baljsn_encoder.h:2310
Encoder_SelectionVisitor(Formatter *formatter, bsl::ostream *logStream, bool isNextObjectFirst, const EncoderOptions &options)
Definition baljsn_encoder.h:2295
Definition baljsn_encoder.h:615
Encoder_ValueDispatcher(Formatter *formatter, bsl::ostream *logStream, FormattingMode formattingMode, bool isNextObjectFirst, const EncoderOptions &options)
Definition baljsn_encoder.h:1811
bool isNextObjectFirst() const
Definition baljsn_encoder.h:2018
int FormattingMode
Definition baljsn_encoder.h:626
int operator()(const bsl::vector< char > &value, bdlat_TypeCategory::Array category)
Definition baljsn_encoder.h:1827
Definition baljsn_encoder.h:225
int encode(bsl::streambuf *streamBuf, const TYPE &value, const EncoderOptions &options)
Definition baljsn_encoder.h:1331
~Encoder()=default
Destroy this object.
bsl::string loggedMessages() const
Definition baljsn_encoder.h:1419
Definition baljsn_formatter.h:255
int openMember(const bsl::string_view &name)
void closeArray(bool formatAsEmptyArray=false)
void openArray(bool formatAsEmptyArray=false)
int putValue(const TYPE &value, const EncoderOptions *options=0)
Definition baljsn_formatter.h:419
void putNullValue()
Definition baljsn_formatter.h:410
void addArrayElementSeparator()
int nestingDepth() const
Return the number of currently open nested objects or arrays.
Definition baljsn_formatter.h:429
Definition bdlsb_memoutstreambuf.h:212
Definition bslstl_ostringstream.h:175
void str(const StringType &value)
Definition bslstl_ostringstream.h:581
Definition bslstl_stringview.h:441
BSLS_KEYWORD_CONSTEXPR const_pointer data() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_stringview.h:1760
Definition bslstl_string.h:1281
Definition bslstl_vector.h:1025
Definition bslma_allocator.h:457
static int accessByCategory(const TYPE &object, ACCESSOR &accessor)
Definition bdlat_typecategory.h:1444
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_ASSERT_OPT(X)
Definition bsls_assert.h:1856
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition baljsn_datumdecoderoptions.h:113
bsl::size_t size(const TYPE &array)
Return the number of elements in the specified array.
int accessElement(const TYPE &array, ACCESSOR &accessor, int index)
int accessSelection(const TYPE &object, ACCESSOR &accessor)
@ k_UNDEFINED_SELECTION_ID
Definition bdlat_choicefunctions.h:511
int selectionId(const TYPE &object)
const BaseType< TYPE >::Type & convertToBaseType(const TYPE &object)
void toString(bsl::string *result, const TYPE &value)
bool isNull(const TYPE &object)
int accessValue(const TYPE &object, ACCESSOR &accessor)
int accessAttributes(const TYPE &object, ACCESSOR &accessor)
bdlat_TypeCategory::Value select(const TYPE &object)
Definition baljsn_encoder.h:316
Encoder_EncodeImplUtil ThisUtil
ThisUtil is a convenience alias for this utility struct.
Definition baljsn_encoder.h:321
int FormattingMode
Definition baljsn_encoder.h:329
static void openDocument(bsl::ostream *outputStream, const EncoderOptions &options)
Definition baljsn_encoder.h:1433
static int validateChoice(bsl::ostream *logStream, const TYPE &value)
Definition baljsn_encoder.h:1544
static int encodeMember(bool *isMemberEmpty, Formatter *formatter, bsl::ostream *logStream, const bsl::string_view &memberName, const bsl::vector< char > &member, FormattingMode formattingMode, const EncoderOptions &options, bool isFirstMember, bdlat_TypeCategory::Array category)
static void encodeObjectPrefix(bool *isPrefixEmpty, Formatter *formatter, FormattingMode formattingMode)
Definition baljsn_encoder.h:1570
static int encode(bsl::ostream *jsonStream, const TYPE &value, const EncoderOptions &options=EncoderOptions())
Definition baljsn_encoder.h:1457
static int encodeSimpleValue(Formatter *formatter, const TYPE &value, const EncoderOptions &options)
Definition baljsn_encoder.h:1560
static void encodeObjectSuffix(bool *isSuffixEmpty, Formatter *formatter, FormattingMode formattingMode)
Definition baljsn_encoder.h:1585
static int encodeCharArray(Formatter *formatter, const bsl::vector< char > &value, const EncoderOptions &options)
static int encodeNonEmptyArray(Formatter *formatter, bsl::ostream *logStream, const TYPE &value, const EncoderOptions &options)
Definition baljsn_encoder.h:1609
static int encodeMemberPrefix(Formatter *formatter, bsl::ostream *logStream, const bsl::string_view &memberName, bool isFirstMember)
Definition baljsn_encoder.h:1741
static int validate(bsl::ostream *logStream, const TYPE &value, bdlat_TypeCategory::Choice category)
Definition baljsn_encoder.h:1529
static void closeDocument(bsl::ostream *outputStream, const EncoderOptions &options)
Definition baljsn_encoder.h:1444
static void encodeEmptyArray(Formatter *formatter)
Definition baljsn_encoder.h:1602
static int accessValueByCategory(const TYPE &object, ACCESSOR &accessor)
Definition bdlat_nullablevalueutil.h:323
@ e_DEFAULT
Definition bdlat_formattingmode.h:110
@ e_UNTAGGED
Definition bdlat_formattingmode.h:118
Definition bdlat_typecategory.h:1035
Definition bdlat_typecategory.h:1036
Definition bdlat_typecategory.h:1037
Definition bdlat_typecategory.h:1034
Definition bdlat_typecategory.h:1038
Definition bdlat_typecategory.h:1039
Definition bdlat_typecategory.h:1040
Definition bdlat_typecategory.h:1041
Value
Definition bdlat_typecategory.h:1044
@ e_ARRAY_CATEGORY
Definition bdlat_typecategory.h:1046
@ e_CHOICE_CATEGORY
Definition bdlat_typecategory.h:1047
@ e_SEQUENCE_CATEGORY
Definition bdlat_typecategory.h:1051
static bsl::ostream & indent(bsl::ostream &stream, int level, int spacesPerLevel=4)
This struct is empty and represents a nil type.
Definition bslmf_nil.h:131