BDE 4.39.x Production Release
Loading...
Searching...
No Matches
balxml_utf8readerwrapper.h
Go to the documentation of this file.
1/// @file balxml_utf8readerwrapper.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// balxml_utf8readerwrapper.h -*-C++-*-
8#ifndef INCLUDED_BALXML_UTF8READERWRAPPER
9#define INCLUDED_BALXML_UTF8READERWRAPPER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup balxml_utf8readerwrapper balxml_utf8readerwrapper
15/// @brief Provide wrapper for `Reader` to check input UTF-8 validity.
16/// @addtogroup bal
17/// @{
18/// @addtogroup balxml
19/// @{
20/// @addtogroup balxml_utf8readerwrapper
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#balxml_utf8readerwrapper-purpose"> Purpose</a>
25/// * <a href="#balxml_utf8readerwrapper-classes"> Classes </a>
26/// * <a href="#balxml_utf8readerwrapper-description"> Description </a>
27/// * <a href="#balxml_utf8readerwrapper-usage"> Usage </a>
28/// * <a href="#balxml_utf8readerwrapper-example-1-routine-parsing"> Example 1: Routine Parsing: </a>
29///
30/// # Purpose {#balxml_utf8readerwrapper-purpose}
31/// Provide wrapper for `Reader` to check input UTF-8 validity.
32///
33/// # Classes {#balxml_utf8readerwrapper-classes}
34///
35/// - balxml::Utf8ReaderWrapper: Wrap a `Reader`, check UTF-8 input.
36///
37/// @see balxml_reader, balxml_errorinfo, bdlde_utf8streambufinputwrapper
38///
39/// # Description {#balxml_utf8readerwrapper-description}
40/// This component supplies a mechanism,
41/// `balxml::Utf8ReaderWrapper`, which holds another object of type
42/// `balxml::Reader` and forwards operations to the held object. The held
43/// object is to operate on a `bsl::streambuf`, which is in fact a
44/// `bdlde::Utf8CheckingInStreamBufWrapper` contained in the object, which holds
45/// another `bsl::streambuf` and forward actions to that held `bsl::streambuf`.
46///
47/// The `bdlde_Utf8StreamBufInputWrapper` detects invalid UTF-8. If the input
48/// contains nothing but valid UTF-8, the `bdlde_Utf8StreamBufInputWrapper`
49/// simply forwards all operations to the `bsl::streambuf` it holds, and the
50/// wrapper has no influence on behavior.
51///
52/// Similarly, if the input contains nothing but valid UTF-8, the reader wrapper
53/// simply forwards all operations to the held `Reader` and has no influence on
54/// behavior.
55///
56/// If invalid UTF-8 occurs in the input, `errorInfo().message()` will reflect
57/// the nature of the UTF-8 error.
58///
59/// ## Usage {#balxml_utf8readerwrapper-usage}
60///
61///
62/// This section illustrates intended use of this component.
63///
64/// ### Example 1: Routine Parsing: {#balxml_utf8readerwrapper-example-1-routine-parsing}
65///
66///
67/// Utility function to skip past white space.
68/// @code
69/// int advancePastWhiteSpace(balxml::Reader& reader)
70/// {
71/// static const char whiteSpace[] = "\n\r\t ";
72/// const char *value = 0;
73/// int type = 0;
74/// int rc = 0;
75///
76/// do {
77/// rc = reader.advanceToNextNode();
78/// value = reader.nodeValue();
79/// type = reader.nodeType();
80/// } while ((0 == rc && type == balxml::Reader::e_NODE_TYPE_WHITESPACE) ||
81/// (type == balxml::Reader::e_NODE_TYPE_TEXT &&
82/// bsl::strlen(value) == bsl::strspn(value, whiteSpace)));
83///
84/// assert( reader.nodeType() != balxml::Reader::e_NODE_TYPE_WHITESPACE);
85///
86/// return rc;
87/// }
88/// @endcode
89/// Then, in `main`, we parse an XML string using the UTF-8 reader wrapper:
90///
91/// The following string describes xml for a very simple user directory. The
92/// top level element contains one xml namespace attribute, with one embedded
93/// entry describing a user. The person's name contains some non-ascii UTF-8.
94/// @code
95/// static const char TEST_XML_STRING[] =
96/// "<?xml version='1.0' encoding='UTF-8'?>\n"
97/// "<directory-entry xmlns:dir='http://bloomberg.com/schemas/directory'>\n"
98/// " <name>John Smith\xe7\x8f\x8f</name>\n"
99/// " <phone dir:phonetype='cell'>212-318-2000</phone>\n"
100/// " <address/>\n"
101/// "</directory-entry>\n";
102/// @endcode
103/// In order to read the XML, we first need to construct a
104/// `balxml::NamespaceRegistry` object, a `balxml::PrefixStack` object, and a
105/// `Utf8ReaderWrapper` object.
106/// @code
107/// balxml::NamespaceRegistry namespaces;
108/// balxml::PrefixStack prefixStack(&namespaces);
109/// balxml::MiniReader miniReader;
110/// balxml::Utf8ReaderWrapper reader(&miniReader);
111///
112/// assert(!reader.isOpen());
113/// @endcode
114/// The reader uses a `balxml::PrefixStack` to manage namespace prefixes so we
115/// need to set it before we call open.
116/// @code
117/// reader.setPrefixStack(&prefixStack);
118/// assert(reader.prefixStack());
119/// assert(reader.prefixStack() == &prefixStack);
120/// @endcode
121/// Now we call the `open` method to setup the reader for parsing using the data
122/// contained in the in the XML string.
123/// @code
124/// reader.open(TEST_XML_STRING, sizeof(TEST_XML_STRING) -1, 0, "UTF-8");
125/// @endcode
126/// Confirm that the `bdem::Reader` has opened properly
127/// @code
128/// assert( reader.isOpen());
129/// assert(!bsl::strncmp(reader.documentEncoding(), "UTF-8", 5));
130/// assert( reader.nodeType() == balxml::Reader::e_NODE_TYPE_NONE);
131/// assert(!reader.nodeName());
132/// assert(!reader.nodeHasValue());
133/// assert(!reader.nodeValue());
134/// assert(!reader.nodeDepth());
135/// assert(!reader.numAttributes());
136/// assert(!reader.isEmptyElement());
137/// @endcode
138/// Advance through all the nodes and assert all information contained at each
139/// node is correct.
140///
141/// Assert the next node's document type is xml.
142/// @code
143/// int rc = advancePastWhiteSpace(reader);
144/// assert( 0 == rc);
145/// assert( reader.nodeType() ==
146/// balxml::Reader::e_NODE_TYPE_XML_DECLARATION);
147/// assert(!bsl::strcmp(reader.nodeName(), "xml"));
148/// assert( reader.nodeHasValue());
149/// assert(!bsl::strcmp(reader.nodeValue(), "version='1.0' encoding='UTF-8'"));
150/// assert( reader.nodeDepth() == 1);
151/// assert(!reader.numAttributes());
152/// assert(!reader.isEmptyElement());
153/// assert( 0 == rc);
154/// assert( reader.nodeDepth() == 1);
155/// @endcode
156/// Advance to the top level element, which has one attribute, the xml
157/// namespace. Assert the namespace information has been added correctly to the
158/// prefix stack.
159/// @code
160/// rc = advancePastWhiteSpace(reader);
161/// assert( 0 == rc);
162/// assert( reader.nodeType() == balxml::Reader::e_NODE_TYPE_ELEMENT);
163/// assert(!bsl::strcmp(reader.nodeName(), "directory-entry"));
164/// assert(!reader.nodeHasValue());
165/// assert( reader.nodeDepth() == 1);
166/// assert( reader.numAttributes() == 1);
167/// assert(!reader.isEmptyElement());
168///
169/// assert(!bsl::strcmp(prefixStack.lookupNamespacePrefix("dir"), "dir"));
170/// assert(prefixStack.lookupNamespaceId("dir") == 0);
171/// assert(!bsl::strcmp(prefixStack.lookupNamespaceUri("dir"),
172/// "http://bloomberg.com/schemas/directory"));
173/// @endcode
174/// The XML being read contains one entry describing a user, advance the users
175/// name name and assert all information can be read correctly.
176/// @code
177/// rc = advancePastWhiteSpace(reader);
178/// assert( 0 == rc);
179/// assert( reader.nodeType() == balxml::Reader::e_NODE_TYPE_ELEMENT);
180/// assert(!bsl::strcmp(reader.nodeName(), "name"));
181/// assert(!reader.nodeHasValue());
182/// assert( reader.nodeDepth() == 2);
183/// assert( reader.numAttributes() == 0);
184/// assert(!reader.isEmptyElement());
185///
186/// rc = reader.advanceToNextNode();
187/// assert( 0 == rc);
188/// assert( reader.nodeType() == balxml::Reader::e_NODE_TYPE_TEXT);
189/// assert( reader.nodeHasValue());
190/// assert(!bsl::strcmp(reader.nodeValue(), "John Smith\xe7\x8f\x8f"));
191/// assert( reader.nodeDepth() == 3);
192/// assert( reader.numAttributes() == 0);
193/// assert(!reader.isEmptyElement());
194///
195/// rc = reader.advanceToNextNode();
196/// assert( 0 == rc);
197/// assert( reader.nodeType() == balxml::Reader::e_NODE_TYPE_END_ELEMENT);
198/// assert(!bsl::strcmp(reader.nodeName(), "name"));
199/// assert(!reader.nodeHasValue());
200/// assert( reader.nodeDepth() == 2);
201/// assert( reader.numAttributes() == 0);
202/// assert(!reader.isEmptyElement());
203/// @endcode
204/// Advance to the user's phone number and assert all information can be read
205/// correctly.
206/// @code
207/// rc = advancePastWhiteSpace(reader);
208/// assert( 0 == rc);
209/// assert( reader.nodeType() == balxml::Reader::e_NODE_TYPE_ELEMENT);
210/// assert(!bsl::strcmp(reader.nodeName(), "phone"));
211/// assert(!reader.nodeHasValue());
212/// assert( reader.nodeDepth() == 2);
213/// assert( reader.numAttributes() == 1);
214/// assert(!reader.isEmptyElement());
215/// @endcode
216/// The phone node has one attribute, look it up and assert the
217/// `balxml::ElementAttribute` contains valid information and that the prefix
218/// returns the correct namespace URI from the prefix stack.
219/// @code
220/// balxml::ElementAttribute elemAttr;
221///
222/// rc = reader.lookupAttribute(&elemAttr, 0);
223/// assert( 0 == rc);
224/// assert(!elemAttr.isNull());
225/// assert(!bsl::strcmp(elemAttr.qualifiedName(), "dir:phonetype"));
226/// assert(!bsl::strcmp(elemAttr.value(), "cell"));
227/// assert(!bsl::strcmp(elemAttr.prefix(), "dir"));
228/// assert(!bsl::strcmp(elemAttr.localName(), "phonetype"));
229/// assert(!bsl::strcmp(elemAttr.namespaceUri(),
230/// "http://bloomberg.com/schemas/directory"));
231/// assert( elemAttr.namespaceId() == 0);
232///
233/// assert(!bsl::strcmp(prefixStack.lookupNamespaceUri(elemAttr.prefix()),
234/// elemAttr.namespaceUri()));
235///
236/// rc = advancePastWhiteSpace(reader);
237/// assert( 0 == rc);
238/// assert( reader.nodeType() == balxml::Reader::e_NODE_TYPE_TEXT);
239/// assert( reader.nodeHasValue());
240/// assert(!bsl::strcmp(reader.nodeValue(), "212-318-2000"));
241/// assert( reader.nodeDepth() == 3);
242/// assert( reader.numAttributes() == 0);
243/// assert(!reader.isEmptyElement());
244///
245/// rc = advancePastWhiteSpace(reader);
246/// assert( 0 == rc);
247/// assert( reader.nodeType() == balxml::Reader::e_NODE_TYPE_END_ELEMENT);
248/// assert(!bsl::strcmp(reader.nodeName(), "phone"));
249/// assert(!reader.nodeHasValue());
250/// assert( reader.nodeDepth() == 2);
251/// assert( reader.numAttributes() == 0);
252/// assert(!reader.isEmptyElement());
253/// @endcode
254/// Advance to the user's address and assert all information can be read
255/// correctly.
256/// @code
257/// rc = advancePastWhiteSpace(reader);
258/// assert( 0 == rc);
259/// assert( reader.nodeType() == balxml::Reader::e_NODE_TYPE_ELEMENT);
260/// assert(!bsl::strcmp(reader.nodeName(), "address"));
261/// assert(!reader.nodeHasValue());
262/// assert( reader.nodeDepth() == 2);
263/// assert( reader.numAttributes() == 0);
264/// assert( reader.isEmptyElement());
265/// @endcode
266/// Advance to the end element.
267/// @code
268/// rc = advancePastWhiteSpace(reader);
269/// assert( 0 == rc);
270/// assert( reader.nodeType() == balxml::Reader::e_NODE_TYPE_END_ELEMENT);
271/// assert(!bsl::strcmp(reader.nodeName(), "directory-entry"));
272/// assert(!reader.nodeHasValue());
273/// assert( reader.nodeDepth() == 1);
274/// assert( reader.numAttributes() == 0);
275/// assert(!reader.isEmptyElement());
276/// @endcode
277/// Close the reader.
278/// @code
279/// reader.close();
280/// assert(!reader.isOpen());
281///
282/// return 0;
283/// @endcode
284/// @}
285/** @} */
286/** @} */
287
288/** @addtogroup bal
289 * @{
290 */
291/** @addtogroup balxml
292 * @{
293 */
294/** @addtogroup balxml_utf8readerwrapper
295 * @{
296 */
297
298#include <balscm_version.h>
299
300#include <balxml_errorinfo.h>
301#include <balxml_reader.h>
302
305
307#include <bsls_keyword.h>
308
309#include <bsl_cstddef.h> // for size_t
310#include <bsl_functional.h>
311#include <bsl_fstream.h>
312#include <bsl_streambuf.h>
313
314
315namespace balxml {
316
317class ElementAttribute;
318class ErrorInfo;
319class PrefixStack;
320
321 // =======================
322 // class Utf8ReaderWrapper
323 // =======================
324
325/// This class "has a" pointer to a held and wrapped `Reader` object, and
326/// operations on this object are passed to the held reader. The held
327/// reader is passed a `Utf8CheckingInStreamBufWrapper`, which holds and
328/// wraps a normal `streambuf`. The `Utf8CheckingInStreamBufWrapper` checks
329/// input for invalid UTF-8, and if it detects any, makes the diagnosis of
330/// the problem available through the `errorInfo` accessor.
331///
332/// See @ref balxml_utf8readerwrapper
333class Utf8ReaderWrapper : public Reader {
334
335 // DATA
337 bdlsb::FixedMemInStreamBuf d_fixedStreamBuf;
338 bsl::ifstream d_stream;
339 Reader * d_reader_p;
340 ErrorInfo d_errorInfo;
341 bool d_useHeldErrorInfo;
342
343 private:
344 // NOT IMPLEMENTED
346 Utf8ReaderWrapper& operator=(const Utf8ReaderWrapper&);
347
348 public:
349 // TRAITS
352
353 private:
354 // PRIVATE MANIPULATORS
355
356 /// Open the held reader with `d_utf8StreamBuf`, as well as the specified `url` and `encoding`.
357 ///
358 /// \note Note that all public `open`
359 /// functions of this class prepare `d_utf8StreamBuf` and then delegate
360 /// to this function as part of their implementation.
361 int doOpen(const char *url, const char *encoding);
362
363 /// Return a pointer providing modifiable access to the held `Reader`.
364 Reader *heldReader();
365
366 /// Called when a UTF-8 error is encountered, to make `d_errorInfo` into
367 /// a combination of `heldReader()->errorInfo()` and the nature of the
368 /// UTF-8 error as reported by the specified `utf8Rc`.
369 ///
370 /// \pre The behavior is undefined unless `utf8Rc < 0` and `utf8Rc` is one of the values
371 /// enumerated by `Utf8Util::ErrorStatus`.
372 void reportUtf8Error(int utf8Rc);
373
374 // PRIVATE ACCESSORS
375
376 /// Return a pointer providing non-modifiable access to the held
377 /// `Reader`.
378 const Reader *heldReader() const;
379
380 public:
381 // CREATORS
382
383 /// Create a `Utf8ReaderWrapper` that holds the specified `reader`.
384 /// Optionally specify a `basicAllocator` used to supply memory. If
385 /// `basicAllocator` is 0, the currently installed default allocator is used.
386 ///
387 /// \pre The behavior is undefined unless `reader` has never been
388 /// opened or closed.
389 explicit
391 bslma::Allocator *basicAllocator = 0);
392
393 /// Close the held reader and destroy this object.
395
396 // MANIPULATORS
397
398 // ** setup methods **
399
400 /// Set the options of the held reader to the flags in the specified
401 /// `flags`. The options for the reader are persistent, i.e., the options are not reset by `close`.
402 ///
403 /// \pre The behavior is undefined if this
404 /// method is called after calling `open` and before calling `close`;
405 /// except that derived classes are permitted to specify valid behavior
406 /// for calling this function for specific arguments while the reader is
407 /// open.
408 void setOptions(unsigned int flags) BSLS_KEYWORD_OVERRIDE;
409
410 /// Set the prefix stack to the stack at the optionally specified
411 /// `prefixes` address or disable prefix stack support if `prefixes` is
412 /// null. This stack is used to push and pop namespace prefixes as the
413 /// parse progresses, so that, at any point, the stack will reflect the
414 /// set of active prefixes for the current node. It is legitimate to
415 /// pass a stack that already contains prefixes, these prefixes shall be
416 /// preserved when `close` is called, i.e., the prefix stack shall be
417 /// returned to the stack depth it had when `setPrefixStack` was called.
418 ///
419 /// \pre The behavior is undefined if this method is called after calling
420 /// `open` and before calling `close`.
422
423 /// Set the external XML resource resolver to the specified `resolver`.
424 /// The XML resource resolver is used by the @ref balxml_reader to find and
425 /// open an external resources (See the `XmlResolverFunctor` typedef for
426 /// more details). The XML resource resolver remains valid; it is not
427 /// affected by a call to `close` and should be available until the reader is destroyed.
428 ///
429 /// \pre The behavior is undefined if this method is
430 /// called after calling `open` and before calling `close`.
432
433 // ** open/close methods **
434
435 /// Set up the reader for parsing using the data contained in the XML
436 /// file described by the specified `filename`, and set the encoding
437 /// value to the optionally specified `encoding` ("ASCII", "UTF-8",
438 /// etc). Returns 0 on success and non-zero otherwise. The encoding
439 /// passed to `Reader::open` will take effect only when there is no
440 /// encoding information in the original document, i.e., the encoding
441 /// information obtained from the XML file described by the `filename`
442 /// trumps all. If there is no encoding provided within the document
443 /// and `encoding` is null or a blank string is passed, then set the
444 /// encoding to the default "UTF-8". It is an error to `open` a reader that is already open.
445 ///
446 /// \note Note that the reader will not be on a valid
447 /// node until `advanceToNextNode` is called.
448 int open(const char *filename, const char *encoding = 0)
450
451 /// Set up the reader for parsing using the data contained in the
452 /// specified (XML) `buffer` of the specified `size`, set the base URL
453 /// to the optionally specified `url` and set the encoding value to the
454 /// optionally specified `encoding` ("ASCII", "UTF-8", etc). Return 0
455 /// on success and non-zero otherwise. If `url` is null or a blank
456 /// string is passed, then base URL will be empty. The encoding passed
457 /// to `Reader::open` will take effect only when there is no encoding
458 /// information in the original document, i.e., the encoding information
459 /// obtained from the (XML) `buffer` trumps all. If there is no
460 /// encoding provided within the document and `encoding` is null or a
461 /// blank string is passed, then set the encoding to the default
462 /// "UTF-8". It is an error to `open` a reader that is already open.
463 ///
464 /// \note Note that the reader will not be on a valid node until
465 /// `advanceToNextNode` is called.
466 int open(const char *buffer,
467 bsl::size_t size,
468 const char *url = 0,
469 const char *encoding = 0) BSLS_KEYWORD_OVERRIDE;
470
471 /// Set up the reader for parsing using the data contained in the
472 /// specified (XML) `stream`, set the base URL to the optionally
473 /// specified `url` and set the encoding value to the optionally
474 /// specified `encoding` ("ASCII", "UTF-8", etc). Return 0 on success
475 /// and non-zero otherwise. If `url` is null or a blank string is
476 /// passed, then base URL will be empty. The encoding passed to
477 /// `Reader::open` will take effect only when there is no encoding
478 /// information in the original document, i.e., the encoding information
479 /// obtained from the (XML) `stream` trumps all. If there is no
480 /// encoding provided within the document and `encoding` is null or a
481 /// blank string is passed, then set the encoding to the default
482 /// "UTF-8". It is an error to `open` a reader that is already open.
483 ///
484 /// \note Note that the reader will not be on a valid node until
485 /// `advanceToNextNode` is called.
486 int open(bsl::streambuf *stream,
487 const char *url = 0,
488 const char *encoding = 0) BSLS_KEYWORD_OVERRIDE;
489
490 /// Close the reader. Most, but not all state is reset. Specifically,
491 /// the XML resource resolver and the prefix stack remain. The prefix
492 /// stack shall be returned to the stack depth it had when
493 /// `setPrefixStack` was called. Call the method `open` to reuse the reader.
494 ///
495 /// \note Note that `close` invalidates all strings and data
496 /// structures obtained via `Reader` accessors. E.g., the pointer
497 /// returned from `nodeName` for this node will not be valid once
498 /// `close` is called.
500
501 // ** navigation method **
502
503 /// Move to the next node in the data steam created by `open` thus
504 /// allowing the node's properties to be queried via the `Reader`
505 /// accessors. Return 0 on successful read, 1 if there are no more nodes to read, and a negative number otherwise.
506 ///
507 /// \note Note that each call
508 /// to `advanceToNextNode` invalidates strings and data structures
509 /// returned when `Reader` accessors where call for the "prior node".
510 /// E.g., the pointer returned from `nodeName` for this node will not be valid once `advanceToNextNode` is called.
511 ///
512 /// \note Note that the reader will
513 /// not be on a valid node until the first call to `advanceToNextNode`
514 /// after the reader is opened.
516
517 // ACCESSORS
518
519 /// Return the allocator used by this object to allocate memory.
520 bslma::Allocator *allocator() const;
521
522 /// Return the document encoding or NULL on error. The returned poiner
523 /// is owned by this object and must not be modified or deallocated by
524 /// the caller. The returned pointer becomes invalid when `close` is
525 /// called or the reader is destroyed.
527
528 /// Return a reference to the non-modifiable error information for this
529 /// reader. The returned value becomes invalid when `close` is called
530 /// or the reader is destroyed.
532
533 /// Return the current column number within the input stream. The
534 /// current column number is the number of characters since the last
535 /// newline was read by the reader plus one, i.e., the first column of
536 /// each line is column number one. Return 0 if not available.
537 ///
538 /// \note Note that a derived-class implementation is not required to count
539 /// columns and may just return 0.
541
542 /// Return the current line number within the input stream. The current
543 /// line is the last line for which the reader has not yet seen a
544 /// newline. Lines are counted starting at one from the time a stream is provided to `open`. Return 0 if not available.
545 ///
546 /// \note Note that a
547 /// derived-class implementation is not required to count lines and may
548 /// just return 0.
550
551 /// Return true if the current node is an element (i.e., node type is
552 /// `BAEXML_NODE_TYPE_ELEMENT`) that ends with `/>`; and false otherwise.
553 ///
554 /// \note Note that `<a/>` will be considered empty but `<a></a>`
555 /// will not.
557
558 /// Return true if `open` was called successfully and `close` has not
559 /// yet been called and false otherwise.
561
562 /// Find the attribute at the specified `index` in the current node, and
563 /// fill in the specified `attribute` structure. Return 0 on success, 1
564 /// if no attribute is found at the `index`, and an a negative value
565 /// otherwise. The strings that were filled into the `attribute`
566 /// structure are invalid upon the next `advanceToNextNode` or `close`
567 /// is called.
569 int index) const BSLS_KEYWORD_OVERRIDE;
570
571 /// Find the attribute with the specified `qname` (qualified name) in
572 /// the current node, and fill in the specified `attribute` structure.
573 /// Return 0 on success, 1 if there is no attribute found with `qname`,
574 /// and a negative value otherwise. The strings that were filled into
575 /// the `attribute` structure are invalid upon the next
576 /// `advanceToNextNode` or `close` is called.
578 const char *qname) const BSLS_KEYWORD_OVERRIDE;
579
580 /// Find the attribute with the specified `localName` and specified
581 /// `namespaceUri` in the current node, and fill in the specified
582 /// `attribute` structure. Return 0 on success, 1 if there is no
583 /// attribute found with `localName` and `namespaceUri`, and a negative
584 /// value otherwise. If `namespaceUri` == 0 or a blank string is
585 /// passed, then the document's default namespace will be used. The
586 /// strings that were filled into the `attribute` structure are invalid
587 /// upon the next `advanceToNextNode` or `close` is called.
588 int
590 ElementAttribute *attribute,
591 const char *localName,
592 const char *namespaceUri) const BSLS_KEYWORD_OVERRIDE;
593
594 /// Find the attribute with the specified `localName` and specified
595 /// `namespaceId` in the current node, and fill in the specified
596 /// `attribute` structure. Return 0 on success, 1 if there is no
597 /// attribute found with `localName` and `namespaceId`, and a negative
598 /// value otherwise. If `namespaceId` == -1, then the document's
599 /// default namespace will be used. The strings that were filled into
600 /// the `attribute` structure are invalid upon the next
601 /// `advanceToNextNode` or `close` is called.
603 ElementAttribute *attribute,
604 const char *localName,
605 int namespaceId) const BSLS_KEYWORD_OVERRIDE;
606
607 /// Return the base URI name of the current node if the current node has
608 /// a base URI and NULL otherwise. The returned pointer is owned by
609 /// this object and must not be modified or deallocated by the caller.
610 /// The returned pointer becomes invalid upon the next
611 /// `advanceToNextNode`, when `close` is called or the reader is
612 /// destroyed.
614
615 /// Return the nesting depth of the current node in the XML document.
616 /// The root node has depth 0.
618
619 /// Return the local name of the current node if the current node has a
620 /// local name and NULL otherwise. The returned pointer is owned by
621 /// this object and must not be modified or deallocated by the caller.
622 /// The returned pointer becomes invalid upon the next
623 /// `advanceToNextNode`, when `close` is called or the reader is
624 /// destroyed.
626
627 /// Return true if the current node has a value and false otherwise.
629
630 /// Return the qualified name of the current node if the current node
631 /// has a name and NULL otherwise. The returned pointer is owned by
632 /// this object and must not be modified or deallocated by the caller.
633 /// The returned pointer becomes invalid upon the next
634 /// `advanceToNextNode`, when `close` is called or the reader is
635 /// destroyed.
636 const char *nodeName() const BSLS_KEYWORD_OVERRIDE;
637
638 /// Return the namespace ID of the current node if the current node has
639 /// a namespace id and a negative number otherwise.
641
642 /// Return the namespace URI name of the current node if the current
643 /// node has a namespace URI and NULL otherwise. The returned pointer
644 /// is owned by this object and must not be modified or deallocated by
645 /// the caller. The returned pointer becomes invalid upon the next
646 /// `advanceToNextNode`, when `close` is called or the reader is
647 /// destroyed.
649
650 /// Return the prefix name of the current node if the correct node has a
651 /// prefix name and NULL otherwise. The returned pointer is owned by
652 /// this object and must not be modified or deallocated by the caller.
653 /// The returned pointer becomes invalid upon the next
654 /// `advanceToNextNode`, when `close` is called or the reader is
655 /// destroyed.
657
658 /// Return the node type of the current node if the reader `isOpen` and
659 /// has not encounter an error and `Reader::NONE` otherwise.
661
662 /// Return the value of the current node if the current node has a value
663 /// and NULL otherwise. The returned pointer is owned by this object
664 /// and must not be modified or deallocated by the caller. The returned
665 /// pointer becomes invalid upon the next `advanceToNextNode`, when
666 /// `close` is called or the reader is destroyed.
667 const char *nodeValue() const BSLS_KEYWORD_OVERRIDE;
668
669 /// Return the number of attributes for the current node if that node
670 /// has attributes and 0 otherwise.
672
673 /// Return the option flags.
674 unsigned int options() const BSLS_KEYWORD_OVERRIDE;
675
676 /// Return a pointer to the modifiable prefix stack that is used by this
677 /// reader to manage namespace prefixes or 0 if namespace support is disabled.
678 ///
679 /// \pre The behavior is undefined if the returned prefix stack is
680 /// augmented in any way after calling `open` and before calling
681 /// `close`.
683
684 /// Return the external XML resource resolver.
686};
687
688// ============================================================================
689// INLINE DEFINITIONS
690// ============================================================================
691
692 // ------------
693 // class Reader
694 // ------------
695
696// PRIVATE MANIPULATORS
697inline
698Reader *Utf8ReaderWrapper::heldReader()
699{
700 return d_reader_p;
701}
702
703// PRIVATE ACCESSORS
704inline
705const Reader *Utf8ReaderWrapper::heldReader() const
706{
707 return d_reader_p;
708}
709
710} // close package namespace
711
712
713#endif // INCLUDED_BALXML_UTF8READERWRAPPER
714
715// ----------------------------------------------------------------------------
716// Copyright 2020 Bloomberg Finance L.P.
717//
718// Licensed under the Apache License, Version 2.0 (the "License");
719// you may not use this file except in compliance with the License.
720// You may obtain a copy of the License at
721//
722// http://www.apache.org/licenses/LICENSE-2.0
723//
724// Unless required by applicable law or agreed to in writing, software
725// distributed under the License is distributed on an "AS IS" BASIS,
726// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
727// See the License for the specific language governing permissions and
728// limitations under the License.
729// ----------------------------- END-OF-FILE ----------------------------------
730
731/** @} */
732/** @} */
733/** @} */
Definition balxml_elementattribute.h:290
Definition balxml_errorinfo.h:353
Definition balxml_prefixstack.h:137
Definition balxml_reader.h:835
NodeType
Definition balxml_reader.h:839
Definition balxml_utf8readerwrapper.h:333
const char * nodeValue() const BSLS_KEYWORD_OVERRIDE
bool isOpen() const BSLS_KEYWORD_OVERRIDE
Utf8ReaderWrapper(Reader *reader, bslma::Allocator *basicAllocator=0)
int nodeNamespaceId() const BSLS_KEYWORD_OVERRIDE
BSLMF_NESTED_TRAIT_DECLARATION(Utf8ReaderWrapper, bslma::UsesBslmaAllocator)
void setOptions(unsigned int flags) BSLS_KEYWORD_OVERRIDE
XmlResolverFunctor resolver() const BSLS_KEYWORD_OVERRIDE
Return the external XML resource resolver.
bool nodeHasValue() const BSLS_KEYWORD_OVERRIDE
Return true if the current node has a value and false otherwise.
const char * nodeBaseUri() const BSLS_KEYWORD_OVERRIDE
int open(const char *filename, const char *encoding=0) BSLS_KEYWORD_OVERRIDE
const char * nodeName() const BSLS_KEYWORD_OVERRIDE
int getLineNumber() const BSLS_KEYWORD_OVERRIDE
void setPrefixStack(PrefixStack *prefixes) BSLS_KEYWORD_OVERRIDE
~Utf8ReaderWrapper() BSLS_KEYWORD_OVERRIDE
Close the held reader and destroy this object.
const char * documentEncoding() const BSLS_KEYWORD_OVERRIDE
const ErrorInfo & errorInfo() const BSLS_KEYWORD_OVERRIDE
int advanceToNextNode() BSLS_KEYWORD_OVERRIDE
const char * nodeNamespaceUri() const BSLS_KEYWORD_OVERRIDE
bslma::Allocator * allocator() const
Return the allocator used by this object to allocate memory.
const char * nodeLocalName() const BSLS_KEYWORD_OVERRIDE
unsigned int options() const BSLS_KEYWORD_OVERRIDE
Return the option flags.
int lookupAttribute(ElementAttribute *attribute, int index) const BSLS_KEYWORD_OVERRIDE
int nodeDepth() const BSLS_KEYWORD_OVERRIDE
void setResolver(XmlResolverFunctor resolver) BSLS_KEYWORD_OVERRIDE
int getColumnNumber() const BSLS_KEYWORD_OVERRIDE
NodeType nodeType() const BSLS_KEYWORD_OVERRIDE
int numAttributes() const BSLS_KEYWORD_OVERRIDE
PrefixStack * prefixStack() const BSLS_KEYWORD_OVERRIDE
const char * nodePrefix() const BSLS_KEYWORD_OVERRIDE
void close() BSLS_KEYWORD_OVERRIDE
bool isEmptyElement() const BSLS_KEYWORD_OVERRIDE
Definition bdlde_utf8checkinginstreambufwrapper.h:244
Definition bdlsb_fixedmeminstreambuf.h:187
Forward declaration.
Definition bslstl_function.h:946
Definition bslma_allocator.h:545
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:695
Definition balxml_base64parser.h:150
Definition bdlat_valuetypefunctions.h:939
Definition baljsn_encoder_testtypes.h:76
Definition bslma_usesbslmaallocator.h:344