BDE 4.14.0 Production release
Loading...
Searching...
No Matches
balxml_listparser.h
Go to the documentation of this file.
1/// @file balxml_listparser.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// balxml_listparser.h -*-C++-*-
8#ifndef INCLUDED_BALXML_LISTPARSER
9#define INCLUDED_BALXML_LISTPARSER
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup balxml_listparser balxml_listparser
15/// @brief Provide push parser for lists.
16/// @addtogroup bal
17/// @{
18/// @addtogroup balxml
19/// @{
20/// @addtogroup balxml_listparser
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#balxml_listparser-purpose"> Purpose</a>
25/// * <a href="#balxml_listparser-classes"> Classes </a>
26/// * <a href="#balxml_listparser-description"> Description </a>
27/// * <a href="#balxml_listparser-usage"> Usage </a>
28/// * <a href="#balxml_listparser-example-1-basic-usage"> Example 1: Basic Usage </a>
29///
30/// # Purpose {#balxml_listparser-purpose}
31/// Provide push parser for lists.
32///
33/// # Classes {#balxml_listparser-classes}
34///
35/// - balxml::ListParser: push parser for lists
36///
37/// @see bdlat_arrayfunctions
38///
39/// # Description {#balxml_listparser-description}
40/// The `balxml::ListParser` class template provided by this
41/// component can be used to parse lists into an object that supports
42/// `bdlat_ArrayFunctions`.
43///
44/// This class template is a model of the `PushParser` concept, which contains
45/// the following methods:
46/// @code
47/// int beginParse(TYPE *object);
48/// // Prepare the parser to start parsing a new value and associate the
49/// // specified 'object' with the parser. Return 0 if successful and
50/// // non-zero otherwise.
51///
52/// int endParse();
53/// // Ends the parse operation and store the value parsed from the pushed
54/// // characters into the associated object. Return 0 if successful and
55/// // non-zero otherwise. The behavior is undefined unless an object is
56/// // associated with this parser. Upon successful completion, the parser
57/// // will be disassociated with the object.
58///
59/// template <typename INPUT_ITERATOR>
60/// int pushCharacters(INPUT_ITERATOR begin, INPUT_ITERATOR end);
61/// // Push the characters ranging from the specified 'begin' up to (but
62/// // not including) the specified 'end' into this parser. Return 0 if
63/// // successful and non-zero otherwise. The parameterized
64/// // 'INPUT_ITERATOR' must be dereferenceable to a 'char' value. The
65/// // behavior is undefined unless an object is associated with this
66/// // parser.
67/// @endcode
68///
69/// ## Usage {#balxml_listparser-usage}
70///
71///
72/// This section illustrates intended use of this component.
73///
74/// ### Example 1: Basic Usage {#balxml_listparser-example-1-basic-usage}
75///
76///
77/// The following snippets of code illustrate the usage of this component.
78/// Suppose you had an input stream that contained a list of doubles. The
79/// following `loadDoublesFromListStream` function loads this data into an
80/// `bsl::vector<double>`:
81/// @code
82/// #include <balxml_listparser.h>
83///
84/// #include <bdlt_date.h>
85///
86/// #include <istream>
87/// #include <iterator>
88/// #include <vector>
89/// #include <sstream>
90/// #include <string>
91///
92/// using namespace BloombergLP;
93///
94/// int parseDouble(double *result, const char *data, int dataLength);
95///
96/// int loadDoublesFromListStream(bsl::vector<double> *result,
97/// bsl::istream& stream)
98/// {
99/// enum { k_FAILURE = -1 };
100///
101/// balxml::ListParser<bsl::vector<double> > parser(&parseDouble);
102///
103/// if (0 != parser.beginParse(result)) {
104/// return k_FAILURE;
105/// }
106///
107/// if (0 != parser.pushCharacters(bsl::istreambuf_iterator<char>(stream),
108/// bsl::istreambuf_iterator<char>())) {
109/// return k_FAILURE;
110/// }
111///
112/// return parser.endParse();
113/// }
114/// @endcode
115/// The `parseDouble` function is implemented as follows:
116/// @code
117/// int parseDouble(double *result, const char *data, int dataLength)
118/// {
119/// bsl::stringstream ss(bsl::string(data, dataLength));
120/// ss >> (*result);
121/// return 0;
122/// }
123/// @endcode
124/// The following function demonstrates the `loadDoublesFromListStream`
125/// function:
126/// @code
127/// void usageExample()
128/// {
129/// const char INPUT[] = "1.5 2.0 3.8 1.0";
130///
131/// bsl::vector<double> vec;
132/// bsl::istringstream iss(INPUT);
133///
134/// int result = loadDoublesFromListStream(&vec, iss);
135///
136/// assert(0 == result);
137/// assert(4 == vec.size());
138/// assert(1.5 == vec[0]);
139/// assert(2.0 == vec[1]);
140/// assert(3.8 == vec[2]);
141/// assert(1.0 == vec[3]);
142/// }
143/// @endcode
144/// @}
145/** @} */
146/** @} */
147
148/** @addtogroup bal
149 * @{
150 */
151/** @addtogroup balxml
152 * @{
153 */
154/** @addtogroup balxml_listparser
155 * @{
156 */
157
158#include <balscm_version.h>
159
160#include <bdlat_arrayfunctions.h>
161
162#include <bslalg_typetraits.h>
163
164#include <bdlf_bind.h>
165#include <bdlf_placeholder.h>
166
167#include <bdlb_chartype.h>
168
169#include <bsls_assert.h>
170#include <bsls_review.h>
171
172#include <bsl_functional.h>
173#include <bsl_memory.h>
174#include <bsl_string.h>
175
176
177
178namespace balxml {
179 // ======================
180 // class ListParser<TYPE>
181 // ======================
182
183/// This is a push parser for lists.
184///
185/// See @ref balxml_listparser
186template <class TYPE>
188
189 // PRIVATE TYPES
190 typedef typename
192
193 public:
194 // TYPES
195 typedef int (*ParseElementFunction)(ElementType*, const char*, int);
196 typedef bsl::function<int(ElementType*, const char*, int)>
198
199 private:
200 // PRIVATE DATA MEMBERS
201 bsl::string d_characters; // accumulated characters
202 TYPE *d_object_p; // associated object
203 ParseElementCallback d_parseElementCallback; // callback for parsing
204 // elements
205
206 // NOT IMPLEMENTED
207 ListParser(const ListParser&);
208 ListParser& operator=(const ListParser&);
209
210 // PRIVATE MANIPULATORS
211
212 /// Append an element to the associated object having the specified
213 /// `data` of the specified `dataLength`.
214 int appendElement(const char *data, int dataLength);
215
216 public:
217 // CREATORS
218
219 /// Create a parser for lists using the specified `parseElementCallback`
220 /// functor to parse each element and the optionally specified
221 /// `basicAllocator` for supplying memory. If `basicAllocator` is 0,
222 /// the currently installed default allocator will be used.
223 explicit ListParser(ParseElementCallback parseElementCallback,
224 bslma::Allocator *basicAllocator = 0);
225
226#ifdef DOXYGEN // Generated by compiler:
227
228 ~ListParser();
229 // Destroy this object.
230
231#endif
232
233 /// Prepare the parser to start parsing a new value and associate the
234 /// specified `object` with the parser. Return 0 if successful and
235 /// non-zero otherwise.
236 int beginParse(TYPE *object);
237
238 /// Ends the parse operation and store the value parsed from the pushed
239 /// characters into the associated object. Return 0 if successful and
240 /// non-zero otherwise. The behavior is undefined unless an object is
241 /// associated with this parser. Upon successful completion, the parser
242 /// will be disassociated with the object.
243 int endParse();
244
245 /// Push the characters ranging from the specified `begin` up to (but
246 /// not including) the specified `end` into this parser. Return 0 if
247 /// successful and non-zero otherwise. The parameterized
248 /// `INPUT_ITERATOR` must be dereferenceable to a `char` value. The
249 /// behavior is undefined unless an object is associated with this
250 /// parser.
251 template <class INPUT_ITERATOR>
252 int pushCharacters(INPUT_ITERATOR begin, INPUT_ITERATOR end);
253};
254
255// ============================================================================
256// INLINE DEFINITIONS
257// ============================================================================
258
259 // ----------------------
260 // class ListParser<TYPE>
261 // ----------------------
262
263// PRIVATE MANIPULATORS
264
265template <class TYPE>
266int ListParser<TYPE>::appendElement(const char *data, int dataLength)
267{
268 BSLS_ASSERT(data);
269 BSLS_ASSERT(0 < dataLength);
270
271 enum { k_SUCCESS = 0, k_FAILURE = -1 };
272
273 const int i = static_cast<int>(bdlat_ArrayFunctions::size(*d_object_p));
274
275 bdlat_ArrayFunctions::resize(d_object_p, i + 1);
276
277 typedef bsl::function<int(ElementType*)> Functor;
278
280
281 Functor parseElementFunctor = bdlf::BindUtil::bind(d_parseElementCallback,
282 _1,
283 data,
284 dataLength);
285
286 if (0 != bdlat_ArrayFunctions::manipulateElement(d_object_p,
287 parseElementFunctor,
288 i)) {
289 // remove the new object from the array
290 bdlat_ArrayFunctions::resize(d_object_p, i);
291
292 return k_FAILURE; // RETURN
293 }
294
295 return k_SUCCESS;
296}
297
298// CREATORS
299
300template <class TYPE>
302 bslma::Allocator *basicAllocator)
303: d_characters(basicAllocator)
304, d_object_p(0)
305, d_parseElementCallback(bsl::allocator_arg_t(),
306 bsl::allocator<ParseElementCallback>(basicAllocator),
307 parseElementCallback)
308{
309}
310
311// MANIPULATORS
312
313template <class TYPE>
315{
316 BSLS_ASSERT(object);
317
318 enum { k_SUCCESS = 0 };
319
320 d_characters.clear();
321 d_object_p = object;
322
323 bdlat_ArrayFunctions::resize(d_object_p, 0);
324
325 return k_SUCCESS;
326}
327
328template <class TYPE>
330{
331 BSLS_ASSERT(d_object_p);
332
333 enum { k_SUCCESS = 0, k_FAILURE = -1 };
334
335 if (!d_characters.empty()) {
336 if (0 != appendElement(d_characters.data(),
337 static_cast<int>(d_characters.length()))) {
338 return k_FAILURE; // RETURN
339 }
340 }
341
342 d_object_p = 0;
343
344 return k_SUCCESS;
345}
346
347template <class TYPE>
348template <class INPUT_ITERATOR>
349int ListParser<TYPE>::pushCharacters(INPUT_ITERATOR begin, INPUT_ITERATOR end)
350{
351 BSLS_ASSERT(d_object_p);
352
353 enum { k_SUCCESS = 0, k_FAILURE = -1 };
354
355 while (begin != end) {
356 const char character = *begin;
357
358 ++begin;
359
360 if (bdlb::CharType::isSpace(character)) {
361 if (!d_characters.empty()) {
362 if (0 != appendElement(
363 d_characters.data(),
364 static_cast<int>(d_characters.length()))) {
365 return k_FAILURE; // RETURN
366 }
367
368 d_characters.clear();
369 }
370 }
371 else {
372 d_characters.push_back(character);
373 }
374 }
375
376 return k_SUCCESS;
377}
378
379} // close package namespace
380
381
382#endif // ! defined(INCLUDED_BAEXML_LISTPARSER)
383
384// ----------------------------------------------------------------------------
385// Copyright 2015 Bloomberg Finance L.P.
386//
387// Licensed under the Apache License, Version 2.0 (the "License");
388// you may not use this file except in compliance with the License.
389// You may obtain a copy of the License at
390//
391// http://www.apache.org/licenses/LICENSE-2.0
392//
393// Unless required by applicable law or agreed to in writing, software
394// distributed under the License is distributed on an "AS IS" BASIS,
395// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
396// See the License for the specific language governing permissions and
397// limitations under the License.
398// ----------------------------- END-OF-FILE ----------------------------------
399
400/** @} */
401/** @} */
402/** @} */
Definition balxml_listparser.h:187
int(* ParseElementFunction)(ElementType *, const char *, int)
Definition balxml_listparser.h:195
int pushCharacters(INPUT_ITERATOR begin, INPUT_ITERATOR end)
Definition balxml_listparser.h:349
int endParse()
Definition balxml_listparser.h:329
int beginParse(TYPE *object)
Definition balxml_listparser.h:314
bsl::function< int(ElementType *, const char *, int)> ParseElementCallback
Definition balxml_listparser.h:197
static Bind< bslmf::Nil, t_FUNC, Bind_BoundTuple0 > bind(t_FUNC func)
Definition bdlf_bind.h:1830
Definition bslstl_string.h:1281
Forward declaration.
Definition bslstl_function.h:934
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
int manipulateElement(TYPE *array, MANIPULATOR &manipulator, int index)
void resize(TYPE *array, int newSize)
bsl::size_t size(const TYPE &array)
Return the number of elements in the specified array.
const PlaceHolder< 1 > _1
Definition bdlb_printmethods.h:283
Definition bdlat_arrayfunctions.h:712
static bool isSpace(char character)
Definition bdlb_chartype.h:842