Coverage Report

Created: 2024-04-23 06:04

/src/resiprocate/resip/stack/ParserContainerBase.cxx
Line
Count
Source (jump to first uncovered line)
1
#include "rutil/ResipAssert.h"
2
3
#include "resip/stack/ParserContainerBase.hxx"
4
#include "resip/stack/Embedded.hxx"
5
6
using namespace resip;
7
using namespace std;;
8
9
const ParserContainerBase::HeaderKit ParserContainerBase::HeaderKit::Empty;
10
11
ParserContainerBase::ParserContainerBase(Headers::Type type)
12
   : mType(type),
13
     mPool(0)
14
0
{}
15
16
ParserContainerBase::ParserContainerBase(const ParserContainerBase& rhs)
17
   : mType(rhs.mType),
18
     mParsers(),
19
     mPool(0)
20
0
{
21
0
   copyParsers(rhs.mParsers);
22
0
}
23
24
ParserContainerBase::ParserContainerBase(Headers::Type type,
25
                                          PoolBase& pool)
26
   : mType(type),
27
     mParsers(StlPoolAllocator<HeaderKit, PoolBase>(&pool)),
28
     mPool(&pool)
29
203
{}
30
31
ParserContainerBase::ParserContainerBase(const ParserContainerBase& rhs,
32
                                          PoolBase& pool)
33
   : mType(rhs.mType),
34
     mParsers(StlPoolAllocator<HeaderKit, PoolBase>(&pool)),
35
     mPool(&pool)
36
0
{
37
0
   copyParsers(rhs.mParsers);
38
0
}
39
40
ParserContainerBase::~ParserContainerBase()
41
203
{
42
203
   freeParsers();
43
203
}
44
45
ParserContainerBase&
46
ParserContainerBase::operator=(const ParserContainerBase& rhs)
47
0
{
48
0
   if (this != &rhs)
49
0
   {
50
0
      freeParsers();
51
0
      mParsers.clear();
52
0
      copyParsers(rhs.mParsers);
53
0
   }
54
0
   return *this;
55
0
}
56
57
void
58
ParserContainerBase::pop_front() 
59
0
{
60
0
   resip_assert(!mParsers.empty());
61
0
   freeParser(mParsers.front());
62
0
   mParsers.erase(mParsers.begin());
63
0
}
64
 
65
void
66
ParserContainerBase::pop_back() 
67
0
{
68
0
   resip_assert(!mParsers.empty());
69
0
   freeParser(mParsers.back());
70
0
   mParsers.pop_back(); 
71
0
}
72
73
void
74
ParserContainerBase::append(const ParserContainerBase& source) 
75
0
{
76
0
   copyParsers(source.mParsers);
77
0
}
78
79
EncodeStream& 
80
ParserContainerBase::encode(const Data& headerName, 
81
                            EncodeStream& str) const
82
0
{
83
   // !jf! this is not strictly correct since some headers are allowed to
84
   // be empty: Supported, Accept-Encoding, Allow-Events, Allow,
85
   // Accept,Accept-Language 
86
0
   if (!mParsers.empty())
87
0
   {
88
0
      if (!headerName.empty())
89
0
      {
90
0
         str << headerName << Symbols::COLON[0] << Symbols::SPACE[0];
91
0
      }
92
         
93
0
      for (Parsers::const_iterator i = mParsers.begin(); 
94
0
           i != mParsers.end(); ++i)
95
0
      {
96
0
         if (i != mParsers.begin())
97
0
         {
98
0
            if (Headers::isCommaEncoding(mType))
99
0
            {
100
0
               str << Symbols::COMMA[0] << Symbols::SPACE[0];
101
0
            }
102
0
            else
103
0
            {
104
0
               str << Symbols::CRLF << headerName << Symbols::COLON[0] << Symbols::SPACE[0];
105
0
            }
106
0
         }
107
108
0
         i->encode(str);
109
0
      }
110
111
0
      str << Symbols::CRLF;
112
0
   }
113
         
114
0
   return str;
115
0
}
116
117
EncodeStream&
118
ParserContainerBase::encodeEmbedded(const Data& headerName, 
119
                                    EncodeStream& str) const
