BDE 4.14.0 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 <bdlat_arrayfunctions.h>
305#include <bdlat_formattingmode.h>
308#include <bdlat_typecategory.h>
309#include <bdlat_typename.h>
311
312#include <bdlb_string.h>
313
315
316#include <bslma_allocator.h>
317#include <bslma_default.h>
318
319#include <bslmf_conditional.h>
320
321#include <bsls_assert.h>
322#include <bsls_keyword.h>
323#include <bsls_objectbuffer.h>
324#include <bsls_review.h>
325
326#include <bsl_algorithm.h> // bsl::min
327#include <bsl_istream.h>
328#include <bsl_map.h>
329#include <bsl_ostream.h>
330#include <bsl_streambuf.h>
331#include <bsl_string.h>
332#include <bsl_vector.h>
333#include <bsl_cstddef.h> // NULL
334#include <bsl_cstring.h>
335#include <bsl_cstdlib.h>
336#include <bsl_cerrno.h>
337
338#ifndef BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
339#include <bslmf_if.h>
340#endif // BDE_DONT_ALLOW_TRANSITIVE_INCLUDES
341
342
343namespace balxml {
344
345class Reader;
346class ErrorInfo;
347class Decoder;
348
349 // ============================
350 // class Decoder_ElementContext
351 // ============================
352
353/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
354///
355/// This protocol class contain functions related to parsing XML elements.
356/// When the Decoder reads the XML document, it forwards the information
357/// about the current node as events to this protocol. There are several
358/// implementations of this protocol, depending on the type of element. The
359/// correct implementation for each type is selected by the
360/// `Decoder_SelectContext` meta-function. Each of the functions take a
361/// `context` parameter, which contains members related to the context of
362/// the decoder.
363///
364/// See @ref balxml_decoder
366
367 public:
368 /// For syntactic purposes only.
370
371 // CALLBACKS
372 virtual int startElement(Decoder *decoder) = 0;
373
374 virtual int endElement(Decoder *decoder) = 0;
375
376 virtual int addCharacters(const char *chars,
377 bsl::size_t length,
378 Decoder *decoder) = 0;
379
380 virtual int parseAttribute(const char *name,
381 const char *value,
382 bsl::size_t lenValue,
383 Decoder *decoder) = 0;
384
385 virtual int parseSubElement(const char *elementName, Decoder *decoder) = 0;
386
387 int beginParse(Decoder *decoder);
388};
389
390 // =============
391 // class Decoder
392 // =============
393
394/// Engine for decoding value-semantic objects in XML format. The `decode`
395/// methods are function templates that will decode any object that meets
396/// the requirements of a sequence or choice object as defined in the
397/// @ref bdlat_sequencefunctions and @ref bdlat_choicefunctions components.
398/// These generic frameworks provide a common compile-time interface for
399/// manipulating struct-like and union-like objects.
400///
401/// See @ref balxml_decoder
402class Decoder {
403
407
408 // PRIVATE TYPES
409
410 /// This class provides stream for logging using
411 /// `bdlsb::MemOutStreamBuf` as a streambuf. The logging stream is
412 /// created on demand, i.e., during the first attempt to log message.
413 ///
414 /// See @ref balxml_decoder
415 class MemOutStream : public bsl::ostream {
417
418 // NOT IMPLEMENTED
419 MemOutStream(const MemOutStream&);
420 MemOutStream& operator=(const MemOutStream&);
421
422 public:
423 // CREATORS
424
425 /// Create a new stream using the optionally specified
426 /// `basicAllocator`.
427 MemOutStream(bslma::Allocator *basicAllocator = 0);
428
429 /// Destroy this stream and release memory back to the allocator.
430 ~MemOutStream() BSLS_KEYWORD_OVERRIDE;
431
432 // MANIPULATORS
433
434 /// Reset the internal streambuf to empty.
435 void reset();
436
437 // ACCESSORS
438
439 /// Return a pointer to the memory containing the formatted values
440 /// formatted to this stream. The data is not null-terminated
441 /// unless a null character was appended onto this stream.
442 const char *data() const;
443
444 /// Return the length of the formatted data, including null
445 /// characters appended to the stream, if any.
446 int length() const;
447 };
448
449 // DATA
450 const DecoderOptions *d_options; // held, not owned
451 Utf8ReaderWrapper d_utf8ReaderWrapper;
452 Reader *d_reader; // held, not owned
453 ErrorInfo *d_errorInfo; // held, not owned
454
455 bslma::Allocator *d_allocator; // held, not owned
456
457 // placeholder for MemOutStream
458 bsls::ObjectBuffer<MemOutStream> d_logArea;
459
460 // if not zero, log stream was created at the moment of first logging
461 // and must be destroyed
462 MemOutStream *d_logStream;
463
464 bsl::ostream *d_errorStream; // held, not owned
465 bsl::ostream *d_warningStream; // held, not owned
466
467 bsl::string d_sourceUri; // URI of input document
468 int d_errorCount; // error count
469 int d_warningCount; // warning count
470
471 int d_numUnknownElementsSkipped;
472 // number of unknown
473 // elements skipped
474
475 bool d_fatalError; // fatal error flag
476
477 // remaining number of nesting levels allowed
478 int d_remainingDepth;
479
480 // NOT IMPLEMENTED
481 Decoder(const Decoder&);
482 Decoder operator=(const Decoder&);
483
484 private:
485 // PRIVATE MANIPULATORS
486
487 /// Return the stream for logging. Note the if stream has not been
488 /// created yet, it will be created during this call.
489 bsl::ostream& logStream();
490
491 void resetErrors();
492 int checkForReaderErrors();
493 int checkForErrors(const ErrorInfo& errInfo);
494
495 /// When decoding a structure, make sure that the root tag of the XML
496 /// matches the structure of the specified `object` that we are decoding
497 /// into. Return 0 if it does.
498 template <class TYPE>
499 int validateTopElement(const TYPE *object);
500
501 void setDecoderError(ErrorInfo::Severity severity, bsl::string_view msg);
502
503 int readTopElement();
504 int parse(Decoder_ElementContext *context);
505
506 template <class TYPE>
507 int decodeImp(TYPE *object, bdlat_TypeCategory::DynamicType);
508
509 template <class TYPE, class ANY_CATEGORY>
510 int decodeImp(TYPE *object, ANY_CATEGORY);
511
512 public:
513 // CREATORS
515 Reader *reader,
516 ErrorInfo *errInfo,
517 bslma::Allocator *basicAllocator);
518
519 /// Construct a decoder object using the specified `options` and the
520 /// specified `reader` to perform the XML-level parsing. If the
521 /// (optionally) specified `errorInfo` is non-null, it is used to store
522 /// information about most serious error encountered during parsing.
523 /// During parsing, error and warning messages will be written to the
524 /// (optionally) specified `errorStream` and `warningStream`
525 /// respectively. The behavior is undefined unless `options` and
526 /// `reader` are both non-zero. The behavior becomes undefined if the
527 /// objects pointed to by any of the arguments is destroyed before this
528 /// object has completed parsing.
530 Reader *reader,
531 ErrorInfo *errInfo = 0,
532 bsl::ostream *errorStream = 0,
533 bsl::ostream *warningStream = 0,
534 bslma::Allocator *basicAllocator = 0);
535
536 /// Call `close` and destroy this object.
538
539 // MANIPULATORS
540
541 /// Put the associated `Reader` object (i.e., the `reader` specified at
542 /// construction) into a closed state.
543 void close();
544
545 /// Open the associated `Reader` object (see `Reader::open`) to read XML
546 /// data from the specified `stream`. The (optionally) specified `uri`
547 /// is used for identifying the input document in error messages.
548 /// Return 0 on success and non-zero otherwise.
549 int open(bsl::istream& stream, const char *uri = 0);
550
551 /// Open the associated `Reader` object (see `Reader::open`) to read XML
552 /// data from the specified stream `buffer`. The (optionally) specified
553 /// `uri` is used for identifying the input document in error messages.
554 /// Return 0 on success and non-zero otherwise.
555 int open(bsl::streambuf *buffer, const char *uri = 0);
556
557 /// Open the associated `Reader` object (see `Reader::open`) to read XML
558 /// data from memory at the specified `buffer`, with the specified
559 /// `length`. The (optionally) specified `uri` is used for identifying
560 /// the input document in error messages. Return 0 on success and
561 /// non-zero otherwise.
562 int open(const char *buffer, bsl::size_t length, const char *uri = 0);
563
564 /// Open the associated `Reader` object (see `Reader::open`) to read XML
565 /// data from the file with the specified `filename`. Return 0 on
566 /// success and non-zero otherwise.
567 int open(const char *filename);
568
569 /// Decode the specified `object` of parameterized `TYPE` from the
570 /// specified input `stream`. Return a reference to the modifiable
571 /// `stream`. If a decoding error is detected, `stream.fail()` will be
572 /// `true` after this method returns. The (optionally) specified `uri`
573 /// is used for identifying the input document in error messages. A
574 /// compilation error will result unless `TYPE` conforms to the
575 /// requirements of a `bdlat` sequence or choice, as described in
576 /// @ref bdlat_sequencefunctions and @ref bdlat_choicefunctions .
577 template <class TYPE>
578 bsl::istream& decode(bsl::istream& stream,
579 TYPE *object,
580 const char *uri = 0);
581
582 /// Decode the specified `object` of parameterized `TYPE` from the
583 /// specified stream `buffer`. The (optionally) specified `uri` is
584 /// used for identifying the input document in error messages. Return
585 /// 0 on success, and a non-zero value otherwise. A compilation error
586 /// will result unless `TYPE` conforms to the requirements of a bdlat
587 /// sequence or choice, as described in @ref bdlat_sequencefunctions and
588 /// @ref bdlat_choicefunctions .
589 template <class TYPE>
590 int decode(bsl::streambuf *buffer, TYPE *object, const char *uri = 0);
591
592 /// Decode the specified `object` of parameterized `TYPE` from the
593 /// memory at the specified `buffer` address, having the specified
594 /// `length`. The (optionally) specified `uri` is used for identifying
595 /// the input document in error messages. Return 0 on success, and a
596 /// non-zero value otherwise. A compilation error will result unless
597 /// `TYPE` conforms to the requirements of a bdlat sequence or choice,
598 /// as described in @ref bdlat_sequencefunctions and
599 /// @ref bdlat_choicefunctions .
600 template <class TYPE>
601 int decode(const char *buffer,
602 bsl::size_t length,
603 TYPE *object,
604 const char *uri = 0);
605
606 /// Decode the specified `object` of parameterized `TYPE` from the file
607 /// with the specified `filename`. Return 0 on success, and a non-zero
608 /// value otherwise. A compilation error will result unless `TYPE`
609 /// conforms to the requirements of a bdlat sequence or choice, as
610 /// described in @ref bdlat_sequencefunctions and @ref bdlat_choicefunctions .
611 template <class TYPE>
612 int decode(const char *filename, TYPE *object);
613
614 /// Decode the specified `object` of parameterized `TYPE` from the
615 /// input source specified by a previous call to `open` and leave the
616 /// reader in an open state. Return 0 on success, and a non-zero value
617 /// otherwise. A compilation error will result unless `TYPE` conforms
618 /// to the requirements of a bdlat sequence or choice, as described in
619 /// @ref bdlat_sequencefunctions and @ref bdlat_choicefunctions . The
620 /// behavior is undefined unless this call was preceded by a prior
621 /// successful call to `open`
622 template <class TYPE>
623 int decode(TYPE *object);
624
625 /// Set the number of unknown elements skipped by the decoder during
626 /// the current decoding operation to the specified `value`. The
627 /// behavior is undefined unless `0 <= value`.
628 void setNumUnknownElementsSkipped(int value);
629
630 //ACCESSORS
631
632 /// Return a pointer to the non-modifiable decoder options provided at
633 /// construction.
634 const DecoderOptions *options() const;
635
636 /// Return the a pointer to the modifiable reader associated with this
637 /// decoder (i.e., the `reader` pointer provided at construction).
638 Reader *reader() const;
639
640 /// Return a pointer to the modifiable error-reporting structure
641 /// associated with this decoder (i.e., the `errInfo` pointer provided
642 /// at construction). The value stored in the error structure is reset
643 /// to indicate no error on a successful call to `open`.
644 ErrorInfo *errorInfo() const;
645
646 /// Return pointer to the error stream.
647 bsl::ostream *errorStream() const;
648
649 /// Return pointer to the warning stream.
650 bsl::ostream *warningStream() const;
651
652 /// Return the number of unknown elements that were skipped during the
653 /// previous decoding operation. Note that unknown elements are skipped
654 /// only if `true == options()->skipUnknownElements()`.
655 int numUnknownElementsSkipped() const;
656
657 /// Return the severity of the most severe warning or error encountered
658 /// during the last call to the `decode` method. The severity is reset
659 /// each time `decode` is called.
660 ErrorInfo::Severity errorSeverity() const;
661
662 /// Return a string containing any error, warning, or trace messages
663 /// that were logged during the last call to the `decode` method. The
664 /// log is reset each time `decode` is called.
665 bslstl::StringRef loggedMessages() const;
666
667 /// Return the number of errors that occurred during decoding. This
668 /// number is reset to zero on a call to `open`.
669 int errorCount() const;
670
671 /// Return the number of warnings that occurred during decoding. This
672 /// number is reset to zero on a call to `open`.
673 int warningCount() const;
674};
675
676 // =========================
677 // class Decoder_ErrorLogger
678 // =========================
679
680/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
681///
682/// This class is used for logging errors and warnings. The usage of this
683/// class is simplified with macros, which are defined below.
684///
685/// See @ref balxml_decoder
687
688 // DATA
689 Decoder::MemOutStream d_stream;
690 ErrorInfo::Severity d_severity; // severity
691 Decoder *d_decoder; // context
692
693 private:
694 // NOT IMPLEMENTED
696 Decoder_ErrorLogger& operator=(const Decoder_ErrorLogger&);
697
698 public:
699 // CREATORS
700
701 /// Construct a logger for the specified `decoder`.
703 : d_stream(decoder->d_allocator)
704 , d_severity(severity)
705 , d_decoder(decoder)
706 {
707 }
708
709 /// Set the decoder's error message to the contents of the message
710 /// stream.
712 {
713 d_decoder->setDecoderError(d_severity,
714 bsl::string_view(d_stream.data(),
715 d_stream.length()));
716 }
717
718 bsl::ostream& stream()
719 {
720 return d_stream;
721 }
722};
723} // close package namespace
724
725// --- Anything below this line is implementation specific. Do not use. ----
726
727// LOGGING MACROS
728
729/// Usage: BAEXML_LOG_ERROR(myDecoder) << "Message"
730/// << value << BALXML_DECODER_LOG_END;
731#define BALXML_DECODER_LOG_ERROR(reporter) \
732 do { \
733 balxml::Decoder_ErrorLogger \
734 logger(balxml::ErrorInfo::e_ERROR, reporter); \
735 logger.stream()
736
737/// Usage: BAEXML_LOG_WARNING(myDecoder) << "Message"
738/// << value << BALXML_DECODER_LOG_END;
739#define BALXML_DECODER_LOG_WARNING(reporter) \
740 do { \
741 balxml::Decoder_ErrorLogger \
742 logger(balxml::ErrorInfo::e_WARNING, reporter); \
743 logger.stream()
744
745/// See usage of BALXML_DECODER_LOG_ERROR and BALXML_DECODER_LOG_WARNING,
746/// above.
747#define BALXML_DECODER_LOG_END \
748 bsl::flush; \
749 } while (false)
750
751// FORWARD DECLARATIONS
752
753
754namespace balxml {
755
756class Decoder_ElementContext;
757
758template <class TYPE>
759class Decoder_ChoiceContext;
760template <class TYPE>
761class Decoder_CustomizedContext;
762template <class TYPE, class PARSER>
763class Decoder_PushParserContext;
764template <class TYPE>
765class Decoder_SequenceContext;
766template <class TYPE>
767class Decoder_SimpleContext;
768template <class TYPE>
769class Decoder_UTF8Context;
770
771class Decoder_UnknownElementContext;
772
773class Decoder_StdStringContext; // proxy context
774class Decoder_StdVectorCharContext; // proxy context
775
776 // ==============================
777 // class Decoder_ListParser<TYPE>
778 // ==============================
779
780/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
781///
782/// This is a wrapper around `ListParser<TYPE>`. The
783/// `Decoder_PushParserContext` class needs a default constructible push
784/// parser. However, `ListParser<TYPE>` is not default constructible - it
785/// requires an `parseElementCallback`. This wrapper provides a default
786/// constructor that passes `TypesParserUtil::parseDefault` as the callback.
787///
788/// See @ref balxml_decoder
789template <class TYPE>
791
792 // PRIVATE TYPES
793 typedef typename
794 ListParser<TYPE>::ParseElementFunction ParseElementFunction;
795 typedef typename
797
798 // DATA
799 ListParser<TYPE> d_imp; // implementation object
800
801 private:
802 // NOT IMPLEMENTED
804 Decoder_ListParser& operator=(const Decoder_ListParser&);
805
806 // COMPILER BUG WORKAROUNDS
807
808 /// This function is provided to work around a bug in the AIX compiler.
809 /// It incorrectly complains that the following constructor initializer
810 /// list for `d_imp` is invalid:
811 /// @code
812 /// : d_imp((ParseElementFunction)&TypesParserUtil::parseDefault)
813 /// @endcode
814 /// The error message generated by the AIX compiler is:
815 /// @code
816 /// An object of type "BloombergLP::balxml::ListParser<TYPE>" cannot be
817 /// constructed from an rvalue of type "ParseElementFunction".
818 /// @endcode
819 /// To work around this, an explicit `convert` function is used to aid
820 /// the conversion.
821 static ParseElementCallback convert(ParseElementFunction func)
822 {
823 ParseElementCallback temp(func);
824 return temp;
825 }
826
827 public:
828 // CREATORS
830 : d_imp(convert(&TypesParserUtil::parseDefault))
831 {
832 }
833
834 // Using destructor generated by compiler:
835 // ~Decoder_ListParser();
836
837 // MANIPULATORS
838 int beginParse(TYPE *object)
839 {
840 return d_imp.beginParse(object);
841 }
842
844 {
845 return d_imp.endParse();
846 }
847
848 template <class INPUT_ITERATOR>
849 int pushCharacters(INPUT_ITERATOR begin, INPUT_ITERATOR end)
850 {
851 return d_imp.pushCharacters(begin, end);
852 }
853};
854} // close package namespace
855
856 // ===============================================
857 // struct balxml::Decoder_InstantiateContext<TYPE>
858 // ===============================================
859
860namespace balxml {
861
862/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
863///
864/// This `struct` instantiates a context for the parameterized `TYPE` that
865/// falls under the parameterized `CATEGORY`.
866template <class CATEGORY, class TYPE>
868
869/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
870template <class TYPE>
875
876/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
877template <>
883
884/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
885template <class TYPE>
890
891/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
892template <class TYPE>
897
898/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
899template <class TYPE>
904
905/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
906template <>
912
913/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
914///
915/// Note: Customized are treated as simple types (i.e., they are parsed by
916/// `TypesParserUtil`).
917template <class TYPE>
923
924/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
925///
926/// Note: Enums are treated as simple types (i.e., they are parsed by
927/// `TypesParserUtil`).
928template <class TYPE>
934
935 // ==================================
936 // struct Decoder_SelectContext<TYPE>
937 // ==================================
938
939/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
940///
941/// This meta-function is used to select a context for the parameterized
942/// `TYPE`.
943template <class TYPE>
945
946 private:
947 typedef typename
949
950 public:
951 typedef typename
953};
954
955 // =================================
956 // class Decoder_ChoiceContext<TYPE>
957 // =================================
958
959/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
960///
961/// This is the context for types that fall under
962/// `bdlat_TypeCategory::Choice`.
963///
964/// See @ref balxml_decoder
965template <class TYPE>
967
968 // DATA
969 bool d_isSelectionNameKnown;
970 TYPE *d_object_p;
971 bool d_selectionIsRepeatable;
972 bsl::string d_selectionName;
973
974 // NOT IMPLEMENTED
977
978 public:
979 // CREATORS
980 Decoder_ChoiceContext(TYPE *object, int formattingMode);
981
982 // Using compiler generated destructor:
983 // ~Decoder_ChoiceContext();
984
985 // CALLBACKS
986 int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
987
988 int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
989
990 int addCharacters(const char *chars,
991 bsl::size_t length,
993
994 int parseAttribute(const char *name,
995 const char *value,
996 bsl::size_t lenValue,
998
999 int parseSubElement(const char *elementName,
1001};
1002
1003 // =============================
1004 // class Decoder_NillableContext
1005 // =============================
1006
1007/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1008///
1009/// Context for elements that have `bdlat_FormattingMode::e_NILLABLE`. It
1010/// acts as a proxy and forwards all callbacks to the held
1011/// `d_elementContext_p`. If `endElement` is called directly after
1012/// `startElement`, then the `isNil()` accessor will return true.
1013///
1014/// See @ref balxml_decoder
1016
1017 // DATA
1018 Decoder_ElementContext *d_elementContext_p;
1019 bool d_isNil;
1020
1021 // NOT IMPLEMENTED
1024
1025 public:
1026 // CREATORS
1028
1030
1031 // CALLBACKS
1032 int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1033
1034 int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1035
1036 int addCharacters(const char *chars,
1037 bsl::size_t length,
1039
1040 int parseAttribute(const char *name,
1041 const char *value,
1042 bsl::size_t lenValue,
1044
1045 int parseSubElement(const char *elementName,
1047
1048 // MANIPULATORS
1049
1050 /// Set the element context to the specified `elementContext`. The
1051 /// behavior of all methods in this class are undefined if this method
1052 /// has not been called.
1053 void setElementContext(Decoder_ElementContext *elementContext);
1054
1055 // ACCESSORS
1056
1057 /// Return `true` if the element is nil.
1058 bool isNil() const;
1059};
1060
1061 // ====================================================
1062 // class Decoder_PushParserContext<TYPE, PARSER>
1063 // ====================================================
1064
1065/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1066///
1067/// Context for types that use one of the following push parsers:
1068/// @code
1069/// o Base64Parser
1070/// o HexParser
1071/// o Decoder_ListParser
1072/// @endcode
1073///
1074/// See @ref balxml_decoder
1075template <class TYPE, class PARSER>
1077
1078 // DATA
1079 int d_formattingMode;
1080 TYPE *d_object_p;
1081 PARSER d_parser;
1082
1083 // NOT IMPLEMENTED
1086
1087 public:
1088 // CREATORS
1089 Decoder_PushParserContext(TYPE *object, int formattingMode);
1090
1091 // Using compiler generated destructor:
1092 // ~Decoder_PushParserContext();
1093
1094 // CALLBACKS
1095 int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1096
1097 int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1098
1099 int addCharacters(const char *chars,
1100 bsl::size_t length,
1102
1103 int parseAttribute(const char *name,
1104 const char *value,
1105 bsl::size_t lenValue,
1107
1108 int parseSubElement(const char *elementName,
1110};
1111
1112 // ===================================
1113 // class Decoder_SequenceContext<TYPE>
1114 // ===================================
1115
1116/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1117///
1118/// Context for types that fall under `bdlat_TypeCategory::Sequence`.
1119///
1120/// See @ref balxml_decoder
1121template <class TYPE>
1123
1124 // DATA
1125 bdlb::NullableValue<int> d_simpleContentId;
1126 TYPE *d_object_p;
1127
1128 // NOT IMPLEMENTED
1131
1132 public:
1133 // CREATORS
1134 Decoder_SequenceContext(TYPE *object, int formattingMode);
1135
1136 // Using compiler generated destructor:
1137 // ~Decoder_SequenceContext();
1138
1139 // CALLBACKS
1140 int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1141
1142 int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1143
1144 int addCharacters(const char *chars,
1145 bsl::size_t length,
1147
1148 int parseAttribute(const char *name,
1149 const char *value,
1150 bsl::size_t lenValue,
1152
1153 int parseSubElement(const char *elementName,
1155};
1156
1157 // =================================
1158 // class Decoder_SimpleContext<TYPE>
1159 // =================================
1160
1161/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1162///
1163/// Context for simple types (uses TypesParserUtil).
1164///
1165/// See @ref balxml_decoder
1166template <class TYPE>
1168
1169 // DATA
1170 //bsl::string d_chars;
1171 int d_formattingMode;
1172 TYPE *d_object_p;
1173
1174 // NOT IMPLEMENTED
1176 Decoder_SimpleContext &operator=(const Decoder_SimpleContext &);
1177
1178 public:
1179 // CREATORS
1180 Decoder_SimpleContext(TYPE *object, int formattingMode);
1181
1182 // Using compiler generated destructor:
1183 // ~Decoder_SimpleContext();
1184
1185 // CALLBACKS
1186 int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1187
1188 int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1189
1190 int addCharacters(const char *chars,
1191 bsl::size_t length,
1193
1194 int parseAttribute(const char *name,
1195 const char *value,
1196 bsl::size_t lenValue,
1198
1199 int parseSubElement(const char *elementName,
1201};
1202
1203 // =====================================
1204 // class Decoder_CustomizedContext<TYPE>
1205 // =====================================
1206
1207/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1208///
1209/// This is the context for types that fall under
1210/// `bdlat_TypeCategory::Customized`.
1211///
1212/// See @ref balxml_decoder
1213template <class TYPE>
1215
1216 typedef typename
1218
1220 BaseType>::Type BaseContext;
1221 // DATA
1222 TYPE *d_object;
1223 BaseType d_baseObj;
1224 BaseContext d_baseContext;
1225
1226 // NOT IMPLEMENTED
1229
1230 public:
1231 // CREATORS
1232 Decoder_CustomizedContext(TYPE *object, int formattingMode);
1233
1234 // Using compiler generated destructor:
1235 // ~Decoder_CustomizedContext();
1236
1237 // CALLBACKS
1238 int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1239
1240 int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1241
1242 int addCharacters(const char *chars,
1243 bsl::size_t length,
1245
1246 int parseAttribute(const char *name,
1247 const char *value,
1248 bsl::size_t lenValue,
1250
1251 int parseSubElement(const char *elementName,
1253};
1254
1255 // ===================================
1256 // class Decoder_UnknownElementContext
1257 // ===================================
1258
1259/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1260///
1261/// Context for unknown elements. This context is used when an unknown
1262/// element is found, and the user selected.
1263///
1264/// See @ref balxml_decoder
1266
1267 private:
1268 // NOT IMPLEMENTED
1272
1273 public:
1274 // CREATORS
1276
1277 // Using compiler generated destructor:
1278 // ~Decoder_UnknownElementContext();
1279
1280 // CALLBACKS
1282
1284
1285 int addCharacters(const char *chars,
1286 bsl::size_t length,
1288
1289 int parseAttribute(const char *name,
1290 const char *value,
1291 bsl::size_t lenValue,
1293
1294 int parseSubElement(const char *elementName,
1296};
1297
1298 // =========================
1299 // class Decoder_UTF8Context
1300 // =========================
1301
1302/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1303///
1304/// Context for UTF8 strings (i.e., `bsl::string` and `bsl::vector<char>`).
1305///
1306/// See @ref balxml_decoder
1307template <class TYPE>
1309
1310 // DATA
1311 TYPE *d_object_p;
1312
1313 // NOT IMPLEMENTED
1315 Decoder_UTF8Context& operator=(const Decoder_UTF8Context&);
1316
1317 public:
1318 // CREATORS
1319 Decoder_UTF8Context(TYPE *object, int formattingMode);
1320
1321 // Generated by compiler:
1322 // ~Decoder_UTF8Context();
1323
1324 // CALLBACKS
1325 int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1326
1327 int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1328
1329 int addCharacters(const char *chars,
1330 bsl::size_t length,
1332
1333 int parseAttribute(const char *name,
1334 const char *value,
1335 bsl::size_t lenValue,
1337
1338 int parseSubElement(const char *elementName,
1340};
1341
1342 // ==============================
1343 // class Decoder_StdStringContext
1344 // ==============================
1345
1346/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1347///
1348/// Proxy context for `bsl::string`. This is just a proxy context. It will
1349/// forward all callbacks to the appropriate context, based on the
1350/// formatting mode.
1351///
1352/// See @ref balxml_decoder
1354
1355 public:
1356 // TYPES
1357
1358 // Note that these typedefs need to be made public because Sun compiler
1359 // complains that they are inaccessible from the union (below).
1365
1366 private:
1367 // DATA
1368 union {
1372 };
1373
1374 Decoder_ElementContext *d_context_p;
1375
1376 // NOT IMPLEMENTED
1379
1380 public:
1381 // CREATORS
1382 Decoder_StdStringContext(bsl::string *object, int formattingMode);
1383
1385
1386 // CALLBACKS
1387 int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1388
1389 int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1390
1391 int addCharacters(const char *chars,
1392 bsl::size_t length,
1394
1395 int parseAttribute(const char *name,
1396 const char *value,
1397 bsl::size_t lenValue,
1399
1400 int parseSubElement(const char *elementName,
1402};
1403
1404 // ==================================
1405 // class Decoder_StdVectorCharContext
1406 // ==================================
1407
1408/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1409///
1410/// Proxy context for `bsl::string`. This is just a proxy context. It will
1411/// forward all callbacks to the appropriate context, based on the
1412/// formatting mode.
1413///
1414/// See @ref balxml_decoder
1416
1417 public:
1418 // TYPES
1419
1420 // Note that these typedefs need to be made public because Sun compiler
1421 // complains that they are inaccessible from the union (below).
1432
1433 private:
1434 // DATA
1435 union {
1440 };
1441
1442 Decoder_ElementContext *d_context_p;
1443
1444 // NOT IMPLEMENTED
1448
1449 public:
1450 // CREATORS
1452 int formattingMode);
1453
1455
1456 // CALLBACKS
1457 int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1458
1459 int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE;
1460
1461 int addCharacters(const char *chars,
1462 bsl::size_t length,
1464
1465 int parseAttribute(const char *name,
1466 const char *value,
1467 bsl::size_t lenValue,
1469
1470 int parseSubElement(const char *elementName,
1472};
1473
1474 // ====================================
1475 // class Decoder_PrepareSequenceContext
1476 // ====================================
1477
1478/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1479///
1480/// This class does one thing:
1481/// @code
1482/// o finds an element that has the 'IS_SIMPLE_CONTENT' flag set
1483/// @endcode
1484///
1485/// See @ref balxml_decoder
1487
1488 // DATA
1489 bdlb::NullableValue<int> *d_simpleContentId_p; // held, not owned
1490
1491 // NOT IMPLEMENTED
1495
1496 public:
1497 // CREATORS
1499
1500 // Using compiler generated destructor:
1501 // ~Decoder_PrepareSequenceContext();
1502
1503 // MANIPULATORS
1504 template <class TYPE, class INFO_TYPE>
1505 int operator()(const TYPE &object, const INFO_TYPE &info);
1506};
1507
1508 // ========================================
1509 // class Decoder_ParseSequenceSimpleContent
1510 // ========================================
1511
1512/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1513///
1514/// Parse simple content.
1515///
1516/// See @ref balxml_decoder
1518
1519 // DATA
1520 //const bsl::string *d_chars_p; // content characters
1521 const char *d_chars_p; // content characters
1522 bsl::size_t d_len;
1523 Decoder *d_decoder; // error logger (held)
1524
1525 // NOT IMPLEMENTED
1530
1531 public:
1532 // CREATORS
1534 const char *chars,
1535 bsl::size_t len);
1536
1537 // Generated by compiler:
1538 // ~Decoder_ParseSequenceSimpleContent();
1539
1540 // MANIPULATORS
1541 template <class TYPE, class INFO_TYPE>
1542 int operator()(TYPE *object, const INFO_TYPE& info);
1543
1544 template <class INFO_TYPE>
1545 int operator()(bsl::string *object, const INFO_TYPE& info);
1546};
1547
1548 // =====================================
1549 // class Decoder_ParseSequenceSubElement
1550 // =====================================
1551
1552/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1553///
1554/// This is similar to `Decoder_ParseObject`.
1555///
1556/// See @ref balxml_decoder
1558
1559 // DATA
1560 Decoder *d_decoder; // held, not owned
1561 const char *d_elementName_p; // held, not owned
1562 bsl::size_t d_lenName;
1563
1564 // NOT IMPLEMENTED
1568
1569 public:
1570 // CREATORS
1572 const char *elementName,
1573 bsl::size_t lenName);
1574
1575 // Using compiler-generated destructor:
1576 // ~Decoder_ParseSequenceSubElement();
1577
1578 // MANIPULATORS
1579 template <class TYPE, class INFO_TYPE>
1580 int operator()(TYPE *object, const INFO_TYPE &info);
1581
1582 template <class TYPE>
1583 int execute(TYPE *object, int id, int formattingMode);
1584};
1585
1586 // ============================
1587 // class Decoder_ParseAttribute
1588 // ============================
1589
1590/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1591///
1592/// Parse an attribute.
1593///
1594/// See @ref balxml_decoder
1596
1597 // DATA
1598 Decoder *d_decoder; // error logger (held)
1599 bool d_failed; // set to true if parsing failed
1600
1601 const char *d_name_p; // attribute name (held)
1602 const char *d_value_p; // attribute value (held)
1603 bsl::size_t d_value_length;
1604
1605 public:
1606 // IMPLEMENTATION MANIPULATORS
1607 template <class TYPE>
1608 int executeImp(TYPE *object,
1609 int formattingMode,
1611 template <class TYPE>
1612 int executeImp(TYPE *object,
1613 int formattingMode,
1615 template <class TYPE, class ANY_CATEGORY>
1616 int executeImp(TYPE *object, int formattingMode, ANY_CATEGORY);
1617
1618 private:
1619 // NOT IMPLEMENTED
1622 operator=(const Decoder_ParseAttribute&);
1623
1624 public:
1625 // CREATORS
1627 const char *name,
1628 const char *value,
1629 bsl::size_t lengthValue);
1630
1631 // Generated by compiler:
1632 // ~Decoder_ParseAttribute();
1633
1634 // MANIPULATORS
1635 template <class TYPE, class INFO_TYPE>
1636 int operator()(TYPE *object, const INFO_TYPE& info);
1637
1638 template <class TYPE>
1639 int execute(TYPE *object, int formattingMode);
1640
1641 // ACCESSORS
1642 bool failed() const;
1643};
1644
1645 // =========================
1646 // class Decoder_ParseObject
1647 // =========================
1648
1649/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1650///
1651/// Parse the visited object.
1652///
1653/// See @ref balxml_decoder
1655
1656 // PRIVATE TYPES
1657 struct CanBeListOrRepetition { };
1658 struct CanBeRepetitionOnly { };
1659
1660 // DATA
1661 Decoder *d_decoder; // held, not owned
1662 const char *d_elementName_p; // held, not owned
1663 bsl::size_t d_lenName;
1664
1665 // NOT IMPLEMENTED
1667 Decoder_ParseObject& operator=(const Decoder_ParseObject&);
1668
1669 public:
1670 // IMPLEMENTATION MANIPULATORS
1672 int formattingMode,
1674
1675 template <class TYPE>
1676 int executeImp(bsl::vector<TYPE> *object,
1677 int formattingMode,
1679
1680 template <class TYPE>
1681 int executeImp(TYPE *object,
1682 int formattingMode,
1684
1685 template <class TYPE>
1686 int executeImp(TYPE *object,
1687 int formattingMode,
1689
1690 template <class TYPE>
1691 int executeImp(TYPE *object,
1692 int formattingMode,
1694
1695 template <class TYPE>
1696 int executeImp(TYPE *object,
1697 int formattingMode,
1699
1700 template <class TYPE>
1701 int executeImp(TYPE *object,
1702 int formattingMode,
1704
1705 template <class TYPE>
1706 int executeImp(TYPE *object,
1707 int formattingMode,
1709
1710 template <class TYPE, class ANY_CATEGORY>
1711 int executeImp(TYPE *object, int formattingMode, ANY_CATEGORY);
1712
1713 template <class TYPE>
1714 int executeArrayImp(TYPE *object,
1715 int formattingMode,
1716 CanBeListOrRepetition);
1717
1718 template <class TYPE>
1719 int executeArrayImp(TYPE *object, int formattingMode, CanBeRepetitionOnly);
1720
1721 template <class TYPE>
1722 int executeArrayRepetitionImp(TYPE *object, int formattingMode);
1723
1724 public:
1725 // CREATORS
1727 const char *elementName,
1728 bsl::size_t lenName);
1729
1730 // Using compiler-generated destructor:
1731 // ~Decoder_ParseObject();
1732
1733 // MANIPULATORS
1734 template <class TYPE, class INFO_TYPE>
1735 int operator()(TYPE *object, const INFO_TYPE &info);
1736
1737 template <class TYPE>
1738 int execute(TYPE *object, int formattingMode);
1739};
1740
1741 // =================================
1742 // class Decoder_ParseNillableObject
1743 // =================================
1744
1745/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1746///
1747/// See @ref balxml_decoder
1749
1750 // DATA
1751 int d_formattingMode;
1752 Decoder_NillableContext d_nillableContext;
1753 Decoder *d_decoder;
1754
1755 public:
1756 // IMPLEMENTATION MANIPULATORS
1757 template <class TYPE>
1758 int executeImp(TYPE *object, bdlat_TypeCategory::DynamicType);
1759
1760 template <class TYPE, class ANY_CATEGORY>
1761 int executeImp(TYPE *object, ANY_CATEGORY);
1762
1763 private:
1764 // NOT IMPLEMENTED
1767
1768 public:
1769 /// Construct a functor to parse nillable objects.
1770 Decoder_ParseNillableObject(Decoder *decoder, int formattingMode);
1771
1772 // Using compiler-generated destructor:
1773 // ~Decoder_ParseNillableObject();
1774
1775 // MANIPULATORS
1776
1777 /// Visit the specified `object`.
1778 template <class TYPE>
1779 int operator()(TYPE *object);
1780
1781 // ACCESSORS
1782
1783 /// Return `true` if the value was nil, and false otherwise.
1784 bool isNil() const;
1785};
1786
1787// ============================================================================
1788// PROXY CLASSES
1789// ============================================================================
1790
1791 // =============================
1792 // struct Decoder_decodeImpProxy
1793 // =============================
1794
1795/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1797
1798 // DATA
1800
1801 // CREATORS
1802
1803 // Creators have been omitted to allow simple static initialization of this
1804 // struct.
1805
1806 // FUNCTIONS
1807 template <class TYPE>
1808 inline
1810 {
1812 return -1;
1813 }
1814
1815 template <class TYPE, class ANY_CATEGORY>
1816 inline
1817 int operator()(TYPE *object, ANY_CATEGORY category)
1818 {
1819 return d_decoder->decodeImp(object, category);
1820 }
1821};
1822
1823 // ==========================================
1824 // struct Decoder_ParseAttribute_executeProxy
1825 // ==========================================
1826
1827/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1829
1830 // DATA
1833
1834 // CREATORS
1835
1836 // Creators have been omitted to allow simple static initialization of this
1837 // struct.
1838
1839 // FUNCTIONS
1840 template <class TYPE>
1841 inline
1842 int operator()(TYPE *object)
1843 {
1844 return d_instance_p->execute(object, d_formattingMode);
1845 }
1846};
1847
1848 // =============================================
1849 // struct Decoder_ParseAttribute_executeImpProxy
1850 // =============================================
1851
1852/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1854
1855 // DATA
1858
1859 // CREATORS
1860
1861 // Creators have been omitted to allow simple static initialization of this
1862 // struct.
1863
1864 // FUNCTIONS
1865 template <class TYPE>
1866 inline
1868 {
1870 return -1;
1871 }
1872
1873 template <class TYPE, class ANY_CATEGORY>
1874 inline
1875 int operator()(TYPE *object, ANY_CATEGORY category)
1876 {
1877 return d_instance_p->executeImp(object, d_formattingMode, category);
1878 }
1879};
1880
1881 // =======================================
1882 // struct Decoder_ParseObject_executeProxy
1883 // =======================================
1884
1885/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1887
1888 // DATA
1891
1892 // CREATORS
1893
1894 // Creators have been omitted to allow simple static initialization of this
1895 // struct.
1896
1897 // FUNCTIONS
1898 template <class TYPE>
1899 inline
1900 int operator()(TYPE *object)
1901 {
1902 return d_instance_p->execute(object, d_formattingMode);
1903 }
1904};
1905
1906 // ==========================================
1907 // struct Decoder_ParseObject_executeImpProxy
1908 // ==========================================
1909
1910/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1912
1913 // DATA
1916
1917 // CREATORS
1918
1919 // Creators have been omitted to allow simple static initialization of this
1920 // struct.
1921
1922 // FUNCTIONS
1923 template <class TYPE>
1924 inline
1926 {
1928 return -1;
1929 }
1930
1931 template <class TYPE, class ANY_CATEGORY>
1932 inline
1933 int operator()(TYPE *object, ANY_CATEGORY category)
1934 {
1935 return d_instance_p->executeImp(object, d_formattingMode, category);
1936 }
1937};
1938
1939 // ==================================================
1940 // struct Decoder_ParseNillableObject_executeImpProxy
1941 // ==================================================
1942
1943/// COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
1945
1946 // DATA
1948
1949 // CREATORS
1950
1951 // Creators have been omitted to allow simple static initialization of this
1952 // struct.
1953
1954 // FUNCTIONS
1955 template <class TYPE>
1956 inline
1958 {
1960 return -1;
1961 }
1962
1963 template <class TYPE, class ANY_CATEGORY>
1964 inline
1965 int operator()(TYPE *object, ANY_CATEGORY category)
1966 {
1967 return d_instance_p->executeImp(object, category);
1968 }
1969};
1970} // close package namespace
1971
1972// ============================================================================
1973// INLINE DEFINITIONS
1974// ============================================================================
1975
1976 // -----------------------------------
1977 // class balxml::Decoder::MemOutStream
1978 // -----------------------------------
1979
1980inline
1981balxml::Decoder::MemOutStream::MemOutStream(bslma::Allocator *basicAllocator)
1982: bsl::ostream(0)
1983, d_sb(bslma::Default::allocator(basicAllocator))
1984{
1985 rdbuf(&d_sb);
1986}
1987
1988// MANIPULATORS
1989inline
1991{
1992 d_sb.reset();
1993}
1994
1995// ACCESSORS
1996inline
1998{
1999 return d_sb.data();
2000}
2001
2002inline
2004{
2005 return (int)d_sb.length();
2006}
2007
2008namespace balxml {
2009inline
2010void Decoder::setNumUnknownElementsSkipped(int value)
2011{
2012 BSLS_REVIEW(0 <= value);
2013
2014 d_numUnknownElementsSkipped = value;
2015}
2016
2017 // -------------
2018 // class Decoder
2019 // -------------
2020
2021inline
2022const DecoderOptions *Decoder::options() const
2023{
2024 return d_options;
2025}
2026
2027inline
2028Reader *Decoder::reader() const
2029{
2030 return d_reader;
2031}
2032
2033inline
2034ErrorInfo *Decoder::errorInfo() const
2035{
2036 return d_errorInfo;
2037}
2038
2039inline
2040bsl::ostream *Decoder::errorStream() const
2041{
2042 return d_errorStream;
2043}
2044
2045inline
2046int Decoder::numUnknownElementsSkipped() const
2047{
2048 return d_numUnknownElementsSkipped;
2049}
2050
2051inline
2052bsl::ostream *Decoder::warningStream() const
2053{
2054 return d_warningStream;
2055}
2056
2057inline
2058int Decoder::errorCount() const
2059{
2060 return d_errorCount;
2061}
2062
2063inline
2064int Decoder::warningCount() const
2065{
2066 return d_warningCount;
2067}
2068
2069/// If we're decoding a structure (aka `sequence` or `choice`), check to
2070/// make sure that the root tag in the XML matches the name of the specified
2071/// `TYPE` that we are decoding into. If `TYPE` has not implemented the
2072/// bdlat introspection protocol, then the class name will be NULL, and we
2073/// cannot check it against the tag name.
2074template <class TYPE>
2075inline
2076int Decoder::validateTopElement(const TYPE *object) {
2077
2078 // has the user asked us to validate the root tag?
2079 if (!d_options->validateRootTag()) {
2080 return 0; // RETURN
2081 }
2082
2083 // Are we decoding a sequence or a choice?
2084 typedef typename bdlat_TypeCategory::Select<TYPE>::Type Category_t;
2087 return 0; // RETURN
2088 }
2089
2090 // Do we have introspection on 'TYPE'?
2091 const char *typeName = bdlat_TypeName::className(*object);
2092 if (0 == typeName) { // no introspection support for 'TYPE'
2093 return 0; // RETURN
2094 }
2095
2096 // Does the class name match the root tag?
2097 const char *nodeName = d_reader->nodeName(); // this is the root tag
2098 if (0 == strcmp(nodeName, typeName)) {
2099 return 0; // RETURN
2100 }
2101
2103 << "The root object is of type '" << nodeName << "',"
2104 << " but we're attempting to decode an object of type "
2105 << "'" << typeName << "'." << BALXML_DECODER_LOG_END;
2106 return -1;
2107}
2108
2109
2110inline
2111int Decoder::open(bsl::istream& stream, const char *uri)
2112{
2113 return open(stream.rdbuf(), uri);
2114}
2115
2116template <class TYPE>
2117bsl::istream& Decoder::decode(bsl::istream& stream,
2118 TYPE *object,
2119 const char *uri)
2120{
2121 if (!stream.good()) {
2122
2124 << "The input stream is invalid. "
2125 << "Unable to decode XML object. "
2127
2128 return stream; // RETURN
2129 }
2130
2131 if (0 != this->decode(stream.rdbuf(), object, uri)) {
2132 stream.setstate(bsl::ios_base::failbit);
2133 }
2134
2135 return stream;
2136}
2137
2138template <class TYPE>
2139int
2140Decoder::decode(bsl::streambuf *buffer, TYPE *object, const char *uri)
2141{
2142 if (this->open(buffer, uri) != 0) {
2143
2144 return this->errorCount(); // RETURN
2145
2146 }
2147
2148 int ret = validateTopElement(object);
2149 if (0 == ret) {
2150 ret = this->decode(object);
2151 }
2152
2153 switch(errorSeverity()) {
2154 case ErrorInfo::e_NO_ERROR:
2155 break;
2156 case ErrorInfo::e_WARNING:
2157 if (d_warningStream) {
2158 *d_warningStream << loggedMessages();
2159 }
2160 break;
2161 default:
2162 if (d_errorStream) {
2163 *d_errorStream << loggedMessages();
2164 }
2165 break;
2166 }
2167
2168 this->close();
2169 return ret;
2170}
2171
2172template <class TYPE>
2173int Decoder::decode(const char *buffer,
2174 bsl::size_t buflen,
2175 TYPE *object,
2176 const char *uri)
2177{
2178 if (this->open(buffer, buflen, uri) != 0) {
2179
2180 return this->errorCount(); // RETURN
2181 }
2182
2183 int ret = validateTopElement(object);
2184 if (0 == ret) {
2185 ret = this->decode(object);
2186 }
2187
2188 this->close();
2189 return ret;
2190}
2191
2192template <class TYPE>
2193int Decoder::decode(const char *filename, TYPE *object)
2194{
2195 if (this->open(filename) != 0) {
2196
2197 return this->errorCount(); // RETURN
2198 }
2199
2200 int ret = validateTopElement(object);
2201 if (0 == ret) {
2202 ret = this->decode(object);
2203 }
2204
2205 this->close();
2206 return ret;
2207}
2208
2209template <class TYPE>
2210inline
2211int Decoder::decode(TYPE *object)
2212{
2214
2215 typedef typename
2217
2218 this->decodeImp(object, TypeCategory());
2219
2220 return this->errorCount();
2221}
2222
2223template <class TYPE>
2224inline
2225int Decoder::decodeImp(TYPE *object, bdlat_TypeCategory::DynamicType)
2226{
2227 Decoder_decodeImpProxy proxy = { this };
2228 int ret = bdlat_TypeCategoryUtil::manipulateByCategory(object, proxy);
2229 if (0 != ret) {
2231 << "The object being decoded is a 'DynamicType', and "
2232 "attempting to manipulate the object by its dynamic "
2233 "category returned a non-zero status."
2235 return ret;
2236 }
2237
2238 return 0;
2239}
2240
2241template <class TYPE, class ANY_CATEGORY>
2242inline
2243int Decoder::decodeImp(TYPE *object, ANY_CATEGORY)
2244{
2245 typedef typename
2246 Decoder_InstantiateContext<ANY_CATEGORY, TYPE>::Type ContextType;
2247
2248 ContextType elementContext(object, d_options->formattingMode());
2249
2250 return elementContext.beginParse(this);
2251}
2252
2253 // ---------------------------------
2254 // class Decoder_ChoiceContext<TYPE>
2255 // ---------------------------------
2256
2257template <class TYPE>
2258inline
2260 int formattingMode)
2261: d_isSelectionNameKnown(false)
2262, d_object_p(object)
2263, d_selectionIsRepeatable(false)
2264, d_selectionName()
2265{
2266 (void) formattingMode;
2268 (formattingMode & bdlat_FormattingMode::e_TYPE_MASK));
2269}
2270
2271// CALLBACKS
2272
2273template <class TYPE>
2275{
2276 enum { k_SUCCESS = 0 };
2277
2278 d_isSelectionNameKnown = false; // no selection seen yet
2279
2280 return k_SUCCESS;
2281}
2282
2283template <class TYPE>
2285{
2286 enum { k_SUCCESS = 0, k_FAILURE = -1 };
2287
2288 if (!d_isSelectionNameKnown) {
2290 << "No elements selected in choice."
2292
2293 return k_FAILURE; // will trigger failure in parser // RETURN
2294 }
2295
2296 return k_SUCCESS;
2297}
2298
2299template <class TYPE>
2301 bsl::size_t length,
2302 Decoder *decoder)
2303{
2304 enum { k_SUCCESS = 0, k_FAILURE = -1 };
2305
2306 BSLS_REVIEW(0 != length);
2307
2308 const char *begin = chars;
2309 const char *end = begin + length;
2310
2312
2313 if (begin != end) {
2315 << "Invalid characters \""
2316 << bsl::string(begin, end - begin)
2317 << "\" when parsing choice."
2319
2320 return k_FAILURE; // will trigger failure in parser // RETURN
2321 }
2322
2323 return k_SUCCESS;
2324}
2325
2326template <class TYPE>
2327inline
2329 const char *,
2330 bsl::size_t,
2331 Decoder *)
2332{
2333 enum { k_ATTRIBUTE_IGNORED = 0 };
2334
2335 return k_ATTRIBUTE_IGNORED;
2336}
2337
2338template <class TYPE>
2340 Decoder *decoder)
2341{
2342 enum { k_FAILURE = -1 };
2343
2344 const int lenName = static_cast<int>(bsl::strlen(elementName));
2345
2346 if (d_isSelectionNameKnown
2347 && (!d_selectionIsRepeatable || d_selectionName != elementName))
2348 {
2350 << "Only one selection is permitted inside choice."
2352
2353 return k_FAILURE; // RETURN
2354 }
2355
2356 bool wasSelectionNameKnown = d_isSelectionNameKnown;
2357 d_isSelectionNameKnown = true;
2358
2359 if (decoder->options()->skipUnknownElements() &&
2360 false == bdlat_ChoiceFunctions::hasSelection(*d_object_p,
2361 elementName,
2362 lenName)) {
2364 decoder->numUnknownElementsSkipped() + 1);
2365 d_selectionIsRepeatable = true; // assume repeatable
2366 d_selectionName.assign(elementName, lenName);
2367
2368 Decoder_UnknownElementContext unknownElement;
2369 return unknownElement.beginParse(decoder); // RETURN
2370 }
2371
2372 if (!wasSelectionNameKnown) {
2373 if (0 != bdlat_ChoiceFunctions::makeSelection(d_object_p,
2374 elementName,
2375 lenName)) {
2377 << "Unable to make selection: \""
2378 << elementName
2379 << "\"."
2381
2382 return k_FAILURE; // RETURN
2383 }
2384
2385 d_selectionIsRepeatable = true; // TBD: check if repeatable
2386 d_selectionName.assign(elementName, lenName);
2387 }
2388
2389 Decoder_ParseObject parseObject(decoder, elementName, lenName);
2390 return bdlat_ChoiceFunctions::manipulateSelection(d_object_p, parseObject);
2391}
2392
2393 // ----------------------------------------------------
2394 // class Decoder_PushParserContext<TYPE, PARSER>
2395 // ----------------------------------------------------
2396
2397// CREATORS
2398template <class TYPE, class PARSER>
2399inline
2401 TYPE *object,
2402 int formattingMode)
2403: d_formattingMode(formattingMode), d_object_p(object)
2404{
2405}
2406
2407// CALLBACKS
2408
2409template <class TYPE, class PARSER>
2411{
2412 int result = d_parser.beginParse(d_object_p);
2413
2414 if (0 != result) {
2416 << "Unable to begin parsing list or binary type"
2417
2418 << "\"."
2420 }
2421
2422 return result;
2423}
2424
2425template <class TYPE, class PARSER>
2427{
2428 int result = d_parser.endParse();
2429
2430 if (0 != result) {
2432 << "Unable to end parsing list or binary type"
2433 << "\"."
2435 }
2436
2437 return result;
2438}
2439
2440template <class TYPE, class PARSER>
2442 const char *chars,
2443 bsl::size_t length,
2444 Decoder *decoder)
2445{
2446 const char *begin = chars;
2447 const char *end = begin + length;
2448
2449 int result = d_parser.pushCharacters(begin, end);
2450
2451 if (0 != result) {
2453 << "Unable to push \"" << chars
2454 << "\" when parsing list or binary type"
2455
2456 << "\"."
2458 }
2459
2460 return result;
2461}
2462
2463template <class TYPE, class PARSER>
2464inline
2466 const char *,
2467 bsl::size_t,
2468 Decoder *)
2469{
2470 enum { k_ATTRIBUTE_IGNORED = 0 };
2471
2472 return k_ATTRIBUTE_IGNORED;
2473}
2474
2475template <class TYPE, class PARSER>
2477 const char *elementName,
2478 Decoder *decoder)
2479{
2480 enum { k_FAILURE = -1 };
2481
2483 << "Unexpected sub-element \"" << elementName
2484 << "\" when parsing list or binary type"
2485 << "\"."
2487
2488 return k_FAILURE;
2489}
2490
2491 // -----------------------------------
2492 // class Decoder_SequenceContext<TYPE>
2493 // -----------------------------------
2494
2495// CREATORS
2496template <class TYPE>
2497inline
2499 int formattingMode)
2500: d_object_p(object)
2501{
2502 (void) formattingMode;
2504 (formattingMode & bdlat_FormattingMode::e_TYPE_MASK));
2505
2506 // {DRQS 153551134<GO>}: gcc can occasionally mis-diagnose
2507 // 'd_simpleContentId' as uninitialized. This workaround avoids that
2508 // problem (which can cause build failures if '-Wmaybe-uninitialized' and
2509 // '-Werror' are set). See also {DRQS 75130685<GO>} and {DRQS
2510 // 115347303<GO>}.
2511 d_simpleContentId.makeValue(0);
2512 d_simpleContentId.reset();
2513}
2514
2515// CALLBACKS
2516
2517template <class TYPE>
2519{
2520 //d_chars.clear();
2521
2522 Decoder_PrepareSequenceContext prepareSequenceContext(&d_simpleContentId);
2523
2525 d_object_p,
2526 prepareSequenceContext);
2527
2528 if (0 != ret) {
2530 << "Unable to prepare sequence context!"
2532 }
2533
2534 return ret;
2535}
2536
2537template <class TYPE>
2539{
2540 enum { k_SUCCESS = 0 };
2541
2542 return k_SUCCESS;
2543}
2544
2545template <class TYPE>
2547 bsl::size_t length,
2548 Decoder *decoder)
2549{
2550 enum { k_SUCCESS = 0, k_FAILURE = -1 };
2551
2552 BSLS_REVIEW(0 != length);
2553
2554 if (d_simpleContentId.isNull()) {
2555
2556 const char *begin = chars;
2557 const char *end = begin + length;
2558
2560
2561 if (begin != end) {
2563 << "Unexpected characters: \""
2564 << bsl::string(begin, end - begin)
2565 << "\"."
2567
2568 return k_FAILURE; // RETURN
2569 }
2570 return k_SUCCESS; // RETURN
2571 }
2572
2573 Decoder_ParseSequenceSimpleContent parseSimpleContent(decoder,
2574 chars,
2575 length);
2576
2578 d_object_p,
2579 parseSimpleContent,
2580 d_simpleContentId.value());
2581}
2582
2583template <class TYPE>
2585 const char *value,
2586 bsl::size_t lenValue,
2587 Decoder *decoder)
2588{
2589 enum { k_SUCCESS = 0, k_ATTRIBUTE_IGNORED = 0, k_FAILURE = -1 };
2590
2591 const int lenName = static_cast<int>(bsl::strlen(name));
2592
2593 Decoder_ParseAttribute visitor(decoder, name, value, lenValue);
2594
2596 visitor,
2597 name,
2598 lenName)) {
2599 if (visitor.failed()) {
2600 return k_FAILURE; // RETURN
2601 }
2602 return k_ATTRIBUTE_IGNORED; // RETURN
2603 }
2604
2605 return k_SUCCESS;
2606}
2607
2608template <class TYPE>
2610 Decoder *decoder)
2611{
2612 enum { k_FAILURE = -1 };
2613
2614 const int lenName = static_cast<int>(bsl::strlen(elementName));
2615
2616 if (decoder->options()->skipUnknownElements()
2617 && false == bdlat_SequenceFunctions::hasAttribute(*d_object_p,
2618 elementName,
2619 lenName)) {
2621 decoder->numUnknownElementsSkipped() + 1);
2622 Decoder_UnknownElementContext unknownElement;
2623 return unknownElement.beginParse(decoder); // RETURN
2624 }
2625
2626 Decoder_ParseSequenceSubElement visitor(decoder, elementName, lenName);
2627
2629 visitor,
2630 elementName,
2631 lenName);
2632}
2633
2634 // ---------------------------------
2635 // class Decoder_SimpleContext<TYPE>
2636 // ---------------------------------
2637
2638// CREATORS
2639template <class TYPE>
2640inline
2642 int formattingMode)
2643: d_formattingMode(formattingMode)
2644, d_object_p(object)
2645{
2646}
2647
2648// CALLBACKS
2649
2650template <class TYPE>
2652{
2653 enum { k_SUCCESS = 0 };
2654
2655 //d_chars.clear();
2656
2657 return k_SUCCESS;
2658}
2659
2660template <class TYPE>
2662{
2663 enum { k_SUCCESS = 0, k_FAILURE = -1 };
2664
2665 return k_SUCCESS;
2666}
2667
2668template <class TYPE>
2670 bsl::size_t length,
2671 Decoder *decoder)
2672{
2673 enum { k_SUCCESS = 0, k_FAILURE = -1 };
2674
2675 const char *begin = chars;
2676 const char *end = begin + length;
2677
2679
2680 if (0 != TypesParserUtil::parse(d_object_p,
2681 begin,
2682 static_cast<int>(end - begin),
2683 d_formattingMode)) {
2685 << "Unable to parse \""
2686 << bsl::string(begin, end)
2687 << "\" when parsing list or binary type"
2688 << "\".\n"
2690
2691 return k_FAILURE; // RETURN
2692 }
2693
2694 return k_SUCCESS;
2695}
2696
2697template <class TYPE>
2698inline
2700 const char *,
2701 bsl::size_t,
2702 Decoder *)
2703{
2704 enum { k_ATTRIBUTE_IGNORED = 0 };
2705
2706 return k_ATTRIBUTE_IGNORED;
2707}
2708
2709template <class TYPE>
2711 Decoder *decoder)
2712{
2713 enum { k_FAILURE = -1 };
2714
2716 << "Attempted to create sub context for \""
2717 << elementName << "\" inside simple type"
2718
2719 << "\"."
2721
2722 return k_FAILURE; // will trigger failure in parser
2723}
2724
2725 // -------------------------------------
2726 // class Decoder_CustomizedContext<TYPE>
2727 // -------------------------------------
2728
2729// CREATORS
2730template <class TYPE>
2731inline
2733 TYPE *object,
2734 int formattingMode)
2735: d_object (object)
2736, d_baseObj()
2737, d_baseContext(&d_baseObj, formattingMode)
2738{
2739}
2740
2741// CALLBACKS
2742
2743template <class TYPE>
2745{
2746 return d_baseContext.startElement (decoder);
2747}
2748
2749template <class TYPE>
2751{
2752 enum { k_SUCCESS = 0, k_FAILURE = -1 };
2753 int rc = d_baseContext.endElement(decoder);
2754 if (rc == k_SUCCESS
2756 d_baseObj)) {
2757 return k_SUCCESS; // RETURN
2758 }
2759
2760 return k_FAILURE;
2761}
2762
2763template <class TYPE>
2765 bsl::size_t length,
2766 Decoder *decoder)
2767{
2768 return d_baseContext.addCharacters(chars, length, decoder);
2769}
2770
2771template <class TYPE>
2773 const char *value,
2774 bsl::size_t lenValue,
2775 Decoder *decoder)
2776{
2777 return d_baseContext.parseAttribute(name, value, lenValue, decoder);
2778}
2779
2780template <class TYPE>
2782 Decoder *decoder)
2783{
2784 return d_baseContext.parseSubElement(elementName, decoder);
2785}
2786
2787 // -------------------------
2788 // class Decoder_UTF8Context
2789 // -------------------------
2790
2791// CREATORS
2792template <class TYPE>
2793inline
2795: d_object_p(object)
2796{
2797}
2798
2799// CALLBACKS
2800
2801template <class TYPE>
2802inline
2804{
2805 enum { k_SUCCESS = 0 };
2806
2807 d_object_p->clear();
2808
2809 return k_SUCCESS;
2810}
2811
2812template <class TYPE>
2813inline
2815{
2816 enum { k_SUCCESS = 0 };
2817
2818 return k_SUCCESS;
2819}
2820
2821template <class TYPE>
2822inline int
2824 bsl::size_t length,
2825 Decoder *)
2826{
2827 enum { k_SUCCESS = 0 };
2828
2829 d_object_p->insert(d_object_p->end(), chars, chars + length);
2830
2831 return k_SUCCESS;
2832}
2833
2834template <class TYPE>
2835inline
2837 const char *,
2838 bsl::size_t,
2839 Decoder *)
2840{
2841 enum { k_ATTRIBUTE_IGNORED = 0 };
2842
2843 return k_ATTRIBUTE_IGNORED;
2844}
2845
2846template <class TYPE>
2848 Decoder *decoder)
2849{
2850 enum { k_FAILURE = -1 };
2851
2853 << "Attempted to create sub context for \""
2854 << elementName << "\" inside UTF8 type."
2856
2857 return k_FAILURE; // will trigger failure in parser
2858}
2859
2860 // ------------------------------------
2861 // class Decoder_PrepareSequenceContext
2862 // ------------------------------------
2863
2864// CREATORS
2865inline
2866Decoder_PrepareSequenceContext::Decoder_PrepareSequenceContext(
2867 bdlb::NullableValue<int> *simpleContentId)
2868: d_simpleContentId_p(simpleContentId)
2869{
2870 d_simpleContentId_p->reset();
2871}
2872
2873// MANIPULATORS
2874template <class TYPE, class INFO_TYPE>
2876 const INFO_TYPE& info)
2877{
2878 enum { k_SUCCESS = 0 };
2879
2880 if (info.formattingMode() & bdlat_FormattingMode::e_SIMPLE_CONTENT) {
2881 BSLS_ASSERT_SAFE(d_simpleContentId_p->isNull());
2882 d_simpleContentId_p->makeValue(info.id());
2883 }
2884
2885 return k_SUCCESS;
2886}
2887
2888 // ----------------------------------------
2889 // class Decoder_ParseSequenceSimpleContent
2890 // ----------------------------------------
2891
2892// CREATORS
2893inline
2894Decoder_ParseSequenceSimpleContent::Decoder_ParseSequenceSimpleContent(
2895 Decoder *decoder,
2896 const char *chars,
2897 bsl::size_t len)
2898: d_chars_p(chars), d_len(len), d_decoder(decoder)
2899{
2900 BSLS_REVIEW(d_chars_p);
2901 BSLS_REVIEW(d_decoder);
2902}
2903
2904// MANIPULATORS
2905template <class TYPE, class INFO_TYPE>
2907 const INFO_TYPE& info)
2908{
2909 BSLS_ASSERT_SAFE(info.formattingMode()
2911
2912 enum { k_SUCCESS = 0, k_FAILURE = -1 };
2913
2914 const char *begin = d_chars_p;
2915 const char *end = begin + d_len;
2916
2918
2919 if (0 != TypesParserUtil::parse(object,
2920 begin,
2921 static_cast<int>(end - begin),
2922 info.formattingMode())) {
2923 BALXML_DECODER_LOG_ERROR(d_decoder)
2924 << "Unable to parse \""
2925 << bsl::string(begin, end)
2926 << "\" within simple content"
2927
2928 << "\"."
2930
2931 return k_FAILURE; // RETURN
2932 }
2933
2934 return k_SUCCESS;
2935}
2936
2937template <class INFO_TYPE>
2938inline
2940 const INFO_TYPE& info)
2941{
2942 enum { k_SUCCESS = 0 };
2943
2944 BSLS_ASSERT_SAFE(info.formattingMode()
2946
2947 (void) info;
2948
2949 object->assign(d_chars_p, d_len);
2950
2951 return k_SUCCESS;
2952}
2953
2954 // -------------------------------------
2955 // class Decoder_ParseSequenceSubElement
2956 // -------------------------------------
2957
2958// CREATORS
2959inline
2960Decoder_ParseSequenceSubElement::Decoder_ParseSequenceSubElement(
2961 Decoder *decoder,
2962 const char *elementName,
2963 bsl::size_t lenName)
2964: d_decoder(decoder), d_elementName_p(elementName), d_lenName(lenName)
2965{
2966}
2967
2968// MANIPULATORS
2969template <class TYPE, class INFO_TYPE>
2970inline
2972 const INFO_TYPE& info)
2973{
2974 return execute(object, info.id(), info.formattingMode());
2975}
2976
2977template <class TYPE>
2979 int,
2980 int formattingMode)
2981{
2982 enum { k_FAILURE = -1 };
2983 Decoder_ParseObject parseObject(d_decoder, d_elementName_p, d_lenName);
2984
2985 return parseObject.execute(object, formattingMode);
2986}
2987
2988 // ----------------------------
2989 // class Decoder_ParseAttribute
2990 // ----------------------------
2991
2992// PRIVATE MANIPULATORS
2993template <class TYPE>
2995 TYPE *object,
2996 int formattingMode,
2998{
3001 }
3002
3004 this, formattingMode
3005 };
3006
3008}
3009
3010template <class TYPE>
3011inline
3013 TYPE *object,
3014 int formattingMode,
3016{
3018 formattingMode };
3020}
3021
3022template <class TYPE, class ANY_CATEGORY>
3024 int formattingMode,
3025 ANY_CATEGORY)
3026{
3027 enum { k_SUCCESS = 0, k_FAILURE = - 1 };
3028
3029 bool isAttribute = formattingMode
3031
3032 if (!isAttribute) {
3034 << "Object '" << d_name_p << "' is "
3035 << "being parsed as an attribute, "
3036 << "but it does not have the "
3037 << "'IS_ATTRIBUTE' flag set."
3039 }
3040
3041 if (0 != TypesParserUtil::parse(object,
3042 d_value_p,
3043 static_cast<int>(d_value_length),
3044 formattingMode)) {
3045 BALXML_DECODER_LOG_ERROR(d_decoder)
3046 << "Unable to parse \""
3047 << bsl::string(d_value_p, d_value_length)
3048 << "\" (for '" << d_name_p << "' attribute)"
3049
3050 << "\".\n"
3052
3053 d_failed = true;
3054
3055 return k_FAILURE; // RETURN
3056 }
3057
3058 return k_SUCCESS;
3059}
3060
3061// CREATORS
3062inline
3063Decoder_ParseAttribute::Decoder_ParseAttribute(Decoder *decoder,
3064 const char *name,
3065 const char *value,
3066 bsl::size_t lengthValue)
3067: d_decoder(decoder)
3068, d_failed(false)
3069, d_name_p(name)
3070, d_value_p(value)
3071, d_value_length(lengthValue)
3072{
3073 BSLS_REVIEW(d_decoder);
3074 BSLS_REVIEW(d_name_p);
3075 BSLS_REVIEW(d_value_p);
3076}
3077
3078// MANIPULATORS
3079template <class TYPE, class INFO_TYPE>
3080inline
3081int Decoder_ParseAttribute::operator()(TYPE *object, const INFO_TYPE& info)
3082{
3083 return execute(object, info.formattingMode());
3084}
3085
3086template <class TYPE>
3087inline
3088int Decoder_ParseAttribute::execute(TYPE *object, int formattingMode)
3089{
3090 typedef typename
3092
3093 return executeImp(object, formattingMode, TypeCategory());
3094}
3095
3096// ACCESSORS
3097inline
3099{
3100 return d_failed;
3101}
3102
3103 // -------------------------
3104 // class Decoder_ParseObject
3105 // -------------------------
3106
3107// PRIVATE MANIPULATORS
3108template <class TYPE>
3109inline
3111 int formattingMode,
3113{
3114 typedef bdlat_TypeCategory::Select<TYPE> Selector;
3115
3116 enum {
3117 CAN_BE_REPETITION_ONLY
3118 = ( (int)Selector::e_SELECTION
3120 || (int)Selector::e_SELECTION
3122 };
3123
3124 typedef typename bsl::conditional<CAN_BE_REPETITION_ONLY,
3125 CanBeRepetitionOnly,
3126 CanBeListOrRepetition>::type Toggle;
3127
3128 return executeArrayImp(object, formattingMode, Toggle());
3129}
3130
3131template <class TYPE>
3132inline
3134 int formattingMode,
3136{
3137 return executeArrayImp(object, formattingMode, CanBeListOrRepetition());
3138}
3139
3140template <class TYPE>
3142 TYPE *object,
3143 int formattingMode,
3145{
3146 enum { k_FAILURE = -1 };
3147
3148 if (formattingMode & bdlat_FormattingMode::e_UNTAGGED) {
3149 if (d_decoder->options()->skipUnknownElements()
3151 *object,
3152 d_elementName_p,
3153 static_cast<int>(d_lenName))) {
3155 d_decoder->numUnknownElementsSkipped() + 1);
3156 Decoder_UnknownElementContext unknownElement;
3157 return unknownElement.beginParse(d_decoder); // RETURN
3158 }
3159
3161 object,
3162 *this,
3163 d_elementName_p,
3164 static_cast<int>(d_lenName));
3165 // RETURN
3166 }
3167
3168 typedef typename
3170 bdlat_TypeCategory::Sequence, TYPE>::Type Context;
3171
3172 Context context(object, formattingMode);
3173
3174 return context.beginParse(d_decoder);
3175}
3176
3177template <class TYPE>
3179 int formattingMode,
3181{
3182 enum { k_FAILURE = -1 };
3183
3184 bool isUntagged = formattingMode & bdlat_FormattingMode::e_UNTAGGED;
3185
3186 if (isUntagged) {
3187 if (d_decoder->options()->skipUnknownElements()
3189 *object,
3190 d_elementName_p,
3191 static_cast<int>(d_lenName))) {
3193 d_decoder->numUnknownElementsSkipped() + 1);
3194 Decoder_UnknownElementContext unknownElement;
3195 return unknownElement.beginParse(d_decoder); // RETURN
3196 }
3197
3199 object,
3200 d_elementName_p,
3201 static_cast<int>(d_lenName))) {
3202 BALXML_DECODER_LOG_ERROR(d_decoder)
3203 << "Unable to make selection: \""
3204 << d_elementName_p
3205 << "\"."
3207
3208 return k_FAILURE; // RETURN
3209 }
3210
3211 return bdlat_ChoiceFunctions::manipulateSelection(object, *this);
3212 // RETURN
3213 }
3214
3215 typedef typename
3217 bdlat_TypeCategory::Choice, TYPE>::Type Context;
3218
3219 Context context(object, formattingMode);
3220
3221 return context.beginParse(d_decoder);
3222}
3223
3224template <class TYPE>
3226 TYPE *object,
3227 int formattingMode,
3229{
3230 enum { k_SUCCESS = 0, k_FAILURE = -1 };
3231
3234 }
3235
3236 bool isNillable = formattingMode & bdlat_FormattingMode::e_NILLABLE;
3237
3238 if (isNillable) {
3239 Decoder_ParseNillableObject parseAsNillable(d_decoder, formattingMode);
3240
3242 object,
3243 parseAsNillable)) {
3244 return k_FAILURE; // RETURN
3245 }
3246
3247 if (parseAsNillable.isNil()) {
3248 // reset the object to null
3250 }
3251
3252 return k_SUCCESS; // RETURN
3253 }
3254
3255 Decoder_ParseObject_executeProxy proxy = { this, formattingMode };
3256
3258}
3259
3260template <class TYPE>
3262 TYPE *object,
3263 int formattingMode,
3265{
3266 typedef typename
3269 Context;
3270
3271 Context context(object, formattingMode);
3272
3273 return context.beginParse(d_decoder);
3274}
3275
3276template <class TYPE>
3277inline
3279 TYPE *object,
3280 int formattingMode,
3282{
3284 this, formattingMode
3285 };
3286
3288}
3289
3290template <class TYPE, class ANY_CATEGORY>
3291inline
3293 int formattingMode,
3294 ANY_CATEGORY)
3295{
3296 typedef typename
3298
3299 Context context(object, formattingMode);
3300
3301 return context.beginParse(d_decoder);
3302}
3303
3304template <class TYPE>
3306 int formattingMode,
3307 CanBeListOrRepetition)
3308{
3309 if (formattingMode & bdlat_FormattingMode::e_LIST) {
3311 ListContext;
3312
3313 ListContext listContext(object, formattingMode);
3314
3315 return listContext.beginParse(d_decoder); // RETURN
3316 } else {
3317 return executeArrayRepetitionImp(object, formattingMode); // RETURN
3318 }
3319}
3320
3321template <class TYPE>
3322inline
3324 int formattingMode,
3325 CanBeRepetitionOnly)
3326{
3327 return executeArrayRepetitionImp(object, formattingMode);
3328}
3329
3330template <class TYPE>
3332 int formattingMode)
3333{
3336
3337 Decoder_ParseObject_executeProxy proxy = { this, formattingMode };
3338
3339 const int i = static_cast<int>(bdlat_ArrayFunctions::size(*object));
3340
3341 bdlat_ArrayFunctions::resize(object, i + 1);
3342
3343 return bdlat_ArrayFunctions::manipulateElement(object, proxy, i);
3344}
3345
3346// CREATORS
3347inline
3348Decoder_ParseObject::Decoder_ParseObject(Decoder *decoder,
3349 const char *elementName,
3350 bsl::size_t lenName)
3351: d_decoder(decoder)
3352, d_elementName_p(elementName)
3353, d_lenName(lenName)
3354{
3355 BSLS_REVIEW(d_elementName_p);
3356 BSLS_REVIEW(d_decoder);
3357}
3358
3359// MANIPULATORS
3360template <class TYPE, class INFO_TYPE>
3361inline
3362int Decoder_ParseObject::operator()(TYPE *object, const INFO_TYPE &info)
3363{
3364 return execute(object, info.formattingMode());
3365}
3366
3367template <class TYPE>
3368inline
3369int Decoder_ParseObject::execute(TYPE *object, int formattingMode)
3370{
3371 typedef typename
3373
3374 return executeImp(object, formattingMode, TypeCategory());
3375}
3376
3377 // ---------------------------------
3378 // class Decoder_ParseNillableObject
3379 // ---------------------------------
3380
3381// IMPLEMENTATION MANIPULATORS
3382template <class TYPE>
3383inline
3392
3393template <class TYPE, class ANY_CATEGORY>
3394inline
3395int Decoder_ParseNillableObject::executeImp(TYPE *object, ANY_CATEGORY)
3396{
3397 typedef typename
3399
3400 Context elementContext(object, d_formattingMode);
3401
3402 d_nillableContext.setElementContext(&elementContext);
3403
3404 return d_nillableContext.beginParse(d_decoder);
3405}
3406
3407inline
3408Decoder_ParseNillableObject::Decoder_ParseNillableObject(
3409 Decoder *decoder,
3410 int formattingMode)
3411: d_formattingMode(formattingMode)
3412, d_nillableContext()
3413, d_decoder(decoder)
3414{
3415}
3416
3417// MANIPULATORS
3418template <class TYPE>
3419inline
3421{
3422 typedef typename
3424
3425 return executeImp(object, TypeCategory());
3426}
3427
3428// ACCESSORS
3429inline
3431{
3432 return d_nillableContext.isNil();
3433}
3434
3435} // close package namespace
3436
3437
3438#endif
3439
3440// ----------------------------------------------------------------------------
3441// Copyright 2015 Bloomberg Finance L.P.
3442//
3443// Licensed under the Apache License, Version 2.0 (the "License");
3444// you may not use this file except in compliance with the License.
3445// You may obtain a copy of the License at
3446//
3447// http://www.apache.org/licenses/LICENSE-2.0
3448//
3449// Unless required by applicable law or agreed to in writing, software
3450// distributed under the License is distributed on an "AS IS" BASIS,
3451// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
3452// See the License for the specific language governing permissions and
3453// limitations under the License.
3454// ----------------------------- END-OF-FILE ----------------------------------
3455
3456/** @} */
3457/** @} */
3458/** @} */
Definition balxml_base64parser.h:161
Definition balxml_decoderoptions.h:72
bool skipUnknownElements() const
Definition balxml_decoderoptions.h:525
Definition balxml_decoder.h:966
int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2274
int parseSubElement(const char *elementName, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2339
int parseAttribute(const char *name, const char *value, bsl::size_t lenValue, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2328
int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2284
int addCharacters(const char *chars, bsl::size_t length, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2300
Definition balxml_decoder.h:1214
int parseAttribute(const char *name, const char *value, bsl::size_t lenValue, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2772
int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2744
int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2750
int addCharacters(const char *chars, bsl::size_t length, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2764
int parseSubElement(const char *elementName, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2781
Definition balxml_decoder.h:365
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:686
Decoder_ErrorLogger(ErrorInfo::Severity severity, Decoder *decoder)
Construct a logger for the specified decoder.
Definition balxml_decoder.h:702
~Decoder_ErrorLogger()
Definition balxml_decoder.h:711
bsl::ostream & stream()
Definition balxml_decoder.h:718
Definition balxml_decoder.h:790
int beginParse(TYPE *object)
Definition balxml_decoder.h:838
Decoder_ListParser()
Definition balxml_decoder.h:829
int pushCharacters(INPUT_ITERATOR begin, INPUT_ITERATOR end)
Definition balxml_decoder.h:849
int endParse()
Definition balxml_decoder.h:843
Definition balxml_decoder.h:1015
~Decoder_NillableContext() BSLS_KEYWORD_OVERRIDE
void setElementContext(Decoder_ElementContext *elementContext)
bool isNil() const
Return true if the element is nil.
Definition balxml_decoder.h:1595
int executeImp(TYPE *object, int formattingMode, bdlat_TypeCategory::NullableValue)
Definition balxml_decoder.h:2994
int execute(TYPE *object, int formattingMode)
Definition balxml_decoder.h:3088
int operator()(TYPE *object, const INFO_TYPE &info)
Definition balxml_decoder.h:3081
bool failed() const
Definition balxml_decoder.h:3098
Definition balxml_decoder.h:1748
bool isNil() const
Return true if the value was nil, and false otherwise.
Definition balxml_decoder.h:3430
int executeImp(TYPE *object, bdlat_TypeCategory::DynamicType)
Definition balxml_decoder.h:3384
int operator()(TYPE *object)
Visit the specified object.
Definition balxml_decoder.h:3420
Definition balxml_decoder.h:1654
int executeArrayRepetitionImp(TYPE *object, int formattingMode)
Definition balxml_decoder.h:3331
int operator()(TYPE *object, const INFO_TYPE &info)
Definition balxml_decoder.h:3362
int executeImp(bsl::vector< char > *object, int formattingMode, bdlat_TypeCategory::Array)
int execute(TYPE *object, int formattingMode)
Definition balxml_decoder.h:3369
int executeArrayImp(TYPE *object, int formattingMode, CanBeListOrRepetition)
Definition balxml_decoder.h:3305
Definition balxml_decoder.h:1517
int operator()(TYPE *object, const INFO_TYPE &info)
Definition balxml_decoder.h:2906
Definition balxml_decoder.h:1557
int operator()(TYPE *object, const INFO_TYPE &info)
Definition balxml_decoder.h:2971
int execute(TYPE *object, int id, int formattingMode)
Definition balxml_decoder.h:2978
Definition balxml_decoder.h:1486
int operator()(const TYPE &object, const INFO_TYPE &info)
Definition balxml_decoder.h:2875
Definition balxml_decoder.h:1076
int parseSubElement(const char *elementName, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2476
int addCharacters(const char *chars, bsl::size_t length, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2441
int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2426
int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2410
int parseAttribute(const char *name, const char *value, bsl::size_t lenValue, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2465
Definition balxml_decoder.h:1122
int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2538
int parseSubElement(const char *elementName, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2609
int addCharacters(const char *chars, bsl::size_t length, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2546
int parseAttribute(const char *name, const char *value, bsl::size_t lenValue, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2584
int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2518
Definition balxml_decoder.h:1167
int parseAttribute(const char *name, const char *value, bsl::size_t lenValue, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2699
int parseSubElement(const char *elementName, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2710
int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2661
int addCharacters(const char *chars, bsl::size_t length, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2669
int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2651
Definition balxml_decoder.h:1353
Decoder_PushParserContext< bsl::string, Base64Parser< bsl::string > > Base64Context
Definition balxml_decoder.h:1361
bsls::ObjectBuffer< UTF8Context > d_utf8Context
Definition balxml_decoder.h:1371
Decoder_StdStringContext(bsl::string *object, int formattingMode)
bsls::ObjectBuffer< HexContext > d_hexContext
Definition balxml_decoder.h:1370
bsls::ObjectBuffer< Base64Context > d_base64Context
Definition balxml_decoder.h:1369
Decoder_UTF8Context< bsl::string > UTF8Context
Definition balxml_decoder.h:1364
~Decoder_StdStringContext() BSLS_KEYWORD_OVERRIDE
Decoder_PushParserContext< bsl::string, HexParser< bsl::string > > HexContext
Definition balxml_decoder.h:1363
Definition balxml_decoder.h:1415
bsls::ObjectBuffer< UTF8Context > d_utf8Context
Definition balxml_decoder.h:1439
bsls::ObjectBuffer< ListContext > d_listContext
Definition balxml_decoder.h:1438
~Decoder_StdVectorCharContext() BSLS_KEYWORD_OVERRIDE
Decoder_PushParserContext< bsl::vector< char >, Decoder_ListParser< bsl::vector< char > > > ListContext
Definition balxml_decoder.h:1430
bsls::ObjectBuffer< HexContext > d_hexContext
Definition balxml_decoder.h:1437
Decoder_StdVectorCharContext(bsl::vector< char > *object, int formattingMode)
Decoder_UTF8Context< bsl::vector< char > > UTF8Context
Definition balxml_decoder.h:1431
Decoder_PushParserContext< bsl::vector< char >, HexParser< bsl::vector< char > > > HexContext
Definition balxml_decoder.h:1427
bsls::ObjectBuffer< Base64Context > d_base64Context
Definition balxml_decoder.h:1436
Decoder_PushParserContext< bsl::vector< char >, Base64Parser< bsl::vector< char > > > Base64Context
Definition balxml_decoder.h:1424
Definition balxml_decoder.h:1308
int parseSubElement(const char *elementName, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2847
int endElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2814
int startElement(Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2803
int parseAttribute(const char *name, const char *value, bsl::size_t lenValue, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2836
int addCharacters(const char *chars, bsl::size_t length, Decoder *decoder) BSLS_KEYWORD_OVERRIDE
Definition balxml_decoder.h:2823
Definition balxml_decoder.h:1265
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:402
int open(bsl::istream &stream, const char *uri=0)
Definition balxml_decoder.h:2111
friend class Decoder_ErrorLogger
Definition balxml_decoder.h:406
const DecoderOptions * options() const
Definition balxml_decoder.h:2022
void setNumUnknownElementsSkipped(int value)
Definition balxml_decoder.h:2010
ErrorInfo::Severity errorSeverity() const
int warningCount() const
Definition balxml_decoder.h:2064
Reader * reader() const
Definition balxml_decoder.h:2028
bsl::istream & decode(bsl::istream &stream, TYPE *object, const char *uri=0)
Definition balxml_decoder.h:2117
bsl::ostream * errorStream() const
Return pointer to the error stream.
Definition balxml_decoder.h:2040
bsl::ostream * warningStream() const
Return pointer to the warning stream.
Definition balxml_decoder.h:2052
bslstl::StringRef loggedMessages() const
ErrorInfo * errorInfo() const
Definition balxml_decoder.h:2034
int numUnknownElementsSkipped() const
Definition balxml_decoder.h:2046
int errorCount() const
Definition balxml_decoder.h:2058
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:349
int endParse()
Definition balxml_listparser.h:329
int beginParse(TYPE *object)
Definition balxml_listparser.h:314
Definition balxml_reader.h:835
Definition balxml_utf8readerwrapper.h:333
Definition bdlb_nullablevalue.h:257
bool isNull() const BSLS_KEYWORD_NOEXCEPT
Return true if this object is null, and false otherwise.
Definition bdlb_nullablevalue.h:1779
TYPE & makeValue(BSLS_COMPILERFEATURES_FORWARD_REF(BDE_OTHER_TYPE) value)
Definition bdlb_nullablevalue.h:1717
Definition bdlsb_memoutstreambuf.h:212
Definition bslstl_stringview.h:441
Definition bslstl_string.h:1281
Definition bslstl_vector.h:1025
Definition bslma_allocator.h:457
#define BALXML_DECODER_LOG_WARNING(reporter)
Definition balxml_decoder.h:739
int length() const
Definition balxml_decoder.h:2003
const char * data() const
Definition balxml_decoder.h:1997
void reset()
Reset the internal streambuf to empty.
Definition balxml_decoder.h:1990
#define BALXML_DECODER_LOG_END
Definition balxml_decoder.h:747
#define BALXML_DECODER_LOG_ERROR(reporter)
Definition balxml_decoder.h:731
static int manipulateByCategory(TYPE *object, MANIPULATOR &manipulator)
Definition bdlat_typecategory.h:1404
static const char * className(const TYPE &object)
Definition bdlat_typename.h:1017
#define BSLS_ASSERT_SAFE(X)
Definition bsls_assert.h:1762
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:653
#define BSLS_REVIEW(X)
Definition bsls_review.h:949
Definition balxml_base64parser.h:150
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 convertFromBaseType(TYPE *object, const BASE_TYPE &value)
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 bdlb_printmethods.h:283
basic_string< char > string
Definition bslstl_string.h:782
Definition balxml_encoderoptions.h:68
Definition bdlt_iso8601util.h:691
Definition bslstl_algorithm.h:82
Decoder_PushParserContext< TYPE, Decoder_ListParser< TYPE > > Type
Definition balxml_decoder.h:873
Decoder_StdVectorCharContext Type
Definition balxml_decoder.h:881
Decoder_ChoiceContext< TYPE > Type
Definition balxml_decoder.h:888
Decoder_CustomizedContext< TYPE > Type
Definition balxml_decoder.h:921
Decoder_SimpleContext< TYPE > Type
Definition balxml_decoder.h:932
Decoder_SequenceContext< TYPE > Type
Definition balxml_decoder.h:895
Decoder_SimpleContext< TYPE > Type
Definition balxml_decoder.h:902
Decoder_StdStringContext Type
Definition balxml_decoder.h:910
Definition balxml_decoder.h:867
COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
Definition balxml_decoder.h:1853
int operator()(TYPE *object, ANY_CATEGORY category)
Definition balxml_decoder.h:1875
Decoder_ParseAttribute * d_instance_p
Definition balxml_decoder.h:1856
int operator()(TYPE *, bslmf::Nil)
Definition balxml_decoder.h:1867
int d_formattingMode
Definition balxml_decoder.h:1857
COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
Definition balxml_decoder.h:1828
int operator()(TYPE *object)
Definition balxml_decoder.h:1842
Decoder_ParseAttribute * d_instance_p
Definition balxml_decoder.h:1831
int d_formattingMode
Definition balxml_decoder.h:1832
COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
Definition balxml_decoder.h:1944
Decoder_ParseNillableObject * d_instance_p
Definition balxml_decoder.h:1947
int operator()(TYPE *object, ANY_CATEGORY category)
Definition balxml_decoder.h:1965
int operator()(TYPE *, bslmf::Nil)
Definition balxml_decoder.h:1957
COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
Definition balxml_decoder.h:1911
int operator()(TYPE *object, ANY_CATEGORY category)
Definition balxml_decoder.h:1933
int operator()(TYPE *, bslmf::Nil)
Definition balxml_decoder.h:1925
int d_formattingMode
Definition balxml_decoder.h:1915
Decoder_ParseObject * d_instance_p
Definition balxml_decoder.h:1914
COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
Definition balxml_decoder.h:1886
Decoder_ParseObject * d_instance_p
Definition balxml_decoder.h:1889
int operator()(TYPE *object)
Definition balxml_decoder.h:1900
int d_formattingMode
Definition balxml_decoder.h:1890
Definition balxml_decoder.h:944
Decoder_InstantiateContext< TypeCategory, TYPE >::Type Type
Definition balxml_decoder.h:952
COMPONENT-PRIVATE CLASS. DO NOT USE OUTSIDE OF THIS COMPONENT.
Definition balxml_decoder.h:1796
int operator()(TYPE *object, ANY_CATEGORY category)
Definition balxml_decoder.h:1817
Decoder * d_decoder
Definition balxml_decoder.h:1799
int operator()(TYPE *, bslmf::Nil)
Definition balxml_decoder.h:1809
Definition balxml_typesparserutil.h:199
static int parse(TYPE *result, const char *input, int inputLength, int formattingMode)
Definition balxml_typesparserutil.h:943
TYPE::BaseType Type
Definition bdlat_customizedtypefunctions.h:536
@ e_LIST
Definition bdlat_formattingmode.h:122
@ e_TYPE_MASK
Definition bdlat_formattingmode.h:115
@ e_ATTRIBUTE
Definition bdlat_formattingmode.h:119
@ e_DEFAULT
Definition bdlat_formattingmode.h:110
@ e_NILLABLE
Definition bdlat_formattingmode.h:121
@ e_UNTAGGED
Definition bdlat_formattingmode.h:118
@ e_SIMPLE_CONTENT
Definition bdlat_formattingmode.h:120
Definition bdlat_typecategory.h:1035
Definition bdlat_typecategory.h:1036
Definition bdlat_typecategory.h:1037
Definition bdlat_typecategory.h:1034
Definition bdlat_typecategory.h:1039
Definition bdlat_typecategory.h:1083
Definition bdlat_typecategory.h:1040
Definition bdlat_typecategory.h:1041
Definition bdlat_typecategory.h:1031
@ e_CHOICE_CATEGORY
Definition bdlat_typecategory.h:1047
@ e_SEQUENCE_CATEGORY
Definition bdlat_typecategory.h:1051
static void skipLeadingTrailing(const char **begin, const char **end)
Definition bslmf_conditional.h:120
Definition bslmf_issame.h:146
This struct is empty and represents a nil type.
Definition bslmf_nil.h:131
Definition bsls_objectbuffer.h:276