BDE 4.14.0 Production release
Loading...
Searching...
No Matches
balxml_prefixstack.h
Go to the documentation of this file.
1/// @file balxml_prefixstack.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// balxml_prefixstack.h -*-C++-*-
8#ifndef INCLUDED_BALXML_PREFIXSTACK
9#define INCLUDED_BALXML_PREFIXSTACK
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup balxml_prefixstack balxml_prefixstack
15/// @brief Provide a unique integer ID for each XML namespace.
16/// @addtogroup bal
17/// @{
18/// @addtogroup balxml
19/// @{
20/// @addtogroup balxml_prefixstack
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#balxml_prefixstack-purpose"> Purpose</a>
25/// * <a href="#balxml_prefixstack-classes"> Classes </a>
26/// * <a href="#balxml_prefixstack-description"> Description </a>
27/// * <a href="#balxml_prefixstack-usage"> Usage </a>
28/// * <a href="#balxml_prefixstack-example-1-basic-usage"> Example 1: Basic Usage </a>
29///
30/// # Purpose {#balxml_prefixstack-purpose}
31/// Provide a unique integer ID for each XML namespace.
32///
33/// # Classes {#balxml_prefixstack-classes}
34///
35/// - balxml::PrefixStack: stack of (namespace prefix, unique integer ID) pairs
36///
37/// @see balxml_namespaceregistry
38///
39/// # Description {#balxml_prefixstack-description}
40/// `balxml::PrefixStack` keeps a collection of pairs - the prefix
41/// string and the integer associated with each namespace uri. Registration of
42/// prefix with namespace works similar to "pushing in stack", i.e., it hides
43/// the previous prefix<->namespaces association. Deregistration of prefix
44/// removes the current association and opens the previous association of given
45/// prefix.
46///
47/// It is safe to read or modify multiple instances of `balxml::PrefixStack`
48/// simultaneously, each from a separate thread. It is safe to read a single
49/// instance of `balxml::PrefixStack` from multiple threads, provided no thread
50/// is modifying it at the same time. It is not safe to read or modify an
51/// instance of `balxml::PrefixStack` from one thread while any other thread is
52/// modifying the same instance. Modifying a `balxml::PrefixStack` objects may
53/// modify the referenced `balxml::NamespaceRegistry` object. It is not safe to
54/// read or modify an instance of `balxml::PrefixStack` from one thread while
55/// any other thread is (directly or indirectly) modifying the referenced
56/// `balxml::NamespaceRegistry`.
57///
58/// ## Usage {#balxml_prefixstack-usage}
59///
60///
61/// This section illustrates intended use of this component.
62///
63/// ### Example 1: Basic Usage {#balxml_prefixstack-example-1-basic-usage}
64///
65///
66/// In this example we demonstrate registering several prefixes with different
67/// namespaces and printing them along with their ID.
68/// @code
69/// balxml::NamespaceRegistry namespaces;
70/// balxml::PrefixStack prefixes(namespaces, allocator);
71///
72/// bsl::string uri1 = "http://www.google.com";
73/// bsl::string uri2 = "http://www.yahoo.com";
74/// bsl::string uri3 = "http://www.hotmail.com";
75/// bsl::string uri4 = "http://www.msn.com";
76///
77/// bsl::string prefix1 = "a";
78/// bsl::string prefix2 = "b";
79/// bsl::string prefix3 = "c";
80///
81/// int namespaceId1 = prefixes.pushPrefix(prefix1, uri1);
82/// int namespaceId2 = prefixes.pushPrefix(prefix2, uri2);
83/// int namespaceId3 = prefixes.pushPrefix(prefix3, uri3);
84///
85/// bsl::cout << prefix1 << ":" << namespaceId1 << bsl::endl;
86/// bsl::cout << prefix2 << ":" << namespaceId2 << bsl::endl;
87/// bsl::cout << prefix3 << ":" << namespaceId3 << bsl::endl;
88///
89/// int namespaceId4 = prefixes.pushPrefix(prefix1, uri4);
90///
91/// bsl::cout << prefix1 << ":" << namespaceId1 << bsl::endl;
92///
93/// prefixes.popPrefix(prefix1);
94///
95/// bsl::cout << prefix1 << ":" << namespaceId1 << bsl::endl;
96///
97/// @endcode
98/// @}
99/** @} */
100/** @} */
101
102/** @addtogroup bal
103 * @{
104 */
105/** @addtogroup balxml
106 * @{
107 */
108/** @addtogroup balxml_prefixstack
109 * @{
110 */
111
112#include <balscm_version.h>
113
114#include <bslma_allocator.h>
115
116#include <bsls_assert.h>
117#include <bsls_review.h>
118
119#include <bsl_iosfwd.h>
120#include <bsl_string.h>
121#include <bsl_utility.h>
122#include <bsl_vector.h>
123
124
125namespace balxml {
126
127class NamespaceRegistry;
128
129 // =================
130 // class PrefixStack
131 // =================
132
133/// `PrefixStack` allows associating a unique integer (namespace ID) with
134/// prefix.
135///
136/// See @ref balxml_prefixstack
138
139 // PRIVATE TYPES
141
142 // DATA
143 NamespaceRegistry *d_namespaceRegistry;
144
145 PrefixVector d_prefixes; // vector of pairs of namespace
146 // prefix and integer id of the
147 // namespace
148
149 int d_numPrefixes; // number of prefixes
150
151 // NOT IMPLEMENTED
152 PrefixStack& operator=(const PrefixStack&); // = delete
153
154 public:
155 // CREATORS
156
157 /// Create an empty registry. Optionally specify a `basicAllocator`
158 /// used to supply memory. If `basicAllocator` is 0, the currently
159 /// installed default allocator is used.
161 bslma::Allocator *basicAllocator = 0);
162
163 /// Create a registry object having the same value as the specified
164 /// `original` object. Optionally specify a `basicAllocator` used to
165 /// supply memory. If `basicAllocator` is 0, the currently installed
166 /// default allocator is used.
167 PrefixStack(const PrefixStack& original,
168 bslma::Allocator *basicAllocator = 0);
169
170 /// Destroy this object.
171 ~PrefixStack();
172
173 // MANIPULATORS
174
175 /// Map the specified `namespaceUri` to the specified `prefix` and
176 /// return the namespace Id. New mapping eclipses previous mapping.
177 int pushPrefix(const bsl::string_view& prefix,
178 const bsl::string_view& namespaceUri);
179
180 /// Remove the specified last `count` number prefixes. Return the
181 /// number of actually removed prefixes.
182 int popPrefixes(int count);
183
184 /// Removes all prefixes from the internal collection.
185 void reset();
186
187 /// Restore stack to the specified `size`. The behavior is undefined if
188 /// PrefixStack contains fewer prefixes than requested size.
189 void restoreToSize(int size);
190
191 // ACCESSORS
192
193 /// Return the current number of prefixes in the stack.
194 int numPrefixes() const;
195
196 /// Return the pointer of `NamespaceRegistry` associated with this
197 /// PrefixStack.
199
200 /// Return a copy of the specified `prefix` if `prefix` is registered or
201 /// an empty string if `prefix` is not registered.
202 const char *lookupNamespacePrefix(const bsl::string_view& prefix) const;
203
204 /// Return ID of the namespace registered for the specified `prefix` or
205 /// -1 if not registered.
206 int lookupNamespaceId(const bsl::string_view& prefix) const;
207
208 /// Return the URI of the namespace registered for the specified
209 /// `prefix` or empty string if not registered.
210 const char *lookupNamespaceUri(const bsl::string_view& prefix) const;
211
212 /// Return the URI of the namespace of the specified `nsId` or empty
213 /// string if not registered.
214 const char *lookupNamespaceUri(int nsId) const;
215
216 /// Return the namespace prefix at the specified `index` in the prefix
217 /// stack, where an `index` of 0 is the oldest prefix on the stack. If
218 /// `index` is negative, return the prefix at position 'numPrefixes() -
219 /// index'. Thus, an `index` of -1 will return the most recent prefix
220 /// on the stack (i.e., the top of the stack). The behavior is
221 /// undefined if `index > numPrefixes()` or `index < -numPrefixes()`.
222 const char *namespacePrefixByIndex(int index) const;
223
224 /// Return the namespace ID at the specified `index` in the prefix
225 /// stack, where an `index` of 0 is the oldest ID on the stack. If
226 /// `index` is negative, return the ID at position 'numPrefixes() -
227 /// index'. Thus, an `index` of -1 will return the most recent ID on
228 /// the stack (i.e., the top of the stack). The behavior is undefined
229 /// if `index > numPrefixes()` or `index < -numPrefixes()`.
230 int namespaceIdByIndex(int index) const;
231
232 /// Return the namespace URI at the specified `index` in the prefix
233 /// stack, where an `index` of 0 is the oldest URI on the stack. If
234 /// `index` is negative, return the URI at position 'numPrefixes() -
235 /// index'. Thus, an `index` of -1 will return the most recent URI on
236 /// the stack (i.e., the top of the stack). The behavior is undefined
237 /// if `index > numPrefixes()` or `index < -numPrefixes()`.
238 const char *namespaceUriByIndex(int index) const;
239
240 /// Print the content of this object to the specified `stream`. The
241 /// optionally specified `fullNames` specifies how namespaces should be
242 /// printed: `true` for the full names and `false` only for IDs.
243 void print(bsl::ostream& stream, bool fullNames = false) const;
244};
245
246// ============================================================================
247// INLINE DEFINITIONS
248// ============================================================================
249
250// CREATORS
251inline
255
256// MANIPULATORS
257inline
259{
260 d_numPrefixes = 0;
261 d_prefixes.clear();
262}
263
264inline
266{
267 BSLS_ASSERT(size <= d_numPrefixes);
268 d_numPrefixes = size;
269}
270
271// ACCESSORS
272inline
274{
275 return d_namespaceRegistry;
276}
277
278inline
280{
281 return d_numPrefixes;
282}
283
284inline
285const char *PrefixStack::namespacePrefixByIndex(int index) const
286{
287 index = (index < 0 ? d_numPrefixes + index : index);
288 BSLS_ASSERT(0 <= index && index < d_numPrefixes);
289 return d_prefixes[index].first.c_str();
290}
291
292inline
294{
295 index = (index < 0 ? d_numPrefixes + index : index);
296 BSLS_ASSERT(0 <= index && index < d_numPrefixes);
297 return d_prefixes[index].second;
298}
299
300} // close package namespace
301
302
303#endif
304
305// ----------------------------------------------------------------------------
306// Copyright 2015 Bloomberg Finance L.P.
307//
308// Licensed under the Apache License, Version 2.0 (the "License");
309// you may not use this file except in compliance with the License.
310// You may obtain a copy of the License at
311//
312// http://www.apache.org/licenses/LICENSE-2.0
313//
314// Unless required by applicable law or agreed to in writing, software
315// distributed under the License is distributed on an "AS IS" BASIS,
316// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
317// See the License for the specific language governing permissions and
318// limitations under the License.
319// ----------------------------- END-OF-FILE ----------------------------------
320
321/** @} */
322/** @} */
323/** @} */
Definition balxml_namespaceregistry.h:181
Definition balxml_prefixstack.h:137
void reset()
Removes all prefixes from the internal collection.
Definition balxml_prefixstack.h:258
const char * namespaceUriByIndex(int index) const
int lookupNamespaceId(const bsl::string_view &prefix) const
PrefixStack(NamespaceRegistry *namespaceRegistry, bslma::Allocator *basicAllocator=0)
NamespaceRegistry * namespaceRegistry() const
Definition balxml_prefixstack.h:273
const char * namespacePrefixByIndex(int index) const
Definition balxml_prefixstack.h:285
PrefixStack(const PrefixStack &original, bslma::Allocator *basicAllocator=0)
int namespaceIdByIndex(int index) const
Definition balxml_prefixstack.h:293
void restoreToSize(int size)
Definition balxml_prefixstack.h:265
int numPrefixes() const
Return the current number of prefixes in the stack.
Definition balxml_prefixstack.h:279
int popPrefixes(int count)
~PrefixStack()
Destroy this object.
Definition balxml_prefixstack.h:252
const char * lookupNamespacePrefix(const bsl::string_view &prefix) const
void print(bsl::ostream &stream, bool fullNames=false) const
const char * lookupNamespaceUri(int nsId) const
int pushPrefix(const bsl::string_view &prefix, const bsl::string_view &namespaceUri)
const char * lookupNamespaceUri(const bsl::string_view &prefix) const
Definition bslstl_stringview.h:441
Definition bslstl_vector.h:1025
void swap(vector &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits void clear() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:1712
Definition bslma_allocator.h:457
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition balxml_base64parser.h:150