BDE 4.14.0 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
357 /// specified `url` and `encoding`. Note that all public `open`
358 /// functions of this class prepare `d_utf8StreamBuf` and then delegate
359 /// to this function as part of their implementation.
360 int doOpen(const char *url, const char *encoding);
361
362 /// Return a pointer providing modifiable access to the held `Reader`.
363 Reader *heldReader();
364
365 /// Called when a UTF-8 error is encountered, to make `d_errorInfo` into
366 /// a combination of `heldReader()->errorInfo()` and the nature of the
367 /// UTF-8 error as reported by the specified `utf8Rc`. The behavior is
368 /// undefined unless `utf8Rc < 0` and `utf8Rc` is one of the values
369 /// enumerated by `Utf8Util::ErrorStatus`.
370 void reportUtf8Error(int utf8Rc);
371
372 // PRIVATE ACCESSORS
373
374 /// Return a pointer providing non-modifiable access to the held
375 /// `Reader`.
376 const Reader *heldReader() const;
377
378 public:
379 // CREATORS
380
381 /// Create a `Utf8ReaderWrapper` that holds the specified `reader`.
382 /// Optionally specify a `basicAllocator` used to supply memory. If
383 /// `basicAllocator` is 0, the currently installed default allocator is
384 /// used. The behavior is undefined unless `reader` has never been
385 /// opened or closed.
386 explicit
388 bslma::Allocator *basicAllocator = 0);
389
390 /// Close the held reader and destroy this object.
392
393 // MANIPULATORS
394
395 // ** setup methods **
396
397 /// Set the options of the held reader to the flags in the specified
398 /// `flags`. The options for the reader are persistent, i.e., the
399 /// options are not reset by `close`. The behavior is undefined if this
400 /// method is called after calling `open` and before calling `close`;
401 /// except that derived classes are permitted to specify valid behavior
402 /// for calling this function for specific arguments while the reader is
403 /// open.
404 void setOptions(unsigned int flags) BSLS_KEYWORD_OVERRIDE;
405
406 /// Set the prefix stack to the stack at the optionally specified
407 /// `prefixes` address or disable prefix stack support if `prefixes` is
408 /// null. This stack is used to push and pop namespace prefixes as the
409 /// parse progresses, so that, at any point, the stack will reflect the
410 /// set of active prefixes for the current node. It is legitimate to
411 /// pass a stack that already contains prefixes, these prefixes shall be
412 /// preserved when `close` is called, i.e., the prefix stack shall be
413 /// returned to the stack depth it had when `setPrefixStack` was called.
414 /// The behavior is undefined if this method is called after calling
415 /// `open` and before calling `close`.
417
418 /// Set the external XML resource resolver to the specified `resolver`.
419 /// The XML resource resolver is used by the @ref balxml_reader to find and
420 /// open an external resources (See the `XmlResolverFunctor` typedef for
421 /// more details). The XML resource resolver remains valid; it is not
422 /// affected by a call to `close` and should be available until the
423 /// reader is destroyed. The behavior is undefined if this method is
424 /// called after calling `open` and before calling `close`.
426
427 // ** open/close methods **
428
429 /// Set up the reader for parsing using the data contained in the XML
430 /// file described by the specified `filename`, and set the encoding
431 /// value to the optionally specified `encoding` ("ASCII", "UTF-8",
432 /// etc). Returns 0 on success and non-zero otherwise. The encoding
433 /// passed to `Reader::open` will take effect only when there is no
434 /// encoding information in the original document, i.e., the encoding
435 /// information obtained from the XML file described by the `filename`
436 /// trumps all. If there is no encoding provided within the document
437 /// and `encoding` is null or a blank string is passed, then set the
438 /// encoding to the default "UTF-8". It is an error to `open` a reader
439 /// that is already open. Note that the reader will not be on a valid
440 /// node until `advanceToNextNode` is called.
441 int open(const char *filename, const char *encoding = 0)
443
444 /// Set up the reader for parsing using the data contained in the
445 /// specified (XML) `buffer` of the specified `size`, set the base URL
446 /// to the optionally specified `url` and set the encoding value to the
447 /// optionally specified `encoding` ("ASCII", "UTF-8", etc). Return 0
448 /// on success and non-zero otherwise. If `url` is null or a blank
449 /// string is passed, then base URL will be empty. The encoding passed
450 /// to `Reader::open` will take effect only when there is no encoding
451 /// information in the original document, i.e., the encoding information
452 /// obtained from the (XML) `buffer` trumps all. If there is no
453 /// encoding provided within the document and `encoding` is null or a
454 /// blank string is passed, then set the encoding to the default
455 /// "UTF-8". It is an error to `open` a reader that is already open.
456 /// Note that the reader will not be on a valid node until
457 /// `advanceToNextNode` is called.
458 int open(const char *buffer,
459 bsl::size_t size,
460 const char *url = 0,
461 const char *encoding = 0) BSLS_KEYWORD_OVERRIDE;
462
463 /// Set up the reader for parsing using the data contained in the
464 /// specified (XML) `stream`, set the base URL to the optionally
465 /// specified `url` and set the encoding value to the optionally
466 /// specified `encoding` ("ASCII", "UTF-8", etc). Return 0 on success
467 /// and non-zero otherwise. If `url` is null or a blank string is
468 /// passed, then base URL will be empty. The encoding passed to
469 /// `Reader::open` will take effect only when there is no encoding
470 /// information in the original document, i.e., the encoding information
471 /// obtained from the (XML) `stream` trumps all. If there is no
472 /// encoding provided within the document and `encoding` is null or a
473 /// blank string is passed, then set the encoding to the default
474 /// "UTF-8". It is an error to `open` a reader that is already open.
475 /// Note that the reader will not be on a valid node until
476 /// `advanceToNextNode` is called.
477 int open(bsl::streambuf *stream,
478 const char *url = 0,
479 const char *encoding = 0) BSLS_KEYWORD_OVERRIDE;
480
481 /// Close the reader. Most, but not all state is reset. Specifically,
482 /// the XML resource resolver and the prefix stack remain. The prefix
483 /// stack shall be returned to the stack depth it had when
484 /// `setPrefixStack` was called. Call the method `open` to reuse the
485 /// reader. Note that `close` invalidates all strings and data
486 /// structures obtained via `Reader` accessors. E.g., the pointer
487 /// returned from `nodeName` for this node will not be valid once
488 /// `close` is called.
490
491 // ** navigation method **
492
493 /// Move to the next node in the data steam created by `open` thus
494 /// allowing the node's properties to be queried via the `Reader`
495 /// accessors. Return 0 on successful read, 1 if there are no more
496 /// nodes to read, and a negative number otherwise. Note that each call
497 /// to `advanceToNextNode` invalidates strings and data structures
498 /// returned when `Reader` accessors where call for the "prior node".
499 /// E.g., the pointer returned from `nodeName` for this node will not be
500 /// valid once `advanceToNextNode` is called. Note that the reader will
501 /// not be on a valid node until the first call to `advanceToNextNode`
502 /// after the reader is opened.
504
505 // ACCESSORS
506
507 /// Return the allocator used by this object to allocate memory.
508 bslma::Allocator *allocator() const;
509
510 /// Return the document encoding or NULL on error. The returned poiner
511 /// is owned by this object and must not be modified or deallocated by
512 /// the caller. The returned pointer becomes invalid when `close` is
513 /// called or the reader is destroyed.
515
516 /// Return a reference to the non-modifiable error information for this
517 /// reader. The returned value becomes invalid when `close` is called
518 /// or the reader is destroyed.
520
521 /// Return the current column number within the input stream. The
522 /// current column number is the number of characters since the last
523 /// newline was read by the reader plus one, i.e., the first column of
524 /// each line is column number one. Return 0 if not available. Note
525 /// that a derived-class implementation is not required to count
526 /// columns and may just return 0.
528
529 /// Return the current line number within the input stream. The current
530 /// line is the last line for which the reader has not yet seen a
531 /// newline. Lines are counted starting at one from the time a stream
532 /// is provided to `open`. Return 0 if not available. Note that a
533 /// derived-class implementation is not required to count lines and may
534 /// just return 0.
536
537 /// Return true if the current node is an element (i.e., node type is
538 /// `BAEXML_NODE_TYPE_ELEMENT`) that ends with `/>`; and false
539 /// otherwise. Note that `<a/>` will be considered empty but `<a></a>`
540 /// will not.
542
543 /// Return true if `open` was called successfully and `close` has not
544 /// yet been called and false otherwise.
546
547 /// Find the attribute at the specified `index` in the current node, and
548 /// fill in the specified `attribute` structure. Return 0 on success, 1
549 /// if no attribute is found at the `index`, and an a negative value
550 /// otherwise. The strings that were filled into the `attribute`
551 /// structure are invalid upon the next `advanceToNextNode` or `close`
552 /// is called.
554 int index) const BSLS_KEYWORD_OVERRIDE;
555
556 /// Find the attribute with the specified `qname` (qualified name) in
557 /// the current node, and fill in the specified `attribute` structure.
558 /// Return 0 on success, 1 if there is no attribute found with `qname`,
559 /// and a negative value otherwise. The strings that were filled into
560 /// the `attribute` structure are invalid upon the next
561 /// `advanceToNextNode` or `close` is called.
563 const char *qname) const BSLS_KEYWORD_OVERRIDE;
564
565 /// Find the attribute with the specified `localName` and specified
566 /// `namespaceUri` in the current node, and fill in the specified
567 /// `attribute` structure. Return 0 on success, 1 if there is no
568 /// attribute found with `localName` and `namespaceUri`, and a negative
569 /// value otherwise. If `namespaceUri` == 0 or a blank string is
570 /// passed, then the document's default namespace will be used. The
571 /// strings that were filled into the `attribute` structure are invalid
572 /// upon the next `advanceToNextNode` or `close` is called.
573 int
575 ElementAttribute *attribute,
576 const char *localName,
577 const char *namespaceUri) const BSLS_KEYWORD_OVERRIDE;
578
579 /// Find the attribute with the specified `localName` and specified
580 /// `namespaceId` in the current node, and fill in the specified
581 /// `attribute` structure. Return 0 on success, 1 if there is no
582 /// attribute found with `localName` and `namespaceId`, and a negative
583 /// value otherwise. If `namespaceId` == -1, then the document's
584 /// default namespace will be used. The strings that were filled into
585 /// the `attribute` structure are invalid upon the next
586 /// `advanceToNextNode` or `close` is called.
588 ElementAttribute *attribute,
589 const char *localName,
590 int namespaceId) const BSLS_KEYWORD_OVERRIDE;
591
592 /// Return the base URI name of the current node if the current node has
593 /// a base URI and NULL otherwise. The returned pointer is owned by
594 /// this object and must not be modified or deallocated by the caller.
595 /// The returned pointer becomes invalid upon the next
596 /// `advanceToNextNode`, when `close` is called or the reader is
597 /// destroyed.
599
600 /// Return the nesting depth of the current node in the XML document.
601 /// The root node has depth 0.
603
604 /// Return the local name of the current node if the current node has a
605 /// local name and NULL otherwise. The returned pointer is owned by
606 /// this object and must not be modified or deallocated by the caller.
607 /// The returned pointer becomes invalid upon the next
608 /// `advanceToNextNode`, when `close` is called or the reader is
609 /// destroyed.
611
612 /// Return true if the current node has a value and false otherwise.
614
615 /// Return the qualified name of the current node if the current node
616 /// has a name and NULL otherwise. The returned pointer is owned by
617 /// this object and must not be modified or deallocated by the caller.
618 /// The returned pointer becomes invalid upon the next
619 /// `advanceToNextNode`, when `close` is called or the reader is
620 /// destroyed.
621 const char *nodeName() const BSLS_KEYWORD_OVERRIDE;
622
623 /// Return the namespace ID of the current node if the current node has
624 /// a namespace id and a negative number otherwise.
626
627 /// Return the namespace URI name of the current node if the current
628 /// node has a namespace URI and NULL otherwise. The returned pointer
629 /// is owned by this object and must not be modified or deallocated by
630 /// the caller. The returned pointer becomes invalid upon the next
631 /// `advanceToNextNode`, when `close` is called or the reader is
632 /// destroyed.
634
635 /// Return the prefix name of the current node if the correct node has a
636 /// prefix name and NULL otherwise. The returned pointer is owned by
637 /// this object and must not be modified or deallocated by the caller.
638 /// The returned pointer becomes invalid upon the next
639 /// `advanceToNextNode`, when `close` is called or the reader is
640 /// destroyed.
642
643 /// Return the node type of the current node if the reader `isOpen` and
644 /// has not encounter an error and `Reader::NONE` otherwise.
646
647 /// Return the value of the current node if the current node has a value
648 /// and NULL otherwise. The returned pointer is owned by this object
649 /// and must not be modified or deallocated by the caller. The returned
650 /// pointer becomes invalid upon the next `advanceToNextNode`, when
651 /// `close` is called or the reader is destroyed.
652 const char *nodeValue() const BSLS_KEYWORD_OVERRIDE;
653
654 /// Return the number of attributes for the current node if that node
655 /// has attributes and 0 otherwise.
657
658 /// Return the option flags.
659 unsigned int options() const BSLS_KEYWORD_OVERRIDE;
660
661 /// Return a pointer to the modifiable prefix stack that is used by this
662 /// reader to manage namespace prefixes or 0 if namespace support is
663 /// disabled. The behavior is undefined if the returned prefix stack is
664 /// augmented in any way after calling `open` and before calling
665 /// `close`.
667
668 /// Return the external XML resource resolver.
670};
671
672// ============================================================================
673// INLINE DEFINITIONS
674// ============================================================================
675
676 // ------------
677 // class Reader
678 // ------------
679
680// PRIVATE MANIPULATORS
681inline
682Reader *Utf8ReaderWrapper::heldReader()
683{
684 return d_reader_p;
685}
686
687// PRIVATE ACCESSORS
688inline
689const Reader *Utf8ReaderWrapper::heldReader() const
690{
691 return d_reader_p;
692}
693
694} // close package namespace
695
696
697#endif // INCLUDED_BALXML_UTF8READERWRAPPER
698
699// ----------------------------------------------------------------------------
700// Copyright 2020 Bloomberg Finance L.P.
701//
702// Licensed under the Apache License, Version 2.0 (the "License");
703// you may not use this file except in compliance with the License.
704// You may obtain a copy of the License at
705//
706// http://www.apache.org/licenses/LICENSE-2.0
707//
708// Unless required by applicable law or agreed to in writing, software
709// distributed under the License is distributed on an "AS IS" BASIS,
710// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
711// See the License for the specific language governing permissions and
712// limitations under the License.
713// ----------------------------- END-OF-FILE ----------------------------------
714
715/** @} */
716/** @} */
717/** @} */
Definition balxml_elementattribute.h:289
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:934
Definition bslma_allocator.h:457
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:653
Definition balxml_base64parser.h:150
Definition bdlb_printmethods.h:283
Definition balxml_encoderoptions.h:68
Definition bslma_usesbslmaallocator.h:343