BDE 4.14.0 Production release
Loading...
Searching...
No Matches
balxml_namespaceregistry.h
Go to the documentation of this file.
1/// @file balxml_namespaceregistry.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// balxml_namespaceregistry.h -*-C++-*-
8#ifndef INCLUDED_BALXML_NAMESPACEREGISTRY
9#define INCLUDED_BALXML_NAMESPACEREGISTRY
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup balxml_namespaceregistry balxml_namespaceregistry
15/// @brief Provide a unique integer ID for each XML namespace.
16/// @addtogroup bal
17/// @{
18/// @addtogroup balxml
19/// @{
20/// @addtogroup balxml_namespaceregistry
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#balxml_namespaceregistry-purpose"> Purpose</a>
25/// * <a href="#balxml_namespaceregistry-classes"> Classes </a>
26/// * <a href="#balxml_namespaceregistry-description"> Description </a>
27/// * <a href="#balxml_namespaceregistry-preregistered-namespaces"> Preregistered Namespaces </a>
28/// * <a href="#balxml_namespaceregistry-thread-safety"> Thread Safety </a>
29/// * <a href="#balxml_namespaceregistry-usage"> Usage </a>
30///
31/// # Purpose {#balxml_namespaceregistry-purpose}
32/// Provide a unique integer ID for each XML namespace.
33///
34/// # Classes {#balxml_namespaceregistry-classes}
35///
36/// - balxml::NamespaceRegistry: namespace-to-id mapping registry
37///
38/// @see balxml_prefixstack
39///
40/// # Description {#balxml_namespaceregistry-description}
41/// This component provides an in-core value-semantic type,
42/// `balxml::NamespaceRegistry`, that associates an integer ID with each
43/// registered namespace URI. In typical usage, client code would call the
44/// `lookupOrRegister` method each time it encounters a namespace URI. The
45/// `lookupOrRegister` method will return the ID corresponding to the URI,
46/// assigning a new ID if none already exists. The client can also retrieve
47/// the ID an already-registered namespace by providing the URI to the `lookup`
48/// method and can retrieve the URI of an already-registered namespace by
49/// providing the ID to the `lookup` method.
50///
51/// Note that namespace IDs may be negative. Client code should not assume an
52/// incremental assignment of IDs starting at zero. (See Preregistered
53/// Namespaces), below.
54///
55/// ## Preregistered Namespaces {#balxml_namespaceregistry-preregistered-namespaces}
56///
57///
58/// Even before any namespaces have been registered, a
59/// `balxml::NamespaceRegistry` can be used to lookup several preregistered
60/// namespaces. The IDs for these preregistered namespaces are declared as
61/// constants within the `balxml::NamespaceRegistry` class. These constants and
62/// their associated URI's are as follows:
63/// @code
64/// Namespace ID URI String
65/// ============ ==========
66/// BAEXML_XML http://www.w3.org/XML/1998/namespace
67/// BAEXML_XMLNS http://www.w3.org/2000/xmlns/
68/// BAEXML_XMLSCHEMA http://www.w3.org/2001/XMLSchema
69/// BAEXML_XMLSCHEMA_INSTANCE http://www.w3.org/2001/XMLSchema-instance
70/// BAEXML_WSDL http://schemas.xmlsoap.org/wsdl/
71/// BAEXML_WSDL_SOAP http://schemas.xmlsoap.org/wsdl/soap/
72/// BAEXML_BDEM http://bloomberg.com/schemas/bdem
73/// @endcode
74/// Note that the above constants are negative numbers. In addition, the
75/// value, -1, is permanently assigned to the empty string. The use of
76/// predefined namespace IDs allows client code avoid lookups of the above,
77/// well-known URIs.
78///
79/// ## Thread Safety {#balxml_namespaceregistry-thread-safety}
80///
81///
82/// It is safe to read or modify multiple instances of
83/// `balxml::NamespaceRegistry` simultaneously, each from a separate thread. It
84/// is safe to read a single instance of `balxml::NamespaceRegistry` from
85/// multiple threads, provided no thread is modifying it at the same time. It
86/// is not safe to read or modify an instance of `balxml::NamespaceRegistry`
87/// from one thread while any other thread is modifying the same instance.
88///
89/// ## Usage {#balxml_namespaceregistry-usage}
90///
91///
92/// Typically, a program will register namespaces as it encounters them in an
93/// XML document. Alternatively, namespaces that are important to the program
94/// are registered in advance, as in the following code:
95/// @code
96/// const char googleUri[] = "http://www.google.com/schemas/results.xsd";
97/// const char yahooUri[] = "http://www.yahoo.com/xsd/searchResults.xsd";
98///
99/// balxml::NamespaceRegistry namespaceRegistry;
100/// int googleId = namespaceRegistry.lookupOrRegister(googleUri);
101/// assert(googleId >= 0);
102/// int yahooId = namespaceRegistry.lookupOrRegister(yahooUri);
103/// assert(yahooId >= 0);
104/// assert(yahooId != googleId);
105/// @endcode
106/// Later, IDs can be looked up without concern for whether they have already
107/// been registered. Any new namespaces are simply given a new ID:
108/// @code
109/// char input[100];
110///
111/// // First input is a new namespace URI.
112/// bsl::strcpy(input, "http://www.bloomberg.com/schemas/example.xsd");
113/// int id1 = namespaceRegistry.lookupOrRegister(input);
114/// assert(id1 >= 0);
115/// assert(id1 != googleId);
116/// assert(id1 != yahooId);
117///
118/// // Next input happens to be the same as yahoo.
119/// bsl::strcpy(input, "http://www.yahoo.com/xsd/searchResults.xsd");
120/// int id2 = namespaceRegistry.lookupOrRegister(input);
121/// assert(id2 == yahooId);
122/// @endcode
123/// If one of the preregistered namespaces is presented, it's predefined ID is
124/// returned, even though it was never explicitly registered:
125/// @code
126/// bsl::strcpy(input, "http://www.w3.org/2001/XMLSchema");
127/// int id3 = namespaceRegistry.lookupOrRegister(input);
128/// assert(id3 == balxml::NamespaceRegistry::BAEXML_XMLSCHEMA);
129/// @endcode
130/// Using the `lookup` method, a namespace ID can be looked up without
131/// registering it. In this case, an unregistered namespace will result in an
132/// ID of -1:
133/// @code
134/// assert(googleId == namespaceRegistry.lookup(googleUri));
135/// assert(balxml::NamespaceRegistry::BAEXML_BDEM ==
136/// namespaceRegistry.lookup("http://bloomberg.com/schemas/bdem"));
137/// assert(-1 == namespaceRegistry.lookup("urn:1234"));
138/// @endcode
139/// There is also a `lookup` method for performing the reverse mapping -- from
140/// ID to URI:
141/// @code
142/// const char *uri = namespaceRegistry.lookup(googleId);
143/// assert(0 == bsl::strcmp(uri, googleUri));
144/// @endcode
145/// @}
146/** @} */
147/** @} */
148
149/** @addtogroup bal
150 * @{
151 */
152/** @addtogroup balxml
153 * @{
154 */
155/** @addtogroup balxml_namespaceregistry
156 * @{
157 */
158
159#include <balscm_version.h>
160
161#include <bslma_allocator.h>
163
165
166#include <bsl_string.h>
167#include <bsl_vector.h>
168#include <bsl_iosfwd.h>
169
170
171
172namespace balxml {
173 // =======================
174 // class NamespaceRegistry
175 // =======================
176
177/// Mapping that associates a unique integer with each registered namespace
178/// URI.
179///
180/// See @ref balxml_namespaceregistry
182
183 private:
184 // PRIVATE MEMBER VARIABLES
185 bsl::vector<bsl::string> d_namespaces; // vector of namespaces, indexed by
186 // the namespace ID.
187
188 /// Must be a friend for engineering reasons. Unlike most
189 /// value-semantic types, there is no efficient way to read the entire
190 /// value of a namespace registry object.
191 friend inline
193 const NamespaceRegistry& rhs);
194
195 public:
196 // TRAITS
199
200 // PUBLIC TYPES
201 enum {
202 // Preregistered namespace IDs.
203 e_NO_NAMESPACE = -1, // (empty URI string)
204
205 e_PREDEF_MIN = 0x40000000,
206
207 e_XML = e_PREDEF_MIN, // http://www.w3.org/XML/1998/namespace
208 e_XMLNS, // http://www.w3.org/2000/xmlns/
209 e_XMLSCHEMA, // http://www.w3.org/2001/XMLSchema
210 e_XMLSCHEMA_INSTANCE, // http://www.w3.org/2001/XMLSchema-instance
211 e_WSDL, // http://schemas.xmlsoap.org/wsdl/
212 e_WSDL_SOAP, // http://schemas.xmlsoap.org/wsdl/soap/
213 e_BDEM, // http://bloomberg.com/schemas/bdem
214
216#ifndef BDE_OMIT_INTERNAL_DEPRECATED
236#endif // BDE_OMIT_INTERNAL_DEPRECATED
237 };
238
239 // CREATORS
240
241 /// Construct an empty registry. Optionally specify a `basicAllocator`
242 /// used to supply memory. If `basicAllocator` is 0, the current
243 /// default allocator is used.
244 NamespaceRegistry(bslma::Allocator *basicAllocator = 0);
245
246 /// Construct a copy of the specified `other` namespace registry using
247 /// the (optionally) specified `basicAllocator`. For a given URI, the
248 /// results of calling `lookup` by URI will produce equal results for
249 /// this object and for `other`. For a given integer ID, the result of
250 /// calling `lookup` by ID will produce different pointers that compare
251 /// equal using `strcmp`.
253 bslma::Allocator *basicAllocator=0);
254
255 /// Destroy this object. Release all memory to the allocator used at
256 /// construction.
258
259 // MANIPULATORS
260
261 /// Discard the contents of this registry and assign it the contents of
262 /// the specified `rhs` registry. For a given URI, the results of
263 /// calling `lookup` by URI will produce equal results for this object
264 /// and for `rhs`. For a given integer ID, the result of calling
265 /// `lookup` by ID will produce different pointers that compare equal
266 /// using `strcmp`.
268
269 /// Return the integer ID for the specified `namespaceUri`, assigning a
270 /// new ID if the `namespaceUri` has not been registered before. Note
271 /// that the IDs for pre-registered namespaces (including the empty
272 /// URI) are less than zero. (See "Preregistered Namespaces" in the
273 /// 'balxml_namespaceregistry component-level documentation.)
274 int lookupOrRegister(const bsl::string_view& namespaceUri);
275
276 /// Removes all registered namespaces. Preregistered namespaces are
277 /// not removed.
278 void reset();
279
280 // ACCESSORS
281
282 /// Return the integer ID for the specified `namespaceUri` or -1 if the
283 /// namespace has not been registered. Note that not all negative
284 /// return values correspond to unregistered namespaces. Preregistered
285 /// namespaces always have negative IDs. (See "Preregistered
286 /// Namespaces" in the @ref balxml_namespaceregistry component-level
287 /// documentation.) Note that a return value of -1 can mean either an
288 /// unregistered namespace or an empty URI string. This dual-use of -1
289 /// is deliberate and simplifies error handling in most clients.
290 int lookup(const bsl::string_view& namespaceUri) const;
291
292 /// Return the null-terminated string containing the URI of the
293 /// namespace registered with the specified `id` or an empty (not null)
294 /// string if `id` does not correspond to a preregistered namespace or
295 /// a namespace that was previously registered with this object.
296 const char *lookup(int id) const;
297
298 /// Print the contents of this object to the specified `stream` in
299 /// human-readable form.
300 void print(bsl::ostream& stream) const;
301};
302
303// ============================================================================
304// INLINE DEFINITIONS
305// ============================================================================
306
307// FREE OPERATORS
308
309/// Return true if the specified `lhs` registry has the same value as the
310/// specified `rhs` registry and false otherwise. The two registries have
311/// the same value if, for any possible URI string, `u`,
312/// `lhs.lookup(u) == rhs.lookup(u)`.
313inline
314bool operator==(const NamespaceRegistry& lhs, const NamespaceRegistry& rhs);
315
316/// Return true if the specified `lhs` registry does not have the same
317/// value as the specified `rhs` registry and false otherwise. The two
318/// registries do not have the same value if there exists a URI string,
319/// `u`, such that `lhs.lookup(u)` != `rhs.lookup(u)`.
320inline
321bool operator!=(const NamespaceRegistry& lhs, const NamespaceRegistry& rhs);
322
323/// Print the contents of the specified `r` registry to the specified `os`
324/// stream in human-readable form and return a modifiable reference to
325/// `os`.
326inline
327bsl::ostream& operator<<(bsl::ostream& os, const NamespaceRegistry& r);
328
329// CREATORS
330inline
332: d_namespaces(basicAllocator)
333{
334}
335
336inline
338 bslma::Allocator *basicAllocator)
339: d_namespaces(other.d_namespaces, basicAllocator)
340{
341}
342
343inline
347
348// MANIPULATORS
349inline
352{
353 d_namespaces = rhs.d_namespaces;
354 return *this;
355}
356
357inline
359{
360 d_namespaces.clear();
361}
362} // close package namespace
363
364// FREE OPERATORS
365inline
366bool balxml::operator==(const NamespaceRegistry& lhs,
367 const NamespaceRegistry& rhs)
368{
369 return lhs.d_namespaces == rhs.d_namespaces;
370}
371
372inline
373bool balxml::operator!=(const NamespaceRegistry& lhs,
374 const NamespaceRegistry& rhs)
375{
376 return ! (lhs == rhs);
377}
378
379inline
380bsl::ostream& balxml::operator<<(bsl::ostream& os, const NamespaceRegistry& r)
381{
382 r.print(os);
383 return os;
384}
385
386
387
388#endif // ! defined(INCLUDED_BAEXML_NAMESPACEREGISTRY)
389
390// ----------------------------------------------------------------------------
391// Copyright 2015 Bloomberg Finance L.P.
392//
393// Licensed under the Apache License, Version 2.0 (the "License");
394// you may not use this file except in compliance with the License.
395// You may obtain a copy of the License at
396//
397// http://www.apache.org/licenses/LICENSE-2.0
398//
399// Unless required by applicable law or agreed to in writing, software
400// distributed under the License is distributed on an "AS IS" BASIS,
401// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
402// See the License for the specific language governing permissions and
403// limitations under the License.
404// ----------------------------- END-OF-FILE ----------------------------------
405
406/** @} */
407/** @} */
408/** @} */
Definition balxml_namespaceregistry.h:181
void reset()
Definition balxml_namespaceregistry.h:358
NamespaceRegistry(bslma::Allocator *basicAllocator=0)
Definition balxml_namespaceregistry.h:331
void print(bsl::ostream &stream) const
int lookupOrRegister(const bsl::string_view &namespaceUri)
const char * lookup(int id) const
@ NSID_XMLSCHEMA_INSTANCE
Definition balxml_namespaceregistry.h:231
@ BAEXML_XMLSCHEMA_INSTANCE
Definition balxml_namespaceregistry.h:222
@ e_PREDEF_MIN
Definition balxml_namespaceregistry.h:205
@ e_XMLSCHEMA_INSTANCE
Definition balxml_namespaceregistry.h:210
@ NSID_PREDEF_MIN
Definition balxml_namespaceregistry.h:227
@ e_XMLNS
Definition balxml_namespaceregistry.h:208
@ NSID_PREDEF_MAX
Definition balxml_namespaceregistry.h:235
@ NSID_XML
Definition balxml_namespaceregistry.h:228
@ NSID_XMLNS
Definition balxml_namespaceregistry.h:229
@ e_WSDL
Definition balxml_namespaceregistry.h:211
@ e_WSDL_SOAP
Definition balxml_namespaceregistry.h:212
@ BAEXML_XML
Definition balxml_namespaceregistry.h:219
@ e_XMLSCHEMA
Definition balxml_namespaceregistry.h:209
@ BAEXML_PREDEF_MAX
Definition balxml_namespaceregistry.h:215
@ e_NO_NAMESPACE
Definition balxml_namespaceregistry.h:203
@ BAEXML_XMLNS
Definition balxml_namespaceregistry.h:220
@ NSID_XMLSCHEMA
Definition balxml_namespaceregistry.h:230
@ NSID_NO_NAMESPACE
Definition balxml_namespaceregistry.h:226
@ NSID_WSDL
Definition balxml_namespaceregistry.h:232
@ e_XML
Definition balxml_namespaceregistry.h:207
@ BAEXML_XMLSCHEMA
Definition balxml_namespaceregistry.h:221
@ BAEXML_PREDEF_MIN
Definition balxml_namespaceregistry.h:218
@ NSID_WSDL_SOAP
Definition balxml_namespaceregistry.h:233
@ BAEXML_WSDL
Definition balxml_namespaceregistry.h:223
@ e_BDEM
Definition balxml_namespaceregistry.h:213
@ NSID_BDEM
Definition balxml_namespaceregistry.h:234
@ BAEXML_NO_NAMESPACE
Definition balxml_namespaceregistry.h:217
@ BAEXML_WSDL_SOAP
Definition balxml_namespaceregistry.h:224
@ BAEXML_BDEM
Definition balxml_namespaceregistry.h:225
BSLMF_NESTED_TRAIT_DECLARATION(NamespaceRegistry, bslma::UsesBslmaAllocator)
int lookup(const bsl::string_view &namespaceUri) const
~NamespaceRegistry()
Definition balxml_namespaceregistry.h:344
NamespaceRegistry & operator=(const NamespaceRegistry &rhs)
Definition balxml_namespaceregistry.h:351
friend bool operator==(const NamespaceRegistry &lhs, const NamespaceRegistry &rhs)
Definition bslstl_stringview.h:441
Definition bslstl_vector.h:1025
Definition bslma_allocator.h:457
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition balxml_base64parser.h:150
bsl::ostream & operator<<(bsl::ostream &stream, const ConfigSchema &schema)
bool operator==(const DecoderOptions &lhs, const DecoderOptions &rhs)
bool operator!=(const DecoderOptions &lhs, const DecoderOptions &rhs)
Definition bslma_usesbslmaallocator.h:343