BDE 4.39.x Production Release
Loading...
Searching...
No Matches
balxml_decoder.h
Go to the documentation of this file.
1/// @file balxml_decoder.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// balxml_decoder.h -*-C++-*-
8#ifndef INCLUDED_BALXML_DECODER
9#define INCLUDED_BALXML_DECODER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup balxml_decoder balxml_decoder
15/// @brief Provide a generic translation from XML into C++ objects.
16/// @addtogroup bal
17/// @{
18/// @addtogroup balxml
19/// @{
20/// @addtogroup balxml_decoder
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#balxml_decoder-purpose"> Purpose</a>
25/// * <a href="#balxml_decoder-classes"> Classes </a>
26/// * <a href="#balxml_decoder-description"> Description </a>
27/// * <a href="#balxml_decoder-usage"> Usage </a>
28/// * <a href="#balxml_decoder-example-1-generating-code-from-a-schema"> Example 1: Generating Code from a Schema </a>
29/// * <a href="#balxml_decoder-example-2-error-and-warning-streams"> Example 2: Error and Warning Streams </a>
30///
31/// # Purpose {#balxml_decoder-purpose}
32/// Provide a generic translation from XML into C++ objects.
33///
34/// # Classes {#balxml_decoder-classes}
35///
36/// - balxml::Decoder: an XML decoder
37///
38/// @see balxml_decoderoptions, balxml_encoder, balber_berdecoder
39///
40/// # Description {#balxml_decoder-description}
41/// This component provides a class `balxml::Decoder` for decoding
42/// value-semantic objects in XML format. The `decode` methods are function
43/// templates that will decode any object that meets the requirements of a
44/// sequence or choice object as defined in the @ref bdlat_sequencefunctions and
45/// @ref bdlat_choicefunctions components. These generic frameworks provide a
46/// common compile-time interface for manipulating struct-like and union-like
47/// objects.
48///
49/// There are two usage models for using `balxml::Decoder`. The common case,
50/// when the type of object being decoded is known in advance, involves calling
51/// one of a set of `decode` method templates that decode a specified
52/// value-semantic object from a specified stream or other input source. The
53/// caller may specify the input for `decode` as a file, an `bsl::istream`, an
54/// `bsl::streambuf`, or a memory buffer.
55///
56/// A less common but more flexible usage model involves calling the `open` to
57/// open the XML document from the specified input, then calling `decode` to
58/// decode to an object without specifying the input source, and finally
59/// calling `close` to close the input source. The `open` method positions the
60/// internal reader to the root element node, so the caller can examine the
61/// root element, decide what type of object is contained in the input
62/// stream/source, and construct an object of the needed type before calling
63/// `decode` to read from the already open input source. Thus the input data
64/// is not constrained to a single root element type.
65///
66/// Although the XML format is very useful for debugging and for conforming to
67/// external data-interchange specifications, it is relatively expensive to
68/// encode and decode and relatively bulky to transmit. It is more efficient
69/// to use a binary encoding (such as BER) if the encoding format is under your
70/// control. (See @ref balber_berdecoder .)
71///
72/// ## Usage {#balxml_decoder-usage}
73///
74///
75/// This section illustrates intended use of this component.
76///
77/// ### Example 1: Generating Code from a Schema {#balxml_decoder-example-1-generating-code-from-a-schema}
78///
79///
80/// Suppose we have the following XML schema inside a file called
81/// `employee.xsd`:
82/// @code
83/// <?xml version='1.0' encoding='UTF-8'?>
84/// <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
85/// xmlns:test='http://bloomberg.com/schemas/test'
86/// targetNamespace='http://bloomberg.com/schemas/test'
87/// elementFormDefault='unqualified'>
88///
89/// <xs:complexType name='Address'>
90/// <xs:sequence>
91/// <xs:element name='street' type='xs:string'/>
92/// <xs:element name='city' type='xs:string'/>
93/// <xs:element name='state' type='xs:string'/>
94/// </xs:sequence>
95/// </xs:complexType>
96///
97/// <xs:complexType name='Employee'>
98/// <xs:sequence>
99/// <xs:element name='name' type='xs:string'/>
100/// <xs:element name='homeAddress' type='test:Address'/>
101/// <xs:element name='age' type='xs:int'/>
102/// </xs:sequence>
103/// </xs:complexType>
104///
105/// <xs:element name='Address' type='test:Address'/>
106/// <xs:element name='Employee' type='test:Employee'/>
107///
108/// </xs:schema>
109/// @endcode
110/// Using the `bas_codegen.pl` tool, we can generate C++ classes for this
111/// schema:
112/// @code
113/// $ bas_codegen.pl -m msg -p test -E xsdfile.xsd
114/// @endcode
115/// This tool will generate the header and implementation files for the
116/// @ref test_address and @ref test_employee components in the current directory.
117///
118/// The following function decodes an XML string into a `test::Employee` object
119/// and verifies the results:
120/// @code
121/// #include <test_employee.h>
122/// #include <balxml_decoder.h>
123/// #include <balxml_decoderoptions.h>
124/// #include <balxml_errorinfo.h>
125/// #include <balxml_minireader.h>
126/// #include <bsl_sstream.h>
127///
128/// using namespace BloombergLP;
129///
130/// int main()
131/// {
132/// const char INPUT[] = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
133/// "<Employee>\n"
134/// " <name>Bob</name>\n"
135/// " <homeAddress>\n"
136/// " <street>Some Street</street>\n"
137/// " <city>Some City</city>\n"
138/// " <state>Some State</state>\n"
139/// " </homeAddress>\n"
140/// " <age>21</age>\n"
141/// "</Employee>\n";
142///
143/// bsl::stringstream ss(INPUT);
144///
145/// test::Employee bob;
146///
147/// balxml::DecoderOptions options;
148/// balxml::MiniReader reader;
149/// balxml::ErrorInfo errInfo;
150///
151/// balxml::Decoder decoder(&options, &reader, &errInfo);
152///
153/// decoder.decode(ss, &bob);
154///
155/// assert(ss);
156/// assert("Bob" == bob.name());
157/// assert("Some Street" == bob.homeAddress().street());
158/// assert("Some City" == bob.homeAddress().city());
159/// assert("Some State" == bob.homeAddress().state());
160/// assert(21 == bob.age());
161///
162/// return 0;
163/// }
164/// @endcode
165///
166/// ### Example 2: Error and Warning Streams {#balxml_decoder-example-2-error-and-warning-streams}
167///
168///
169/// The following snippets of code illustrate how to pass an error stream and
170/// warning stream to the `decode` function. We will use the same
171/// @ref test_employee component from the previous usage example. Note that the
172/// input XML string contains an error. (The `homeAddress` object has an
173/// element called `country`, which does not exist in the schema.):
174/// @code
175/// #include <test_employee.h>
176/// #include <balxml_decoder.h>
177/// #include <balxml_decoderoptions.h>
178/// #include <balxml_errorinfo.h>
179/// #include <balxml_minireader.h>
180/// #include <bsl_sstream.h>
181///
182/// using namespace BloombergLP;
183///
184/// int main()
185/// {
186/// const char INPUT[] = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
187/// "<Employee>\n"
188/// " <name>Bob</name>\n"
189/// " <homeAddress>\n"
190/// " <street>Some Street</street>\n"
191/// " <city>Some City</city>\n"
192/// " <state>Some State</state>\n"
193/// " <country>Some Country</country>\n"
194/// " </homeAddress>\n"
195/// " <age>21</age>\n"
196/// "</Employee>\n";
197///
198/// bsl::stringstream ss(INPUT);
199///
200/// test::Employee bob;
201///
202/// balxml::DecoderOptions options;
203/// balxml::MiniReader reader;
204/// balxml::ErrorInfo errInfo;
205///
206/// options.setSkipUnknownElements(false);
207/// balxml::Decoder decoder(&options, &reader, &errInfo,
208/// &bsl::cerr, &bsl::cerr);
209/// decoder.decode(ss, &bob);
210///
211/// assert(!ss);
212///
213/// return 0;
214/// }
215/// @endcode
216/// Note that the input stream is invalidated to indicate that an error
217/// occurred. Also note that the following error message will be printed on
218/// `bsl::cerr`:
219/// @code
220/// employee.xml:8.18: Error: Unable to decode sub-element 'country'.\n"
221/// employee.xml:8.18: Error: Unable to decode sub-element 'homeAddress'.\n";
222/// @endcode
223/// The following snippets of code illustrate how to open decoder and read the
224/// first node before calling `decode`:
225/// @code
226/// int main()
227/// {
228/// const char INPUT[] =
229/// "<?xml version='1.0' encoding='UTF-8' ?>\n"
230/// "<Employee xmlns='http://www.bde.com/bdem_test'>\n"
231/// " <name>Bob</name>\n"
232/// " <homeAddress>\n"
233/// " <street>Some Street</street>\n"
234/// " <state>Some State</state>\n"
235/// " <city>Some City</city>\n"
236/// " <country>Some Country</country>\n"
237/// " </homeAddress>\n"
238/// " <age>21</age>\n"
239/// "</Employee>\n";
240///
241/// balxml::MiniReader reader;
242/// balxml::ErrorInfo errInfo;
243/// balxml::DecoderOptions options;
244///
245/// balxml::Decoder decoder(&options, &reader, &errInfo,
246/// &bsl::cerr, &bsl::cerr);
247///
248/// @endcode
249/// Now we open the document, but we don't begin decoding yet:
250/// @code
251/// int rc = decoder.open(INPUT, sizeof(INPUT) - 1);
252/// assert(0 == rc);
253/// @endcode
254/// Depending on the value of the first node, we can now determine whether the
255/// document is an `Address` object or an `Employee` object, and construct the
256/// target object accordingly:
257/// @code
258/// if (0 == bsl::strcmp(reader.nodeLocalName(), "Address")) {
259/// test::Address addr;
260/// rc = decoder.decode(&addr);
261/// bsl::cout << addr;
262/// }
263/// else {
264/// test::Employee bob;
265/// rc = decoder.decode(&bob);
266/// bsl::cout << bob;
267/// }
268///
269/// assert(0 == rc);
270/// @endcode
271/// When decoding is complete, we must close the decoder object:
272/// @code
273/// decoder.close();
274/// return 0;
275/// }
276/// @endcode
277/// @}
278/** @} */
279/** @} */
280
281/** @addtogroup bal
282 * @{
283 */
284/** @addtogroup balxml
285 * @{
286 */
287/** @addtogroup balxml_decoder
288 * @{
289 */
290
291#include <balscm_version.h>
292
293#include <balxml_base64parser.h>
295#include <balxml_hexparser.h>
296#include <balxml_listparser.h>
298#include <balxml_errorinfo.h>
299#include <balxml_reader.h>
301
302#include <bdlar_refutil.h>
303
304#include <bdlat_arrayfunctions.h>
307#include <bdlat_formattingmode.h>
310#include <bdlat_typecategory.h>
311#include <bdlat_typename.h>
313
314#include <bdlb_string.h>
315
317
318#include <bslma_allocator.h>
319#include <bslma_default.h>
320
321#include <bslmf_conditional.h>
322
323#include <bsls_assert.h>
324#include <bsls_keyword.h>
325#include <bsls_objectbuffer.h>
326#include <bsls_review.h>
327
328#include <bsl_algorithm.h> // bsl::min
329#include <bsl_istream.h>
330#include <bsl_map.h>
331#include <bsl_ostream.h>
332#include <bsl_streambuf.h>
333#include <bsl_string.h>
334#include <bsl_vector.h>
335#include <bsl_cstddef.h> // NULL
336#include <bsl_cstring.h>
337#include <bsl_cstdlib.h>
338#include <bsl_cerrno.h>
339
340#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
341#include <bslmf_if.h>
342#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
343
344
345namespace balxml {
346
347class Reader;
348class ErrorInfo;
349class Decoder;
350
351 // ============================
352 // class Decoder_ElementContext
353 // ============================
354
355/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
356///
357/// This protocol class contain functions related to parsing XML elements.
358/// When the Decoder reads the XML document, it forwards the information
359/// about the current node as events to this protocol. There are several
360/// implementations of this protocol, depending on the type of element. The
361/// correct implementation for each type is selected by the
362/// `Decoder_SelectContext` meta-function. Each of the functions take a
363/// `context` parameter, which contains members related to the context of
364/// the decoder.
365///
366/// See @ref balxml_decoder
368
369 public:
370 /// For syntactic purposes only.
372
373 // CALLBACKS
374 virtual int startElement(Decoder *decoder) = 0;
375
376 virtual int endElement(Decoder *decoder) = 0;
377
378 virtual int addCharacters(const char *chars,
379 bsl::size_t length,
380 Decoder *decoder) = 0;
381
382 virtual int parseAttribute(const char *name,
383 const char *value,
384 bsl::size_t lenValue,
385 Decoder *decoder) = 0;
386
387 virtual int parseSubElement(const char *elementName, Decoder *decoder) = 0;
388
389 int beginParse(Decoder *decoder);
390};
391
392 // =============
393 // class Decoder
394 // =============
395
396/// Engine for decoding value-semantic objects in XML format. The `decode`
397/// methods are function templates that will decode any object that meets
398/// the requirements of a sequence or choice object as defined in the
399/// @ref bdlat_sequencefunctions and @ref bdlat_choicefunctions components.
400/// These generic frameworks provide a common compile-time interface for
401/// manipulating struct-like and union-like objects.
402///
403/// See @ref balxml_decoder
404class Decoder {
405
410
411 // PRIVATE TYPES
412
413 /// This class provides stream for logging using
414 /// `bdlsb::MemOutStreamBuf` as a streambuf. The logging stream is
415 /// created on demand, i.e., during the first attempt to log message.
416 ///
417 /// See @ref balxml_decoder
418 class MemOutStream : public bsl::ostream {
420
421 private:
422 // NOT IMPLEMENTED
423 MemOutStream(const MemOutStream&);
424 MemOutStream& operator=(const MemOutStream&);
425
426 public:
427 // CREATORS
428
429 /// Create a new stream using the optionally specified
430 /// `basicAllocator`.
431 MemOutStream(bslma::Allocator *basicAllocator = 0);
432
433 /// Destroy this stream and release memory back to the allocator.
434 ~MemOutStream() BSLS_KEYWORD_OVERRIDE;
435
436 // MANIPULATORS
437
438 /// Reset the internal streambuf to empty.
439 void reset();
440
441 // ACCESSORS
442
443 /// Return a pointer to the memory containing the formatted values
444 /// formatted to this stream. The data is not null-terminated
445 /// unless a null character was appended onto this stream.
446 const char *data() const;
447
448 /// Return the length of the formatted data, including null
449 /// characters appended to the stream, if any.
450 int length() const;
451 };
452
454
455 // DATA
456 const DecoderOptions *d_options; // held, not owned
457 Utf8ReaderWrapper d_utf8ReaderWrapper;
458 Reader *d_reader; // held, not owned
459 ErrorInfo *d_errorInfo; // held, not owned
460
461 bslma::Allocator *d_allocator; // held, not owned
462
463 // placeholder for MemOutStream
464 bsls::ObjectBuffer<MemOutStream> d_logArea;
465
466 // if not zero, log stream was created at the moment of first logging
467 // and must be destroyed
468 MemOutStream *d_logStream;
469
470 bsl::ostream *d_errorStream; // held, not owned
471 bsl::ostream *d_warningStream; // held, not owned
472
473 bsl::string d_sourceUri; // URI of input document
474 int d_errorCount; // error count
475 int d_warningCount; // warning count
476
477 int d_numUnknownElementsSkipped;
478 // number of unknown
479 // elements skipped
480
481 bool d_fatalError; // fatal error flag
482
483 // remaining number of nesting levels allowed
484 int d_remainingDepth;
485
486 private:
487 // NOT IMPLEMENTED
488 Decoder(const Decoder&);
489 Decoder operator=(const Decoder&);
490
491 private:
492 // PRIVATE MANIPULATORS
493
494 /// Return the stream for logging. Note the if stream has not been
495 /// created yet, it will be created during this call.
496 bsl::ostream& logStream();
497
498 void resetErrors();
499 int checkForReaderErrors();
500 int checkForErrors(const ErrorInfo& errInfo);
501
502 /// When decoding a structure, make sure that the root tag of the XML
503 /// matches the structure of the specified `object` that we are decoding
504 /// into. Return 0 if it does.
505 template <class TYPE>
506 int validateTopElement(const TYPE *object);
507
508 void setDecoderError(ErrorInfo::Severity severity, bsl::string_view msg);
509
510 int readTopElement();
511 int parse(Decoder_ElementContext *context);
512
513 template <class TYPE>
514 int decodeCustomized(TYPE *object, int formattingMode);
515
516 template <class TYPE>
517 int decodeImp(TYPE *object, bdlat_TypeCategory::CustomizedType);
518
519 template <class TYPE>
520 int decodeImp(TYPE *object, bdlat_TypeCategory::DynamicType);
521
522 template <class TYPE>
523 int decodeImp(TYPE *, bdlat_TypeCategory::NullableValue); // stub
524
525 template <class TYPE, class ANY_CATEGORY>
526 int decodeImp(TYPE *object, ANY_CATEGORY);
527
528 public:
529 // CREATORS
531 Reader *reader,
532 ErrorInfo *errInfo,
533 bslma::Allocator *basicAllocator);
534
535 /// Construct a decoder object using the specified `options` and the
536 /// specified `reader` to perform the XML-level parsing. If the
537 /// (optionally) specified `errorInfo` is non-null, it is used to store
538 /// information about most serious error encountered during parsing.
539 /// During parsing, error and warning messages will be written to the
540 /// (optionally) specified `errorStream` and `warningStream` respectively.
541 ///
542 /// \pre The behavior is undefined unless `options` and
543 /// `reader` are both non-zero. The behavior becomes undefined if the
544 /// objects pointed to by any of the arguments is destroyed before this
545 /// object has completed parsing.
547 Reader *reader,
548 ErrorInfo *errInfo = 0,
549 bsl::ostream *errorStream = 0,
550 bsl::ostream *warningStream = 0,
551 bslma::Allocator *basicAllocator = 0);
552
553 /// Call `close` and destroy this object.
555
556 // MANIPULATORS
557
558 /// Put the associated `Reader` object (i.e., the `reader` specified at
559 /// construction) into a closed state.
560 void close();
561
562 /// Open the associated `Reader` object (see `Reader::open`) to read XML
563 /// data from the specified `stream`. The (optionally) specified `uri`
564 /// is used for identifying the input document in error messages.
565 /// Return 0 on success and non-zero otherwise.
566 int open(bsl::istream& stream, const char *uri = 0);
567
568 /// Open the associated `Reader` object (see `Reader::open`) to read XML
569 /// data from the specified stream `buffer`. The (optionally) specified
570 /// `uri` is used for identifying the input document in error messages.
571 /// Return 0 on success and non-zero otherwise.
572 int open(bsl::streambuf *buffer, const char *uri = 0);
573
574 /// Open the associated `Reader` object (see `Reader::open`) to read XML
575 /// data from memory at the specified `buffer`, with the specified
576 /// `length`. The (optionally) specified `uri` is used for identifying
577 /// the input document in error messages. Return 0 on success and
578 /// non-zero otherwise.
579 int open(const char *buffer, bsl::size_t length, const char *uri = 0);
580
581 /// Open the associated `Reader` object (see `Reader::open`) to read XML
582 /// data from the file with the specified `filename`. Return 0 on
583 /// success and non-zero otherwise.
584 int open(const char *filename);
585
586 /// Decode the specified `object` of parameterized `TYPE` from the
587 /// specified input `stream`. Return a reference to the modifiable
588 /// `stream`. If a decoding error is detected, `stream.fail()` will be
589 /// `true` after this method returns. The (optionally) specified `uri`
590 /// is used for identifying the input document in error messages. A
591 /// compilation error will result unless `TYPE` conforms to the
592 /// requirements of a `bdlat` sequence or choice, as described in
593 /// @ref bdlat_sequencefunctions and @ref bdlat_choicefunctions .
594 template <class TYPE>
595 bsl::istream& decode(bsl::istream& stream,
596 TYPE *object,
597 const char *uri = 0);
598
599 /// Decode the specified `object` of parameterized `TYPE` from the
600 /// specified stream `buffer`. The (optionally) specified `uri` is
601 /// used for identifying the input document in error messages. Return
602 /// 0 on success, and a non-zero value otherwise. A compilation error
603 /// will result unless `TYPE` conforms to the requirements of a bdlat
604 /// sequence or choice, as described in @ref bdlat_sequencefunctions and
605 /// @ref bdlat_choicefunctions .
606 template <class TYPE>
607 int decode(bsl::streambuf *buffer, TYPE *object, const char *uri = 0);
608
609 /// Decode the specified `object` of parameterized `TYPE` from the
610 /// memory at the specified `buffer` address, having the specified
611 /// `length`. The (optionally) specified `uri` is used for identifying
612 /// the input document in error messages. Return 0 on success, and a
613 /// non-zero value otherwise. A compilation error will result unless
614 /// `TYPE` conforms to the requirements of a bdlat sequence or choice,
615 /// as described in @ref bdlat_sequencefunctions and
616 /// @ref bdlat_choicefunctions .
617 template <class TYPE>
618 int decode(const char *buffer,
619 bsl::size_t length,
620 TYPE *object,
621 const char *uri = 0);
622
623 /// Decode the specified `object` of parameterized `TYPE` from the file
624 /// with the specified `filename`. Return 0 on success, and a non-zero
625 /// value otherwise. A compilation error will result unless `TYPE`
626 /// conforms to the requirements of a bdlat sequence or choice, as
627 /// described in @ref bdlat_sequencefunctions and @ref bdlat_choicefunctions .
628 template <class TYPE>
629 int decode(const char *filename, TYPE *object);
630
631 /// Decode the specified `object` of parameterized `TYPE` from the
632 /// input source specified by a previous call to `open` and leave the
633 /// reader in an open state. Return 0 on success, and a non-zero value
634 /// otherwise. A compilation error will result unless `TYPE` conforms
635 /// to the requirements of a bdlat sequence or choice, as described in
636 /// @ref bdlat_sequencefunctions and @ref bdlat_choicefunctions .
637 ///
638 /// \pre The behavior is undefined unless this call was preceded by a prior
639 /// successful call to `open`
640 template <class TYPE>
641 int decode(TYPE *object);
642
643 /// Decode the specified `object` of parameterized `TYPE` from the
644 /// specified input `stream`. Return a reference to the modifiable
645 /// `stream`. If a decoding error is detected, `stream.fail()` will be
646 /// `true` after this method returns. The (optionally) specified `uri` is
647 /// used for identifying the input document in error messages. A
648 /// compilation error will result unless `TYPE` conforms to the
649 /// requirements of a `bdlat` sequence or choice, as described in `bdlat_sequencefunctions` and `bdlat_choicefunctions`.
650 ///
651 /// \note Note that this
652 /// function behaves identically to `decode`, but does not instantiate any
653 /// templates at compile time at the expense of being slightly slower at
654 /// runtime; see the `balxml` package documentation for more details.
655 template <class TYPE>
656 bsl::istream& decodeAny(bsl::istream& stream,
657 TYPE *object,
658 const char *uri = 0);
659 bsl::istream& decodeAny(bsl::istream& stream,
660 bdlar::AnyRef *object,
661 const char *uri = 0);
662
663 /// Decode the specified `object` of parameterized `TYPE` from the
664 /// specified stream `buffer`. The (optionally) specified `uri` is used
665 /// for identifying the input document in error messages. Return 0 on
666 /// success, and a non-zero value otherwise. A compilation error will
667 /// result unless `TYPE` conforms to the requirements of a `bdlat` sequence
668 /// or choice, as described in @ref bdlat_sequencefunctions and `bdlat_choicefunctions`.
669 ///
670 /// \note Note that this function behaves identically
671 /// to `decode`, but does not instantiate any templates at compile time at
672 /// the expense of being slightly slower at runtime; see the `balxml`
673 /// package documentation for more details.
674 template <class TYPE>
675 int decodeAny(bsl::streambuf *buffer, TYPE *object, const char *uri = 0);
676 int decodeAny(bsl::streambuf *buffer,
677 bdlar::AnyRef *object,
678 const char *uri = 0);
679
680 /// Decode the specified `object` of parameterized `TYPE` from the input
681 /// source specified by a previous call to `open` and leave the reader in
682 /// an open state. Return 0 on success, and a non-zero value otherwise. A
683 /// compilation error will result unless `TYPE` conforms to the
684 /// requirements of a bdlat sequence or choice, as described in
685 /// @ref bdlat_sequencefunctions and @ref bdlat_choicefunctions .
686 ///
687 /// \pre The behavior is undefined unless this call was preceded by a prior successful call to `open`.
688 ///
689 /// \note Note that this function behaves identically to `decode`, but
690 /// does not instantiate any templates at compile time at the expense of
691 /// being slightly slower at runtime; see the `balxml` package
692 /// documentation for more details.
693 template <class TYPE>
694 int decodeAny(TYPE *object);
695 int decodeAny(bdlar::AnyRef *object);
696
697 /// Set the number of unknown elements skipped by the decoder during
698 /// the current decoding operation to the specified `value`.
699 ///
700 /// \pre The behavior is undefined unless `0 <= value`.
701 void setNumUnknownElementsSkipped(int value);
702
703 //ACCESSORS
704
705 /// Return a pointer to the non-modifiable decoder options provided at
706 /// construction.
707 const DecoderOptions *options() const;
708
709 /// Return the a pointer to the modifiable reader associated with this
710 /// decoder (i.e., the `reader` pointer provided at construction).
711 Reader *reader() const;
712
713 /// Return a pointer to the modifiable error-reporting structure
714 /// associated with this decoder (i.e., the `errInfo` pointer provided
715 /// at construction). The value stored in the error structure is reset
716 /// to indicate no error on a successful call to `open`.
717 ErrorInfo *errorInfo() const;
718
719 /// Return pointer to the error stream.
720 bsl::ostream *errorStream() const;
721
722 /// Return pointer to the warning stream.
723 bsl::ostream *warningStream() const;
724
725 /// Return the number of unknown elements that were skipped during the previous decoding operation.
726 ///
727 /// \note Note that unknown elements are skipped
728 /// only if `true == options()->skipUnknownElements()`.
729 int numUnknownElementsSkipped() const;
730
731 /// Return the severity of the most severe warning or error encountered
732 /// during the last call to the `decode` method. The severity is reset
733 /// each time `decode` is called.
734 ErrorInfo::Severity errorSeverity() const;
735
736 /// Return a string containing any error, warning, or trace messages
737 /// that were logged during the last call to the `decode` method. The
738 /// log is reset each time `decode` is called.
739 bslstl::StringRef loggedMessages() const;
740
741 /// Return the number of errors that occurred during decoding. This
742 /// number is reset to zero on a call to `open`.
743 int errorCount() const;
744
745 /// Return the number of warnings that occurred during decoding. This
746 /// number is reset to zero on a call to `open`.
747 int warningCount() const;
748};
749
750 // =========================
751 // class Decoder_ErrorLogger
752 // =========================
753
754/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
755///
756/// This class is used for logging errors and warnings. The usage of this
757/// class is simplified with macros, which are defined below.
758///
759/// See @ref balxml_decoder
761
762 // DATA
763 Decoder::MemOutStream d_stream;
764 ErrorInfo::Severity d_severity; // severity
765 Decoder *d_decoder; // context
766
767 private:
768 // NOT IMPLEMENTED
770 Decoder_ErrorLogger& operator=(const Decoder_ErrorLogger&);
771
772 public:
773 // CREATORS
774
775 /// Construct a logger for the specified `decoder`.
777 : d_stream(decoder->d_allocator)
778 , d_severity(severity)
779 , d_decoder(decoder)
780 {
781 }
782
783 /// Set the decoder's error message to the contents of the message
784 /// stream.
786 {
787 d_decoder->setDecoderError(d_severity,
788 bsl::string_view(d_stream.data(),
789 d_stream.length()));
790 }
791
792 bsl::ostream& stream()
793 {
794 return d_stream;
795 }
796};
797} // close package namespace
798
799// --- Anything below this line is implementation specific. Do not use. ----
800
801// LOGGING MACROS
802
803/// Usage: BAEXML_LOG_ERROR(myDecoder) << "Message"
804/// << value << BALXML_DECODER_LOG_END;
805#define BALXML_DECODER_LOG_ERROR(reporter) \
806 do { \
807 balxml::Decoder_ErrorLogger \
808 logger(balxml::ErrorInfo::e_ERROR, reporter); \
809 logger.stream()
810
811/// Usage: BAEXML_LOG_WARNING(myDecoder) << "Message"
812/// << value << BALXML_DECODER_LOG_END;
813#define BALXML_DECODER_LOG_WARNING(reporter) \
814 do { \
815 balxml::Decoder_ErrorLogger \
816 logger(balxml::ErrorInfo::e_WARNING, reporter); \
817 logger.stream()
818
819/// See usage of BALXML_DECODER_LOG_ERROR and BALXML_DECODER_LOG_WARNING,
820/// above.
821#define BALXML_DECODER_LOG_END \
822 bsl::flush; \
823 } while (false)
824
825// FORWARD DECLARATIONS
826
827
828namespace balxml {
829
830class Decoder_ElementContext;
831
832template <class TYPE>
833class Decoder_ChoiceContext;
834template <class TYPE, class PARSER>
835class Decoder_PushParserContext;
836template <class TYPE>
837class Decoder_SequenceContext;
838template <class TYPE>
839class Decoder_SimpleContext;
840template <class TYPE>
841class Decoder_UTF8Context;
842
843class Decoder_UnknownElementContext;
844
845class Decoder_StdStringContext; // proxy context
846class Decoder_StdVectorCharContext; // proxy context
847
848 // ==============================
849 // class Decoder_ListParser<TYPE>
850 // ==============================
851
852/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
853///
854/// This is a wrapper around `ListParser<TYPE>`. The
855/// `Decoder_PushParserContext` class needs a default constructible push
856/// parser. However, `ListParser<TYPE>` is not default constructible - it
857/// requires an `parseElementCallback`. This wrapper provides a default
858/// constructor that passes `TypesParserUtil::parseDefault` as the callback.
859///
860/// See @ref balxml_decoder
861template <class TYPE>
863
864 // PRIVATE TYPES
865 typedef typename
866 ListParser<TYPE>::ParseElementFunction ParseElementFunction;
867 typedef typename
869
870 // DATA
871 ListParser<TYPE> d_imp; // implementation object
872
873 private:
874 // NOT IMPLEMENTED
876 Decoder_ListParser& operator=(const Decoder_ListParser&);
877
878 // COMPILER BUG WORKAROUNDS
879
880 /// This function is provided to work around a bug in the AIX compiler.
881 /// It incorrectly complains that the following constructor initializer
882 /// list for `d_imp` is invalid:
883 /// @code
884 /// : d_imp((ParseElementFunction)&TypesParserUtil::parseDefault)
885 /// @endcode
886 /// The error message generated by the AIX compiler is:
887 /// @code
888 /// An object of type "BloombergLP::balxml::ListParser<TYPE>" cannot be
889 /// constructed from an rvalue of type "ParseElementFunction".
890 /// @endcode
891 /// To work around this, an explicit `convert` function is used to aid
892 /// the conversion.
893 static ParseElementCallback convert(ParseElementFunction func)
894 {
895 ParseElementCallback temp(func);
896 return temp;
897 }
898
899 public:
900 // CREATORS
902 : d_imp(convert(&TypesParserUtil::parseDefault))
903 {
904 }
905
906 // Using destructor generated by compiler:
907 // ~Decoder_ListParser();
908
909 // MANIPULATORS
910 int beginParse(TYPE *object)
911 {
912 return d_imp.beginParse(object);
913 }
914
916 {
917 return d_imp.endParse();
918 }
919
920 template <class INPUT_ITERATOR>
921 int pushCharacters(INPUT_ITERATOR begin, INPUT_ITERATOR end)
922 {
923 return d_imp.pushCharacters(begin, end);
924 }
925};
926} // close package namespace
927
928 // ===============================================
929 // struct balxml::Decoder_InstantiateContext<TYPE>
930 // ===============================================
931
932namespace balxml {
933
934/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
935///
936/// This `struct` instantiates a context for the parameterized `TYPE` that
937/// falls under the parameterized `CATEGORY`.
938template <class CATEGORY, class TYPE>
940
941/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
942template <class TYPE>
947
948/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
949template <>
955
956/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
957template <class TYPE>
962
963/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
964template <class TYPE>
969
970/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
971template <class TYPE>
976
977/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
978template <>
984
985/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
986///
987/// Note: Enums are treated as simple types (i.e., they are parsed by
988/// `TypesParserUtil`).
989template <class TYPE>
995
996 // ==================================
997 // struct Decoder_SelectContext<TYPE>
998 // ==================================
999
1000/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1001///
1002/// This meta-function is used to select a context for the parameterized
1003/// `TYPE`.
1004///
1005/// See @ref balxml_decoder
1006template <class TYPE>
1008
1009 private:
1010 typedef typename
1012
1013 public:
1014 typedef typename
1016};
1017
1018 // =================================
1019 // class Decoder_ChoiceContext<TYPE>
1020 // =================================
1021
1022/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1023///
1024/// This is the context for types that fall under
1025/// `bdlat_TypeCategory::Choice`.
1026///
1027/// See @ref balxml_decoder
1028template <class TYPE>
1030
1031 // DATA
1032 bool d_isSelectionNameKnown;
1033 TYPE *d_object_p;
1034 bool d_selectionIsRepeatable;
1035 bsl::string d_selectionName;
1036
1037 private:
1038 // NOT IMPLEMENTED
1040 Decoder_ChoiceContext &operator=(const Decoder_ChoiceContext &);
1041
1042 public:
1043 // CREATORS
1044 Decoder_ChoiceContext(TYPE *object, int formattingMode);
1045
1046 // Using compiler generated destructor:
1047 // ~Decoder_ChoiceContext();
1048
1049 // CALLBACKS
1050 int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1051
1052 int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1053
1054 int addCharacters(const char *chars,
1055 bsl::size_t length,
1057
1058 int parseAttribute(const char *name,
1059 const char *value,
1060 bsl::size_t lenValue,
1062
1063 int parseSubElement(const char *elementName,
1065};
1066
1067 // =============================
1068 // class Decoder_NillableContext
1069 // =============================
1070
1071/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1072///
1073/// Context for elements that have `bdlat_FormattingMode::e_NILLABLE`. It
1074/// acts as a proxy and forwards all callbacks to the held
1075/// `d_elementContext_p`. If `endElement` is called directly after
1076/// `startElement`, then the `isNil()` accessor will return true.
1077///
1078/// See @ref balxml_decoder
1080
1081 // DATA
1082 Decoder_ElementContext *d_elementContext_p;
1083 bool d_isNil;
1084
1085 private:
1086 // NOT IMPLEMENTED
1089
1090 public:
1091 // CREATORS
1093
1095
1096 // CALLBACKS
1097 int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1098
1099 int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1100
1101 int addCharacters(const char *chars,
1102 bsl::size_t length,
1104
1105 int parseAttribute(const char *name,
1106 const char *value,
1107 bsl::size_t lenValue,
1109
1110 int parseSubElement(const char *elementName,
1112
1113 // MANIPULATORS
1114
1115 /// Set the element context to the specified `elementContext`. The
1116 /// behavior of all methods in this class are undefined if this method
1117 /// has not been called.
1118 void setElementContext(Decoder_ElementContext *elementContext);
1119
1120 // ACCESSORS
1121
1122 /// Return `true` if the element is nil.
1123 bool isNil() const;
1124};
1125
1126 // ====================================================
1127 // class Decoder_PushParserContext<TYPE, PARSER>
1128 // ====================================================
1129
1130/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1131///
1132/// Context for types that use one of the following push parsers:
1133/// @code
1134/// o Base64Parser
1135/// o HexParser
1136/// o Decoder_ListParser
1137/// @endcode
1138///
1139/// See @ref balxml_decoder
1140template <class TYPE, class PARSER>
1142
1143 // DATA
1144 int d_formattingMode;
1145 TYPE *d_object_p;
1146 PARSER d_parser;
1147
1148 private:
1149 // NOT IMPLEMENTED
1152
1153 public:
1154 // CREATORS
1155 Decoder_PushParserContext(TYPE *object, int formattingMode);
1156
1157 // Using compiler generated destructor:
1158 // ~Decoder_PushParserContext();
1159
1160 // CALLBACKS
1161 int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1162
1163 int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1164
1165 int addCharacters(const char *chars,
1166 bsl::size_t length,
1168
1169 int parseAttribute(const char *name,
1170 const char *value,
1171 bsl::size_t lenValue,
1173
1174 int parseSubElement(const char *elementName,
1176};
1177
1178 // ===================================
1179 // class Decoder_SequenceContext<TYPE>
1180 // ===================================
1181
1182/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1183///
1184/// Context for types that fall under `bdlat_TypeCategory::Sequence`.
1185///
1186/// See @ref balxml_decoder
1187template <class TYPE>
1189
1190 // DATA
1191 bdlb::NullableValue<int> d_simpleContentId;
1192 TYPE *d_object_p;
1193
1194 private:
1195 // NOT IMPLEMENTED
1198
1199 public:
1200 // CREATORS
1201 Decoder_SequenceContext(TYPE *object, int formattingMode);
1202
1203 // Using compiler generated destructor:
1204 // ~Decoder_SequenceContext();
1205
1206 // CALLBACKS
1207 int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1208
1209 int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1210
1211 int addCharacters(const char *chars,
1212 bsl::size_t length,
1214
1215 int parseAttribute(const char *name,
1216 const char *value,
1217 bsl::size_t lenValue,
1219
1220 int parseSubElement(const char *elementName,
1222};
1223
1224 // =================================
1225 // class Decoder_SimpleContext<TYPE>
1226 // =================================
1227
1228/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1229///
1230/// Context for simple types (uses TypesParserUtil).
1231///
1232/// See @ref balxml_decoder
1233template <class TYPE>
1235
1236 // DATA
1237 //bsl::string d_chars;
1238 int d_formattingMode;
1239 TYPE *d_object_p;
1240
1241 private:
1242 // NOT IMPLEMENTED
1244 Decoder_SimpleContext &operator=(const Decoder_SimpleContext &);
1245
1246 public:
1247 // CREATORS
1248 Decoder_SimpleContext(TYPE *object, int formattingMode);
1249
1250 // Using compiler generated destructor:
1251 // ~Decoder_SimpleContext();
1252
1253 // CALLBACKS
1254 int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1255
1256 int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1257
1258 int addCharacters(const char *chars,
1259 bsl::size_t length,
1261
1262 int parseAttribute(const char *name,
1263 const char *value,
1264 bsl::size_t lenValue,
1266
1267 int parseSubElement(const char *elementName,
1269};
1270
1271 // ===================================
1272 // class Decoder_UnknownElementContext
1273 // ===================================
1274
1275/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1276///
1277/// Context for unknown elements. This context is used when an unknown
1278/// element is found, and the user selected.
1279///
1280/// See @ref balxml_decoder
1282
1283 private:
1284 // NOT IMPLEMENTED
1288
1289 public:
1290 // CREATORS
1292
1293 // Using compiler generated destructor:
1294 // ~Decoder_UnknownElementContext();
1295
1296 // CALLBACKS
1298
1300
1301 int addCharacters(const char *chars,
1302 bsl::size_t length,
1304
1305 int parseAttribute(const char *name,
1306 const char *value,
1307 bsl::size_t lenValue,
1309
1310 int parseSubElement(const char *elementName,
1312};
1313
1314 // =========================
1315 // class Decoder_UTF8Context
1316 // =========================
1317
1318/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1319///
1320/// Context for UTF8 strings (i.e., `bsl::string` and `bsl::vector<char>`).
1321///
1322/// See @ref balxml_decoder
1323template <class TYPE>
1325
1326 // DATA
1327 TYPE *d_object_p;
1328
1329 private:
1330 // NOT IMPLEMENTED
1332 Decoder_UTF8Context& operator=(const Decoder_UTF8Context&);
1333
1334 public:
1335 // CREATORS
1336 Decoder_UTF8Context(TYPE *object, int formattingMode);
1337
1338 // Generated by compiler:
1339 // ~Decoder_UTF8Context();
1340
1341 // CALLBACKS
1342 int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1343
1344 int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1345
1346 int addCharacters(const char *chars,
1347 bsl::size_t length,
1349
1350 int parseAttribute(const char *name,
1351 const char *value,
1352 bsl::size_t lenValue,
1354
1355 int parseSubElement(const char *elementName,
1357};
1358
1359 // ==============================
1360 // class Decoder_StdStringContext
1361 // ==============================
1362
1363/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1364///
1365/// Proxy context for `bsl::string`. This is just a proxy context. It will
1366/// forward all callbacks to the appropriate context, based on the
1367/// formatting mode.
1368///
1369/// See @ref balxml_decoder
1371
1372 public:
1373 // TYPES
1374
1375 // Note that these typedefs need to be made public because Sun compiler
1376 // complains that they are inaccessible from the union (below).
1382
1383 private:
1384 // DATA
1385 union {
1389 };
1390
1391 Decoder_ElementContext *d_context_p;
1392
1393 private:
1394 // NOT IMPLEMENTED
1397
1398 public:
1399 // CREATORS
1400 Decoder_StdStringContext(bsl::string *object, int formattingMode);
1401
1403
1404 // CALLBACKS
1405 int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1406
1407 int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1408
1409 int addCharacters(const char *chars,
1410 bsl::size_t length,
1412
1413 int parseAttribute(const char *name,
1414 const char *value,
1415 bsl::size_t lenValue,
1417
1418 int parseSubElement(const char *elementName,
1420};
1421
1422 // ==================================
1423 // class Decoder_StdVectorCharContext
1424 // ==================================
1425
1426/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1427///
1428/// Proxy context for `bsl::string`. This is just a proxy context. It will
1429/// forward all callbacks to the appropriate context, based on the
1430/// formatting mode.
1431///
1432/// See @ref balxml_decoder
1434
1435 public:
1436 // TYPES
1437
1438 // Note that these typedefs need to be made public because Sun compiler
1439 // complains that they are inaccessible from the union (below).
1450
1451 private:
1452 // DATA
1453 union {
1458 };
1459
1460 Decoder_ElementContext *d_context_p;
1461
1462 private:
1463 // NOT IMPLEMENTED
1467
1468 public:
1469 // CREATORS
1471 int formattingMode);
1472
1474
1475 // CALLBACKS
1476 int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1477
1478 int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1479
1480 int addCharacters(const char *chars,
1481 bsl::size_t length,
1483
1484 int parseAttribute(const char *name,
1485 const char *value,
1486 bsl::size_t lenValue,
1488
1489 int parseSubElement(const char *elementName,
1491};
1492
1493 // ====================================
1494 // class Decoder_PrepareSequenceContext
1495 // ====================================
1496
1497/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1498///
1499/// This class does one thing:
1500/// @code
1501/// o finds an element that has the 'IS_SIMPLE_CONTENT' flag set
1502/// @endcode
1503///
1504/// See @ref balxml_decoder
1506
1507 // DATA
1508 bdlb::NullableValue<int> *d_simpleContentId_p; // held, not owned
1509
1510 private:
1511 // NOT IMPLEMENTED
1515
1516 public:
1517 // CREATORS
1519
1520 // Using compiler generated destructor:
1521 // ~Decoder_PrepareSequenceContext();
1522
1523 // MANIPULATORS
1524 template <class TYPE, class INFO_TYPE>
1525 int operator()(const TYPE &object, const INFO_TYPE &info);
1526};
1527
1528 // ========================================
1529 // class Decoder_ParseSequenceSimpleContent
1530 // ========================================
1531
1532/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1533///
1534/// Parse simple content.
1535///
1536/// See @ref balxml_decoder
1538
1539 // DATA
1540 //const bsl::string *d_chars_p; // content characters
1541 const char *d_chars_p; // content characters
1542 bsl::size_t d_len;
1543 Decoder *d_decoder; // error logger (held)
1544
1545 private:
1546 // NOT IMPLEMENTED
1551
1552 public:
1553 // CREATORS
1555 const char *chars,
1556 bsl::size_t len);
1557
1558 // Generated by compiler:
1559 // ~Decoder_ParseSequenceSimpleContent();
1560
1561 // MANIPULATORS
1562 template <class TYPE, class INFO_TYPE>
1563 int operator()(TYPE *object, const INFO_TYPE& info);
1564
1565 template <class INFO_TYPE>
1566 int operator()(bsl::string *object, const INFO_TYPE& info);
1567};
1568
1569 // =====================================
1570 // class Decoder_ParseSequenceSubElement
1571 // =====================================
1572
1573/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1574///
1575/// This is similar to `Decoder_ParseObject`.
1576///
1577/// See @ref balxml_decoder
1579
1580 // DATA
1581 Decoder *d_decoder; // held, not owned
1582 const char *d_elementName_p; // held, not owned
1583 bsl::size_t d_lenName;
1584
1585 private:
1586 // NOT IMPLEMENTED
1590
1591 public:
1592 // CREATORS
1594 const char *elementName,
1595 bsl::size_t lenName);
1596
1597 // Using compiler-generated destructor:
1598 // ~Decoder_ParseSequenceSubElement();
1599
1600 // MANIPULATORS
1601 template <class TYPE, class INFO_TYPE>
1602 int operator()(TYPE *object, const INFO_TYPE &info);
1603
1604 template <class TYPE>
1605 int execute(TYPE *object, int id, int formattingMode);
1606};
1607
1608 // ============================
1609 // class Decoder_ParseAttribute
1610 // ============================
1611
1612/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1613///
1614/// Parse an attribute.
1615///
1616/// See @ref balxml_decoder
1618
1619 // DATA
1620 Decoder *d_decoder; // error logger (held)
1621 bool d_failed; // set to true if parsing failed
1622
1623 const char *d_name_p; // attribute name (held)
1624 const char *d_value_p; // attribute value (held)
1625 bsl::size_t d_value_length;
1626
1627 public:
1628 // IMPLEMENTATION MANIPULATORS
1629 template <class TYPE>
1630 int executeImp(TYPE *object,
1631 int formattingMode,
1633 template <class TYPE>
1634 int executeImp(TYPE *object,
1635 int formattingMode,
1637 template <class TYPE, class ANY_CATEGORY>
1638 int executeImp(TYPE *object, int formattingMode, ANY_CATEGORY);
1639
1640 private:
1641 // NOT IMPLEMENTED
1644 operator=(const Decoder_ParseAttribute&);
1645
1646 public:
1647 // CREATORS
1649 const char *name,
1650 const char *value,
1651 bsl::size_t lengthValue);
1652
1653 // Generated by compiler:
1654 // ~Decoder_ParseAttribute();
1655
1656 // MANIPULATORS
1657 template <class TYPE, class INFO_TYPE>
1658 int operator()(TYPE *object, const INFO_TYPE& info);
1659
1660 template <class TYPE>
1661 int execute(TYPE *object, int formattingMode);
1662
1663 // ACCESSORS
1664 bool failed() const;
1665};
1666
1667 // =========================
1668 // class Decoder_ParseObject
1669 // =========================
1670
1671/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1672///
1673/// Parse the visited object.
1674///
1675/// See @ref balxml_decoder
1677
1678 // PRIVATE TYPES
1679 struct CanBeListOrRepetition { };
1680 struct CanBeRepetitionOnly { };
1681
1682 // DATA
1683 Decoder *d_decoder; // held, not owned
1684 const char *d_elementName_p; // held, not owned
1685 bsl::size_t d_lenName;
1686
1687 private:
1688 // NOT IMPLEMENTED
1690 Decoder_ParseObject& operator=(const Decoder_ParseObject&);
1691
1692 public:
1693 // IMPLEMENTATION MANIPULATORS
1695 int formattingMode,
1697
1698 template <class TYPE>
1699 int executeImp(bsl::vector<TYPE> *object,
1700 int formattingMode,
1702
1703 template <class TYPE>
1704 int executeImp(TYPE *object,
1705 int formattingMode,
1707
1708 template <class TYPE>
1709 int executeImp(TYPE *object,
1710 int formattingMode,
1712
1713 template <class TYPE>
1714 int executeImp(TYPE *object,
1715 int formattingMode,
1717
1718 template <class TYPE>
1719 int executeImp(TYPE *object,
1720 int formattingMode,
1722
1723 template <class TYPE>
1724 int executeImp(TYPE *object,
1725 int formattingMode,
1727
1728 template <class TYPE>
1729 int executeImp(TYPE *object,
1730 int formattingMode,
1732
1733 template <class TYPE, class ANY_CATEGORY>
1734 int executeImp(TYPE *object, int formattingMode, ANY_CATEGORY);
1735
1736 template <class TYPE>
1737 int executeArrayImp(TYPE *object,
1738 int formattingMode,
1739 CanBeListOrRepetition);
1740
1741 template <class TYPE>
1742 int executeArrayImp(TYPE *object, int formattingMode, CanBeRepetitionOnly);
1743
1744 template <class TYPE>
1745 int executeArrayRepetitionImp(TYPE *object, int formattingMode);
1746
1747 public:
1748 // CREATORS
1750 const char *elementName,
1751 bsl::size_t lenName);
1752
1753 // Using compiler-generated destructor:
1754 // ~Decoder_ParseObject();
1755
1756 // MANIPULATORS
1757 template <class TYPE, class INFO_TYPE>
1758 int operator()(TYPE *object, const INFO_TYPE &info);
1759
1760 template <class TYPE>
1761 int execute(TYPE *object, int formattingMode);
1762};
1763
1764 // =================================
1765 // class Decoder_ParseNillableObject
1766 // =================================
1767
1768/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1769///
1770/// See @ref balxml_decoder
1772
1773 // DATA
1774 int d_formattingMode;
1775 Decoder_NillableContext d_nillableContext;
1776 Decoder *d_decoder;
1777
1778 // PRIVATE TYPES
1779 struct CustomizedManipulator;
1780
1781 public:
1782 // IMPLEMENTATION MANIPULATORS
1783 template <class TYPE>
1784 int executeImp(TYPE *object, bdlat_TypeCategory::DynamicType);
1785
1786 template <class TYPE>
1787 int executeImp(TYPE *object, bdlat_TypeCategory::CustomizedType);
1788
1789 template <class TYPE>
1790 int executeImp(TYPE *, bdlat_TypeCategory::NullableValue); // stub
1791
1792 template <class TYPE, class ANY_CATEGORY>
1793 int executeImp(TYPE *object, ANY_CATEGORY);
1794
1795 private:
1796 // NOT IMPLEMENTED
1799
1800 public:
1801 /// Construct a functor to parse nillable objects.
1802 Decoder_ParseNillableObject(Decoder *decoder, int formattingMode);
1803
1804 // Using compiler-generated destructor:
1805 // ~Decoder_ParseNillableObject();
1806
1807 // MANIPULATORS
1808
1809 /// Visit the specified `object`.
1810 template <class TYPE>
1811 int operator()(TYPE *object);
1812
1813 // ACCESSORS
1814
1815 /// Return `true` if the value was nil, and false otherwise.
1816 bool isNil() const;
1817};
1818
1819// ============================================================================
1820// PROXY CLASSES
1821// ============================================================================
1822
1823 // =============================
1824 // struct Decoder_decodeImpProxy
1825 // =============================
1826
1827/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1828///
1829/// See @ref balxml_decoder
1831
1832 // DATA
1834
1835 // CREATORS
1836
1837 // Creators have been omitted to allow simple static initialization of this
1838 // struct.
1839
1840 // FUNCTIONS
1841 template <class TYPE>
1842 inline
1844 {
1846 return -1;
1847 }
1848
1849 template <class TYPE, class ANY_CATEGORY>
1850 inline
1851 int operator()(TYPE *object, ANY_CATEGORY category)
1852 {
1853 return d_decoder->decodeImp(object, category);
1854 }
1855};
1856
1857 // ==========================================
1858 // struct Decoder_ParseAttribute_executeProxy
1859 // ==========================================
1860
1861/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1862///
1863/// See @ref balxml_decoder
1865
1866 // DATA
1869
1870 // CREATORS
1871
1872 // Creators have been omitted to allow simple static initialization of this
1873 // struct.
1874
1875 // FUNCTIONS
1876 template <class TYPE>
1877 inline
1878 int operator()(TYPE *object)
1879 {
1880 return d_instance_p->execute(object, d_formattingMode);
1881 }
1882};
1883
1884 // =============================================
1885 // struct Decoder_ParseAttribute_executeImpProxy
1886 // =============================================
1887
1888/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1889///
1890/// See @ref balxml_decoder
1892
1893 // DATA
1896
1897 // CREATORS
1898
1899 // Creators have been omitted to allow simple static initialization of this
1900 // struct.
1901
1902 // FUNCTIONS
1903 template <class TYPE>
1904 inline
1906 {
1908 return -1;
1909 }
1910
1911 template <class TYPE, class ANY_CATEGORY>
1912 inline
1913 int operator()(TYPE *object, ANY_CATEGORY category)
1914 {
1915 return d_instance_p->executeImp(object, d_formattingMode, category);
1916 }
1917};
1918
1919 // =======================================
1920 // struct Decoder_ParseObject_executeProxy
1921 // =======================================
1922
1923/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1924///
1925/// See @ref balxml_decoder
1927
1928 // DATA
1931
1932 // CREATORS
1933
1934 // Creators have been omitted to allow simple static initialization of this
1935 // struct.
1936
1937 // FUNCTIONS
1938 template <class TYPE>
1939 inline
1940 int operator()(TYPE *object)
1941 {
1942 return d_instance_p->execute(object, d_formattingMode);
1943 }
1944};
1945
1946 // ==========================================
1947 // struct Decoder_ParseObject_executeImpProxy
1948 // ==========================================
1949
1950/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1951///
1952/// See @ref balxml_decoder
1954
1955 // DATA
1958
1959 // CREATORS
1960
1961 // Creators have been omitted to allow simple static initialization of this
1962 // struct.
1963
1964 // FUNCTIONS
1965 template <class TYPE>
1966 inline
1968 {
1970 return -1;
1971 }
1972
1973 template <class TYPE, class ANY_CATEGORY>
1974 inline
1975 int operator()(TYPE *object, ANY_CATEGORY category)
1976 {
1977 return d_instance_p->executeImp(object, d_formattingMode, category);
1978 }
1979};
1980
1981 // ==================================================
1982 // struct Decoder_ParseNillableObject_executeImpProxy
1983 // ==================================================
1984
1985/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1986///
1987/// See @ref balxml_decoder
1989
1990 // DATA
1992
1993 // CREATORS
1994
1995 // Creators have been omitted to allow simple static initialization of this
1996 // struct.
1997
1998 // FUNCTIONS
1999 template <class TYPE>
2000 inline
2002 {
2004 return -1;
2005 }
2006
2007 template <class TYPE, class ANY_CATEGORY>
2008 inline
2009 int operator()(TYPE *object, ANY_CATEGORY category)
2010 {
2011 return d_instance_p->executeImp(object, category);
2012 }
2013};
2014} // close package namespace
2015
2016// ============================================================================
2017// INLINE DEFINITIONS
2018// ============================================================================
2019
2020 // -----------------------------------
2021 // class balxml::Decoder::MemOutStream
2022 // -----------------------------------
2023
2024inline
2025balxml::Decoder::MemOutStream::MemOutStream(bslma::Allocator *basicAllocator)
2026: bsl::ostream(0)
2027, d_sb(bslma::Default::allocator(basicAllocator))
2028{
2029 rdbuf(&d_sb);
2030}
2031
2032// MANIPULATORS
2033inline
2035{
2036 d_sb.reset();
2037}
2038
2039// ACCESSORS
2040inline
2042{
2043 return d_sb.data();
2044}
2045
2046inline
2048{
2049 return (int)d_sb.length();
2050}
2051
2052namespace balxml {
2053inline
2054void Decoder::setNumUnknownElementsSkipped(int value)
2055{
2056 BSLS_REVIEW(0 <= value);
2057
2058 d_numUnknownElementsSkipped = value;
2059}
2060
2061 // -------------
2062 // class Decoder
2063 // -------------
2064
2065inline
2066const DecoderOptions *Decoder::options() const
2067{
2068 return d_options;
2069}
2070
2071inline
2072Reader *Decoder::reader() const
2073{
2074 return d_reader;
2075}
2076
2077inline
2078ErrorInfo *Decoder::errorInfo() const
2079{
2080 return d_errorInfo;
2081}
2082
2083inline
2084bsl::ostream *Decoder::errorStream() const
2085{
2086 return d_errorStream;
2087}
2088
2089inline
2090int Decoder::numUnknownElementsSkipped() const
2091{
2092 return d_numUnknownElementsSkipped;
2093}
2094
2095inline
2096bsl::ostream *Decoder::warningStream() const
2097{
2098 return d_warningStream;
2099}
2100
2101inline
2102int Decoder::errorCount() const
2103{
2104 return d_errorCount;
2105}
2106
2107inline
2108int Decoder::warningCount() const
2109{
2110 return d_warningCount;
2111}
2112
2113/// If we're decoding a structure (aka `sequence` or `choice`), check to
2114/// make sure that the root tag in the XML matches the name of the specified
2115/// `TYPE` that we are decoding into. If `TYPE` has not implemented the
2116/// bdlat introspection protocol, then the class name will be NULL, and we
2117/// cannot check it against the tag name.
2118template <class TYPE>
2119inline
2120int Decoder::validateTopElement(const TYPE *object) {
2121
2122 // has the user asked us to validate the root tag?
2123 if (!d_options->validateRootTag()) {
2124 return 0; // RETURN
2125 }
2126
2127 // Are we decoding a sequence or a choice?
2128 typedef typename bdlat_TypeCategory::Select<TYPE>::Type Category_t;
2131 return 0; // RETURN
2132 }
2133
2134 // Do we have introspection on 'TYPE'?
2135 const char *typeName = bdlat_TypeName::className(*object);
2136 if (0 == typeName) { // no introspection support for 'TYPE'
2137 return 0; // RETURN
2138 }
2139
2140 // Does the class name match the root tag?
2141 const char *nodeName = d_reader->nodeName(); // this is the root tag
2142 if (0 == strcmp(nodeName, typeName)) {
2143 return 0; // RETURN
2144 }
2145
2147 << "The root object is of type '" << nodeName << "',"
2148 << " but we're attempting to decode an object of type "
2149 << "'" << typeName << "'." << BALXML_DECODER_LOG_END;
2150 return -1;
2151}
2152
2153
2154inline
2155int Decoder::open(bsl::istream& stream, const char *uri)
2156{
2157 return open(stream.rdbuf(), uri);
2158}
2159
2160template <class TYPE>
2161bsl::istream& Decoder::decode(bsl::istream& stream,
2162 TYPE *object,
2163 const char *uri)
2164{
2165 if (!stream.good()) {
2166
2168 << "The input stream is invalid. "
2169 << "Unable to decode XML object. "
2171
2172 return stream; // RETURN
2173 }
2174
2175 if (0 != this->decode(stream.rdbuf(), object, uri)) {
2176 stream.setstate(bsl::ios_base::failbit);
2177 }
2178
2179 return stream;
2180}
2181
2182template <class TYPE>
2183int
2184Decoder::decode(bsl::streambuf *buffer, TYPE *object, const char *uri)
2185{
2186 if (this->open(buffer, uri) != 0) {
2187
2188 return this->errorCount(); // RETURN
2189
2190 }
2191
2192 int ret = validateTopElement(object);
2193 if (0 == ret) {
2194 ret = this->decode(object);
2195 }
2196
2197 switch(errorSeverity()) {
2198 case ErrorInfo::e_NO_ERROR:
2199 break;
2200 case ErrorInfo::e_WARNING:
2201 if (d_warningStream) {
2202 *d_warningStream << loggedMessages();
2203 }
2204 break;
2205 default:
2206 if (d_errorStream) {
2207 *d_errorStream << loggedMessages();
2208 }
2209 break;
2210 }
2211
2212 this->close();
2213 return ret;
2214}
2215
2216template <class TYPE>
2217int Decoder::decode(const char *buffer,
2218 bsl::size_t buflen,
2219 TYPE *object,
2220 const char *uri)
2221{
2222 if (this->open(buffer, buflen, uri) != 0) {
2223
2224 return this->errorCount(); // RETURN
2225 }
2226
2227 int ret = validateTopElement(object);
2228 if (0 == ret) {
2229 ret = this->decode(object);
2230 }
2231
2232 this->close();
2233 return ret;
2234}
2235
2236template <class TYPE>
2237int Decoder::decode(const char *filename, TYPE *object)
2238{
2239 if (this->open(filename) != 0) {
2240
2241 return this->errorCount(); // RETURN
2242 }
2243
2244 int ret = validateTopElement(object);
2245 if (0 == ret) {
2246 ret = this->decode(object);
2247 }
2248
2249 this->close();
2250 return ret;
2251}
2252
2253template <class TYPE>
2254inline
2255int Decoder::decode(TYPE *object)
2256{
2258
2259 typedef typename
2261
2262 this->decodeImp(object, TypeCategory());
2263
2264 return this->errorCount();
2265}
2266
2267template <class TYPE>
2268inline
2269bsl::istream& Decoder::decodeAny(bsl::istream& stream,
2270 TYPE *object,
2271 const char *uri)
2272{
2274 return decodeAny(stream, &ref, uri);
2275}
2276
2277template <class TYPE>
2278inline
2279int Decoder::decodeAny(bsl::streambuf *buffer, TYPE *object, const char *uri)
2280{
2282 return decodeAny(buffer, &ref, uri);
2283}
2284
2285template <class TYPE>
2286inline
2287int Decoder::decodeAny(TYPE *object)
2288{
2290 return decodeAny(&ref);
2291}
2292
2293template <class TYPE>
2294inline
2295int Decoder::decodeImp(TYPE *object, bdlat_TypeCategory::DynamicType)
2296{
2297 Decoder_decodeImpProxy proxy = { this };
2298 int ret = bdlat_TypeCategoryUtil::manipulateByCategory(object, proxy);
2299 if (0 != ret) {
2301 << "The object being decoded is a 'DynamicType', and "
2302 "attempting to manipulate the object by its dynamic "
2303 "category returned a non-zero status."
2305 return ret;
2306 }
2307
2308 return 0;
2309}
2310
2312 // DATA
2315
2316 // MANIPULATORS
2317 template <class t_BASE_TYPE>
2318 int operator()(t_BASE_TYPE *base)
2319 {
2320 typedef typename Decoder_InstantiateContext<
2321 bdlat_TypeCategory::Simple, t_BASE_TYPE>::Type BaseContext;
2322 BaseContext ctx(base, d_formattingMode);
2323 return ctx.beginParse(d_that);
2324 }
2325};
2326
2327template <class TYPE>
2328inline
2329int Decoder::decodeCustomized(TYPE *object, int formattingMode)
2330{
2331 CustomizedManipulator baseManipulator = {this, formattingMode};
2333 object,
2334 baseManipulator);
2335}
2336
2337template <class TYPE>
2338inline
2339int Decoder::decodeImp(TYPE *object, bdlat_TypeCategory::CustomizedType)
2340{
2341 return decodeCustomized(object, d_options->formattingMode());
2342}
2343
2344template <class TYPE>
2345inline
2346int Decoder::decodeImp(TYPE *, bdlat_TypeCategory::NullableValue)
2347{
2348 BSLS_ASSERT_INVOKE_NORETURN("Must not be reached");
2349}
2350
2351template <class TYPE, class ANY_CATEGORY>
2352inline
2353int Decoder::decodeImp(TYPE *object, ANY_CATEGORY)
2354{
2355 typedef typename
2356 Decoder_InstantiateContext<ANY_CATEGORY, TYPE>::Type ContextType;
2357
2358 ContextType elementContext(object, d_options->formattingMode());
2359
2360 return elementContext.beginParse(this);
2361}
2362
2363 // ---------------------------------
2364 // class Decoder_ChoiceContext<TYPE>
2365 // ---------------------------------
2366
2367template <class TYPE>
2368inline
2370 int formattingMode)
2371: d_isSelectionNameKnown(false)
2372, d_object_p(object)
2373, d_selectionIsRepeatable(false)
2374, d_selectionName()
2375{
2376 (void) formattingMode;
2378 (formattingMode & bdlat_FormattingMode::e_TYPE_MASK));
2379}
2380
2381// CALLBACKS
2382
2383template <class TYPE>
2385{
2386 enum { k_SUCCESS = 0 };
2387
2388 d_isSelectionNameKnown = false; // no selection seen yet
2389
2390 return k_SUCCESS;
2391}
2392
2393template <class TYPE>
2395{
2396 enum { k_SUCCESS = 0, k_FAILURE = -1 };
2397
2398 if (!d_isSelectionNameKnown) {
2400 << "No elements selected in choice."
2402
2403 return k_FAILURE; // will trigger failure in parser // RETURN
2404 }
2405
2406 return k_SUCCESS;
2407}
2408
2409template <class TYPE>
2411 bsl::size_t length,
2412 Decoder *decoder)
2413{
2414 enum { k_SUCCESS = 0, k_FAILURE = -1 };
2415
2416 BSLS_REVIEW(0 != length);
2417
2418 const char *begin = chars;
2419 const char *end = begin + length;
2420
2422
2423 if (begin != end) {
2425 << "Invalid characters \""
2426 << bsl::string(begin, end - begin)
2427 << "\" when parsing choice."
2429
2430 return k_FAILURE; // will trigger failure in parser // RETURN
2431 }
2432
2433 return k_SUCCESS;
2434}
2435
2436template <class TYPE>
2437inline
2439 const char *,
2440 bsl::size_t,
2441 Decoder *)
2442{
2443 enum { k_ATTRIBUTE_IGNORED = 0 };
2444
2445 return k_ATTRIBUTE_IGNORED;
2446}
2447
2448template <class TYPE>
2450 Decoder *decoder)
2451{
2452 enum { k_FAILURE = -1 };
2453
2454 const int lenName = static_cast<int>(bsl::strlen(elementName));
2455
2456 if (d_isSelectionNameKnown
2457 && (!d_selectionIsRepeatable || d_selectionName != elementName))
2458 {
2460 << "Only one selection is permitted inside choice."
2462
2463 return k_FAILURE; // RETURN
2464 }
2465
2466 bool wasSelectionNameKnown = d_isSelectionNameKnown;
2467 d_isSelectionNameKnown = true;
2468
2469 if (decoder->options()->skipUnknownElements() &&
2470 false == bdlat_ChoiceFunctions::hasSelection(*d_object_p,
2471 elementName,
2472 lenName)) {
2474 decoder->numUnknownElementsSkipped() + 1);
2475 d_selectionIsRepeatable = true; // assume repeatable
2476 d_selectionName.assign(elementName, lenName);
2477
2478 Decoder_UnknownElementContext unknownElement;
2479 return unknownElement.beginParse(decoder); // RETURN
2480 }
2481
2482 if (!wasSelectionNameKnown) {
2483 if (0 != bdlat_ChoiceFunctions::makeSelection(d_object_p,
2484 elementName,
2485 lenName)) {
2487 << "Unable to make selection: \""
2488 << elementName
2489 << "\"."
2491
2492 return k_FAILURE; // RETURN
2493 }
2494
2495 d_selectionIsRepeatable = true; // TBD: check if repeatable
2496 d_selectionName.assign(elementName, lenName);
2497 }
2498
2499 Decoder_ParseObject parseObject(decoder, elementName, lenName);
2500 return bdlat_ChoiceFunctions::manipulateSelection(d_object_p, parseObject);
2501}
2502
2503 // ----------------------------------------------------
2504 // class Decoder_PushParserContext<TYPE, PARSER>
2505 // ----------------------------------------------------
2506
2507// CREATORS
2508template <class TYPE, class PARSER>
2509inline
2511 TYPE *object,
2512 int formattingMode)
2513: d_formattingMode(formattingMode), d_object_p(object)
2514{
2515}
2516
2517// CALLBACKS
2518
2519template <class TYPE, class PARSER>
2521{
2522 int result = d_parser.beginParse(d_object_p);
2523
2524 if (0 != result) {
2526 << "Unable to begin parsing list or binary type"
2527
2528 << "\"."
2530 }
2531
2532 return result;
2533}
2534
2535template <class TYPE, class PARSER>
2537{
2538 int result = d_parser.endParse();
2539
2540 if (0 != result) {
2542 << "Unable to end parsing list or binary type"
2543 << "\"."
2545 }
2546
2547 return result;
2548}
2549
2550template <class TYPE, class PARSER>
2552 const char *chars,
2553 bsl::size_t length,
2554 Decoder *decoder)
2555{
2556 const char *begin = chars;
2557 const char *end = begin + length;
2558
2559 int result = d_parser.pushCharacters(begin, end);
2560
2561 if (0 != result) {
2563 << "Unable to push \"" << chars
2564 << "\" when parsing list or binary type"
2565
2566 << "\"."
2568 }
2569
2570 return result;
2571}
2572
2573template <class TYPE, class PARSER>
2574inline
2576 const char *,
2577 bsl::size_t,
2578 Decoder *)
2579{
2580 enum { k_ATTRIBUTE_IGNORED = 0 };
2581
2582 return k_ATTRIBUTE_IGNORED;
2583}
2584
2585template <class TYPE, class PARSER>
2587 const char *elementName,
2588 Decoder *decoder)
2589{
2590 enum { k_FAILURE = -1 };
2591
2593 << "Unexpected sub-element \"" << elementName
2594 << "\" when parsing list or binary type"
2595 << "\"."
2597
2598 return k_FAILURE;
2599}
2600
2601 // -----------------------------------
2602 // class Decoder_SequenceContext<TYPE>
2603 // -----------------------------------
2604
2605// CREATORS
2606template <class TYPE>
2607inline
2609 int formattingMode)
2610: d_object_p(object)
2611{
2612 (void) formattingMode;
2614 (formattingMode & bdlat_FormattingMode::e_TYPE_MASK));
2615
2616 // {DRQS 153551134<GO>}: gcc can occasionally mis-diagnose
2617 // 'd_simpleContentId' as uninitialized. This workaround avoids that
2618 // problem (which can cause build failures if '-Wmaybe-uninitialized' and
2619 // '-Werror' are set). See also {DRQS 75130685<GO>} and {DRQS
2620 // 115347303<GO>}.
2621 d_simpleContentId.makeValue(0);
2622 d_simpleContentId.reset();
2623}
2624
2625// CALLBACKS
2626
2627template <class TYPE>
2629{
2630 //d_chars.clear();
2631
2632 Decoder_PrepareSequenceContext prepareSequenceContext(&d_simpleContentId);
2633
2635 d_object_p,
2636 prepareSequenceContext);
2637
2638 if (0 != ret) {
2640 << "Unable to prepare sequence context!"
2642 }
2643
2644 return ret;
2645}
2646
2647template <class TYPE>
2649{
2650 enum { k_SUCCESS = 0 };
2651
2652 return k_SUCCESS;
2653}
2654
2655template <class TYPE>
2657 bsl::size_t length,
2658 Decoder *decoder)
2659{
2660 enum { k_SUCCESS = 0, k_FAILURE = -1 };
2661
2662 BSLS_REVIEW(0 != length);
2663
2664 if (d_simpleContentId.isNull()) {
2665
2666 const char *begin = chars;
2667 const char *end = begin + length;
2668
2670
2671 if (begin != end) {
2673 << "Unexpected characters: \""
2674 << bsl::string(begin, end - begin)
2675 << "\"."
2677
2678 return k_FAILURE; // RETURN
2679 }
2680 return k_SUCCESS; // RETURN
2681 }
2682
2683 Decoder_ParseSequenceSimpleContent parseSimpleContent(decoder,
2684 chars,
2685 length);
2686
2688 d_object_p,
2689 parseSimpleContent,
2690 d_simpleContentId.value());
2691}
2692
2693template <class TYPE>
2695 const char *value,
2696 bsl::size_t lenValue,
2697 Decoder *decoder)
2698{
2699 enum { k_SUCCESS = 0, k_ATTRIBUTE_IGNORED = 0, k_FAILURE = -1 };
2700
2701 const int lenName = static_cast<int>(bsl::strlen(name));
2702
2703 Decoder_ParseAttribute visitor(decoder, name, value, lenValue);
2704
2706 visitor,
2707 name,
2708 lenName)) {
2709 if (visitor.failed()) {
2710 return k_FAILURE; // RETURN
2711 }
2712 return k_ATTRIBUTE_IGNORED; // RETURN
2713 }
2714
2715 return k_SUCCESS;
2716}
2717
2718template <class TYPE>
2720 Decoder *decoder)
2721{
2722 enum { k_FAILURE = -1 };
2723
2724 const int lenName = static_cast<int>(bsl::strlen(elementName));
2725
2726 if (decoder->options()->skipUnknownElements()
2727 && false == bdlat_SequenceFunctions::hasAttribute(*d_object_p,
2728 elementName,
2729 lenName)) {
2731 decoder->numUnknownElementsSkipped() + 1);
2732 Decoder_UnknownElementContext unknownElement;
2733 return unknownElement.beginParse(decoder); // RETURN
2734 }
2735
2736 Decoder_ParseSequenceSubElement visitor(decoder, elementName, lenName);
2737
2739 visitor,
2740 elementName,
2741 lenName);
2742}
2743
2744 // ---------------------------------
2745 // class Decoder_SimpleContext<TYPE>
2746 // ---------------------------------
2747
2748// CREATORS
2749template <class TYPE>
2750inline
2752 int formattingMode)
2753: d_formattingMode(formattingMode)
2754, d_object_p(object)
2755{
2756}
2757
2758// CALLBACKS
2759
2760template <class TYPE>
2762{
2763 enum { k_SUCCESS = 0 };
2764
2765 //d_chars.clear();
2766
2767 return k_SUCCESS;
2768}
2769
2770template <class TYPE>
2772{
2773 enum { k_SUCCESS = 0, k_FAILURE = -1 };
2774
2775 return k_SUCCESS;
2776}
2777
2778template <class TYPE>
2780 bsl::size_t length,
2781 Decoder *decoder)
2782{
2783 enum { k_SUCCESS = 0, k_FAILURE = -1 };
2784
2785 const char *begin = chars;
2786 const char *end = begin + length;
2787
2789
2790 if (0 != TypesParserUtil::parse(d_object_p,
2791 begin,
2792 static_cast<int>(end - begin),
2793 d_formattingMode)) {
2795 << "Unable to parse \""
2796 << bsl::string(begin, end)
2797 << "\" when parsing list or binary type"
2798 << "\".\n"
2800
2801 return k_FAILURE; // RETURN
2802 }
2803
2804 return k_SUCCESS;
2805}
2806
2807template <class TYPE>
2808inline
2810 const char *,
2811 bsl::size_t,
2812 Decoder *)
2813{
2814 enum { k_ATTRIBUTE_IGNORED = 0 };
2815
2816 return k_ATTRIBUTE_IGNORED;
2817}
2818
2819template <class TYPE>
2821 Decoder *decoder)
2822{
2823 enum { k_FAILURE = -1 };
2824
2826 << "Attempted to create sub context for \""
2827 << elementName << "\" inside simple type"
2828
2829 << "\"."
2831
2832 return k_FAILURE; // will trigger failure in parser
2833}
2834
2835 // -------------------------
2836 // class Decoder_UTF8Context
2837 // -------------------------
2838
2839// CREATORS
2840template <class TYPE>
2841inline
2843: d_object_p(object)
2844{
2845}
2846
2847// CALLBACKS
2848
2849template <class TYPE>
2850inline
2852{
2853 enum { k_SUCCESS = 0 };
2854
2855 d_object_p->clear();
2856
2857 return k_SUCCESS;
2858}
2859
2860template <class TYPE>
2861inline
2863{
2864 enum { k_SUCCESS = 0 };
2865
2866 return k_SUCCESS;
2867}
2868
2869template <class TYPE>
2870inline int
2872 bsl::size_t length,
2873 Decoder *)
2874{
2875 enum { k_SUCCESS = 0 };
2876
2877 d_object_p->insert(d_object_p->end(), chars, chars + length);
2878
2879 return k_SUCCESS;
2880}
2881
2882template <class TYPE>
2883inline
2885 const char *,
2886 bsl::size_t,
2887 Decoder *)
2888{
2889 enum { k_ATTRIBUTE_IGNORED = 0 };
2890
2891 return k_ATTRIBUTE_IGNORED;
2892}
2893
2894template <class TYPE>
2896 Decoder *decoder)
2897{
2898 enum { k_FAILURE = -1 };
2899
2901 << "Attempted to create sub context for \""
2902 << elementName << "\" inside UTF8 type."
2904
2905 return k_FAILURE; // will trigger failure in parser
2906}
2907
2908 // ------------------------------------
2909 // class Decoder_PrepareSequenceContext
2910 // ------------------------------------
2911
2912// CREATORS
2913inline
2914Decoder_PrepareSequenceContext::Decoder_PrepareSequenceContext(
2915 bdlb::NullableValue<int> *simpleContentId)
2916: d_simpleContentId_p(simpleContentId)
2917{
2918 d_simpleContentId_p->reset();
2919}
2920
2921// MANIPULATORS
2922template <class TYPE, class INFO_TYPE>
2924 const INFO_TYPE& info)
2925{
2926 enum { k_SUCCESS = 0 };
2927
2928 if (info.formattingMode() & bdlat_FormattingMode::e_SIMPLE_CONTENT) {
2929 BSLS_ASSERT_SAFE(d_simpleContentId_p->isNull());
2930 d_simpleContentId_p->makeValue(info.id());
2931 }
2932
2933 return k_SUCCESS;
2934}
2935
2936 // ----------------------------------------
2937 // class Decoder_ParseSequenceSimpleContent
2938 // ----------------------------------------
2939
2940// CREATORS
2941inline
2942Decoder_ParseSequenceSimpleContent::Decoder_ParseSequenceSimpleContent(
2943 Decoder *decoder,
2944 const char *chars,
2945 bsl::size_t len)
2946: d_chars_p(chars), d_len(len), d_decoder(decoder)
2947{
2948 BSLS_REVIEW(d_chars_p);
2949 BSLS_REVIEW(d_decoder);
2950}
2951
2952// MANIPULATORS
2953template <class TYPE, class INFO_TYPE>
2955 const INFO_TYPE& info)
2956{
2957 BSLS_ASSERT_SAFE(info.formattingMode()
2959
2960 enum { k_SUCCESS = 0, k_FAILURE = -1 };
2961
2962 const char *begin = d_chars_p;
2963 const char *end = begin + d_len;
2964
2966
2967 if (0 != TypesParserUtil::parse(object,
2968 begin,
2969 static_cast<int>(end - begin),
2970 info.formattingMode())) {
2971 BALXML_DECODER_LOG_ERROR(d_decoder)
2972 << "Unable to parse \""
2973 << bsl::string(begin, end)
2974 << "\" within simple content"
2975
2976 << "\"."
2978
2979 return k_FAILURE; // RETURN
2980 }
2981
2982 return k_SUCCESS;
2983}
2984
2985template <class INFO_TYPE>
2986inline
2988 const INFO_TYPE& info)
2989{
2990 enum { k_SUCCESS = 0 };
2991
2992 BSLS_ASSERT_SAFE(info.formattingMode()
2994
2995 (void) info;
2996
2997 object->assign(d_chars_p, d_len);
2998
2999 return k_SUCCESS;
3000}
3001
3002 // -------------------------------------
3003 // class Decoder_ParseSequenceSubElement
3004 // -------------------------------------
3005
3006// CREATORS
3007inline
3008Decoder_ParseSequenceSubElement::Decoder_ParseSequenceSubElement(
3009 Decoder *decoder,
3010 const char *elementName,
3011 bsl::size_t lenName)
3012: d_decoder(decoder), d_elementName_p(elementName), d_lenName(lenName)
3013{
3014}
3015
3016// MANIPULATORS
3017template <class TYPE, class INFO_TYPE>
3018inline
3020 const INFO_TYPE& info)
3021{
3022 return execute(object, info.id(), info.formattingMode());
3023}
3024
3025template <class TYPE>
3027 int,
3028 int formattingMode)
3029{
3030 enum { k_FAILURE = -1 };
3031 Decoder_ParseObject parseObject(d_decoder, d_elementName_p, d_lenName);
3032
3033 return parseObject.execute(object, formattingMode);
3034}
3035
3036 // ----------------------------
3037 // class Decoder_ParseAttribute
3038 // ----------------------------
3039
3040// PRIVATE MANIPULATORS
3041template <class TYPE>
3043 TYPE *object,
3044 int formattingMode,
3046{
3049 }
3050
3052 this, formattingMode
3053 };
3054
3056}
3057
3058template <class TYPE>
3059inline
3061 TYPE *object,
3062 int formattingMode,
3064{
3066 formattingMode };
3068}
3069
3070template <class TYPE, class ANY_CATEGORY>
3072 int formattingMode,
3073 ANY_CATEGORY)
3074{
3075 enum { k_SUCCESS = 0, k_FAILURE = - 1 };
3076
3077 bool isAttribute = formattingMode
3079
3080 if (!isAttribute) {
3082 << "Object '" << d_name_p << "' is "
3083 << "being parsed as an attribute, "
3084 << "but it does not have the "
3085 << "'IS_ATTRIBUTE' flag set."
3087 }
3088
3089 if (0 != TypesParserUtil::parse(object,
3090 d_value_p,
3091 static_cast<int>(d_value_length),
3092 formattingMode)) {
3093 BALXML_DECODER_LOG_ERROR(d_decoder)
3094 << "Unable to parse \""
3095 << bsl::string(d_value_p, d_value_length)
3096 << "\" (for '" << d_name_p << "' attribute)"
3097
3098 << "\".\n"
3100
3101 d_failed = true;
3102
3103 return k_FAILURE; // RETURN
3104 }
3105
3106 return k_SUCCESS;
3107}
3108
3109// CREATORS
3110inline
3111Decoder_ParseAttribute::Decoder_ParseAttribute(Decoder *decoder,
3112 const char *name,
3113 const char *value,
3114 bsl::size_t lengthValue)
3115: d_decoder(decoder)
3116, d_failed(false)
3117, d_name_p(name)
3118, d_value_p(value)
3119, d_value_length(lengthValue)
3120{
3121 BSLS_REVIEW(d_decoder);
3122 BSLS_REVIEW(d_name_p);
3123 BSLS_REVIEW(d_value_p);
3124}
3125
3126// MANIPULATORS
3127template <class TYPE, class INFO_TYPE>
3128inline
3129int Decoder_ParseAttribute::operator()(TYPE *object, const INFO_TYPE& info)
3130{
3131 return execute(object, info.formattingMode());
3132}
3133
3134template <class TYPE>
3135inline
3136int Decoder_ParseAttribute::execute(TYPE *object, int formattingMode)
3137{
3138 typedef typename
3140
3141 return executeImp(object, formattingMode, TypeCategory());
3142}
3143
3144// ACCESSORS
3145inline
3147{
3148 return d_failed;
3149}
3150
3151 // -------------------------
3152 // class Decoder_ParseObject
3153 // -------------------------
3154
3155// PRIVATE MANIPULATORS
3156template <class TYPE>
3157inline
3159 int formattingMode,
3161{
3162 typedef bdlat_TypeCategory::Select<TYPE> Selector;
3163
3164 enum {
3165 CAN_BE_REPETITION_ONLY
3166 = ( (int)Selector::e_SELECTION
3168 || (int)Selector::e_SELECTION
3170 };
3171
3172 typedef typename bsl::conditional<CAN_BE_REPETITION_ONLY,
3173 CanBeRepetitionOnly,
3174 CanBeListOrRepetition>::type Toggle;
3175
3176 return executeArrayImp(object, formattingMode, Toggle());
3177}
3178
3179template <class TYPE>
3180inline
3182 int formattingMode,
3184{
3185 return executeArrayImp(object, formattingMode, CanBeListOrRepetition());
3186}
3187
3188template <class TYPE>
3190 TYPE *object,
3191 int formattingMode,
3193{
3194 enum { k_FAILURE = -1 };
3195
3196 if (formattingMode & bdlat_FormattingMode::e_UNTAGGED) {
3197 if (d_decoder->options()->skipUnknownElements()
3199 *object,
3200 d_elementName_p,
3201 static_cast<int>(d_lenName))) {
3203 d_decoder->numUnknownElementsSkipped() + 1);
3204 Decoder_UnknownElementContext unknownElement;
3205 return unknownElement.beginParse(d_decoder); // RETURN
3206 }
3207
3209 object,
3210 *this,
3211 d_elementName_p,
3212 static_cast<int>(d_lenName));
3213 // RETURN
3214 }
3215
3216 typedef typename
3218 bdlat_TypeCategory::Sequence, TYPE>::Type Context;
3219
3220 Context context(object, formattingMode);
3221
3222 return context.beginParse(d_decoder);
3223}
3224
3225template <class TYPE>
3227 int formattingMode,
3229{
3230 enum { k_FAILURE = -1 };
3231
3232 bool isUntagged = formattingMode & bdlat_FormattingMode::e_UNTAGGED;
3233
3234 if (isUntagged) {
3235 if (d_decoder->options()->skipUnknownElements()
3237 *object,
3238 d_elementName_p,
3239 static_cast<int>(d_lenName))) {
3241 d_decoder->numUnknownElementsSkipped() + 1);
3242 Decoder_UnknownElementContext unknownElement;
3243 return unknownElement.beginParse(d_decoder); // RETURN
3244 }
3245
3247 object,
3248 d_elementName_p,
3249 static_cast<int>(d_lenName))) {
3250 BALXML_DECODER_LOG_ERROR(d_decoder)
3251 << "Unable to make selection: \""
3252 << d_elementName_p
3253 << "\"."
3255
3256 return k_FAILURE; // RETURN
3257 }
3258
3259 return bdlat_ChoiceFunctions::manipulateSelection(object, *this);
3260 // RETURN
3261 }
3262
3263 typedef typename
3265 bdlat_TypeCategory::Choice, TYPE>::Type Context;
3266
3267 Context context(object, formattingMode);
3268
3269 return context.beginParse(d_decoder);
3270}
3271
3272template <class TYPE>
3274 TYPE *object,
3275 int formattingMode,
3277{
3278 enum { k_SUCCESS = 0, k_FAILURE = -1 };
3279
3282 }
3283
3284 bool isNillable = formattingMode & bdlat_FormattingMode::e_NILLABLE;
3285
3286 if (isNillable) {
3287 Decoder_ParseNillableObject parseAsNillable(d_decoder, formattingMode);
3288
3290 object,
3291 parseAsNillable)) {
3292 return k_FAILURE; // RETURN
3293 }
3294
3295 if (parseAsNillable.isNil()) {
3296 // reset the object to null
3298 }
3299
3300 return k_SUCCESS; // RETURN
3301 }
3302
3303 Decoder_ParseObject_executeProxy proxy = { this, formattingMode };
3304
3306}
3307
3308template <class TYPE>
3310 TYPE *object,
3311 int formattingMode,
3313{
3314 return d_decoder->decodeCustomized(object, formattingMode);
3315}
3316
3317template <class TYPE>
3318inline
3320 TYPE *object,
3321 int formattingMode,
3323{
3325 this, formattingMode
3326 };
3327
3329}
3330
3331template <class TYPE, class ANY_CATEGORY>
3332inline
3334 int formattingMode,
3335 ANY_CATEGORY)
3336{
3337 typedef typename
3339
3340 Context context(object, formattingMode);
3341
3342 return context.beginParse(d_decoder);
3343}
3344
3345template <class TYPE>
3347 int formattingMode,
3348 CanBeListOrRepetition)
3349{
3350 if (formattingMode & bdlat_FormattingMode::e_LIST) {
3352 ListContext;
3353
3354 ListContext listContext(object, formattingMode);
3355
3356 return listContext.beginParse(d_decoder); // RETURN
3357 } else {
3358 return executeArrayRepetitionImp(object, formattingMode); // RETURN
3359 }
3360}
3361
3362template <class TYPE>
3363inline
3365 int formattingMode,
3366 CanBeRepetitionOnly)
3367{
3368 return executeArrayRepetitionImp(object, formattingMode);
3369}
3370
3371template <class TYPE>
3373 int formattingMode)
3374{
3377
3378 Decoder_ParseObject_executeProxy proxy = { this, formattingMode };
3379
3380 const int i = static_cast<int>(bdlat_ArrayFunctions::size(*object));
3381
3382 bdlat_ArrayFunctions::resize(object, i + 1);
3383
3384 return bdlat_ArrayFunctions::manipulateElement(object, proxy, i);
3385}
3386
3387// CREATORS
3388inline
3389Decoder_ParseObject::Decoder_ParseObject(Decoder *decoder,
3390 const char *elementName,
3391 bsl::size_t lenName)
3392: d_decoder(decoder)
3393, d_elementName_p(elementName)
3394, d_lenName(lenName)
3395{
3396 BSLS_REVIEW(d_elementName_p);
3397 BSLS_REVIEW(d_decoder);
3398}
3399
3400// MANIPULATORS
3401template <class TYPE, class INFO_TYPE>
3402inline
3403int Decoder_ParseObject::operator()(TYPE *object, const INFO_TYPE &info)
3404{
3405 return execute(object, info.formattingMode());
3406}
3407
3408template <class TYPE>
3409inline
3410int Decoder_ParseObject::execute(TYPE *object, int formattingMode)
3411{
3412 typedef typename
3414
3415 return executeImp(object, formattingMode, TypeCategory());
3416}
3417
3418 // ---------------------------------
3419 // class Decoder_ParseNillableObject
3420 // ---------------------------------
3421
3422// IMPLEMENTATION MANIPULATORS
3423template <class TYPE>
3424inline
3433
3435 // DATA
3438
3439 // MANIPULATORS
3440 template <class t_BASE_TYPE>
3441 int operator()(t_BASE_TYPE *base)
3442 {
3443 typedef typename Decoder_InstantiateContext<
3444 bdlat_TypeCategory::Simple, t_BASE_TYPE>::Type BaseContext;
3445 BaseContext ctx(base, d_that->d_formattingMode);
3446 d_that->d_nillableContext.setElementContext(&ctx);
3447 int rc = d_that->d_nillableContext.beginParse(d_that->d_decoder);
3448 d_isNil = d_that->d_nillableContext.isNil();
3449 return rc;
3450 }
3451};
3452
3453template <class TYPE>
3454inline
3456 TYPE *object,
3458{
3459 CustomizedManipulator baseManipulator = {this, false};
3461 object,
3462 baseManipulator);
3463 return baseManipulator.d_isNil ? 0 : rc;
3464}
3465
3466template <class TYPE>
3467inline
3473
3474template <class TYPE, class ANY_CATEGORY>
3475inline
3476int Decoder_ParseNillableObject::executeImp(TYPE *object, ANY_CATEGORY)
3477{
3478 typedef typename
3480
3481 Context elementContext(object, d_formattingMode);
3482
3483 d_nillableContext.setElementContext(&elementContext);
3484
3485 return d_nillableContext.beginParse(d_decoder);
3486}
3487
3488inline
3489Decoder_ParseNillableObject::Decoder_ParseNillableObject(
3490 Decoder *decoder,
3491 int formattingMode)
3492: d_formattingMode(formattingMode)
3493, d_nillableContext()
3494, d_decoder(decoder)
3495{
3496}
3497
3498// MANIPULATORS
3499template <class TYPE>
3500inline
3502{
3503 typedef typename
3505
3506 return executeImp(object, TypeCategory());
3507}
3508
3509// ACCESSORS
3510inline
3512{
3513 return d_nillableContext.isNil();
3514}
3515
3516} // close package namespace
3517
3518
3519#endif
3520
3521// ----------------------------------------------------------------------------
3522// Copyright 2015 Bloomberg Finance L.P.
3523//
3524// Licensed under the Apache License, Version 2.0 (the "License");
3525// you may not use this file except in compliance with the License.
3526// You may obtain a copy of the License at
3527//
3528// http://www.apache.org/licenses/LICENSE-2.0
3529//
3530// Unless required by applicable law or agreed to in writing, software
3531// distributed under the License is distributed on an "AS IS" BASIS,
3532// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3533// See the License for the specific language governing permissions and
3534// limitations under the License.
3535// ----------------------------- END-OF-FILE ----------------------------------
3536
3537/** @} */
3538/** @} */
3539/** @} */
Definition balxml_base64parser.h:161
Definition balxml_decoderoptions.h:72
bool skipUnknownElements() const
Definition balxml_decoderoptions.h:526
Definition balxml_decoder.h:1029
int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2384
int parseSubElement(const char *elementName, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2449
int parseAttribute(const char *name, const char *value, bsl::size_t lenValue, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2438
int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2394
int addCharacters(const char *chars, bsl::size_t length, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2410
Definition balxml_decoder.h:367
int beginParse(Decoder *decoder)
virtual ~Decoder_ElementContext()
For syntactic purposes only.
virtual int parseSubElement(const char *elementName, Decoder *decoder)=0
virtual int endElement(Decoder *decoder)=0
virtual int addCharacters(const char *chars, bsl::size_t length, Decoder *decoder)=0
virtual int startElement(Decoder *decoder)=0
virtual int parseAttribute(const char *name, const char *value, bsl::size_t lenValue, Decoder *decoder)=0
Definition balxml_decoder.h:760
Decoder_ErrorLogger(ErrorInfo::Severity severity, Decoder *decoder)
Construct a logger for the specified decoder.
Definition balxml_decoder.h:776
~Decoder_ErrorLogger()
Definition balxml_decoder.h:785
bsl::ostream & stream()
Definition balxml_decoder.h:792
Definition balxml_decoder.h:862
int beginParse(TYPE *object)
Definition balxml_decoder.h:910
Decoder_ListParser()
Definition balxml_decoder.h:901
int pushCharacters(INPUT_ITERATOR begin, INPUT_ITERATOR end)
Definition balxml_decoder.h:921
int endParse()
Definition balxml_decoder.h:915
Definition balxml_decoder.h:1079
~Decoder_NillableContext() BSLS_KEYWORD_OVERRIDE
void setElementContext(Decoder_ElementContext *elementContext)
bool isNil() const
Return true if the element is nil.
Definition balxml_decoder.h:1617
int executeImp(TYPE *object, int formattingMode, bdlat_TypeCategory::NullableValue)
Definition balxml_decoder.h:3042
int execute(TYPE *object, int formattingMode)
Definition balxml_decoder.h:3136
int operator()(TYPE *object, const INFO_TYPE &info)
Definition balxml_decoder.h:3129
bool failed() const
Definition balxml_decoder.h:3146
Definition balxml_decoder.h:1771
bool isNil() const
Return true if the value was nil, and false otherwise.
Definition balxml_decoder.h:3511
int executeImp(TYPE *object, bdlat_TypeCategory::DynamicType)
Definition balxml_decoder.h:3425
int operator()(TYPE *object)
Visit the specified object.
Definition balxml_decoder.h:3501
Definition balxml_decoder.h:1676
int executeArrayRepetitionImp(TYPE *object, int formattingMode)
Definition balxml_decoder.h:3372
int operator()(TYPE *object, const INFO_TYPE &info)
Definition balxml_decoder.h:3403
int executeImp(bsl::vector< char > *object, int formattingMode, bdlat_TypeCategory::Array)
int execute(TYPE *object, int formattingMode)
Definition balxml_decoder.h:3410
int executeArrayImp(TYPE *object, int formattingMode, CanBeListOrRepetition)
Definition balxml_decoder.h:3346
Definition balxml_decoder.h:1537
int operator()(TYPE *object, const INFO_TYPE &info)
Definition balxml_decoder.h:2954
Definition balxml_decoder.h:1578
int operator()(TYPE *object, const INFO_TYPE &info)
Definition balxml_decoder.h:3019
int execute(TYPE *object, int id, int formattingMode)
Definition balxml_decoder.h:3026
Definition balxml_decoder.h:1505
int operator()(const TYPE &object, const INFO_TYPE &info)
Definition balxml_decoder.h:2923
Definition balxml_decoder.h:1141
int parseSubElement(const char *elementName, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2586
int addCharacters(const char *chars, bsl::size_t length, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2551
int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2536
int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2520
int parseAttribute(const char *name, const char *value, bsl::size_t lenValue, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2575
Definition balxml_decoder.h:1188
int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2648
int parseSubElement(const char *elementName, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2719
int addCharacters(const char *chars, bsl::size_t length, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2656
int parseAttribute(const char *name, const char *value, bsl::size_t lenValue, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2694
int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2628
Definition balxml_decoder.h:1234
int parseAttribute(const char *name, const char *value, bsl::size_t lenValue, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2809
int parseSubElement(const char *elementName, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2820
int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2771
int addCharacters(const char *chars, bsl::size_t length, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2779
int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2761
Definition balxml_decoder.h:1370
Decoder_PushParserContext< bsl::string, Base64Parser< bsl::string > > Base64Context
Definition balxml_decoder.h:1378
bsls::ObjectBuffer< UTF8Context > d_utf8Context
Definition balxml_decoder.h:1388
Decoder_StdStringContext(bsl::string *object, int formattingMode)
bsls::ObjectBuffer< HexContext > d_hexContext
Definition balxml_decoder.h:1387
bsls::ObjectBuffer< Base64Context > d_base64Context
Definition balxml_decoder.h:1386
Decoder_UTF8Context< bsl::string > UTF8Context
Definition balxml_decoder.h:1381
~Decoder_StdStringContext() BSLS_KEYWORD_OVERRIDE
Decoder_PushParserContext< bsl::string, HexParser< bsl::string > > HexContext
Definition balxml_decoder.h:1380
Definition balxml_decoder.h:1433
bsls::ObjectBuffer< UTF8Context > d_utf8Context
Definition balxml_decoder.h:1457
bsls::ObjectBuffer< ListContext > d_listContext
Definition balxml_decoder.h:1456
~Decoder_StdVectorCharContext() BSLS_KEYWORD_OVERRIDE
Decoder_PushParserContext< bsl::vector< char >, Decoder_ListParser< bsl::vector< char > > > ListContext
Definition balxml_decoder.h:1448
bsls::ObjectBuffer< HexContext > d_hexContext
Definition balxml_decoder.h:1455
Decoder_StdVectorCharContext(bsl::vector< char > *object, int formattingMode)
Decoder_UTF8Context< bsl::vector< char > > UTF8Context
Definition balxml_decoder.h:1449
Decoder_PushParserContext< bsl::vector< char >, HexParser< bsl::vector< char > > > HexContext
Definition balxml_decoder.h:1445
bsls::ObjectBuffer< Base64Context > d_base64Context
Definition balxml_decoder.h:1454
Decoder_PushParserContext< bsl::vector< char >, Base64Parser< bsl::vector< char > > > Base64Context
Definition balxml_decoder.h:1442
Definition balxml_decoder.h:1324
int parseSubElement(const char *elementName, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2895
int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2862
int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2851
int parseAttribute(const char *name, const char *value, bsl::size_t lenValue, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2884
int addCharacters(const char *chars, bsl::size_t length, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2871
Definition balxml_decoder.h:1281
int parseAttribute(const char *name, const char *value, bsl::size_t lenValue, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
int parseSubElement(const char *elementName, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
int addCharacters(const char *chars, bsl::size_t length, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:404
int open(bsl::istream &stream, const char *uri=0)
Definition balxml_decoder.h:2155
friend class Decoder_ErrorLogger
Definition balxml_decoder.h:408
const DecoderOptions * options() const
Definition balxml_decoder.h:2066
void setNumUnknownElementsSkipped(int value)
Definition balxml_decoder.h:2054
ErrorInfo::Severity errorSeverity() const
int warningCount() const
Definition balxml_decoder.h:2108
bsl::istream & decodeAny(bsl::istream &stream, TYPE *object, const char *uri=0)
Definition balxml_decoder.h:2269
Reader * reader() const
Definition balxml_decoder.h:2072
bsl::istream & decode(bsl::istream &stream, TYPE *object, const char *uri=0)
Definition balxml_decoder.h:2161
bsl::ostream * errorStream() const
Return pointer to the error stream.
Definition balxml_decoder.h:2084
bsl::ostream * warningStream() const
Return pointer to the warning stream.
Definition balxml_decoder.h:2096
bslstl::StringRef loggedMessages() const
ErrorInfo * errorInfo() const
Definition balxml_decoder.h:2078
int numUnknownElementsSkipped() const
Definition balxml_decoder.h:2090
int errorCount() const
Definition balxml_decoder.h:2102
Definition balxml_errorinfo.h:353
Severity
Definition balxml_errorinfo.h:358
Definition balxml_hexparser.h:169
Definition balxml_listparser.h:187
int pushCharacters(INPUT_ITERATOR begin, INPUT_ITERATOR end)
Definition balxml_listparser.h:368
int endParse()
Definition balxml_listparser.h:348
int beginParse(TYPE *object)
Definition balxml_listparser.h:333
Definition balxml_reader.h:835
Definition balxml_utf8readerwrapper.h:333
Definition bdlar_anyref.h:85
static bsl::enable_if<!IsDynamic< t_TYPE >::value, AnyRef >::type makeAnyRef(t_TYPE &object)
Make AnyRef to the specified object.
Definition bdlar_refutil.h:209
Definition bdlb_nullablevalue.h:262
bool isNull() const BSLS_KEYWORD_NOEXCEPT
Return true if this object is null, and false otherwise.
Definition bdlb_nullablevalue.h:1829
TYPE & makeValue(BSLS_COMPILERFEATURES_FORWARD_REF(BDE_OTHER_TYPE) value)
Definition bdlb_nullablevalue.h:1767
Definition bdlsb_memoutstreambuf.h:212
Definition bslstl_stringview.h:471
Definition bslstl_string.h:1252
Definition bslstl_vector.h:1120
Definition bslma_allocator.h:545
#define BALXML_DECODER_LOG_WARNING(reporter)
Definition balxml_decoder.h:813
int length() const
Definition balxml_decoder.h:2047
const char * data() const
Definition balxml_decoder.h:2041
void reset()
Reset the internal streambuf to empty.
Definition balxml_decoder.h:2034
#define BALXML_DECODER_LOG_END
Definition balxml_decoder.h:821
#define BALXML_DECODER_LOG_ERROR(reporter)
Definition balxml_decoder.h:805
static int manipulateByCategory(TYPE *object, MANIPULATOR &manipulator)
Definition bdlat_typecategory.h:1414
static const char * className(const TYPE &object)
Definition bdlat_typename.h:1025
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1917
#define BSLS_ASSERT_INVOKE_NORETURN(X)
Definition bsls_assert.h:2101
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:695
#define BSLS_REVIEW(X)
Definition bsls_review.h:1019
Definition balxml_base64parser.h:150
Definition bdlar_accessorref.h:59
int manipulateElement(TYPE *array, MANIPULATOR &manipulator, int index)
void resize(TYPE *array, int newSize)
bsl::size_t size(const TYPE &array)
Return the number of elements in the specified array.
bool hasSelection(const TYPE &object, const char *selectionName, int selectionNameLength)
int manipulateSelection(TYPE *object, MANIPULATOR &manipulator)
int makeSelection(TYPE *object, int selectionId)
int createBaseAndConvert(t_TYPE *object, t_MANIPULATOR &baseManipulator)
bool isNull(const TYPE &object)
int manipulateValue(TYPE *object, MANIPULATOR &manipulator)
void makeValue(TYPE *object)
int manipulateAttribute(TYPE *object, MANIPULATOR &manipulator, const char *attributeName, int attributeNameLength)
int manipulateAttributes(TYPE *object, MANIPULATOR &manipulator)
bool hasAttribute(const TYPE &object, const char *attributeName, int attributeNameLength)
void reset(TYPE *object)
Reset the value of the specified object to its default value.
Definition bdlat_valuetypefunctions.h:939
basic_string< char > string
Definition bslstl_string.h:844
Definition baljsn_encoder_testtypes.h:76
Definition bdlt_iso8601util.h:707
Definition bslstl_algorithm.h:84
Definition balxml_decoder.h:2311
int d_formattingMode
Definition balxml_decoder.h:2314
Decoder * d_that
Definition balxml_decoder.h:2313
int operator()(t_BASE_TYPE *base)
Definition balxml_decoder.h:2318
Decoder_PushParserContext< TYPE, Decoder_ListParser< TYPE > > Type
Definition balxml_decoder.h:945
Decoder_StdVectorCharContext Type
Definition balxml_decoder.h:953
Decoder_ChoiceContext< TYPE > Type
Definition balxml_decoder.h:960
Decoder_SimpleContext< TYPE > Type
Definition balxml_decoder.h:993
Decoder_SequenceContext< TYPE > Type
Definition balxml_decoder.h:967
Decoder_SimpleContext< TYPE > Type
Definition balxml_decoder.h:974
Decoder_StdStringContext Type
Definition balxml_decoder.h:982
Definition balxml_decoder.h:939
Definition balxml_decoder.h:1891
int operator()(TYPE *object, ANY_CATEGORY category)
Definition balxml_decoder.h:1913
Decoder_ParseAttribute * d_instance_p
Definition balxml_decoder.h:1894
int operator()(TYPE *, bslmf::Nil)
Definition balxml_decoder.h:1905
int d_formattingMode
Definition balxml_decoder.h:1895
Definition balxml_decoder.h:1864
int operator()(TYPE *object)
Definition balxml_decoder.h:1878
Decoder_ParseAttribute * d_instance_p
Definition balxml_decoder.h:1867
int d_formattingMode
Definition balxml_decoder.h:1868
int operator()(t_BASE_TYPE *base)
Definition balxml_decoder.h:3441
Decoder_ParseNillableObject * d_that
Definition balxml_decoder.h:3436
Decoder_ParseNillableObject * d_instance_p
Definition balxml_decoder.h:1991
int operator()(TYPE *object, ANY_CATEGORY category)
Definition balxml_decoder.h:2009
int operator()(TYPE *, bslmf::Nil)
Definition balxml_decoder.h:2001
Definition balxml_decoder.h:1953
int operator()(TYPE *object, ANY_CATEGORY category)
Definition balxml_decoder.h:1975
int operator()(TYPE *, bslmf::Nil)
Definition balxml_decoder.h:1967
int d_formattingMode
Definition balxml_decoder.h:1957
Decoder_ParseObject * d_instance_p
Definition balxml_decoder.h:1956
Definition balxml_decoder.h:1926
Decoder_ParseObject * d_instance_p
Definition balxml_decoder.h:1929
int operator()(TYPE *object)
Definition balxml_decoder.h:1940
int d_formattingMode
Definition balxml_decoder.h:1930
Definition balxml_decoder.h:1007
Decoder_InstantiateContext< TypeCategory, TYPE >::Type Type
Definition balxml_decoder.h:1015
Definition balxml_decoder.h:1830
int operator()(TYPE *object, ANY_CATEGORY category)
Definition balxml_decoder.h:1851
Decoder * d_decoder
Definition balxml_decoder.h:1833
int operator()(TYPE *, bslmf::Nil)
Definition balxml_decoder.h:1843
Definition balxml_typesparserutil.h:201
static int parse(TYPE *result, const char *input, int inputLength, int formattingMode)
Definition balxml_typesparserutil.h:954
@ e_LIST
Definition bdlat_formattingmode.h:126
@ e_TYPE_MASK
Definition bdlat_formattingmode.h:119
@ e_ATTRIBUTE
Definition bdlat_formattingmode.h:123
@ e_DEFAULT
Definition bdlat_formattingmode.h:114
@ e_NILLABLE
Definition bdlat_formattingmode.h:125
@ e_UNTAGGED
Definition bdlat_formattingmode.h:122
@ e_SIMPLE_CONTENT
Definition bdlat_formattingmode.h:124
Definition bdlat_typecategory.h:1037
Definition bdlat_typecategory.h:1038
Definition bdlat_typecategory.h:1039
Definition bdlat_typecategory.h:1036
Definition bdlat_typecategory.h:1041
Definition bdlat_typecategory.h:1088
Definition bdlat_typecategory.h:1042
Definition bdlat_typecategory.h:1043
Definition bdlat_typecategory.h:1033
@ e_CHOICE_CATEGORY
Definition bdlat_typecategory.h:1049
@ e_SEQUENCE_CATEGORY
Definition bdlat_typecategory.h:1053
static void skipLeadingTrailing(const char **begin, const char **end)
Definition bslmf_conditional.h:123
Definition bslmf_issame.h:146
Definition bslmf_nil.h:133
Definition bsls_objectbuffer.h:277