120
0
{
121
0
   resip_assert(!headerName.empty());
122
123
0
   if (!mParsers.empty())
124
0
   {
125
126
0
      bool first = true;
127
0
      for (Parsers::const_iterator i = mParsers.begin(); 
128
0
           i != mParsers.end(); ++i)
129
0
      {
130
0
         if (first)
131
0
         {
132
0
            first = false;
133
0
         }
134
0
         else
135
0
         {
136
0
            str << Symbols::AMPERSAND;
137
0
         }
138
139
0
         str << headerName << Symbols::EQUALS;
140
0
         Data buf;
141
0
         {
142
0
            DataStream s(buf);
143
0
            i->encode(s);
144
0
         }
145
0
         str << Embedded::encode(buf);
146
0
      }
147
0
   }
148
0
   return str;
149
0
}
150
151
void 
152
ParserContainerBase::copyParsers(const Parsers& parsers)
153
0
{
154
0
   mParsers.reserve(mParsers.size() + parsers.size());
155
0
   for(Parsers::const_iterator p=parsers.begin(); p!=parsers.end(); ++p)
156
0
   {
157
      // Copy c'tor and assignment operator for HeaderKit are actually poor
158
      // man's move semantics, so we have to implement real copy semantics here.
159
0
      mParsers.push_back(HeaderKit::Empty);
160
161
0
      HeaderKit& kit(mParsers.back());
162
0
      if(p->pc)
163
0
      {
164
0
         kit.pc = makeParser(*(p->pc));
165
0
      } 
166
0
      else 
167
0
      {
168
0
         kit.hfv = p->hfv;
169
0
      }
170
0
   }
171
0
}
172
173
void 
174
ParserContainerBase::freeParsers()
175
203
{
176
406
   for(Parsers::iterator p=mParsers.begin(); p!=mParsers.end(); ++p)
177
203
   {
178
203
      freeParser(*p);
179
203
   }
180
203
}
181
182
bool
183
ParserContainerBase::getHeaderValueByIndex(size_t index, Data& headerValue) const
184
0
{
185
0
   if (index < mParsers.size())
186
0
   {
187
0
      const HeaderKit& hk = mParsers[index];
188
0
      headerValue.clear();
189
0
      DataStream ds(headerValue);
190
0
      hk.encode(ds);
191
0
      return true;
192
0
   }
193
0
   return false;
194
0
}
195
196
197
/* ====================================================================
198
 * The Vovida Software License, Version 1.0 
199
 * 
200
 * Copyright (c) 2023 SIP Spectrum, Inc. www.sipspectrum.com
201
 * Copyright (c) 2005
202
 * 
203
 * Redistribution and use in source and binary forms, with or without
204
 * modification, are permitted provided that the following conditions
205
 * are met:
206
 * 
207
 * 1. Redistributions of source code must retain the above copyright
208
 *    notice, this list of conditions and the following disclaimer.
209
 * 
210
 * 2. Redistributions in binary form must reproduce the above copyright
211
 *    notice, this list of conditions and the following disclaimer in
212
 *    the documentation and/or other materials provided with the
213
 *    distribution.
214
 * 
215
 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
216
 *    and "Vovida Open Communication Application Library (VOCAL)" must
217
 *    not be used to endorse or promote products derived from this
218
 *    software without prior written permission. For written
219
 *    permission, please contact vocal@vovida.org.
220
 *
221
 * 4. Products derived from this software may not be called "VOCAL", nor
222
 *    may "VOCAL" appear in their name, without prior written
223
 *    permission of Vovida Networks, Inc.
224
 * 
225
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
226
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
227
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
228
 * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
229
 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
230
 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
231
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
232
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
233
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
234
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
235
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
236
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
237
 * DAMAGE.
238
 * 
239
 * ====================================================================
240
 * 
241
 * This software consists of voluntary contributions made by Vovida
242
 * Networks, Inc. and many individuals on behalf of Vovida Networks,
243
 * Inc.  For more information on Vovida Networks, Inc., please see
244
 * <http://www.vovida.org/>.
245
 *
246
 */