|
reSIProcate/stack
9694
|
00001 #if defined(HAVE_CONFIG_H) 00002 #include "config.h" 00003 #endif 00004 00005 #include "resip/stack/Mime.hxx" 00006 #include "rutil/Data.hxx" 00007 #include "rutil/DnsUtil.hxx" 00008 #include "rutil/Logger.hxx" 00009 #include "rutil/ParseBuffer.hxx" 00010 //#include "rutil/WinLeakCheck.hxx" // not compatible with placement new used below 00011 00012 using namespace resip; 00013 using namespace std; 00014 00015 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP 00016 00017 //==================== 00018 // MIME 00019 //==================== 00020 Mime::Mime() 00021 : ParserCategory(), 00022 mType(), 00023 mSubType() 00024 {} 00025 00026 Mime::Mime(const Data& type, const Data& subType) 00027 : ParserCategory(), 00028 mType(type), 00029 mSubType(subType) 00030 {} 00031 00032 Mime::Mime(const HeaderFieldValue& hfv, 00033 Headers::Type type, 00034 PoolBase* pool) 00035 : ParserCategory(hfv, type, pool), 00036 mType(), 00037 mSubType() 00038 {} 00039 00040 Mime::Mime(const Mime& rhs, 00041 PoolBase* pool) 00042 : ParserCategory(rhs, pool), 00043 mType(rhs.mType), 00044 mSubType(rhs.mSubType) 00045 {} 00046 00047 Mime& 00048 Mime::operator=(const Mime& rhs) 00049 { 00050 if (this != &rhs) 00051 { 00052 ParserCategory::operator=(rhs); 00053 mType = rhs.mType; 00054 mSubType = rhs.mSubType; 00055 } 00056 return *this; 00057 } 00058 00059 bool 00060 Mime::operator<(const Mime& rhs) const 00061 { 00062 if (isLessThanNoCase(type(), rhs.type())) 00063 { 00064 return true; 00065 } 00066 else if (isLessThanNoCase(rhs.type(), type())) 00067 { 00068 return false; 00069 } 00070 return isLessThanNoCase(subType(), rhs.subType()); 00071 } 00072 00073 bool 00074 Mime::isEqual(const Mime& rhs) const 00075 { 00076 return (isEqualNoCase(type(), rhs.type()) && 00077 isEqualNoCase(subType(), rhs.subType())); 00078 } 00079 00080 bool 00081 Mime::operator==(const Mime& rhs) const 00082 { 00083 return (isEqualNoCase(type(), rhs.type()) && 00084 isEqualNoCase(subType(), rhs.subType())); 00085 } 00086 00087 bool 00088 Mime::operator!=(const Mime& rhs) const 00089 { 00090 return !(*this == rhs); 00091 } 00092 00093 const Data& 00094 Mime::type() const 00095 { 00096 checkParsed(); 00097 return mType; 00098 } 00099 00100 const Data& Mime::subType() const 00101 { 00102 checkParsed(); 00103 return mSubType; 00104 } 00105 00106 Data& 00107 Mime::type() 00108 { 00109 checkParsed(); 00110 return mType; 00111 } 00112 00113 Data& Mime::subType() 00114 { 00115 checkParsed(); 00116 return mSubType; 00117 } 00118 00119 void 00120 Mime::parse(ParseBuffer& pb) 00121 { 00122 const char* anchor = pb.skipWhitespace(); 00123 static std::bitset<256> delimiter1=Data::toBitset("\r\n\t /"); 00124 pb.skipToOneOf(delimiter1); 00125 pb.data(mType, anchor); 00126 00127 pb.skipWhitespace(); 00128 pb.skipChar(Symbols::SLASH[0]); 00129 00130 anchor = pb.skipWhitespace(); 00131 static std::bitset<256> delimiter2=Data::toBitset("\r\n\t ;"); 00132 pb.skipToOneOf(delimiter2); 00133 pb.data(mSubType, anchor); 00134 00135 pb.skipWhitespace(); 00136 parseParameters(pb); 00137 } 00138 00139 ParserCategory* 00140 Mime::clone() const 00141 { 00142 return new Mime(*this); 00143 } 00144 00145 ParserCategory* 00146 Mime::clone(void* location) const 00147 { 00148 return new (location) Mime(*this); 00149 } 00150 00151 ParserCategory* 00152 Mime::clone(PoolBase* pool) const 00153 { 00154 return new (pool) Mime(*this, pool); 00155 } 00156 00157 EncodeStream& 00158 Mime::encodeParsed(EncodeStream& str) const 00159 { 00160 str << mType << Symbols::SLASH << mSubType ; 00161 encodeParameters(str); 00162 return str; 00163 } 00164 00165 ParameterTypes::Factory Mime::ParameterFactories[ParameterTypes::MAX_PARAMETER]={0}; 00166 00167 Parameter* 00168 Mime::createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool) 00169 { 00170 if(type > ParameterTypes::UNKNOWN && type < ParameterTypes::MAX_PARAMETER && ParameterFactories[type]) 00171 { 00172 return ParameterFactories[type](type, pb, terminators, pool); 00173 } 00174 return 0; 00175 } 00176 00177 bool 00178 Mime::exists(const Param<Mime>& paramType) const 00179 { 00180 checkParsed(); 00181 bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL; 00182 return ret; 00183 } 00184 00185 void 00186 Mime::remove(const Param<Mime>& paramType) 00187 { 00188 checkParsed(); 00189 removeParameterByEnum(paramType.getTypeNum()); 00190 } 00191 00192 #define defineParam(_enum, _name, _type, _RFC_ref_ignored) \ 00193 _enum##_Param::DType& \ 00194 Mime::param(const _enum##_Param& paramType) \ 00195 { \ 00196 checkParsed(); \ 00197 _enum##_Param::Type* p = \ 00198 static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ 00199 if (!p) \ 00200 { \ 00201 p = new _enum##_Param::Type(paramType.getTypeNum()); \ 00202 mParameters.push_back(p); \ 00203 } \ 00204 return p->value(); \ 00205 } \ 00206 \ 00207 const _enum##_Param::DType& \ 00208 Mime::param(const _enum##_Param& paramType) const \ 00209 { \ 00210 checkParsed(); \ 00211 _enum##_Param::Type* p = \ 00212 static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum())); \ 00213 if (!p) \ 00214 { \ 00215 InfoLog(<< "Missing parameter " _name " " << ParameterTypes::ParameterNames[paramType.getTypeNum()]); \ 00216 DebugLog(<< *this); \ 00217 throw Exception("Missing parameter " _name, __FILE__, __LINE__); \ 00218 } \ 00219 return p->value(); \ 00220 } 00221 00222 defineParam(accessType, "access-type", DataParameter, "RFC 2046"); 00223 defineParam(boundary, "boundary", DataParameter, "RFC 2046"); 00224 defineParam(charset, "charset", DataParameter, "RFC 2045"); 00225 defineParam(directory, "directory", DataParameter, "RFC 2046"); 00226 defineParam(expiration, "expiration", QuotedDataParameter, "RFC 2046"); 00227 defineParam(micalg, "micalg", DataParameter, "RFC 1847"); 00228 defineParam(mode, "mode", DataParameter, "RFC 2046"); 00229 defineParam(name, "name", DataParameter, "RFC 2046"); 00230 defineParam(permission, "permission", DataParameter, "RFC 2046"); 00231 defineParam(protocol, "protocol", QuotedDataParameter, "RFC 1847"); 00232 defineParam(q, "q", QValueParameter, "RFC 3261"); 00233 defineParam(server, "server", DataParameter, "RFC 2046"); 00234 defineParam(site, "site", DataParameter, "RFC 2046"); 00235 defineParam(size, "size", DataParameter, "RFC 2046"); 00236 defineParam(smimeType, "smime-type", DataParameter, "RFC 2633"); 00237 defineParam(url, "url", QuotedDataParameter, "RFC 4483"); 00238 00239 #undef defineParam 00240 00241 HashValueImp(resip::Mime, data.type().caseInsensitiveTokenHash() ^ data.subType().caseInsensitiveTokenHash()); 00242 00243 /* ==================================================================== 00244 * The Vovida Software License, Version 1.0 00245 * 00246 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 00247 * 00248 * Redistribution and use in source and binary forms, with or without 00249 * modification, are permitted provided that the following conditions 00250 * are met: 00251 * 00252 * 1. Redistributions of source code must retain the above copyright 00253 * notice, this list of conditions and the following disclaimer. 00254 * 00255 * 2. Redistributions in binary form must reproduce the above copyright 00256 * notice, this list of conditions and the following disclaimer in 00257 * the documentation and/or other materials provided with the 00258 * distribution. 00259 * 00260 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00261 * and "Vovida Open Communication Application Library (VOCAL)" must 00262 * not be used to endorse or promote products derived from this 00263 * software without prior written permission. For written 00264 * permission, please contact vocal@vovida.org. 00265 * 00266 * 4. Products derived from this software may not be called "VOCAL", nor 00267 * may "VOCAL" appear in their name, without prior written 00268 * permission of Vovida Networks, Inc. 00269 * 00270 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00271 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00272 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00273 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00274 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00275 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00276 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00277 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00278 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00279 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00280 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00281 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00282 * DAMAGE. 00283 * 00284 * ==================================================================== 00285 * 00286 * This software consists of voluntary contributions made by Vovida 00287 * Networks, Inc. and many individuals on behalf of Vovida Networks, 00288 * Inc. For more information on Vovida Networks, Inc., please see 00289 * <http://www.vovida.org/>. 00290 * 00291 */
1.7.5.1