reSIProcate/stack  9694
CallId.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/CallId.hxx"
00006 #include "resip/stack/UnknownParameter.hxx"
00007 #include "rutil/Data.hxx"
00008 #include "rutil/DnsUtil.hxx"
00009 #include "rutil/Logger.hxx"
00010 #include "rutil/ParseBuffer.hxx"
00011 //#include "rutil/WinLeakCheck.hxx"  // not compatible with placement new used below
00012 
00013 using namespace resip;
00014 using namespace std;
00015 
00016 
00017 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP
00018 
00019 //====================
00020 // CallID:
00021 //====================
00022 CallID::CallID()
00023    : ParserCategory(), 
00024      mValue() 
00025 {}
00026 
00027 CallID::CallID(const HeaderFieldValue& hfv, 
00028                Headers::Type type,
00029                PoolBase* pool) 
00030    : ParserCategory(hfv, type, pool), mValue()
00031 {}
00032 
00033 CallID::CallID(const CallID& rhs,
00034                PoolBase* pool)
00035    : ParserCategory(rhs, pool),
00036      mValue(rhs.mValue)
00037 {}
00038 
00039 CallID&
00040 CallID::operator=(const CallID& rhs)
00041 {
00042    if (this != &rhs)
00043    {
00044       ParserCategory::operator=(rhs);
00045       mValue = rhs.mValue;
00046    }
00047    return *this;
00048 }
00049 
00050 bool
00051 CallID::operator==(const CallID& rhs) const
00052 {
00053    return value() == rhs.value();
00054 }
00055 
00056 ParserCategory *
00057 CallID::clone() const
00058 {
00059    return new CallID(*this);
00060 }
00061 
00062 ParserCategory *
00063 CallID::clone(void* location) const
00064 {
00065    return new (location) CallID(*this);
00066 }
00067 
00068 ParserCategory* 
00069 CallID::clone(PoolBase* pool) const
00070 {
00071    return new (pool) CallID(*this, pool);
00072 }
00073 
00074 Data& 
00075 CallID::value() 
00076 {
00077    checkParsed(); 
00078    return mValue;
00079 }
00080 
00081 const Data& 
00082 CallID::value() const 
00083 {
00084    checkParsed(); 
00085    return mValue;
00086 }
00087 
00088 void
00089 CallID::parse(ParseBuffer& pb)
00090 {
00091    const char* start = pb.skipWhitespace();
00092    static const std::bitset<256> wsOrSemi(Data::toBitset(ParseBuffer::Whitespace).set(Symbols::SEMI_COLON[0]));
00093    pb.skipToOneOf(wsOrSemi);
00094    pb.data(mValue, start);
00095 
00096    parseParameters(pb);
00097 }
00098 
00099 EncodeStream&
00100 CallID::encodeParsed(EncodeStream& str) const
00101 {
00102    str << mValue;
00103    encodeParameters(str);
00104    return str;
00105 }
00106 
00107 ParameterTypes::Factory CallID::ParameterFactories[ParameterTypes::MAX_PARAMETER]={0};
00108 
00109 Parameter* 
00110 CallID::createParam(ParameterTypes::Type type, ParseBuffer& pb, const std::bitset<256>& terminators, PoolBase* pool)
00111 {
00112    if(type > ParameterTypes::UNKNOWN && type < ParameterTypes::MAX_PARAMETER && ParameterFactories[type])
00113    {
00114       return ParameterFactories[type](type, pb, terminators, pool);
00115    }
00116    return 0;
00117 }
00118 
00119 bool 
00120 CallID::exists(const Param<CallID>& paramType) const
00121 {
00122     checkParsed();
00123     bool ret = getParameterByEnum(paramType.getTypeNum()) != NULL;
00124     return ret;
00125 }
00126 
00127 void 
00128 CallID::remove(const Param<CallID>& paramType)
00129 {
00130     checkParsed();
00131     removeParameterByEnum(paramType.getTypeNum());
00132 }
00133 
00134 #define defineParam(_enum, _name, _type, _RFC_ref_ignored)                                                      \
00135 _enum##_Param::DType&                                                                                           \
00136 CallID::param(const _enum##_Param& paramType)                                                           \
00137 {                                                                                                               \
00138    checkParsed();                                                                                               \
00139    _enum##_Param::Type* p =                                                                                     \
00140       static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum()));                            \
00141    if (!p)                                                                                                      \
00142    {                                                                                                            \
00143       p = new _enum##_Param::Type(paramType.getTypeNum());                                                      \
00144       mParameters.push_back(p);                                                                                 \
00145    }                                                                                                            \
00146    return p->value();                                                                                           \
00147 }                                                                                                               \
00148                                                                                                                 \
00149 const _enum##_Param::DType&                                                                                     \
00150 CallID::param(const _enum##_Param& paramType) const                                                     \
00151 {                                                                                                               \
00152    checkParsed();                                                                                               \
00153    _enum##_Param::Type* p =                                                                                     \
00154       static_cast<_enum##_Param::Type*>(getParameterByEnum(paramType.getTypeNum()));                            \
00155    if (!p)                                                                                                      \
00156    {                                                                                                            \
00157       InfoLog(<< "Missing parameter " _name " " << ParameterTypes::ParameterNames[paramType.getTypeNum()]);     \
00158       DebugLog(<< *this);                                                                                       \
00159       throw Exception("Missing parameter " _name, __FILE__, __LINE__);                                          \
00160    }                                                                                                            \
00161    return p->value();                                                                                           \
00162 }
00163 
00164 defineParam(fromTag, "from-tag", DataParameter, "RFC 3891 (not in IANA, apparently)");
00165 defineParam(toTag, "to-tag", DataParameter, "RFC 3891 (not in IANA, apparently)");
00166 defineParam(earlyOnly, "early-only", ExistsParameter, "RFC 3891 (not in IANA, apparently)");
00167 
00168 #undef defineParam
00169 
00170 
00171 /* ====================================================================
00172  * The Vovida Software License, Version 1.0 
00173  * 
00174  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00175  * 
00176  * Redistribution and use in source and binary forms, with or without
00177  * modification, are permitted provided that the following conditions
00178  * are met:
00179  * 
00180  * 1. Redistributions of source code must retain the above copyright
00181  *    notice, this list of conditions and the following disclaimer.
00182  * 
00183  * 2. Redistributions in binary form must reproduce the above copyright
00184  *    notice, this list of conditions and the following disclaimer in
00185  *    the documentation and/or other materials provided with the
00186  *    distribution.
00187  * 
00188  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00189  *    and "Vovida Open Communication Application Library (VOCAL)" must
00190  *    not be used to endorse or promote products derived from this
00191  *    software without prior written permission. For written
00192  *    permission, please contact vocal@vovida.org.
00193  *
00194  * 4. Products derived from this software may not be called "VOCAL", nor
00195  *    may "VOCAL" appear in their name, without prior written
00196  *    permission of Vovida Networks, Inc.
00197  * 
00198  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00199  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00200  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00201  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00202  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00203  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00204  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00205  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00206  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00207  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00208  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00209  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00210  * DAMAGE.
00211  * 
00212  * ====================================================================
00213  * 
00214  * This software consists of voluntary contributions made by Vovida
00215  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00216  * Inc.  For more information on Vovida Networks, Inc., please see
00217  * <http://www.vovida.org/>.
00218  *
00219  */