/src/resiprocate/resip/stack/Mime.cxx
Line | Count | Source (jump to first uncovered line) |
1 | | #if defined(HAVE_CONFIG_H) |
2 | | #include "config.h" |
3 | | #endif |
4 | | |
5 | | #include "resip/stack/Mime.hxx" |
6 | | #include "rutil/Data.hxx" |
7 | | #include "rutil/DnsUtil.hxx" |
8 | | #include "rutil/Logger.hxx" |
9 | | #include "rutil/ParseBuffer.hxx" |
10 | | //#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below |
11 | | |
12 | | using namespace resip; |
13 | | using namespace std; |
14 | | |
15 | | #define RESIPROCATE_SUBSYSTEM Subsystem::SIP |
16 | | |
17 | | //==================== |
18 | | // MIME |
19 | | //==================== |
20 | | Mime::Mime() |
21 | | : ParserCategory(), |
22 | | mType(), |
23 | | mSubType() |
24 | 0 | {} |
25 | | |
26 | | Mime::Mime(const Data& type, const Data& subType) |
27 | | : ParserCategory(), |
28 | | mType(type), |
29 | | mSubType(subType) |
30 | 49 | {} |
31 | | |
32 | | Mime::Mime(const HeaderFieldValue& hfv, |
33 | | Headers::Type type, |
34 | | PoolBase* pool) |
35 | | : ParserCategory(hfv, type, pool), |
36 | | mType(), |
37 | | mSubType() |
38 | 6.45k | {} |
39 | | |
40 | | Mime::Mime(const Mime& rhs, |
41 | | PoolBase* pool) |
42 | | : ParserCategory(rhs, pool), |
43 | | mType(rhs.mType), |
44 | | mSubType(rhs.mSubType) |
45 | 77.5k | {} |
46 | | |
47 | | Mime& |
48 | | Mime::operator=(const Mime& rhs) |
49 | 0 | { |
50 | 0 | if (this != &rhs) |
51 | 0 | { |
52 | 0 | ParserCategory::operator=(rhs); |
53 | 0 | mType = rhs.mType; |
54 | 0 | mSubType = rhs.mSubType; |
55 | 0 | } |
56 | 0 | return *this; |
57 | 0 | } |
58 | | |
59 | | bool |
60 | | Mime::operator<(const Mime& rhs) const |
61 | 0 | { |
62 | 0 | if (isLessThanNoCase(type(), rhs.type())) |
63 | 0 | { |
64 | 0 | return true; |
65 | 0 | } |
66 | 0 | else if (isLessThanNoCase(rhs.type(), type())) |
67 | 0 | { |
68 | 0 | return false; |
69 | 0 | } |
70 | 0 | return isLessThanNoCase(subType(), rhs.subType()); |
71 | 0 | } |
72 | | |
73 | | bool |
74 | | Mime::isEqual(const Mime& rhs) const |
75 | 0 | { |
76 | 0 | return (isEqualNoCase(type(), rhs.type()) && |
77 | 0 | isEqualNoCase(subType(), rhs.subType())); |
78 | 0 | } |
79 | | |
80 | | bool |
81 | | Mime::operator==(const Mime& rhs) const |
82 | 38 | { |
83 | 38 | return (isEqualNoCase(type(), rhs.type()) && |
84 | 38 | isEqualNoCase(subType(), rhs.subType())); |
85 | 38 | } |
86 | | |
87 | | bool |
88 | | Mime::operator!=(const Mime& rhs) const |
89 | 0 | { |
90 | 0 | return !(*this == rhs); |
91 | 0 | } |
92 | | |
93 | | const Data& |
94 | | Mime::type() const |
95 | 150 | { |
96 | 150 | checkParsed(); |
97 | 150 | return mType; |
98 | 150 | } |
99 | | |
100 | | const Data& Mime::subType() const |
101 | 98 | { |
102 | 98 | checkParsed(); |
103 | 98 | return mSubType; |
104 | 98 | } |
105 | | |
106 | | Data& |
107 | | Mime::type() |
108 | 0 | { |
109 | 0 | checkParsed(); |
110 | 0 | return mType; |
111 | 0 | } |
112 | | |
113 | | Data& Mime::subType() |
114 | 0 | { |
115 | 0 | checkParsed(); |
116 | 0 | return mSubType; |
117 | 0 | } |
118 | | |
119 | | void |
120 | | Mime::parse(ParseBuffer& pb) |
121 | 6.45k | { |
122 | 6.45k | const char* anchor = pb.skipWhitespace(); |
123 | 6.45k | static std::bitset<256> delimiter1=Data::toBitset("\r\n\t /"); |
124 | 6.45k | pb.skipToOneOf(delimiter1); |
125 | 6.45k | pb.data(mType, anchor); |
126 | | |
127 | 6.45k | pb.skipWhitespace(); |
128 | 6.45k | pb.skipChar(Symbols::SLASH[0]); |
129 | | |
130 | 6.45k | anchor = pb.skipWhitespace(); |
131 | 6.45k | static std::bitset<256> delimiter2=Data::toBitset("\r\n\t ;"); |
132 | 6.45k | pb.skipToOneOf(delimiter2); |
133 | 6.45k | pb.data(mSubType, anchor); |
134 | | |
135 | 6.45k | pb.skipWhitespace(); |
136 | 6.45k | parseParameters(pb); |
137 | 6.45k | } |
138 | | |
139 | | ParserCategory* |
140 | | Mime::clone() const |
141 | 0 | { |
142 | 0 | return new Mime(*this); |
143 | 0 | } |
144 | | |
145 | | ParserCategory* |
146 | | Mime::clone(void* location) const |
147 | 0 | { |
148 | 0 | return new (location) Mime(*this); |
149 | 0 | } |
150 | | |
151 | | ParserCategory* |
152 | | Mime::clone(PoolBase* pool) const |
153 | 0 | { |
154 | 0 | return new (pool) Mime(*this, pool); |
155 | 0 | } |
156 | | |
157 | | EncodeStream& |
158 | | Mime::encodeParsed(EncodeStream& str) const |
159 | 0 | { |
160 | 0 | str << mType << Symbols::SLASH << mSubType ; |
161 | 0 | encodeParameters(str); |
162 | 0 | return str; |
163 | 0 | } |
164 | | |
165 | | ParameterTypes::Factory Mime::ParameterFactories[ParameterTypes::MAX_PARAMETER]={0}; |
166 | | |
167 | | Parameter* |
168 | | Mime::createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool) |
169 | 48.0k | { |
170 | 48.0k | if(type > ParameterTypes::UNKNOWN && type < ParameterTypes::MAX_PARAMETER && ParameterFactories[type]) |
171 | 3.25k | { |
172 | 3.25k | return ParameterFactories[type](type, pb, terminators, pool); |
173 | 3.25k | } |
174 | 44.8k | return 0; |
175 | 48.0k | } |
176 | | |
177 | | bool |
178 | | Mime::exists(const Param<Mime>& paramType) const |
179 | 6.45k | { |
180 | 6.45k | checkParsed(); |
181 | 6.45k | bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL; |
182 | 6.45k | return ret; |
183 | 6.45k | } |
184 | | |
185 | | void |
186 | | Mime::remove(const Param<Mime>& paramType) |
187 | 0 | { |
188 | 0 | checkParsed(); |
189 | 0 | removeParameterByEnum(paramType.getTypeNum()); |
190 | 0 | } |
191 | | |
192 | | #define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ |
193 | | _enum##_Param::DType& \ |
194 | 12.9k | Mime::param(const _enum##_Param& paramType) \ |
195 | 12.9k | { \ |
196 | 12.9k | checkParsed(); \ |
197 | 12.9k | _enum##_Param::Type* p = \ |
198 | 12.9k | static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ |
199 | 12.9k | if (!p) \ |
200 | 12.9k | { \ |
201 | 6.45k | p = new _enum##_Param::Type(paramType.getTypeNum()); \ |
202 | 6.45k | mParameters.push_back(p); \ |
203 | 6.45k | } \ |
204 | 12.9k | return p->value(); \ |
205 | 12.9k | } \ Unexecuted instantiation: resip::Mime::param(resip::accessType_Param const&) resip::Mime::param(resip::boundary_Param const&) Line | Count | Source | 194 | 12.9k | Mime::param(const _enum##_Param& paramType) \ | 195 | 12.9k | { \ | 196 | 12.9k | checkParsed(); \ | 197 | 12.9k | _enum##_Param::Type* p = \ | 198 | 12.9k | static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ | 199 | 12.9k | if (!p) \ | 200 | 12.9k | { \ | 201 | 6.45k | p = new _enum##_Param::Type(paramType.getTypeNum()); \ | 202 | 6.45k | mParameters.push_back(p); \ | 203 | 6.45k | } \ | 204 | 12.9k | return p->value(); \ | 205 | 12.9k | } \ |
Unexecuted instantiation: resip::Mime::param(resip::charset_Param const&) Unexecuted instantiation: resip::Mime::param(resip::directory_Param const&) Unexecuted instantiation: resip::Mime::param(resip::expiration_Param const&) Unexecuted instantiation: resip::Mime::param(resip::micalg_Param const&) Unexecuted instantiation: resip::Mime::param(resip::mode_Param const&) Unexecuted instantiation: resip::Mime::param(resip::name_Param const&) Unexecuted instantiation: resip::Mime::param(resip::permission_Param const&) Unexecuted instantiation: resip::Mime::param(resip::protocol_Param const&) Unexecuted instantiation: resip::Mime::param(resip::q_Param const&) Unexecuted instantiation: resip::Mime::param(resip::server_Param const&) Unexecuted instantiation: resip::Mime::param(resip::site_Param const&) Unexecuted instantiation: resip::Mime::param(resip::size_Param const&) Unexecuted instantiation: resip::Mime::param(resip::smimeType_Param const&) Unexecuted instantiation: resip::Mime::param(resip::url_Param const&) |
206 | | \ |
207 | | const _enum##_Param::DType& \ |
208 | 0 | Mime::param(const _enum##_Param& paramType) const \ |
209 | 0 | { \ |
210 | 0 | checkParsed(); \ |
211 | 0 | _enum##_Param::Type* p = \ |
212 | 0 | static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ |
213 | 0 | if (!p) \ |
214 | 0 | { \ |
215 | 0 | InfoLog(<< "Missing parameter " _name " " << ParameterTypes::ParameterNames[paramType.getTypeNum()]); \ |
216 | 0 | DebugLog(<< *this); \ |
217 | 0 | throw Exception("Missing parameter " _name, __FILE__, __LINE__); \ |
218 | 0 | } \ |
219 | 0 | return p->value(); \ |
220 | 0 | } Unexecuted instantiation: resip::Mime::param(resip::accessType_Param const&) const Unexecuted instantiation: resip::Mime::param(resip::boundary_Param const&) const Unexecuted instantiation: resip::Mime::param(resip::charset_Param const&) const Unexecuted instantiation: resip::Mime::param(resip::directory_Param const&) const Unexecuted instantiation: resip::Mime::param(resip::expiration_Param const&) const Unexecuted instantiation: resip::Mime::param(resip::micalg_Param const&) const Unexecuted instantiation: resip::Mime::param(resip::mode_Param const&) const Unexecuted instantiation: resip::Mime::param(resip::name_Param const&) const Unexecuted instantiation: resip::Mime::param(resip::permission_Param const&) const Unexecuted instantiation: resip::Mime::param(resip::protocol_Param const&) const Unexecuted instantiation: resip::Mime::param(resip::q_Param const&) const Unexecuted instantiation: resip::Mime::param(resip::server_Param const&) const Unexecuted instantiation: resip::Mime::param(resip::site_Param const&) const Unexecuted instantiation: resip::Mime::param(resip::size_Param const&) const Unexecuted instantiation: resip::Mime::param(resip::smimeType_Param const&) const Unexecuted instantiation: resip::Mime::param(resip::url_Param const&) const |
221 | | |
222 | | defineParam(accessType, "access-type", DataParameter, "RFC 2046"); |
223 | | defineParam(boundary, "boundary", DataParameter, "RFC 2046"); |
224 | | defineParam(charset, "charset", DataParameter, "RFC 2045"); |
225 | | defineParam(directory, "directory", DataParameter, "RFC 2046"); |
226 | | defineParam(expiration, "expiration", QuotedDataParameter, "RFC 2046"); |
227 | | defineParam(micalg, "micalg", DataParameter, "RFC 1847"); |
228 | | defineParam(mode, "mode", DataParameter, "RFC 2046"); |
229 | | defineParam(name, "name", DataParameter, "RFC 2046"); |
230 | | defineParam(permission, "permission", DataParameter, "RFC 2046"); |
231 | | defineParam(protocol, "protocol", QuotedDataParameter, "RFC 1847"); |
232 | | defineParam(q, "q", QValueParameter, "RFC 3261"); |
233 | | defineParam(server, "server", DataParameter, "RFC 2046"); |
234 | | defineParam(site, "site", DataParameter, "RFC 2046"); |
235 | | defineParam(size, "size", DataParameter, "RFC 2046"); |
236 | | defineParam(smimeType, "smime-type", DataParameter, "RFC 2633"); |
237 | | defineParam(url, "url", QuotedDataParameter, "RFC 4483"); |
238 | | |
239 | | #undef defineParam |
240 | | |
241 | | HashValueImp(resip::Mime, data.type().caseInsensitiveTokenHash() ^ data.subType().caseInsensitiveTokenHash()); |
242 | | |
243 | | /* ==================================================================== |
244 | | * The Vovida Software License, Version 1.0 |
245 | | * |
246 | | * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. |
247 | | * |
248 | | * Redistribution and use in source and binary forms, with or without |
249 | | * modification, are permitted provided that the following conditions |
250 | | * are met: |
251 | | * |
252 | | * 1. Redistributions of source code must retain the above copyright |
253 | | * notice, this list of conditions and the following disclaimer. |
254 | | * |
255 | | * 2. Redistributions in binary form must reproduce the above copyright |
256 | | * notice, this list of conditions and the following disclaimer in |
257 | | * the documentation and/or other materials provided with the |
258 | | * distribution. |
259 | | * |
260 | | * 3. The names "VOCAL", "Vovida Open Communication Application Library", |
261 | | * and "Vovida Open Communication Application Library (VOCAL)" must |
262 | | * not be used to endorse or promote products derived from this |
263 | | * software without prior written permission. For written |
264 | | * permission, please contact vocal@vovida.org. |
265 | | * |
266 | | * 4. Products derived from this software may not be called "VOCAL", nor |
267 | | * may "VOCAL" appear in their name, without prior written |
268 | | * permission of Vovida Networks, Inc. |
269 | | * |
270 | | * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED |
271 | | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
272 | | * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND |
273 | | * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA |
274 | | * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES |
275 | | * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, |
276 | | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
277 | | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
278 | | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
279 | | * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
280 | | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE |
281 | | * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH |
282 | | * DAMAGE. |
283 | | * |
284 | | * ==================================================================== |
285 | | * |
286 | | * This software consists of voluntary contributions made by Vovida |
287 | | * Networks, Inc. and many individuals on behalf of Vovida Networks, |
288 | | * Inc. For more information on Vovida Networks, Inc., please see |
289 | | * <http://www.vovida.org/>. |
290 | | * |
291 | | */ |