|
reSIProcate/stack
9694
|
00001 #ifndef RESIP_ParserContainer_hxx 00002 #define RESIP_ParserContainer_hxx 00003 00004 #include <algorithm> 00005 #include <iterator> 00006 00007 #include "resip/stack/HeaderFieldValueList.hxx" 00008 #include "resip/stack/ParserContainerBase.hxx" 00009 00010 namespace resip 00011 { 00012 using std::ptrdiff_t; 00021 template<class T> 00022 class ParserContainer : public ParserContainerBase 00023 { 00024 public: 00025 typedef T value_type; 00026 typedef value_type* pointer; 00027 typedef const value_type* const_pointer; 00028 typedef value_type& reference; 00029 typedef const value_type& const_reference; 00030 typedef ptrdiff_t difference_type; 00031 00035 ParserContainer() 00036 : ParserContainerBase(Headers::UNKNOWN) 00037 {} 00038 00039 ParserContainer(PoolBase& pool) 00040 : ParserContainerBase(Headers::UNKNOWN,pool) 00041 {} 00042 00048 ParserContainer(HeaderFieldValueList* hfvs, 00049 Headers::Type type = Headers::UNKNOWN) 00050 : ParserContainerBase(type) 00051 { 00052 mParsers.reserve(hfvs->size()); 00053 for (HeaderFieldValueList::iterator i = hfvs->begin(); 00054 i != hfvs->end(); i++) 00055 { 00056 // create, store without copying -- 00057 // keeps the HeaderFieldValue from reallocating its buffer 00058 mParsers.push_back(HeaderKit::Empty); 00059 mParsers.back().hfv.init(i->getBuffer(),i->getLength(),false); 00060 } 00061 } 00062 00063 ParserContainer(HeaderFieldValueList* hfvs, 00064 Headers::Type type, 00065 PoolBase& pool) 00066 : ParserContainerBase(type,pool) 00067 { 00068 mParsers.reserve(hfvs->size()); 00069 for (HeaderFieldValueList::iterator i = hfvs->begin(); 00070 i != hfvs->end(); i++) 00071 { 00072 // create, store without copying -- 00073 // keeps the HeaderFieldValue from reallocating its buffer 00074 mParsers.push_back(HeaderKit::Empty); 00075 mParsers.back().hfv.init(i->getBuffer(),i->getLength(),false); 00076 } 00077 } 00078 00082 ParserContainer(const ParserContainer& other) 00083 : ParserContainerBase(other) 00084 {} 00085 00089 ParserContainer(const ParserContainer& other, PoolBase& pool) 00090 : ParserContainerBase(other, pool) 00091 {} 00092 00096 ParserContainer& operator=(const ParserContainer& other) 00097 { 00098 return static_cast<ParserContainer&>(ParserContainerBase::operator=(other)); 00099 } 00100 00104 T& front() 00105 { 00106 return ensureInitialized(mParsers.front(),this); 00107 } 00108 00112 T& back() 00113 { 00114 return ensureInitialized(mParsers.back(),this); 00115 } 00116 00120 const T& front() const 00121 { 00122 return ensureInitialized(mParsers.front(),this); 00123 } 00124 00128 const T& back() const 00129 { 00130 return ensureInitialized(mParsers.back(),this); 00131 } 00132 00136 void push_front(const T & t) 00137 { 00138 mParsers.insert(mParsers.begin(), HeaderKit::Empty); 00139 mParsers.front().pc=makeParser(t); 00140 } 00141 00145 void push_back(const T & t) 00146 { 00147 mParsers.push_back(HeaderKit::Empty); 00148 mParsers.back().pc=makeParser(t); 00149 } 00150 00155 ParserContainer reverse() const 00156 { 00157 ParserContainer tmp(*this); 00158 std::reverse(tmp.mParsers.begin(), tmp.mParsers.end()); 00159 return tmp; 00160 } 00161 00162 typedef ParserContainerBase::Parsers Parsers; 00163 // .dlb. these can be partially hoisted as well 00164 class const_iterator; 00165 00169 class iterator : public std::iterator<std::bidirectional_iterator_tag, T> 00170 { 00171 public: 00172 iterator(typename Parsers::iterator i,ParserContainer* ref) : mIt(i),mRef(ref){} 00173 iterator() : mRef(0) {} 00174 iterator(const iterator& orig) : mIt(orig.mIt), mRef(orig.mRef) {} 00175 00176 iterator operator++() {iterator it(++mIt,mRef); return it;} 00177 iterator operator++(int) {iterator it(mIt++,mRef); return it;} 00178 iterator operator--() {iterator it(--mIt,mRef); return it;} 00179 iterator operator--(int) {iterator it(mIt--,mRef); return it;} 00180 bool operator!=(const iterator& rhs) { return mIt != rhs.mIt; } 00181 bool operator==(const iterator& rhs) { return mIt == rhs.mIt; } 00182 bool operator!=(const const_iterator& rhs) { return mIt != rhs.mIt; } 00183 bool operator==(const const_iterator& rhs) { return mIt == rhs.mIt; } 00184 iterator& operator=(const iterator& rhs) 00185 { 00186 mIt = rhs.mIt; 00187 mRef = rhs.mRef; 00188 return *this; 00189 } 00190 T& operator*() {return ensureInitialized(*mIt,mRef);} 00191 T* operator->() {return &ensureInitialized(*mIt,mRef);} 00192 private: 00193 typename Parsers::iterator mIt; 00194 ParserContainer* mRef; 00195 friend class const_iterator; 00196 friend class ParserContainer; 00197 }; 00198 00203 class const_iterator : public std::iterator<std::bidirectional_iterator_tag, T> 00204 { 00205 public: 00206 const_iterator(Parsers::const_iterator i,const ParserContainer* ref) : mIt(i),mRef(ref){} 00207 const_iterator(const const_iterator& orig) : mIt(orig.mIt), mRef(orig.mRef) {} 00208 const_iterator(const iterator& orig) : mIt(orig.mIt), mRef(orig.mRef) {} 00209 const_iterator() : mRef(0) {} 00210 00211 const_iterator operator++() {const_iterator it(++mIt,mRef); return it;} 00212 const_iterator operator++(int) {const_iterator it(mIt++,mRef); return it;} 00213 const_iterator operator--() {const_iterator it(--mIt,mRef); return it;} 00214 const_iterator operator--(int) {const_iterator it(mIt--,mRef); return it;} 00215 bool operator!=(const const_iterator& rhs) { return mIt != rhs.mIt; } 00216 bool operator==(const const_iterator& rhs) { return mIt == rhs.mIt; } 00217 bool operator!=(const iterator& rhs) { return mIt != rhs.mIt; } 00218 bool operator==(const iterator& rhs) { return mIt == rhs.mIt; } 00219 const_iterator& operator=(const const_iterator& rhs) 00220 { 00221 mIt = rhs.mIt; 00222 mRef = rhs.mRef; 00223 return *this; 00224 } 00225 const_iterator& operator=(const iterator& rhs) 00226 { 00227 mIt = rhs.mIt; 00228 mRef = rhs.mRef; 00229 return *this; 00230 } 00231 const T& operator*() {return ensureInitialized(*mIt,mRef);} 00232 const T* operator->() {return &ensureInitialized(*mIt,mRef);} 00233 private: 00234 friend class iterator; 00235 typename Parsers::const_iterator mIt; 00236 const ParserContainer* mRef; 00237 }; 00238 00242 iterator begin() { return iterator(mParsers.begin(),this); } 00243 00247 iterator end() { return iterator(mParsers.end(),this); } 00248 00253 iterator erase(iterator i) 00254 { 00255 freeParser(*i.mIt); 00256 return iterator(mParsers.erase(i.mIt),this); 00257 } 00258 00262 bool find(const T& rhs) const 00263 { 00264 for (typename Parsers::const_iterator i = mParsers.begin(); 00265 i != mParsers.end(); ++i) 00266 { 00267 // operator== defined by default, but often not usefully 00268 if (rhs.isEqual(ensureInitialized(*i,this))) 00269 { 00270 return true; 00271 } 00272 } 00273 00274 return false; 00275 } 00276 00281 virtual void parseAll() 00282 { 00283 for (typename Parsers::const_iterator i = mParsers.begin(); 00284 i != mParsers.end(); ++i) 00285 { 00286 ensureInitialized(*i,this).checkParsed(); 00287 } 00288 } 00289 00294 const_iterator begin() const { return const_iterator(mParsers.begin(),this); } 00295 00300 const_iterator end() const { return const_iterator(mParsers.end(),this); } 00301 00305 virtual ParserContainerBase* clone() const 00306 { 00307 return new ParserContainer(*this); 00308 } 00309 00310 private: 00311 friend class ParserContainer<T>::iterator; 00312 friend class ParserContainer<T>::const_iterator; 00313 00317 static T& ensureInitialized(HeaderKit& kit, ParserContainer* ref) 00318 { 00319 if(!kit.pc) 00320 { 00321 if(ref) 00322 { 00323 PoolBase* pool(ref->mPool); 00324 kit.pc=new (pool) T(kit.hfv, ref->mType, pool); 00325 } 00326 else 00327 { 00328 kit.pc=new T(kit.hfv, Headers::NONE); 00329 } 00330 } 00331 return *static_cast<T*>(kit.pc); 00332 } 00333 00334 static const T& ensureInitialized(const HeaderKit& kit, 00335 const ParserContainer* ref) 00336 { 00337 if(!kit.pc) 00338 { 00339 HeaderKit& nc_kit(const_cast<HeaderKit&>(kit)); 00340 if(ref) 00341 { 00342 ParserContainer* nc_ref(const_cast<ParserContainer*>(ref)); 00343 PoolBase* pool(nc_ref->mPool); 00344 nc_kit.pc=new (pool) T(kit.hfv, ref->mType, pool); 00345 } 00346 else 00347 { 00348 nc_kit.pc=new T(kit.hfv, Headers::NONE); 00349 } 00350 } 00351 return *static_cast<T*>(kit.pc); 00352 } 00353 }; 00354 00355 template <class T> 00356 EncodeStream& 00357 insert(EncodeStream& s, const resip::ParserContainer<T>& c) 00358 { 00359 s << "["; 00360 for (typename resip::ParserContainer <T>::const_iterator i = c.begin(); 00361 i != c.end(); i++) 00362 { 00363 if (i != c.begin()) 00364 { 00365 s << ", "; 00366 } 00367 // recurse 00368 insert(s, *i); 00369 } 00370 s << "]"; 00371 return s; 00372 } 00373 00374 } 00375 00376 #endif 00377 00378 /* ==================================================================== 00379 * The Vovida Software License, Version 1.0 00380 * 00381 * Copyright (c) 2000-2005 00382 * 00383 * Redistribution and use in source and binary forms, with or without 00384 * modification, are permitted provided that the following conditions 00385 * are met: 00386 * 00387 * 1. Redistributions of source code must retain the above copyright 00388 * notice, this list of conditions and the following disclaimer. 00389 * 00390 * 2. Redistributions in binary form must reproduce the above copyright 00391 * notice, this list of conditions and the following disclaimer in 00392 * the documentation and/or other materials provided with the 00393 * distribution. 00394 * 00395 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00396 * and "Vovida Open Communication Application Library (VOCAL)" must 00397 * not be used to endorse or promote products derived from this 00398 * software without prior written permission. For written 00399 * permission, please contact vocal@vovida.org. 00400 * 00401 * 4. Products derived from this software may not be called "VOCAL", nor 00402 * may "VOCAL" appear in their name, without prior written 00403 * permission of Vovida Networks, Inc. 00404 * 00405 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00406 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00407 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00408 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00409 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00410 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00411 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00412 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00413 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00414 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00415 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00416 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00417 * DAMAGE. 00418 * 00419 * ==================================================================== 00420 * 00421 * This software consists of voluntary contributions made by Vovida 00422 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00423 * Inc. For more information on Vovida Networks, Inc., please see 00424 * <http://www.vovida.org/>. 00425 * 00426 */
1.7.5.1