Coverage Report

Created: 2026-01-09 06:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/resiprocate/resip/stack/HeaderFieldValueList.cxx
Line
Count
Source
1
#if defined(HAVE_CONFIG_H)
2
#include "config.h"
3
#endif
4
5
6
#include "rutil/ResipAssert.h"
7
8
#include "resip/stack/HeaderFieldValue.hxx"
9
#include "resip/stack/HeaderFieldValueList.hxx"
10
#include "resip/stack/ParserContainerBase.hxx"
11
#include "resip/stack/Embedded.hxx"
12
#include "rutil/WinLeakCheck.hxx"
13
14
using namespace resip;
15
16
const HeaderFieldValueList HeaderFieldValueList::Empty;
17
18
HeaderFieldValueList::~HeaderFieldValueList()
19
13.2k
{
20
13.2k
   freeParserContainer();
21
13.2k
}
22
23
HeaderFieldValueList::HeaderFieldValueList(const HeaderFieldValueList& rhs)
24
0
   : mHeaders(),
25
0
     mPool(0),
26
0
     mParserContainer(0)
27
0
{
28
0
   if (rhs.mParserContainer)
29
0
   {
30
0
      mParserContainer = rhs.mParserContainer->clone();
31
0
   }
32
0
   else if(rhs.mHeaders.size())
33
0
   {
34
0
      mHeaders=rhs.mHeaders;
35
0
   }
36
0
}
37
38
HeaderFieldValueList::HeaderFieldValueList(const HeaderFieldValueList& rhs, PoolBase& pool)
39
0
   : mHeaders(StlPoolAllocator<HeaderFieldValue, PoolBase>(&pool)),
40
0
     mPool(&pool),
41
0
     mParserContainer(0)
