BDE 4.39.x 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 private:
152 // NOT IMPLEMENTED
153 PrefixStack& operator=(const PrefixStack&); // = delete
154
155 public:
156 // CREATORS
157
158 /// Create an empty registry. Optionally specify a `basicAllocator`
159 /// used to supply memory. If `basicAllocator` is 0, the currently
160 /// installed default allocator is used.
162 bslma::Allocator *basicAllocator = 0);
163
164 /// Create a registry object having the same value as the specified
165 /// `original` object. Optionally specify a `basicAllocator` used to
166 /// supply memory. If `basicAllocator` is 0, the currently installed
167 /// default allocator is used.
168 PrefixStack(const PrefixStack& original,
169 bslma::Allocator *basicAllocator = 0);
170
171 /// Destroy this object.
172 ~PrefixStack();
173
174 // MANIPULATORS
175
176 /// Map the specified `namespaceUri` to the specified `prefix` and
177 /// return the namespace Id. New mapping eclipses previous mapping.
178 int pushPrefix(const bsl::string_view& prefix,
179 const bsl::string_view& namespaceUri);
180
181 /// Remove the specified last `count` number prefixes. Return the
182 /// number of actually removed prefixes.
183 int popPrefixes(int count);
184
185 /// Removes all prefixes from the internal collection.
186 void reset();
187
188 /// Restore stack to the specified `size`.
189 /// \pre The behavior is undefined if
190 /// PrefixStack contains fewer prefixes than requested size.
191 void restoreToSize(int size);
192
193 // ACCESSORS
194
195 /// Return the current number of prefixes in the stack.
196 int numPrefixes() const;
197
198 /// Return the pointer of `NamespaceRegistry` associated with this
199 /// PrefixStack.
201
202 /// Return a copy of the specified `prefix` if `prefix` is registered or
203 /// an empty string if `prefix` is not registered.
204 const char *lookupNamespacePrefix(const bsl::string_view& prefix) const;
205
206 /// Return ID of the namespace registered for the specified `prefix` or
207 /// -1 if not registered.
208 int lookupNamespaceId(const bsl::string_view& prefix) const;
209
210 /// Return the URI of the namespace registered for the specified
211 /// `prefix` or empty string if not registered.
212 const char *lookupNamespaceUri(const bsl::string_view& prefix) const;
213
214 /// Return the URI of the namespace of the specified `nsId` or empty
215 /// string if not registered.
216 const char *lookupNamespaceUri(int nsId) const;
217
218 /// Return the namespace prefix at the specified `index` in the prefix
219 /// stack, where an `index` of 0 is the oldest prefix on the stack. If
220 /// `index` is negative, return the prefix at position 'numPrefixes() -
221 /// index'. Thus, an `index` of -1 will return the most recent prefix
222 /// on the stack (i.e., the top of the stack).
223 ///
224 /// \pre The behavior is undefined if `index > numPrefixes()` or `index < -numPrefixes()`.
225 const char *namespacePrefixByIndex(int index) const;
226
227 /// Return the namespace ID at the specified `index` in the prefix
228 /// stack, where an `index` of 0 is the oldest ID on the stack. If
229 /// `index` is negative, return the ID at position 'numPrefixes() -
230 /// index'. Thus, an `index` of -1 will return the most recent ID on
231 /// the stack (i.e., the top of the stack).
232 ///
233 /// \pre The behavior is undefined if `index > numPrefixes()` or `index < -numPrefixes()`.
234 int namespaceIdByIndex(int index) const;
235
236 /// Return the namespace URI at the specified `index` in the prefix
237 /// stack, where an `index` of 0 is the oldest URI on the stack. If
238 /// `index` is negative, return the URI at position 'numPrefixes() -
239 /// index'. Thus, an `index` of -1 will return the most recent URI on
240 /// the stack (i.e., the top of the stack).
241 ///
242 /// \pre The behavior is undefined if `index > numPrefixes()` or `index < -numPrefixes()`.
243 const char *namespaceUriByIndex(int index) const;
244
245 /// Print the content of this object to the specified `stream`. The
246 /// optionally specified `fullNames` specifies how namespaces should be
247 /// printed: `true` for the full names and `false` only for IDs.
248 void print(bsl::ostream& stream, bool fullNames = false) const;
249};
250
251// ============================================================================
252// INLINE DEFINITIONS
253// ============================================================================
254
255// CREATORS
256inline
260
261// MANIPULATORS
262inline
264{
265 d_numPrefixes = 0;
266 d_prefixes.clear();
267}
268
269inline
271{
272 BSLS_ASSERT(size <= d_numPrefixes);
273 d_numPrefixes = size;
274}
275
276// ACCESSORS
277inline
279{
280 return d_namespaceRegistry;
281}
282
283inline
285{
286 return d_numPrefixes;
287}
288
289inline
290const char *PrefixStack::namespacePrefixByIndex(int index) const
291{
292 index = (index < 0 ? d_numPrefixes + index : index);
293 BSLS_ASSERT(0 <= index && index < d_numPrefixes);
294 return d_prefixes[index].first.c_str();
295}
296
297inline
299{
300 index = (index < 0 ? d_numPrefixes + index : index);
301 BSLS_ASSERT(0 <= index && index < d_numPrefixes);
302 return d_prefixes[index].second;
303}
304
305} // close package namespace
306
307
308#endif
309
310// ----------------------------------------------------------------------------
311// Copyright 2015 Bloomberg Finance L.P.
312//
313// Licensed under the Apache License, Version 2.0 (the "License");
314// you may not use this file except in compliance with the License.
315// You may obtain a copy of the License at
316//
317// http://www.apache.org/licenses/LICENSE-2.0
318//
319// Unless required by applicable law or agreed to in writing, software
320// distributed under the License is distributed on an "AS IS" BASIS,
321// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
322// See the License for the specific language governing permissions and
323// limitations under the License.
324// ----------------------------- END-OF-FILE ----------------------------------
325
326/** @} */
327/** @} */
328/** @} */
Definition balxml_namespaceregistry.h:181
Definition balxml_prefixstack.h:137
void reset()
Removes all prefixes from the internal collection.
Definition balxml_prefixstack.h:263
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:278
const char * namespacePrefixByIndex(int index) const
Definition balxml_prefixstack.h:290
PrefixStack(const PrefixStack &original, bslma::Allocator *basicAllocator=0)
int namespaceIdByIndex(int index) const
Definition balxml_prefixstack.h:298
void restoreToSize(int size)
Definition balxml_prefixstack.h:270
int numPrefixes() const
Return the current number of prefixes in the stack.
Definition balxml_prefixstack.h:284
int popPrefixes(int count)
~PrefixStack()
Destroy this object.
Definition balxml_prefixstack.h:257
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:471
Definition bslstl_vector.h:1120
void swap(vector &other) BSLS_KEYWORD_NOEXCEPT_SPECIFICATION(AllocatorTraits void clear() BSLS_KEYWORD_NOEXCEPT
Definition bslstl_vector.h:1938
Definition bslma_allocator.h:545
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition balxml_base64parser.h:150