reSIProcate/stack  9694
Mime.cxx
Go to the documentation of this file.
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  */