42
0
{
43
0
   if (rhs.mParserContainer)
44
0
   {
45
0
      mParserContainer = rhs.mParserContainer->clone();
46
0
   }
47
0
   else if(rhs.mHeaders.size())
48
0
   {
49
0
      mHeaders=rhs.mHeaders;
50
0
   }
51
0
}
52
53
HeaderFieldValueList&
54
HeaderFieldValueList::operator=(const HeaderFieldValueList& rhs)
55
0
{
56
0
   if(this!=&rhs)
57
0
   {
58
0
      mHeaders.clear();
59
60
0
      freeParserContainer();
61
62
0
      if (rhs.mParserContainer != 0)
63
0
      {
64
0
         mParserContainer = rhs.mParserContainer->clone();
65
0
      }
66
0
      else
67
0
      {
68
0
         mHeaders=rhs.mHeaders;
69
0
      }
70
0
   }
71
   
72
0
   return *this;
73
0
}
74
75
EncodeStream&
76
HeaderFieldValueList::encode(int headerEnum, EncodeStream& str) const
77
0
{
78
0
   const Data& headerName = Headers::getHeaderName(static_cast<Headers::Type>(headerEnum));
79
80
0
   if (getParserContainer() != 0)
81
0
   {
82
0
      getParserContainer()->encode(headerName, str);
83
0
   }
84
0
   else
85
0
   {
86
0
      if (!headerName.empty())
87
0
      {
88
0
         str << headerName << Symbols::COLON[0] << Symbols::SPACE[0];
89
0
      }
90
91
0
      for (HeaderFieldValueList::const_iterator j = begin();
92
0
           j != end(); j++)
93
0
      {
94
0
         if (j != begin())
95
0
         {
96
0
            if (Headers::isCommaEncoding(static_cast<Headers::Type>(headerEnum)))
97
0
            {
98
0
               str << Symbols::COMMA[0] << Symbols::SPACE[0];
99
0
            }
100
0
            else
101
0
            {
102
0
               str << Symbols::CRLF << headerName << Symbols::COLON << Symbols::SPACE;
103
0
            }
104
0
         }
105
0
         j->encode(str);
106
0
      }
107
0
      str << Symbols::CRLF;
108
0
   }
109
0
   return str;
110
0
}
111
112
EncodeStream&
113
HeaderFieldValueList::encode(const Data& headerName, EncodeStream& str) const
114
0
{
115
0
   if (getParserContainer() != 0)
116
0
   {
117
0
      getParserContainer()->encode(headerName, str);
118
0
   }
119
0
   else
120
0
   {
121
0
      if (!headerName.empty())
122
0
      {
123
0
         str << headerName << Symbols::COLON << Symbols::SPACE;
124
0
      }
125
0
      for (HeaderFieldValueList::const_iterator j = begin();
126
0
           j != end(); j++)
127
0
      {
128
0
         if (j != begin())
129
0
         {
130
0
            str << Symbols::COMMA[0] << Symbols::SPACE[0];
131
0
         }
132
0
         j->encode(str);
133
0
      }
134
0
      str << Symbols::CRLF;
135
0
   }
136
0
   return str;
137
0
}
138
139
EncodeStream&
140
HeaderFieldValueList::encodeEmbedded(const Data& headerName, EncodeStream& str) const
141
0
{
142
0
  resip_assert(!headerName.empty());
143
144
0
   if (getParserContainer() != 0)
145
0
   {
146
0
      getParserContainer()->encodeEmbedded(headerName, str);
147
0
   }
148
0
   else
149
0
   {
150
0
      bool first = true;
151
0
      for (HeaderFieldValueList::const_iterator j = begin();
152
0
           j != end(); j++)
153
0
      {
154
0
         if (first)
155
0
         {
156
0
            first = false;
157
0
         }
158
0
         else
159
0
         {
160
0
            str << Symbols::AMPERSAND;
161
0
         }
162
163
0
         str << headerName << Symbols::EQUALS;
164
0
         Data buf;
165
0
         {
166
0
            DataStream s(buf);
167
0
            j->encode(s);
168
0
         }
169
0
         str << Embedded::encode(buf);
170
0
      }
171
0
   }
172
0
   return str;
173
0
}
174
175
void 
176
HeaderFieldValueList::clear()
177
0
{
178
0
   freeParserContainer();
179
0
   mHeaders.clear();
180
0
}
181
182
bool
183
HeaderFieldValueList::parsedEmpty() const
184
0
{
185
0
   if (mParserContainer)
186
0
   {
187
0
      return mParserContainer->empty();
188
0
   }
189
0
   else
190
0
   {
191
0
      return mHeaders.empty();
192
0
   }
193
0
}
194
195
void 
196
HeaderFieldValueList::freeParserContainer()
197
13.2k
{
198
13.2k
   if(mParserContainer)
199
265
   {
200
265
      mParserContainer->~ParserContainerBase();
201
      // The allocator will check whether this belongs to it, and if not, fall 
202
      // back to global operator delete.
203
265
      if(mPool)
204
265
      {
205
265
         mPool->deallocate(mParserContainer);
206
265
      }
207
0
      else
208
0
      {
209
0
         ::operator delete(mParserContainer);
210
0
      }
211
265
      mParserContainer=0;
212
265
   }
213
13.2k
}
214
215
size_t 
216
HeaderFieldValueList::getNumHeaderValues() const
217
0
{
218
0
   if (mParserContainer)
219
0
   {
220
0
      return mParserContainer->size();
221
0
   }
222
0
   else
223
0
   {
224
0
      return mHeaders.size();
225
0
   }
226
0
}
227
228
bool 
229
HeaderFieldValueList::getHeaderValueByIndex(size_t index, Data& headerValue) const
230
0
{
231
0
   if (mParserContainer)
232
0
   {
233
0
      return mParserContainer->getHeaderValueByIndex(index, headerValue);
234
0
   }
235
0
   else
236
0
   {
237
0
      if (index < mHeaders.size())
238
0
      {
239
0
         const HeaderFieldValue& hfv = mHeaders[index];
240
0
         headerValue.copy(hfv.getBuffer(), hfv.getLength());
241
0
         return true;
242
0
      }
243
0
   }
244
0
   return false;
245
0
}
246
247
248
/* ====================================================================
249
 * The Vovida Software License, Version 1.0 
250
 * 
251
 * Copyright (c) 2023 SIP Spectrum, Inc. www.sipspectrum.com
252
 * Copyright (c) 2000 Vovida Networks, Inc.
253
 * All rights reserved.
254
 * 
255
 * Redistribution and use in source and binary forms, with or without
256
 * modification, are permitted provided that the following conditions
257
 * are met:
258
 * 
259
 * 1. Redistributions of source code must retain the above copyright
260
 *    notice, this list of conditions and the following disclaimer.
261
 * 
262
 * 2. Redistributions in binary form must reproduce the above copyright
263
 *    notice, this list of conditions and the following disclaimer in
264
 *    the documentation and/or other materials provided with the
265
 *    distribution.
266
 * 
267
 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
268
 *    and "Vovida Open Communication Application Library (VOCAL)" must
269
 *    not be used to endorse or promote products derived from this
270
 *    software without prior written permission. For written
271
 *    permission, please contact vocal@vovida.org.
272
 *
273
 * 4. Products derived from this software may not be called "VOCAL", nor
274
 *    may "VOCAL" appear in their name, without prior written
275
 *    permission of Vovida Networks, Inc.
276
 * 
277
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
278
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
279
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
280
 * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
281
 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
282
 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
283
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
284
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
285
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
286
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
287
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
288
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
289
 * DAMAGE.
290
 * 
291
 * ====================================================================
292
 * 
293
 * This software consists of voluntary contributions made by Vovida
294
 * Networks, Inc. and many individuals on behalf of Vovida Networks,
295
 * Inc.  For more information on Vovida Networks, Inc., please see
296
 * <http://www.vovida.org/>.
297
 *
298
 */