reSIProcate/stack  9694
ParserContainerBase.cxx
Go to the documentation of this file.
00001 #include <cassert>
00002 
00003 #include "resip/stack/ParserContainerBase.hxx"
00004 #include "resip/stack/Embedded.hxx"
00005 
00006 using namespace resip;
00007 using namespace std;;
00008 
00009 const ParserContainerBase::HeaderKit ParserContainerBase::HeaderKit::Empty;
00010 
00011 ParserContainerBase::ParserContainerBase(Headers::Type type)
00012    : mType(type),
00013      mPool(0)
00014 {}
00015 
00016 ParserContainerBase::ParserContainerBase(const ParserContainerBase& rhs)
00017    : mType(rhs.mType),
00018      mParsers(),
00019      mPool(0)
00020 {
00021    copyParsers(rhs.mParsers);
00022 }
00023 
00024 ParserContainerBase::ParserContainerBase(Headers::Type type,
00025                                           PoolBase& pool)
00026    : mType(type),
00027      mParsers(StlPoolAllocator<HeaderKit, PoolBase>(&pool)),
00028      mPool(&pool)
00029 {}
00030 
00031 ParserContainerBase::ParserContainerBase(const ParserContainerBase& rhs,
00032                                           PoolBase& pool)
00033    : mType(rhs.mType),
00034      mParsers(StlPoolAllocator<HeaderKit, PoolBase>(&pool)),
00035      mPool(&pool)
00036 {
00037    copyParsers(rhs.mParsers);
00038 }
00039 
00040 ParserContainerBase::~ParserContainerBase()
00041 {
00042    freeParsers();
00043 }
00044 
00045 ParserContainerBase&
00046 ParserContainerBase::operator=(const ParserContainerBase& rhs)
00047 {
00048    if (this != &rhs)
00049    {
00050       freeParsers();
00051       mParsers.clear();
00052       copyParsers(rhs.mParsers);
00053    }
00054    return *this;
00055 }
00056 
00057 void
00058 ParserContainerBase::pop_front() 
00059 {
00060    assert(!mParsers.empty());
00061    freeParser(mParsers.front());
00062    mParsers.erase(mParsers.begin());
00063 }
00064  
00065 void
00066 ParserContainerBase::pop_back() 
00067 {
00068    assert(!mParsers.empty());
00069    freeParser(mParsers.back());
00070    mParsers.pop_back(); 
00071 }
00072 
00073 void
00074 ParserContainerBase::append(const ParserContainerBase& source) 
00075 {
00076    copyParsers(source.mParsers);
00077 }
00078 
00079 EncodeStream& 
00080 ParserContainerBase::encode(const Data& headerName, 
00081                             EncodeStream& str) const
00082 {
00083    // !jf! this is not strictly correct since some headers are allowed to
00084    // be empty: Supported, Accept-Encoding, Allow-Events, Allow,
00085    // Accept,Accept-Language 
00086    if (!mParsers.empty())
00087    {
00088       if (!headerName.empty())
00089       {
00090          str << headerName << Symbols::COLON[0] << Symbols::SPACE[0];
00091       }
00092          
00093       for (Parsers::const_iterator i = mParsers.begin(); 
00094            i != mParsers.end(); ++i)
00095       {
00096          if (i != mParsers.begin())
00097          {
00098             if (Headers::isCommaEncoding(mType))
00099             {
00100                str << Symbols::COMMA[0] << Symbols::SPACE[0];
00101             }
00102             else
00103             {
00104                str << Symbols::CRLF << headerName << Symbols::COLON[0] << Symbols::SPACE[0];
00105             }
00106          }
00107 
00108          i->encode(str);
00109       }
00110 
00111       str << Symbols::CRLF;
00112    }
00113          
00114    return str;
00115 }
00116 
00117 EncodeStream&
00118 ParserContainerBase::encodeEmbedded(const Data& headerName, 
00119                                     EncodeStream& str) const
00120 {
00121    assert(!headerName.empty());
00122 
00123    if (!mParsers.empty())
00124    {
00125 
00126       bool first = true;
00127       for (Parsers::const_iterator i = mParsers.begin(); 
00128            i != mParsers.end(); ++i)
00129       {
00130          if (first)
00131          {
00132             first = false;
00133          }
00134          else
00135          {
00136             str << Symbols::AMPERSAND;
00137          }
00138 
00139          str << headerName << Symbols::EQUALS;
00140          Data buf;
00141          {
00142             DataStream s(buf);
00143             i->encode(s);
00144          }
00145          str << Embedded::encode(buf);
00146       }
00147    }
00148    return str;
00149 }
00150 
00151 void 
00152 ParserContainerBase::copyParsers(const Parsers& parsers)
00153 {
00154    mParsers.reserve(mParsers.size() + parsers.size());
00155    for(Parsers::const_iterator p=parsers.begin(); p!=parsers.end(); ++p)
00156    {
00157       mParsers.push_back(*p);
00158       HeaderKit& kit(mParsers.back());
00159       if(kit.pc)
00160       {
00161          kit.pc = makeParser(*kit.pc);
00162       }
00163    }
00164 }
00165 
00166 void 
00167 ParserContainerBase::freeParsers()
00168 {
00169    for(Parsers::iterator p=mParsers.begin(); p!=mParsers.end(); ++p)
00170    {
00171       freeParser(*p);
00172    }
00173 }
00174 
00175 
00176 /* ====================================================================
00177  * The Vovida Software License, Version 1.0 
00178  * 
00179  * Copyright (c) 2005
00180  * 
00181  * Redistribution and use in source and binary forms, with or without
00182  * modification, are permitted provided that the following conditions
00183  * are met:
00184  * 
00185  * 1. Redistributions of source code must retain the above copyright
00186  *    notice, this list of conditions and the following disclaimer.
00187  * 
00188  * 2. Redistributions in binary form must reproduce the above copyright
00189  *    notice, this list of conditions and the following disclaimer in
00190  *    the documentation and/or other materials provided with the
00191  *    distribution.
00192  * 
00193  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00194  *    and "Vovida Open Communication Application Library (VOCAL)" must
00195  *    not be used to endorse or promote products derived from this
00196  *    software without prior written permission. For written
00197  *    permission, please contact vocal@vovida.org.
00198  *
00199  * 4. Products derived from this software may not be called "VOCAL", nor
00200  *    may "VOCAL" appear in their name, without prior written
00201  *    permission of Vovida Networks, Inc.
00202  * 
00203  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00204  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00205  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00206  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00207  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00208  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00209  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00210  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00211  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00212  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00213  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00214  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00215  * DAMAGE.
00216  * 
00217  * ====================================================================
00218  * 
00219  * This software consists of voluntary contributions made by Vovida
00220  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00221  * Inc.  For more information on Vovida Networks, Inc., please see
00222  * <http://www.vovida.org/>.
00223  *
00224  */