reSIProcate
SIP stack, Dialog Usage Manager and related libraries
Loading...
Searching...
No Matches
ParserContainer.hxx
Go to the documentation of this file.
1#ifndef RESIP_ParserContainer_hxx
2#define RESIP_ParserContainer_hxx
3
4#include <algorithm>
5#include <iterator>
6
9
10namespace resip
11{
12using std::ptrdiff_t;
21template<class T>
23{
24 public:
25 typedef T value_type;
27 typedef const value_type* const_pointer;
30 typedef ptrdiff_t difference_type;
31
38
40 : ParserContainerBase(Headers::UNKNOWN,pool)
41 {}
42
51 {
52 mParsers.reserve(hfvs->size());
54 i != hfvs->end(); i++)
55 {
56 // create, store without copying --
57 // keeps the HeaderFieldValue from reallocating its buffer
58 mParsers.push_back(HeaderKit::Empty);
59 mParsers.back().hfv.init(i->getBuffer(),i->getLength(),false);
60 }
61 }
62
64 Headers::Type type,
65 PoolBase& pool)
66 : ParserContainerBase(type,pool)
67 {
68 mParsers.reserve(hfvs->size());
70 i != hfvs->end(); i++)
71 {
72 // create, store without copying --
73 // keeps the HeaderFieldValue from reallocating its buffer
74 mParsers.push_back(HeaderKit::Empty);
75 mParsers.back().hfv.init(i->getBuffer(),i->getLength(),false);
76 }
77 }
78
83 : ParserContainerBase(other)
84 {}
85
90 : ParserContainerBase(other, pool)
91 {}
92
97 {
98 return static_cast<ParserContainer&>(ParserContainerBase::operator=(other));
99 }
100
104 T& front()
105 {
106 return ensureInitialized(mParsers.front(),this);
107 }
108
112 T& back()
113 {
114 return ensureInitialized(mParsers.back(),this);
115 }
116
120 const T& front() const
121 {
122 return ensureInitialized(mParsers.front(),this);
123 }
124
128 const T& back() const
129 {
130 return ensureInitialized(mParsers.back(),this);
131 }
132
137 T* getByIndex(size_t index)
138 {
139 if (index >= mParsers.size()) return nullptr;
140 return &ensureInitialized(mParsers[index], this);
141 }
142
143 const T* getByIndex(size_t index) const
144 {
145 if (index >= mParsers.size()) return nullptr;
146 return &ensureInitialized(mParsers[index], this);
147 }
148
152 void push_front(const T & t)
153 {
154 mParsers.insert(mParsers.begin(), HeaderKit::Empty);
155 mParsers.front().pc=makeParser(t);
156 }
157
161 void push_back(const T & t)
162 {
163 mParsers.push_back(HeaderKit::Empty);
164 mParsers.back().pc=makeParser(t);
165 }
166
172 {
173 ParserContainer tmp(*this);
174 std::reverse(tmp.mParsers.begin(), tmp.mParsers.end());
175 return tmp;
176 }
177
179 // .dlb. these can be partially hoisted as well
180 class const_iterator;
181
185 class iterator //: public std::iterator<std::bidirectional_iterator_tag, T> // Note: std::iterator deprecated in C++17 usings below cover same functionality
186 {
187 public:
188 using iterator_category = std::bidirectional_iterator_tag;
189 using value_type = T;
190 using difference_type = std::ptrdiff_t;
191 using pointer = T*;
192 using reference = T&;
193
194 iterator(typename Parsers::iterator i,ParserContainer* ref) : mIt(i),mRef(ref){}
195 iterator() : mRef(0) {}
196 iterator(const iterator& orig) : mIt(orig.mIt), mRef(orig.mRef) {}
197
198 iterator operator++() {iterator it(++mIt,mRef); return it;}
199 iterator operator++(int) {iterator it(mIt++,mRef); return it;}
200 iterator operator--() {iterator it(--mIt,mRef); return it;}
201 iterator operator--(int) {iterator it(mIt--,mRef); return it;}
202 friend bool operator!=(const iterator& lhs, const iterator& rhs) { return lhs.mIt != rhs.mIt; }
203 friend bool operator==(const iterator& lhs, const iterator& rhs) { return lhs.mIt == rhs.mIt; }
205 {
206 if (&rhs != this)
207 {
208 mIt = rhs.mIt;
209 mRef = rhs.mRef;
210 }
211 return *this;
212 }
213 T& operator*() {return ensureInitialized(*mIt,mRef);}
214 T* operator->() {return &ensureInitialized(*mIt,mRef);}
215 private:
216 typename Parsers::iterator mIt;
217 ParserContainer* mRef;
218 friend class const_iterator;
219 friend class ParserContainer;
220 };
221
225 class const_iterator //: public std::iterator<std::bidirectional_iterator_tag, T> // Note: std::iterator deprecated in C++17 usings below cover same functionality
226 {
227 public:
228 using iterator_category = std::bidirectional_iterator_tag;
229 using value_type = T;
230 using difference_type = std::ptrdiff_t;
231 using pointer = T*;
232 using reference = T&;
233
234 const_iterator(Parsers::const_iterator i,const ParserContainer* ref) : mIt(i),mRef(ref){}
235 const_iterator(const const_iterator& orig) : mIt(orig.mIt), mRef(orig.mRef) {}
236 const_iterator(const iterator& orig) : mIt(orig.mIt), mRef(orig.mRef) {}
237 const_iterator() : mRef(0) {}
238
239 const_iterator operator++() {const_iterator it(++mIt,mRef); return it;}
240 const_iterator operator++(int) {const_iterator it(mIt++,mRef); return it;}
241 const_iterator operator--() {const_iterator it(--mIt,mRef); return it;}
242 const_iterator operator--(int) {const_iterator it(mIt--,mRef); return it;}
243 friend bool operator!=(const const_iterator& lhs, const const_iterator& rhs) { return lhs.mIt != rhs.mIt; }
244 friend bool operator==(const const_iterator& lhs, const const_iterator& rhs) { return lhs.mIt == rhs.mIt; }
246 {
247 if (&rhs != this)
248 {
249 mIt = rhs.mIt;
250 mRef = rhs.mRef;
251 }
252 return *this;
253 }
255 {
256 mIt = rhs.mIt;
257 mRef = rhs.mRef;
258 return *this;
259 }
260 const T& operator*() {return ensureInitialized(*mIt,mRef);}
261 const T* operator->() {return &ensureInitialized(*mIt,mRef);}
262 private:
263 friend class iterator;
264 typename Parsers::const_iterator mIt;
265 const ParserContainer* mRef;
266 };
267
271 iterator begin() { return iterator(mParsers.begin(),this); }
272
276 iterator end() { return iterator(mParsers.end(),this); }
277
283 {
284 freeParser(*i.mIt);
285 return iterator(mParsers.erase(i.mIt),this);
286 }
287
291 bool find(const T& rhs) const
292 {
293 for (typename Parsers::const_iterator i = mParsers.begin();
294 i != mParsers.end(); ++i)
295 {
296 // operator== defined by default, but often not usefully
297 if (rhs.isEqual(ensureInitialized(*i,this)))
298 {
299 return true;
300 }
301 }
302
303 return false;
304 }
305
310 virtual void parseAll()
311 {
312 for (typename Parsers::const_iterator i = mParsers.begin();
313 i != mParsers.end(); ++i)
314 {
315 ensureInitialized(*i,this).checkParsed();
316 }
317 }
318
323 const_iterator begin() const { return const_iterator(mParsers.begin(),this); }
324
329 const_iterator end() const { return const_iterator(mParsers.end(),this); }
330
334 virtual ParserContainerBase* clone() const
335 {
336 return new ParserContainer(*this);
337 }
338
339 private:
340 friend class ParserContainer<T>::iterator;
341 friend class ParserContainer<T>::const_iterator;
342
346 static T& ensureInitialized(HeaderKit& kit, ParserContainer* ref)
347 {
348 if(!kit.pc)
349 {
350 if(ref)
351 {
352 PoolBase* pool(ref->mPool);
353 kit.pc=new (pool) T(kit.hfv, ref->mType, pool);
354 }
355 else
356 {
357 kit.pc=new T(kit.hfv, Headers::NONE);
358 }
359 }
360 return *static_cast<T*>(kit.pc);
361 }
362
363 static const T& ensureInitialized(const HeaderKit& kit,
364 const ParserContainer* ref)
365 {
366 if(!kit.pc)
367 {
368 HeaderKit& nc_kit(const_cast<HeaderKit&>(kit));
369 if(ref)
370 {
371 ParserContainer* nc_ref(const_cast<ParserContainer*>(ref));
372 PoolBase* pool(nc_ref->mPool);
373 nc_kit.pc=new (pool) T(kit.hfv, ref->mType, pool);
374 }
375 else
376 {
377 nc_kit.pc=new T(kit.hfv, Headers::NONE);
378 }
379 }
380 return *static_cast<T*>(kit.pc);
381 }
382};
383
384template <class T>
387{
388 s << "[";
389 for (typename resip::ParserContainer <T>::const_iterator i = c.begin();
390 i != c.end(); i++)
391 {
392 if (i != c.begin())
393 {
394 s << ", ";
395 }
396 // recurse
397 insert(s, *i);
398 }
399 s << "]";
400 return s;
401}
402
403}
404
405#endif
406
407/* ====================================================================
408 * The Vovida Software License, Version 1.0
409 *
410 * Copyright (c) 2026 SIP Spectrum, Inc. https://www.sipspectrum.com
411 * Copyright (c) 2000-2005 Vovida Networks, Inc. All rights reserved.
412 *
413 * Redistribution and use in source and binary forms, with or without
414 * modification, are permitted provided that the following conditions
415 * are met:
416 *
417 * 1. Redistributions of source code must retain the above copyright
418 * notice, this list of conditions and the following disclaimer.
419 *
420 * 2. Redistributions in binary form must reproduce the above copyright
421 * notice, this list of conditions and the following disclaimer in
422 * the documentation and/or other materials provided with the
423 * distribution.
424 *
425 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
426 * and "Vovida Open Communication Application Library (VOCAL)" must
427 * not be used to endorse or promote products derived from this
428 * software without prior written permission. For written
429 * permission, please contact vocal@vovida.org.
430 *
431 * 4. Products derived from this software may not be called "VOCAL", nor
432 * may "VOCAL" appear in their name, without prior written
433 * permission of Vovida Networks, Inc.
434 *
435 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
436 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
437 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
438 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
439 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
440 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
441 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
442 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
443 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
444 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
445 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
446 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
447 * DAMAGE.
448 *
449 * ====================================================================
450 *
451 * This software consists of voluntary contributions made by Vovida
452 * Networks, Inc. and many individuals on behalf of Vovida Networks,
453 * Inc. For more information on Vovida Networks, Inc., please see
454 * <http://www.vovida.org/>.
455 *
456 */
Maps from header name to derived ParserCategory.
Abstract Base class implemented in derived class ParserContainer.
std::vector< HeaderKit, StlPoolAllocator< HeaderKit, PoolBase > > Parsers
ParserCategory * makeParser(const ParserCategory &orig)
ParserContainerBase & operator=(const ParserContainerBase &rhs)
assignment operator copies the mParsers from the rhs
Parsers mParsers
the actual list (vector) of parsers on which encoding is done
A const_iterator class (bidirectional)
friend bool operator!=(const const_iterator &lhs, const const_iterator &rhs)
const_iterator(Parsers::const_iterator i, const ParserContainer *ref)
const_iterator & operator=(const iterator &rhs)
std::bidirectional_iterator_tag iterator_category
friend bool operator==(const const_iterator &lhs, const const_iterator &rhs)
const_iterator & operator=(const const_iterator &rhs)
const_iterator(const const_iterator &orig)
An iterator class (bidirectional)
std::bidirectional_iterator_tag iterator_category
friend bool operator==(const iterator &lhs, const iterator &rhs)
iterator & operator=(const iterator &rhs)
iterator(typename Parsers::iterator i, ParserContainer *ref)
friend bool operator!=(const iterator &lhs, const iterator &rhs)
Container class for ParserCategory, used by SipMessage to represent multi-valued headers (Contact,...
ParserContainer(const ParserContainer &other)
Copy c'tor.
const value_type & const_reference
ParserContainer reverse() const
Returns a copy of this ParserContainer, in reverse order.
iterator end()
Returns an iterator pointing to the last header field value.
T & back()
Returns the last header field value in this container.
ParserContainer & operator=(const ParserContainer &other)
Assignment operator.
ParserContainer(PoolBase &pool)
T & front()
Returns the first header field value in this container.
virtual void parseAll()
Triggers a parse of all contained header field values.
const T & back() const
Returns the last header field value in this container.
virtual ParserContainerBase * clone() const
Clones this container, and all contained header field values.
ParserContainer(HeaderFieldValueList *hfvs, Headers::Type type, PoolBase &pool)
const_iterator end() const
Returns a const_iterator pointing to the first header field value.
T * getByIndex(size_t index)
Returns a pointer to the header field value at the given 0-based index, or nullptr if the index is ou...
iterator erase(iterator i)
Erases the header field value pointed to by i.
ParserContainer()
Default c'tor.
ParserContainerBase::Parsers Parsers
iterator begin()
Returns an iterator pointing to the first header field value.
void push_front(const T &t)
Inserts a header field value at the front of this container.
ParserContainer(HeaderFieldValueList *hfvs, Headers::Type type=Headers::UNKNOWN)
ParserContainer(const ParserContainer &other, PoolBase &pool)
Copy c'tor.
const value_type * const_pointer
const T * getByIndex(size_t index) const
void push_back(const T &t)
Inserts a header field value at the back of this container.
const_iterator begin() const
Returns a const_iterator pointing to the first header field value.
const T & front() const
Returns the first header field value in this container.
bool find(const T &rhs) const
Finds the first header field value that matches rhs.
dcm! – add UnusedChecking(_enum) below;
EncodeStream & insert(EncodeStream &s, const std::vector< T > &c)
Completely generic insert function.
Definition Inserter.hxx:76
#define EncodeStream
void list()
Definition userAdmin.cxx:66