BDE 4.14.0 Production release
Loading...
Searching...
No Matches
balxml_encoder.h
Go to the documentation of this file.
1/// @file balxml_encoder.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// balxml_encoder.h -*-C++-*-
8#ifndef INCLUDED_BALXML_ENCODER
9#define INCLUDED_BALXML_ENCODER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup balxml_encoder balxml_encoder
15/// @brief Provide an XML encoder utility.
16/// @addtogroup bal
17/// @{
18/// @addtogroup balxml
19/// @{
20/// @addtogroup balxml_encoder
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#balxml_encoder-purpose"> Purpose</a>
25/// * <a href="#balxml_encoder-classes"> Classes </a>
26/// * <a href="#balxml_encoder-description"> Description </a>
27/// * <a href="#balxml_encoder-usage"> Usage </a>
28///
29/// # Purpose {#balxml_encoder-purpose}
30/// Provide an XML encoder utility.
31///
32/// # Classes {#balxml_encoder-classes}
33///
34/// - balxml::Encoder: XML encoder utility class
35///
36/// @see balxml_decoder, balber_berencoder
37///
38/// # Description {#balxml_encoder-description}
39/// This component provides a class for encoding value-semantic
40/// objects in XML format. In particular, the `balxml::Encoder` `class`
41/// contains a parameterized `encode` function that encodes a specified
42/// value-semantic object into a specified stream. There are three overloaded
43/// versions of this function:
44///
45/// * writes to an `bsl::streambuf`
46/// * writes to an `bsl::ostream`
47/// * writes to an `balxml::Formatter`
48///
49/// The `encode` function encodes objects in XML format, which is a very useful
50/// format for debugging. For more efficient performance, a binary encoding
51/// (such as BER) should be used.
52///
53/// This component can be used with types supported by the `bdlat` framework.
54/// In particular, types generated by the `bas_codegen.pl` tool can be used.
55///
56/// ## Usage {#balxml_encoder-usage}
57///
58///
59/// The following snippets of code illustrate the usage of this component.
60/// Suppose we have an XML schema inside a file named `employee.xsd`:
61/// @code
62/// <?xml version='1.0' encoding='UTF-8'?>
63/// <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
64/// xmlns:test='http://bloomberg.com/schemas/test'
65/// targetNamespace='http://bloomberg.com/schemas/test'
66/// elementFormDefault='unqualified'>
67///
68/// <xs:complexType name='Address'>
69/// <xs:sequence>
70/// <xs:element name='street' type='xs:string'/>
71/// <xs:element name='city' type='xs:string'/>
72/// <xs:element name='state' type='xs:string'/>
73/// </xs:sequence>
74/// </xs:complexType>
75///
76/// <xs:complexType name='Employee'>
77/// <xs:sequence>
78/// <xs:element name='name' type='xs:string'/>
79/// <xs:element name='homeAddress' type='test:Address'/>
80/// <xs:element name='age' type='xs:int'/>
81/// </xs:sequence>
82/// </xs:complexType>
83/// </xs:schema>
84/// @endcode
85/// Using the `bas_codegen.pl` tool, we generate C++ classes for this schema as
86/// follows:
87/// @code
88/// $ bas_codegen.pl -m msg -p test employee.xsd
89/// @endcode
90/// This tool will generate the header and implementation files for the
91/// @ref test_messages components in the current directory.
92///
93/// Now suppose we wanted to encode information about a particular employee
94/// using XML encoding to the standard output, and using the `PRETTY` option for
95/// formatting the output. The following function will do this:
96/// @code
97/// #include <test_messages.h>
98///
99/// #include <balxml_encoder.h>
100/// #include <balxml_encodingstyle.h>
101///
102/// #include <bsl_iostream.h>
103/// #include <bsl_sstream.h>
104///
105/// using namespace BloombergLP;
106///
107/// void usageExample()
108/// {
109/// test::Employee bob;
110///
111/// bob.name() = "Bob";
112/// bob.homeAddress().street() = "Some Street";
113/// bob.homeAddress().city() = "Some City";
114/// bob.homeAddress().state() = "Some State";
115/// bob.age() = 21;
116///
117/// balxml::EncoderOptions options;
118/// options.setEncodingStyle(balxml::EncodingStyle::BAEXML_PRETTY);
119///
120/// balxml::Encoder encoder(&options, &bsl::cerr, &bsl::cerr);
121///
122/// const bsl::string EXPECTED_OUTPUT =
123/// "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
124/// "<Employee xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n"
125/// " <name>Bob</name>\n"
126/// " <homeAddress>\n"
127/// " <street>Some Street</street>\n"
128/// " <city>Some City</city>\n"
129/// " <state>Some State</state>\n"
130/// " </homeAddress>\n"
131/// " <age>21</age>\n"
132/// "</Employee>\n";
133///
134/// bsl::ostringstream os;
135/// const int rc = encoder.encodeToStream(os, bob);
136///
137/// assert(0 == rc);
138/// assert(EXPECTED_OUTPUT == os.str());
139/// }
140/// @endcode
141/// @}
142/** @} */
143/** @} */
144
145/** @addtogroup bal
146 * @{
147 */
148/** @addtogroup balxml
149 * @{
150 */
151/** @addtogroup balxml_encoder
152 * @{
153 */
154
155#include <balscm_version.h>
156
158#include <balxml_encodingstyle.h>
159#include <balxml_errorinfo.h> // for Severity
160#include <balxml_formatter.h>
162
163#include <bdlat_arrayfunctions.h>
167#include <bdlat_typecategory.h>
168#include <bdlat_typename.h>
169
171
172#include <bslma_allocator.h>
173#include <bslma_default.h>
175
177
178#include <bsls_assert.h>
179#include <bsls_keyword.h>
180#include <bsls_objectbuffer.h>
181#include <bsls_review.h>
182
183#include <bsl_ostream.h>
184#include <bsl_string.h>
185#include <bsl_vector.h>
186
187
188namespace balxml {
189
190class Encoder_Context;
191
192 // =============
193 // class Encoder
194 // =============
195
196/// This `class` contains the parameterized `encode` functions that encode
197/// `bdlat` types in XML format.
198///
199/// See @ref balxml_encoder
200class Encoder {
201
202 // FRIENDS
203 friend class Encoder_Context;
204
205 private:
206 // PRIVATE TYPES
207
208 /// This class provides stream for logging using
209 /// `bdlsb::MemOutStreamBuf` as a streambuf. The logging stream is
210 /// created on demand, i.e., during the first attempt to log message.
211 class MemOutStream : public bsl::ostream
212 {
214
215 // Not implemented:
216 MemOutStream(const MemOutStream&);
217 MemOutStream& operator=(const MemOutStream&);
218
219 public:
220 // CREATORS
221
222 /// Create a new stream using the optionally specified
223 /// `basicAllocator`.
224 MemOutStream(bslma::Allocator *basicAllocator = 0);
225
226 /// Destroy this stream and release memory back to the allocator.
227 ///
228 /// Although the compiler should generate this destructor
229 /// implicitly, xlC 8 breaks when the destructor is called by name
230 /// unless it is explicitly declared.
231 ~MemOutStream() BSLS_KEYWORD_OVERRIDE;
232
233 // MANIPULATORS
234
235 /// Reset the internal streambuf to empty.
236 void reset();
237
238 // ACCESSORS
239
240 /// Return a pointer to the memory containing the formatted values
241 /// formatted to this stream. The data is not null-terminated
242 /// unless a null character was appended onto this stream.
243 const char *data() const;
244
245 /// Return the length of the formatted data, including null
246 /// characters appended to the stream, if any.
247 int length() const;
248 };
249
250 private:
251 // DATA
252 const EncoderOptions *d_options; // held, not owned
253 bslma::Allocator *d_allocator; // held, not owned
254
255 // placeholder for MemOutStream
256 bsls::ObjectBuffer<MemOutStream> d_logArea;
257
258 // if not zero, log stream was created at the moment of first logging
259 // and must be destroyed
260 MemOutStream *d_logStream;
261
262 ErrorInfo::Severity d_severity; // error severity
263
264 bsl::ostream *d_errorStream; // held, not owned
265 bsl::ostream *d_warningStream; // held, not owned
266
267 // PRIVATE MANIPULATORS
268 ErrorInfo::Severity logError(const char *text,
269 const bsl::string_view& tag,
270 int formattingMode,
271 int index = -1);
272
273 /// Return the stream for logging. Note the if stream has not been
274 /// created yet, it will be created during this call.
275 bsl::ostream& logStream();
276
277 public:
278 // TRAITS
280
281 // CREATORS
282 Encoder(const EncoderOptions *options, bslma::Allocator *basicAllocator);
283
284 /// Construct a encoder object using the specified `options`. Errors
285 /// and warnings will be rendered to the optionally specified
286 /// `errorStream` and `warningStream` respectively.
288 bsl::ostream *errorStream = 0,
289 bsl::ostream *warningStream = 0,
290 bslma::Allocator *basicAllocator = 0);
291
292 /// Destroy this object. This destruction has no effect on objects
293 /// pointed-to by the pointers provided at construction.
295
296 /// Encode the specified non-modifiable `object` to the specified
297 /// `buffer`. Return 0 on success, and a non-zero value otherwise.
298 /// Note that the encoder will use encoder options, error and warning
299 /// streams specified at the construction time.
300 template <class TYPE>
301 int encode(bsl::streambuf *buffer, const TYPE& object);
302
303 /// Encode the specified non-modifiable `object` to the specified
304 /// `stream`. Return 0 on success, and a non-zero value otherwise.
305 /// Note that the encoder will use encoder options, error and warning
306 /// streams specified at the construction time.
307 template <class TYPE>
308 int encodeToStream(bsl::ostream& stream, const TYPE& object);
309
310 /// Encode the specified non-modifiable `object` to the specified
311 /// `stream`. Return a reference to `stream`. If an encoding error is
312 /// detected, `stream.fail()` will be true on return. Note that the
313 /// encoder will use encoder options, error and warning streams
314 /// specified at the construction time. IMPORTANT: The use of
315 /// `stream.fail()` to communicate errors to the caller has two
316 /// consequences: 1) if `stream` is the same as the `errorStream`
317 /// passed to the constructor, then the error message may be suppressed
318 /// (because of the output/error stream becoming invalidated) and 2) it
319 /// is important to call `stream.clear()` after testing the stream
320 /// state. To avoid these issues, we recommend that you use use
321 /// `encodeToStream`, above, instead of this version of `encode`.
322 template <class TYPE>
323 bsl::ostream& encode(bsl::ostream& stream, const TYPE& object);
324
325 /// Encode the specified non-modifiable `object` to the specified
326 /// `formatter`. Return 0 on success, and a non-zero value otherwise.
327 /// Note that encoder will use encoder options, error and warning
328 /// streams specified at the construction time.
329 template <class TYPE>
330 int encode(Formatter& formatter, const TYPE& object);
331
332 //ACCESSORS
333
334 /// Return the encoder options.
335 const EncoderOptions *options() const;
336
337 /// Return `true` if the encoding style in the encoder options is
338 /// defined as `EncodingStyle::BAEXML_COMPACT`, and `false` otherwise.
339 bool isCompact() const;
340
341 /// Return pointer to the error stream.
342 bsl::ostream *errorStream() const;
343
344 /// Return pointer to the warning stream.
345 bsl::ostream *warningStream() const;
346
347 /// Return the severity of the most severe warning or error encountered
348 /// during the last call to the `encode` method. The severity is reset
349 /// each time `encode` is called.
350 ErrorInfo::Severity errorSeverity() const;
351
352 /// Return a string containing any error, warning, or trace messages
353 /// that were logged during the last call to the `encode` method. The
354 /// log is reset each time `encode` is called.
355 bslstl::StringRef loggedMessages() const;
356};
357
358// ---- Anything below this line is implementation specific. Do not use. ----
359
360 // ======================
361 // struct Encoder_Context
362 // ======================
363
364/// This `struct` contains state that is maintained during encoding. It
365/// also contains methods for switching between pretty formatting and
366/// compact formatting, based on the encoding options.
367///
368/// See @ref balxml_encoder
370
371 // DATA
372 Formatter *d_formatter;
373 Encoder *d_encoder;
374
375 // NOT IMPLEMENTED
376 Encoder_Context(const Encoder_Context& other);
377 Encoder_Context& operator=(const Encoder_Context& other);
378
379 public:
380 // CREATORS
381 Encoder_Context(Formatter *formatter, Encoder *encoder);
382
383 // MANIPULATORS
384 template <class NAME_TYPE, class VALUE_TYPE>
385 void addAttribute(const NAME_TYPE& name, const VALUE_TYPE& value);
386
387 template<class NAME_TYPE, class VALUE_TYPE>
388 void addAttribute(const NAME_TYPE& name,
389 const VALUE_TYPE& value,
390 int formattingMode);
391
392 template <class NAME_TYPE>
393 void closeElement(const NAME_TYPE& name);
394
395 void invalidate();
396
397 ErrorInfo::Severity logError(const char *text,
398 const bsl::string_view& tag,
399 int formattingMode,
400 int index = -1);
401
402 template <class NAME_TYPE>
403 void openElement(const NAME_TYPE& name);
404
405 bsl::ostream& rawOutputStream();
406
407 // ACCESSORS
408 const EncoderOptions& encoderOptions() const;
409
410 int status() const;
411};
412
413 // =======================================
414 // struct Encoder_OptionsCompatibilityUtil
415 // =======================================
416
417/// Component-private `struct`. Do not use.
418///
419/// This struct provides a namespace for a suite of functions used to
420/// compute the options for the underlying XML formatter used by the
421/// encoder, given the encoder's options.
423
424 private:
425 // PRIVATE CLASS METHODS
426
427 /// Return the value of the `InitialIndentLevel` field for a
428 /// `FormatterOptions` object that corresponds to the specified
429 /// `encoderOptions`, which is 0 if the `EncodingStyle` of
430 /// `encoderOptions` is `EncodingStyle::e_COMPACT`, and is the value of
431 /// `InitialIndentLevel` of `encoderOptions` otherwise.
432 static int getFormatterInitialIndentLevel(
433 const EncoderOptions& encoderOptions);
434
435 /// Return the value of the `SpacesPerLevel` field for a
436 /// `FormatterOptions` object that corresponds to the specified
437 /// `encoderOptions`, which is 0 if the `EncodingStyle` of
438 /// `encoderOptions` is `EncodingStyle::e_COMPACT`, and is the value of
439 /// `SpacesPerLevel` of `encoderOptions` otherwise.
440 static int getFormatterSpacesPerLevel(
441 const EncoderOptions& encoderOptions);
442
443 /// Return the value of the `WrapColumn` field for a
444 /// `FormatterOptions` object that corresponds to the specified
445 /// `encoderOptions`, which is -1 if the `EncodingStyle` of
446 /// `encoderOptions` is `EncodingStyle::e_COMPACT`, and is the value of
447 /// `WrapColumn` of `encoderOptions` otherwise.
448 static int getFormatterWrapColumn(const EncoderOptions& encoderOptions);
449
450 public:
451 // CLASS METHODS
452
453 /// Load to the specified `formatterIndentLevel`,
454 /// `formatterSpacesPerLevel`, and `formatterWrapColumn`, the number of
455 /// spaces to indent the first element in the XML document, the number
456 /// of spaces to use for indenting each level of nesting in the
457 /// document, and the maximum horizontal column number after which the
458 /// encoder should insert a line break, respectively, based on the
459 /// specified `encoderOptions`. Load to the specified
460 /// `formatterOptions` the options that the formatter should use to emit
461 /// XML, based on the `encoderOptions`. The behavior is undefined
462 /// unless `formatterOptions` has the default value.
464 int *formatterIndentLevel,
465 int *formatterSpacesPerLevel,
466 int *formatterWrapColumn,
467 EncoderOptions *formatterOptions,
468 const EncoderOptions& encoderOptions);
469};
470
471 // ==========================
472 // class Encoder_EncodeObject
473 // ==========================
474
475/// Component-private class. Do not use.
476///
477/// This struct encodes an object *with* enclosing tags. Compared to the
478/// `EncoderUtil_EncodeValue` class below, this class prefixes the value
479/// with an opening tag, and suffixes the value with a closing tag. In
480/// pseudocode, this is equivalent to:
481/// @code
482/// openTag()
483/// Encoder_EncodeValue()
484/// closeTag()
485/// @endcode
486/// There is an overloaded version of `bsl::vector<char>` because, based on
487/// the formatting mode, this class needs to switch between encoding the
488/// value in a single tag (i.e., when using BASE64, TEXT, IS_LIST or HEX)
489/// and encoding the value in multiple tags (i.e., when repetition is used).
490///
491/// See @ref balxml_encoder
493
494 // PRIVATE TYPES
495 struct CanBeListOrRepetition { };
496 struct CanBeRepetitionOnly { };
497
498 // PRIVATE DATA MEMBERS
499 Encoder_Context *d_context_p;
500
501 public:
502 // IMPLEMENTATION MANIPULATORS
503 template <class TYPE>
504 int executeImp(const TYPE& object,
505 const bsl::string_view& tag,
506 int formattingMode,
508
509 template <class TYPE>
510 int executeImp(const TYPE& object,
511 const bsl::string_view& tag,
512 int formattingMode,
514
515 template <class TYPE>
516 int executeImp(const TYPE& object,
517 const bsl::string_view& tag,
518 int formattingMode,
520
521 template <class TYPE, class ANY_CATEGORY>
522 int executeImp(const TYPE& object,
523 const bsl::string_view& tag,
524 int formattingMode,
525 ANY_CATEGORY);
526
527 int executeImp(const bsl::vector<char>& object,
528 const bsl::string_view& tag,
529 int formattingMode,
531
532 template <class TYPE>
533 int executeArrayListImp(const TYPE& object, const bsl::string_view& tag);
534
535 template <class TYPE>
536 int executeArrayRepetitionImp(const TYPE& object,
537 const bsl::string_view& tag,
538 int formattingMode);
539
540 private:
541 // NOT IMPLEMENTED
544
545 public:
546 // CREATORS
547 explicit Encoder_EncodeObject(Encoder_Context *context);
548
549 // Using compiler generated destructor:
550 // ~Encoder_EncodeObject();
551
552 // MANIPULATORS
553 template <class TYPE, class INFO_TYPE>
554 int operator()(const TYPE& object, const INFO_TYPE& info);
555
556 template <class TYPE>
557 int execute(const TYPE& object,
558 const bsl::string_view& tag,
559 int formattingMode);
560};
561
562 // =========================
563 // class Encoder_EncodeValue
564 // =========================
565
566/// Component-private class. Do not use.
567///
568/// This class just encodes a value *without* any enclosing tags.
569///
570/// See @ref balxml_encoder
572
573 // PRIVATE DATA MEMBERS
574 Encoder_Context *d_context_p;
575
576 public:
577 // IMPLEMENTATION MANIPULATORS
578 template <class TYPE>
579 int executeImp(const TYPE& object,
580 int formattingMode,
582
583 template <class TYPE>
584 int executeImp(const TYPE& object,
585 int formattingMode,
587
588 template <class TYPE>
589 int executeImp(const TYPE& object,
590 int formattingMode,
592
593 template <class TYPE, class ANY_CATEGORY>
594 int executeImp(const TYPE& object, int formattingMode, ANY_CATEGORY);
595
596 private:
597 // NOT IMPLEMENTED
599 Encoder_EncodeValue& operator=(const Encoder_EncodeValue&);
600
601 public:
602 // CREATORS
603 explicit Encoder_EncodeValue(Encoder_Context *context);
604
605 // Using compiler generated destructor:
606 // ~Encoder_EncodeValue();
607
608 // MANIPULATORS
609 template <class TYPE, class INFO_TYPE>
610 int operator()(const TYPE& object, const INFO_TYPE& info);
611
612 template <class TYPE>
613 int execute(const TYPE& object, int formattingMode);
614};
615
616 // ===============================
617 // class Encoder_SequenceFirstPass
618 // ===============================
619
620/// Component private class. Do not use.
621///
622/// This class is used as the first pass when encoding elements of a
623/// sequence. It basically does two things:
624/// o encode elements with the
625/// `bdlat_FormattingMode::e_IS_ATTRIBUTE` flag using the
626/// `Formatter::addAttribute` method.
627/// o looks for an element with the
628/// `bdlat_FormattingMode::e_IS_SIMPLE_CONTENT` flag and, if
629/// found, provides accessors to obtain the `id` of the element.
630/// Note that the behavior is undefined unless there is only one
631/// element with `IS_SIMPLE_CONTENT` flag and, if this element exist,
632/// all other elements must have `IS_ATTRIBUTE` flag.
633///
634/// See @ref balxml_encoder
636
637 // PRIVATE DATA MEMBERS
638 Encoder_Context *d_context_p; // held, not owned
639 bool d_hasSubElements; // true if an element with
640 // neither 'IS_ATTRIBUTE' nor
641 // 'IS_SIMPLE_CONTENT' is
642 // found
643 bdlb::NullableValue<int> d_simpleContentId; // the 'id' of the element
644 // with 'IS_SIMPLE_CONTENT'
645 // flag, if found
646
647 public:
648 // IMPLEMENTATION MANIPULATORS
649
650 /// Add an attribute with the specified `name`, the value of the
651 /// specified `object`, using the specified `formattingMode`. Note that
652 /// the last argument is used for overloading purposes only.
653 template <class TYPE>
654 int addAttributeImp(const TYPE& object,
655 const bsl::string_view& name,
656 int formattingMode,
658 template <class TYPE>
659 int addAttributeImp(const TYPE& object,
660 const bsl::string_view& name,
661 int formattingMode,
663 template <class TYPE, class ANY_CATEGORY>
664 int addAttributeImp(const TYPE& object,
665 const bsl::string_view& name,
666 int formattingMode,
667 ANY_CATEGORY);
668
669 /// Add an attribute with the specified `name`, the value of the
670 /// specified `object`, using the specified `formattingMode`.
671 template <class TYPE>
672 int addAttribute(const TYPE& object,
673 const bsl::string_view& name,
674 int formattingMode);
675
676 private:
677 // NOT IMPLEMENTED
680
681 public:
682 // CREATORS
683
684 /// Create a visitor for first pass for sequences.
686
687 // Generated by compiler:
688 // ~Encoder_SequenceFirstPass();
689
690 // MANIPULATORS
691
692 /// Called back when an element is visited.
693 template <class TYPE, class INFO_TYPE>
694 int operator()(const TYPE& object, const INFO_TYPE& info);
695
696 // ACCESSORS
697
698 /// Return true if a sub-element is found, and false otherwise.
699 const bool& hasSubElements() const;
700
701 /// Return a null value if there is no element with `IS_SIMPLE_CONTENT`
702 /// flag, or a non-null value with the integer `id` of the element
703 /// otherwise.
704 const bdlb::NullableValue<int>& simpleContentId() const;
705};
706
707 // ================================
708 // class Encoder_SequenceSecondPass
709 // ================================
710
711/// Component-private class. Do not use.
712///
713/// This class is used as the second pass when encoding elements of a
714/// sequence. It basically calls `EncoderUtil_EncodeObject` for elements
715/// that do not have `IS_ATTRIBUTE` flag. Note that the behavior is
716/// undefined if there is an element with the `IS_SIMPLE_CONTENT` flag.
717///
718/// See @ref balxml_encoder
720
721 // DATA
722
723 // functor used to encode sub-elements
724 Encoder_EncodeObject d_encodeObjectFunctor;
725
726 // NOT IMPLEMENTED
729
730 public:
731 // CREATORS
732
733 /// Create a visitor for the second pass for sequences.
734 explicit
736
737 // Generated by compiler:
738 // ~Encoder_SequenceSecondPass();
739
740 // MANIPULATORS
741
742 /// Called back when an element is visited.
743 template <class TYPE, class INFO_TYPE>
744 int operator()(const TYPE& object, const INFO_TYPE& info);
745};
746
747// ============================================================================
748// PROXY CLASSES
749// ============================================================================
750
751 // ========================================
752 // struct Encoder_EncodeObject_executeProxy
753 // ========================================
754
755/// Component-private struct. Do not use.
757
758 // DATA MEMBERS
762
763 // CREATORS
764
765 // Creators have been omitted to allow simple static initialization of this
766 // struct.
767
768 // FUNCTIONS
769 template <class TYPE>
770 inline
771 int operator()(const TYPE& object)
772 {
773 return d_instance_p->execute(object, *d_tag_p, d_formattingMode);
774 }
775};
776
777 // ===========================================
778 // struct Encoder_EncodeObject_executeImpProxy
779 // ===========================================
780
781/// Component-private struct. Do not use.
783
784 // DATA
788
789 // CREATORS
790
791 // Creators have been omitted to allow simple static initialization of this
792 // struct.
793
794 // FUNCTIONS
795 template <class TYPE>
796 inline
797 int operator()(const TYPE&, bslmf::Nil)
798 {
800 return -1;
801 }
802
803 template <class TYPE, class ANY_CATEGORY>
804 inline
805 int operator()(const TYPE& object, ANY_CATEGORY category)
806 {
807 return d_instance_p->executeImp(object,
808 *d_tag_p,
809 d_formattingMode,
810 category);
811 }
812};
813
814 // ==========================================
815 // struct Encoder_EncodeValue_executeImpProxy
816 // ==========================================
817
818/// Component-private struct. Do not use.
820
821 // DATA MEMBERS
824
825 // CREATORS
826
827 // Creators have been omitted to allow simple static initialization of this
828 // struct.
829
830 // FUNCTIONS
831 template <class TYPE>
832 inline
833 int operator()(const TYPE&, bslmf::Nil)
834 {
836 return -1;
837 }
838
839 template <class TYPE, class ANY_CATEGORY>
840 inline
841 int operator()(const TYPE& object, ANY_CATEGORY category)
842 {
843 return d_instance_p->executeImp(object, d_formattingMode, category);
844 }
845};
846
847 // ==================================================
848 // struct Encoder_SequenceFirstPass_addAttributeProxy
849 // ==================================================
850
851/// Component-private struct. Do not use.
853
854 // DATA MEMBERS
858
859 // CREATORS
860
861 // Creators have been omitted to allow simple static initialization of this
862 // struct.
863
864 // FUNCTIONS
865 template <class TYPE>
866 inline
867 int operator()(const TYPE& object)
868 {
869 return d_instance_p->addAttribute(object, *d_name_p, d_formattingMode);
870 }
871};
872
873 // =====================================================
874 // struct Encoder_SequenceFirstPass_addAttributeImpProxy
875 // =====================================================
876
877/// Component-private struct. Do not use.
879
880 // DATA MEMBERS
884
885 // CREATORS
886
887 // Creators have been omitted to allow simple static initialization of this
888 // struct.
889
890 // FUNCTIONS
891 template <class TYPE>
892 inline
893 int operator()(const TYPE&, bslmf::Nil)
894 {
896 return -1;
897 }
898
899 template <class TYPE, class ANY_CATEGORY>
900 inline
901 int operator()(const TYPE& object, ANY_CATEGORY category)
902 {
903 return d_instance_p->addAttributeImp(object,
904 *d_name_p,
905 d_formattingMode,
906 category);
907 }
908};
909} // close package namespace
910
911// ============================================================================
912// INLINE DEFINITIONS
913// ============================================================================
914
915namespace balxml {
916
917 // ------------------------------
918 // class BerEncoder::MemOutStream
919 // ------------------------------
920
921inline
922Encoder::MemOutStream::MemOutStream(bslma::Allocator *basicAllocator)
923: bsl::ostream(0)
924, d_sb(bslma::Default::allocator(basicAllocator))
925{
926 rdbuf(&d_sb);
927}
928
929// MANIPULATORS
930inline
931void Encoder::MemOutStream::reset()
932{
933 d_sb.reset();
934}
935
936// ACCESSORS
937inline
938const char *Encoder::MemOutStream::data() const
939{
940 return d_sb.data();
941}
942
943inline
944int Encoder::MemOutStream::length() const
945{
946 return (int)d_sb.length();
947}
948
949 // -------------
950 // class Encoder
951 // -------------
952
953inline
955{
956 return EncodingStyle::COMPACT == d_options->encodingStyle();
957}
958
959inline
961{
962 return d_options;
963}
964
965inline
966bsl::ostream *Encoder::errorStream() const
967{
968 return d_errorStream;
969}
970
971inline
972bsl::ostream *Encoder::warningStream() const
973{
974 return d_warningStream;
975}
976
977inline
979{
980 return d_severity;
981}
982
983inline
985{
986 if (d_logStream) {
987 return bslstl::StringRef(d_logStream->data(), d_logStream->length());
988 // RETURN
989 }
990 return bslstl::StringRef();
991}
992
993inline
994bsl::ostream& Encoder::logStream()
995{
996 if (0 == d_logStream) {
997 d_logStream = new(d_logArea.buffer()) MemOutStream(d_allocator);
998 }
999 return *d_logStream;
1000}
1001
1002template <class TYPE>
1003inline
1004int Encoder::encode(bsl::streambuf *buffer, const TYPE& object)
1005{
1006 int indentLevel = 0;
1007 int spacesPerLevel = 0;
1008 int wrapColumn = 0;
1009
1010 EncoderOptions formatterEncoderOptions;
1012 &indentLevel,
1013 &spacesPerLevel,
1014 &wrapColumn,
1015 &formatterEncoderOptions,
1016 *d_options);
1017
1018 Formatter formatter(buffer,
1019 formatterEncoderOptions,
1020 indentLevel,
1021 spacesPerLevel,
1022 wrapColumn);
1023
1024 const int rc = encode(formatter, object);
1025
1026 buffer->pubsync();
1027
1028 return rc;
1029}
1030
1031template <class TYPE>
1032inline
1033int Encoder::encodeToStream(bsl::ostream& stream, const TYPE& object)
1034{
1035 return encode(stream.rdbuf(), object);
1036}
1037
1038template <class TYPE>
1039inline
1040bsl::ostream& Encoder::encode(bsl::ostream& stream, const TYPE& object)
1041{
1042 int indentLevel = 0;
1043 int spacesPerLevel = 0;
1044 int wrapColumn = 0;
1045
1046 EncoderOptions formatterEncoderOptions;
1048 &indentLevel,
1049 &spacesPerLevel,
1050 &wrapColumn,
1051 &formatterEncoderOptions,
1052 *d_options);
1053
1054 Formatter formatter(stream,
1055 formatterEncoderOptions,
1056 indentLevel,
1057 spacesPerLevel,
1058 wrapColumn);
1059
1060 encode(formatter, object);
1061
1062 stream.flush();
1063
1064 return stream;
1065}
1066
1067template <class TYPE>
1068int Encoder::encode(Formatter& formatter, const TYPE& object)
1069{
1070 d_severity = ErrorInfo::e_NO_ERROR;
1071 if (d_logStream != 0) {
1072 d_logStream->reset();
1073 }
1074
1075 Encoder_Context context(&formatter,this);
1076
1077 if (d_options->outputXMLHeader()) {
1078 formatter.addHeader();
1079 }
1080
1081 const char *tag = d_options->tag().empty()
1082 ? bdlat_TypeName::xsdName(object,
1083 d_options->formattingMode())
1084 : d_options->tag().c_str();
1085
1086 context.openElement(tag);
1087
1088 if (!d_options->objectNamespace().empty()) {
1089
1090 context.addAttribute("xmlns", d_options->objectNamespace());
1091
1092 if (d_options->outputXSIAlias()) {
1093 // Only declare the "xsi" namespace and schema location if an
1094 // object namespace was provided because only then can validation
1095 // happen.
1096 context.addAttribute("xmlns:xsi",
1097 "http://www.w3.org/2001/XMLSchema-instance");
1098
1099 if (!d_options->schemaLocation().empty()) {
1100 context.addAttribute("xsi:schemaLocation",
1101 d_options->objectNamespace()
1102 + " "
1103 + d_options->schemaLocation());
1104 }
1105 }
1106 }
1107 else if (d_options->outputXSIAlias()) {
1108 context.addAttribute("xmlns:xsi",
1109 "http://www.w3.org/2001/XMLSchema-instance");
1110 }
1111
1112 Encoder_EncodeValue encodeValue(&context);
1113
1114 int rc = 0;
1115 if (0 != encodeValue.execute(object,d_options->formattingMode())) {
1116
1117 logError("Failed to encode", tag, d_options->formattingMode());
1118
1119 context.invalidate();
1120 rc = -1;
1121 }
1122 else {
1123 context.closeElement(tag);
1124 }
1125
1126 switch (d_severity) {
1127 case ErrorInfo::e_NO_ERROR: {
1128 } break;
1129 case ErrorInfo::e_WARNING: {
1130 if (d_warningStream) {
1131 *d_warningStream << loggedMessages();
1132 }
1133 } break;
1134 default: {
1135 if (d_errorStream) {
1136 *d_errorStream << loggedMessages();
1137 }
1138 } break;
1139 }
1140 return rc;
1141}
1142
1143 // ---------------------
1144 // class Encoder_Context
1145 // ---------------------
1146
1147// MANIPULATORS
1148template <class NAME_TYPE, class VALUE_TYPE>
1149inline
1150void Encoder_Context::addAttribute(const NAME_TYPE& name,
1151 const VALUE_TYPE& value)
1152{
1153 d_formatter->addAttribute(name,
1154 value,
1156}
1157
1158template <class NAME_TYPE, class VALUE_TYPE>
1159inline
1160void Encoder_Context::addAttribute(const NAME_TYPE& name,
1161 const VALUE_TYPE& value,
1162 int formattingMode)
1163{
1164 d_formatter->addAttribute(name, value, formattingMode);
1165}
1166
1167template <class NAME_TYPE>
1168inline
1169void Encoder_Context::closeElement(const NAME_TYPE& name)
1170{
1171 d_formatter->closeElement(name);
1172}
1173
1174inline
1176{
1177 rawOutputStream().setstate(bsl::ios_base::failbit);
1178}
1179
1180inline
1182 const char *text,
1183 const bsl::string_view& tag,
1184 int formattingMode,
1185 int index)
1186{
1187 return d_encoder->logError(text, tag, formattingMode, index);
1188}
1189
1190template <class NAME_TYPE>
1191inline
1192void Encoder_Context::openElement(const NAME_TYPE& name)
1193{
1194 d_formatter->openElement(name);
1195}
1196
1197inline
1199{
1200 return d_formatter->rawOutputStream();
1201}
1202
1203// ACCESSORS
1204inline
1206{
1207 return *d_encoder->options();
1208}
1209
1210inline
1212{
1213 return d_formatter->status();
1214}
1215
1216 // --------------------------
1217 // class Encoder_EncodeObject
1218 // --------------------------
1219
1220// IMPLEMENTATION MANIPULATORS
1221template <class TYPE>
1222inline
1224 const bsl::string_view& tag,
1225 int formattingMode,
1227{
1228 if (formattingMode & bdlat_FormattingMode::e_LIST) {
1229 return executeArrayListImp(object, tag); // RETURN
1230 }
1231 // else { return ... } removed, to prevent warning with gcc-4.1.1 (reach
1232 // end of non-void function), instead, have unconditional:
1233
1234 return executeArrayRepetitionImp(object, tag, formattingMode);
1235}
1236
1237template <class TYPE>
1238inline
1240 const TYPE& object,
1241 const bsl::string_view& tag,
1242 int formattingMode,
1244{
1245 enum { k_SUCCESS = 0 };
1246
1248 if (formattingMode & bdlat_FormattingMode::e_NILLABLE) {
1249 if (!d_context_p->encoderOptions().objectNamespace().empty()
1250 && d_context_p->encoderOptions().outputXSIAlias()) {
1251 // Only add the "xsi:nil" attribute if an object namespace was
1252 // provided because only then can validation happen.
1253 d_context_p->openElement(tag);
1254 d_context_p->addAttribute("xsi:nil", "true");
1255 d_context_p->closeElement(tag);
1256 }
1257 }
1258
1259 return d_context_p->status(); // RETURN
1260 }
1261
1263 this,
1264 &tag,
1265 formattingMode
1266 };
1267
1268 return bdlat_NullableValueFunctions::accessValue(object, proxy);
1269}
1270
1271template <class TYPE>
1272inline
1274 const TYPE& object,
1275 const bsl::string_view& tag,
1276 int formattingMode,
1278{
1280 this,
1281 &tag,
1282 formattingMode
1283 };
1284
1285 return bdlat_TypeCategoryUtil::accessByCategory(object, proxy);
1286}
1287
1288template <class TYPE, class ANY_CATEGORY>
1290 const bsl::string_view& tag,
1291 int formattingMode,
1292 ANY_CATEGORY)
1293{
1294 enum { k_FAILURE = -1 };
1295
1296 bool isUntagged = formattingMode & bdlat_FormattingMode::e_UNTAGGED;
1297
1298 if (!isUntagged) {
1299 d_context_p->openElement(tag);
1300 }
1301
1302 Encoder_EncodeValue encodeValue(d_context_p);
1303
1304 if (0 != encodeValue.execute(object, formattingMode)) {
1305 d_context_p->logError("Unable to encode value", tag, formattingMode);
1306 return k_FAILURE; // RETURN
1307 }
1308
1309 if (!isUntagged) {
1310 d_context_p->closeElement(tag);
1311 }
1312
1313 int ret = d_context_p->status();
1314
1315 if (ret) {
1316 d_context_p->logError("Formatter was invalidated for",
1317 tag,
1318 formattingMode);
1319 }
1320
1321 return ret;
1322}
1323
1324template <class TYPE>
1326 const bsl::string_view& tag)
1327{
1328 d_context_p->openElement(tag);
1329
1331 object,
1332 &d_context_p->encoderOptions());
1333
1334 d_context_p->closeElement(tag);
1335
1336 int ret = d_context_p->status();
1337
1338 if (ret) {
1339
1340 d_context_p->logError(
1341 "Error while encoding list for",
1342 tag,
1344 }
1345
1346 return ret;
1347}
1348
1349template <class TYPE>
1351 const TYPE& object,
1352 const bsl::string_view& tag,
1353 int formattingMode)
1354{
1355 enum { k_SUCCESS = 0, k_FAILURE = -1 };
1356
1357 const int size = (int)bdlat_ArrayFunctions::size(object);
1358
1359 Encoder_EncodeObject_executeProxy proxy = { this, &tag, formattingMode };
1360
1361 for (int i = 0; i < size; ++i) {
1362 if (0 != bdlat_ArrayFunctions::accessElement(object, proxy, i)) {
1363
1364 d_context_p->logError(
1365 "Error while encoding array element",
1366 tag,
1367 formattingMode,
1368 i);
1369
1370 return k_FAILURE; // RETURN
1371 }
1372 }
1373
1374 return k_SUCCESS;
1375}
1376
1377// CREATORS
1378inline
1379Encoder_EncodeObject::Encoder_EncodeObject(Encoder_Context *context)
1380: d_context_p(context)
1381{
1382 BSLS_ASSERT(d_context_p);
1383}
1384
1385// MANIPULATORS
1386template <class TYPE, class INFO_TYPE>
1387inline
1388int Encoder_EncodeObject::operator()(const TYPE& object, const INFO_TYPE& info)
1389{
1390 bsl::string_view name(info.name(), info.nameLength());
1391
1392 return execute(object, name, info.formattingMode());
1393}
1394
1395template <class TYPE>
1396inline
1397int Encoder_EncodeObject::execute(const TYPE& object,
1398 const bsl::string_view& tag,
1399 int formattingMode)
1400{
1401 typedef typename bdlat_TypeCategory::Select<TYPE>::Type TypeCategory;
1402
1403 return executeImp(object, tag, formattingMode, TypeCategory());
1404}
1405
1406 // -------------------------
1407 // class Encoder_EncodeValue
1408 // -------------------------
1409
1410// IMPLEMENTATION MANIPULATORS
1411template <class TYPE>
1412inline
1414 const TYPE& object,
1415 int formattingMode,
1417{
1418 enum { k_SUCCESS = 0, k_FAILURE = -1 };
1419
1420#if defined(BSLS_ASSERT_SAFE_IS_ACTIVE)
1421 int type = formattingMode & bdlat_FormattingMode::e_TYPE_MASK;
1422
1424#else
1425 (void) formattingMode;
1426#endif
1427
1428 Encoder_SequenceFirstPass firstPass(d_context_p);
1429
1430 if (0 != bdlat_SequenceFunctions::accessAttributes(object, firstPass)) {
1431 return k_FAILURE; // RETURN
1432 }
1433
1434 if (!firstPass.simpleContentId().isNull()) {
1435 Encoder_EncodeValue encodeValue(d_context_p);
1436
1438 object,
1439 encodeValue,
1440 firstPass.simpleContentId().value());
1441 // RETURN
1442 }
1443
1444 if (firstPass.hasSubElements()) {
1445 Encoder_SequenceSecondPass secondPass(d_context_p);
1446
1447 return bdlat_SequenceFunctions::accessAttributes(object, secondPass);
1448 // RETURN
1449 }
1450
1451 return k_SUCCESS;
1452}
1453
1454template <class TYPE>
1455inline
1456int Encoder_EncodeValue::executeImp(const TYPE& object,
1457 int formattingMode,
1459{
1460 enum { k_FAILURE = -1 };
1461
1462#if defined(BSLS_ASSERT_SAFE_IS_ACTIVE)
1463 int type = formattingMode & bdlat_FormattingMode::e_TYPE_MASK;
1464
1466#endif
1467
1470
1471 d_context_p->logError("Undefined selection is not allowed ",
1472 "???",
1473 formattingMode);
1474 return k_FAILURE; // RETURN
1475 }
1476
1477 Encoder_EncodeObject encodeObject(d_context_p);
1478
1479 return bdlat_ChoiceFunctions::accessSelection(object, encodeObject);
1480}
1481
1482template <class TYPE>
1483inline
1485 const TYPE& object,
1486 int formattingMode,
1488{
1489 Encoder_EncodeValue_executeImpProxy proxy = { this, formattingMode };
1490
1491 return bdlat_TypeCategoryUtil::accessByCategory(object, proxy);
1492}
1493
1494template <class TYPE, class ANY_CATEGORY>
1495inline
1496int Encoder_EncodeValue::executeImp(const TYPE& object,
1497 int formattingMode,
1498 ANY_CATEGORY)
1499{
1501 object,
1502 formattingMode,
1503 &d_context_p->encoderOptions());
1504
1505 return d_context_p->status();
1506}
1507
1508// CREATORS
1509inline
1510Encoder_EncodeValue::Encoder_EncodeValue(Encoder_Context *context)
1511: d_context_p(context)
1512{
1513 BSLS_ASSERT(d_context_p);
1514}
1515
1516// MANIPULATORS
1517template <class TYPE, class INFO_TYPE>
1518inline
1519int Encoder_EncodeValue::operator()(const TYPE& object, const INFO_TYPE& info)
1520{
1521 typedef typename bdlat_TypeCategory::Select<TYPE>::Type TypeCategory;
1522
1523 return executeImp(object, info.formattingMode(), TypeCategory());
1524}
1525
1526template <class TYPE>
1527inline
1528int Encoder_EncodeValue::execute(const TYPE& object, int formattingMode)
1529{
1530 typedef typename bdlat_TypeCategory::Select<TYPE>::Type TypeCategory;
1531
1532 return executeImp(object, formattingMode, TypeCategory());
1533}
1534
1535 // -------------------------------
1536 // class Encoder_SequenceFirstPass
1537 // -------------------------------
1538
1539// IMPLEMENTATION MANIPULATORS
1540template <class TYPE>
1541inline
1543 const TYPE& object,
1544 const bsl::string_view& name,
1545 int formattingMode,
1547{
1548 enum { k_SUCCESS = 0 };
1549
1551 return k_SUCCESS; // RETURN
1552 }
1553
1555 this,
1556 &name,
1557 formattingMode
1558 };
1559
1560 return bdlat_NullableValueFunctions::accessValue(object, proxy);
1561}
1562
1563template <class TYPE>
1564inline
1566 const TYPE& object,
1567 const bsl::string_view& name,
1568 int formattingMode,
1570{
1572 this,
1573 &name,
1574 formattingMode
1575 };
1576
1577 return bdlat_TypeCategoryUtil::accessByCategory(object, proxy);
1578
1579}
1580
1581template <class TYPE, class ANY_CATEGORY>
1582inline
1584 const TYPE& object,
1585 const bsl::string_view& name,
1586 int formattingMode,
1587 ANY_CATEGORY)
1588{
1589 d_context_p->addAttribute(name, object, formattingMode);
1590
1591 int ret = d_context_p->status();
1592
1593 if (ret) {
1594 d_context_p->logError("Failed to encode attribute",
1595 name,
1596 formattingMode);
1597 }
1598
1599 return ret;
1600}
1601
1602template <class TYPE>
1603inline
1605 const TYPE& object,
1606 const bsl::string_view& name,
1607 int formattingMode)
1608{
1609 typedef typename bdlat_TypeCategory::Select<TYPE>::Type TypeCategory;
1610
1611 return addAttributeImp(object, name, formattingMode, TypeCategory());
1612}
1613
1614// CREATORS
1615inline
1616Encoder_SequenceFirstPass::Encoder_SequenceFirstPass(Encoder_Context *context)
1617: d_context_p(context)
1618, d_hasSubElements(false)
1619{
1620 BSLS_ASSERT(d_context_p);
1621 BSLS_ASSERT(d_simpleContentId.isNull());
1622
1623 // {DRQS 153551134<GO>}: gcc can occasionally mis-diagnose
1624 // 'd_simpleContentId' as uninitialized. This workaround avoids that
1625 // problem (which can cause build failures if '-Wmaybe-uninitialized' and
1626 // '-Werror' are set). See also {DRQS 75130685<GO>} and {DRQS
1627 // 115347303<GO>}.
1628 d_simpleContentId.makeValue(0);
1629 d_simpleContentId.reset();
1630}
1631
1632// MANIPULATORS
1633template <class TYPE, class INFO_TYPE>
1635 const INFO_TYPE& info)
1636{
1637 enum { k_SUCCESS = 0 };
1638
1639 int formattingMode = info.formattingMode();
1640 bool isSimpleContent = formattingMode
1642 bool isAttribute = formattingMode & bdlat_FormattingMode::e_ATTRIBUTE;
1643
1644 if (isSimpleContent) {
1645 BSLS_ASSERT(!isAttribute);
1646 BSLS_ASSERT(!d_hasSubElements);
1647 BSLS_ASSERT(d_simpleContentId.isNull());
1648
1649 d_simpleContentId.makeValue(info.id());
1650 }
1651 else if (isAttribute) {
1652 bsl::string_view name(info.name(), info.nameLength());
1653
1654 return addAttribute(object, name, formattingMode); // RETURN
1655 }
1656 else {
1657 BSLS_ASSERT(d_simpleContentId.isNull());
1658
1659 d_hasSubElements = true;
1660 }
1661
1662 return k_SUCCESS;
1663}
1664
1665// ACCESSORS
1666inline
1668{
1669 return d_hasSubElements;
1670}
1671
1672inline
1675{
1676 return d_simpleContentId;
1677}
1678
1679 // --------------------------------
1680 // class Encoder_SequenceSecondPass
1681 // --------------------------------
1682
1683// CREATORS
1684inline
1685Encoder_SequenceSecondPass::Encoder_SequenceSecondPass(
1686 Encoder_Context* context)
1687: d_encodeObjectFunctor(context)
1688{
1689}
1690
1691// MANIPULATORS
1692template <class TYPE, class INFO_TYPE>
1694 const INFO_TYPE& info)
1695{
1696 enum { k_SUCCESS = 0 };
1697
1698 int formattingMode = info.formattingMode();
1699
1701 !(formattingMode & bdlat_FormattingMode::e_SIMPLE_CONTENT));
1702
1703 if (!(formattingMode & bdlat_FormattingMode::e_ATTRIBUTE)) {
1704 return d_encodeObjectFunctor(object, info); // RETURN
1705 }
1706
1707 return k_SUCCESS;
1708}
1709
1710} // close package namespace
1711
1712
1713#endif
1714
1715// ----------------------------------------------------------------------------
1716// Copyright 2015 Bloomberg Finance L.P.
1717//
1718// Licensed under the Apache License, Version 2.0 (the "License");
1719// you may not use this file except in compliance with the License.
1720// You may obtain a copy of the License at
1721//
1722// http://www.apache.org/licenses/LICENSE-2.0
1723//
1724// Unless required by applicable law or agreed to in writing, software
1725// distributed under the License is distributed on an "AS IS" BASIS,
1726// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1727// See the License for the specific language governing permissions and
1728// limitations under the License.
1729// ----------------------------- END-OF-FILE ----------------------------------
1730
1731/** @} */
1732/** @} */
1733/** @} */
#define BSLMF_NESTED_TRAIT_DECLARATION(t_TYPE, t_TRAIT)
Definition bslmf_nestedtraitdeclaration.h:231
Definition balxml_encoderoptions.h:88
bool outputXSIAlias() const
Return the value of the "OutputXSIAlias" attribute of this object.
Definition balxml_encoderoptions.h:1022
const bsl::string & schemaLocation() const
Definition balxml_encoderoptions.h:950
EncodingStyle::Value encodingStyle() const
Return the value of the "EncodingStyle" attribute of this object.
Definition balxml_encoderoptions.h:1004
bool outputXMLHeader() const
Return the value of the "OutputXMLHeader" attribute of this object.
Definition balxml_encoderoptions.h:1016
const bsl::string & tag() const
Definition balxml_encoderoptions.h:956
static const int DEFAULT_INITIALIZER_FORMATTING_MODE
Definition balxml_encoderoptions.h:196
const bsl::string & objectNamespace() const
Definition balxml_encoderoptions.h:944
int formattingMode() const
Return the value of the "FormattingMode" attribute of this object.
Definition balxml_encoderoptions.h:962
Definition balxml_encoder.h:369
void openElement(const NAME_TYPE &name)
Definition balxml_encoder.h:1192
Encoder_Context(Formatter *formatter, Encoder *encoder)
void addAttribute(const NAME_TYPE &name, const VALUE_TYPE &value)
Definition balxml_encoder.h:1150
const EncoderOptions & encoderOptions() const
Definition balxml_encoder.h:1205
int status() const
Definition balxml_encoder.h:1211
void closeElement(const NAME_TYPE &name)
Definition balxml_encoder.h:1169
void invalidate()
Definition balxml_encoder.h:1175
ErrorInfo::Severity logError(const char *text, const bsl::string_view &tag, int formattingMode, int index=-1)
Definition balxml_encoder.h:1181
bsl::ostream & rawOutputStream()
Definition balxml_encoder.h:1198
Definition balxml_encoder.h:492
int operator()(const TYPE &object, const INFO_TYPE &info)
Definition balxml_encoder.h:1388
int executeImp(const bsl::vector< char > &object, const bsl::string_view &tag, int formattingMode, bdlat_TypeCategory::Array)
int executeArrayRepetitionImp(const TYPE &object, const bsl::string_view &tag, int formattingMode)
Definition balxml_encoder.h:1350
int executeArrayListImp(const TYPE &object, const bsl::string_view &tag)
Definition balxml_encoder.h:1325
int executeImp(const TYPE &object, const bsl::string_view &tag, int formattingMode, bdlat_TypeCategory::Array)
Definition balxml_encoder.h:1223
int execute(const TYPE &object, const bsl::string_view &tag, int formattingMode)
Definition balxml_encoder.h:1397
Definition balxml_encoder.h:571
int execute(const TYPE &object, int formattingMode)
Definition balxml_encoder.h:1528
int executeImp(const TYPE &object, int formattingMode, bdlat_TypeCategory::Sequence)
Definition balxml_encoder.h:1413
int operator()(const TYPE &object, const INFO_TYPE &info)
Definition balxml_encoder.h:1519
Definition balxml_encoder.h:635
const bdlb::NullableValue< int > & simpleContentId() const
Definition balxml_encoder.h:1674
int operator()(const TYPE &object, const INFO_TYPE &info)
Called back when an element is visited.
Definition balxml_encoder.h:1634
int addAttribute(const TYPE &object, const bsl::string_view &name, int formattingMode)
Definition balxml_encoder.h:1604
const bool & hasSubElements() const
Return true if a sub-element is found, and false otherwise.
Definition balxml_encoder.h:1667
int addAttributeImp(const TYPE &object, const bsl::string_view &name, int formattingMode, bdlat_TypeCategory::NullableValue)
Definition balxml_encoder.h:1542
Definition balxml_encoder.h:719
int operator()(const TYPE &object, const INFO_TYPE &info)
Called back when an element is visited.
Definition balxml_encoder.h:1693
Definition balxml_encoder.h:200
bslstl::StringRef loggedMessages() const
Definition balxml_encoder.h:984
bsl::ostream * warningStream() const
Return pointer to the warning stream.
Definition balxml_encoder.h:972
bsl::ostream * errorStream() const
Return pointer to the error stream.
Definition balxml_encoder.h:966
friend class Encoder_Context
Definition balxml_encoder.h:203
bool isCompact() const
Definition balxml_encoder.h:954
ErrorInfo::Severity errorSeverity() const
Definition balxml_encoder.h:978
const EncoderOptions * options() const
Return the encoder options.
Definition balxml_encoder.h:960
int encode(bsl::streambuf *buffer, const TYPE &object)
Definition balxml_encoder.h:1004
int encodeToStream(bsl::ostream &stream, const TYPE &object)
Definition balxml_encoder.h:1033
Definition balxml_errorinfo.h:353
Severity
Definition balxml_errorinfo.h:358
@ e_WARNING
Definition balxml_errorinfo.h:372
@ e_NO_ERROR
Definition balxml_errorinfo.h:371
Definition balxml_formatter.h:511
void openElement(const bsl::string_view &name, WhitespaceType whitespaceMode=e_PRESERVE_WHITESPACE)
int status() const
Definition balxml_formatter.h:1104
void addHeader(const bsl::string_view &encoding="UTF-8")
bsl::ostream & rawOutputStream()
Definition balxml_formatter.h:1031
void closeElement(const bsl::string_view &name)
void addAttribute(const bsl::string_view &name, const TYPE &value, int formattingMode=0)
Definition balxml_formatter.h:899
Definition bdlb_nullablevalue.h:257
bool isNull() const BSLS_KEYWORD_NOEXCEPT
Return true if this object is null, and false otherwise.
Definition bdlb_nullablevalue.h:1779
TYPE & value()
Definition bdlb_nullablevalue.h:1742
TYPE & makeValue(BSLS_COMPILERFEATURES_FORWARD_REF(BDE_OTHER_TYPE) value)
Definition bdlb_nullablevalue.h:1717
Definition bdlsb_memoutstreambuf.h:212
Definition bslstl_stringview.h:441
const CHAR_TYPE * c_str() const BSLS_KEYWORD_NOEXCEPT
Definition bslstl_string.h:6705
bool empty() const BSLS_KEYWORD_NOEXCEPT
Return true if this string has length 0, and false otherwise.
Definition bslstl_string.h:6631
Definition bslstl_vector.h:1025
Definition bslma_allocator.h:457
Definition bslstl_stringref.h:372
static int accessByCategory(const TYPE &object, ACCESSOR &accessor)
Definition bdlat_typecategory.h:1444
static const char * xsdName(const TYPE &object, int format)
Definition bdlat_typename.h:1039
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:653
Definition balxml_base64parser.h:150
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)
bool isNull(const TYPE &object)
int accessValue(const TYPE &object, ACCESSOR &accessor)
int accessAttribute(const TYPE &object, ACCESSOR &accessor, const char *attributeName, int attributeNameLength)
int accessAttributes(const TYPE &object, ACCESSOR &accessor)
Definition bdlb_printmethods.h:283
Definition balxml_encoderoptions.h:68
Definition bdlt_iso8601util.h:691
Definition bslstl_algorithm.h:82
StringRefImp< char > StringRef
Definition bslstl_stringref.h:699
Component-private struct. Do not use.
Definition balxml_encoder.h:782
int operator()(const TYPE &object, ANY_CATEGORY category)
Definition balxml_encoder.h:805
int operator()(const TYPE &, bslmf::Nil)
Definition balxml_encoder.h:797
int d_formattingMode
Definition balxml_encoder.h:787
Encoder_EncodeObject * d_instance_p
Definition balxml_encoder.h:785
const bsl::string_view * d_tag_p
Definition balxml_encoder.h:786
Component-private struct. Do not use.
Definition balxml_encoder.h:756
int d_formattingMode
Definition balxml_encoder.h:761
int operator()(const TYPE &object)
Definition balxml_encoder.h:771
Encoder_EncodeObject * d_instance_p
Definition balxml_encoder.h:759
const bsl::string_view * d_tag_p
Definition balxml_encoder.h:760
Component-private struct. Do not use.
Definition balxml_encoder.h:819
int operator()(const TYPE &object, ANY_CATEGORY category)
Definition balxml_encoder.h:841
int operator()(const TYPE &, bslmf::Nil)
Definition balxml_encoder.h:833
int d_formattingMode
Definition balxml_encoder.h:823
Encoder_EncodeValue * d_instance_p
Definition balxml_encoder.h:822
Definition balxml_encoder.h:422
static void getFormatterOptions(int *formatterIndentLevel, int *formatterSpacesPerLevel, int *formatterWrapColumn, EncoderOptions *formatterOptions, const EncoderOptions &encoderOptions)
Component-private struct. Do not use.
Definition balxml_encoder.h:878
const bsl::string_view * d_name_p
Definition balxml_encoder.h:882
int d_formattingMode
Definition balxml_encoder.h:883
int operator()(const TYPE &object, ANY_CATEGORY category)
Definition balxml_encoder.h:901
int operator()(const TYPE &, bslmf::Nil)
Definition balxml_encoder.h:893
Encoder_SequenceFirstPass * d_instance_p
Definition balxml_encoder.h:881
Component-private struct. Do not use.
Definition balxml_encoder.h:852
int operator()(const TYPE &object)
Definition balxml_encoder.h:867
int d_formattingMode
Definition balxml_encoder.h:857
const bsl::string_view * d_name_p
Definition balxml_encoder.h:856
Encoder_SequenceFirstPass * d_instance_p
Definition balxml_encoder.h:855
@ COMPACT
Definition balxml_encodingstyle.h:75
static bsl::ostream & print(bsl::ostream &stream, const TYPE &object, int formattingMode, const EncoderOptions *encoderOptions=0)
Definition balxml_typesprintutil.h:1161
static bsl::ostream & printList(bsl::ostream &stream, const TYPE &object, const EncoderOptions *encoderOptions=0)
Definition balxml_typesprintutil.h:1253
@ e_LIST
Definition bdlat_formattingmode.h:122
@ e_TYPE_MASK
Definition bdlat_formattingmode.h:115
@ e_ATTRIBUTE
Definition bdlat_formattingmode.h:119
@ e_DEFAULT
Definition bdlat_formattingmode.h:110
@ e_NILLABLE
Definition bdlat_formattingmode.h:121
@ e_UNTAGGED
Definition bdlat_formattingmode.h:118
@ e_SIMPLE_CONTENT
Definition bdlat_formattingmode.h:120
Definition bdlat_typecategory.h:1035
Definition bdlat_typecategory.h:1036
Definition bdlat_typecategory.h:1034
Definition bdlat_typecategory.h:1039
Definition bdlat_typecategory.h:1040
This struct is empty and represents a nil type.
Definition bslmf_nil.h:131
char * buffer()
Definition bsls_objectbuffer.h:344