reSIProcate/stack  9694
Aor.cxx
Go to the documentation of this file.
00001 #include <iostream>
00002 
00003 #include "rutil/ParseBuffer.hxx"
00004 #include "rutil/DataStream.hxx"
00005 #include "rutil/DnsUtil.hxx"
00006 #include "resip/stack/Uri.hxx"
00007 #include "resip/stack/Aor.hxx"
00008 
00009 using namespace resip;
00010 
00011 Aor::Aor()
00012 {
00013 }
00014 
00015 Aor::Aor(const Data& value)
00016 {
00017    ParseBuffer pb(value);
00018    
00019    pb.skipWhitespace();
00020    const char* start = pb.position();
00021    pb.skipToOneOf(":@"); // make sure the colon precedes
00022 
00023    pb.assertNotEof();
00024 
00025    pb.data(mScheme, start);
00026    pb.skipChar(Symbols::COLON[0]);
00027    mScheme.lowercase();
00028 
00029    if (isEqualNoCase(mScheme, Symbols::Tel))
00030    {
00031       const char* anchor = pb.position();
00032       pb.skipToOneOf(ParseBuffer::Whitespace, ";>");
00033       pb.data(mUser, anchor);
00034       if (!pb.eof() && *pb.position() == Symbols::SEMI_COLON[0])
00035       {
00036          anchor = pb.skipChar();
00037          pb.skipToOneOf(ParseBuffer::Whitespace, Symbols::RA_QUOTE);
00038       }
00039       return;
00040    }
00041    
00042    start = pb.position();
00043    pb.skipToChar(Symbols::AT_SIGN[0]);
00044    if (!pb.eof())
00045    {
00046       pb.reset(start);
00047       start = pb.position();
00048       pb.skipToOneOf(":@");
00049       pb.data(mUser, start);
00050       if (!pb.eof() && *pb.position() == Symbols::COLON[0])
00051       {
00052          start = pb.skipChar();
00053          pb.skipToChar(Symbols::AT_SIGN[0]);
00054       }
00055       start = pb.skipChar();
00056    }
00057    else
00058    {
00059       pb.reset(start);
00060    }
00061    
00062    if (*start == '[')
00063    {
00064       start = pb.skipChar();
00065       pb.skipToChar(']');
00066       pb.data(mHost, start);
00067       DnsUtil::canonicalizeIpV6Address(mHost);
00068       pb.skipChar();
00069    }
00070    else
00071    {
00072       pb.skipToOneOf(ParseBuffer::Whitespace, ":;?>");
00073       pb.data(mHost, start);
00074    }
00075 
00076    pb.skipToOneOf(ParseBuffer::Whitespace, ":;?>");
00077    if (!pb.eof() && *pb.position() == ':')
00078    {
00079       start = pb.skipChar();
00080       mPort = pb.integer();
00081       pb.skipToOneOf(ParseBuffer::Whitespace, ";?>");
00082    }
00083    else
00084    {
00085       mPort = 0;
00086    }
00087 }
00088 
00089 Aor::Aor(const Uri& uri) : 
00090    mScheme(uri.scheme()),
00091    mUser(uri.user()),
00092    mHost(uri.host()),
00093    mPort(uri.port())
00094 {
00095    
00096 }
00097 
00098 Aor::Aor(const Aor& aor)
00099 {
00100    *this = aor;
00101 }
00102 
00103 Aor& 
00104 Aor::operator=(const Aor& aor)
00105 {
00106    if (this != &aor)
00107    {
00108       mScheme = aor.mScheme;
00109       mUser = aor.mUser;
00110       mHost = aor.mHost;
00111       mPort = aor.mPort;
00112    }
00113    return *this;
00114 }
00115 
00116       
00117 bool 
00118 Aor::operator==(const Aor& other) const
00119 {
00120    return value() == other.value();
00121 }
00122 
00123 bool 
00124 Aor::operator!=(const Aor& other) const
00125 {
00126    return value() != other.value();
00127 }
00128 
00129 bool 
00130 Aor::operator<(const Aor& other) const
00131 {
00132    return value() < other.value();
00133 }
00134 
00135 const Data& 
00136 Aor::value() const
00137 {
00138    if (mOldScheme != mScheme || 
00139        mOldUser != mUser ||
00140        mOldHost != mHost ||
00141        mOldPort != mPort)
00142    {
00143       mOldHost = mHost;
00144       if (DnsUtil::isIpV6Address(mHost))
00145       {
00146          mCanonicalHost = DnsUtil::canonicalizeIpV6Address(mHost);
00147       }
00148       else
00149       {
00150          mCanonicalHost = mHost;
00151          mCanonicalHost.lowercase();
00152       }
00153 
00154       mOldScheme = mScheme;
00155       mOldUser = mUser;
00156       mOldPort = mPort;
00157 
00158       mValue.reserve(mUser.size() + mCanonicalHost.size() + 10);
00159 
00160       DataStream strm(mValue);
00161       strm << mScheme;
00162       strm << Symbols::COLON;
00163       strm << mUser;
00164       if (!mCanonicalHost.empty())
00165       {
00166          strm << Symbols::AT_SIGN;
00167          strm << mCanonicalHost;
00168 
00169          if (mPort != 0)
00170          {
00171             strm << Symbols::COLON;
00172             strm << Data(mPort);
00173          }
00174       }
00175    }
00176 
00177    return mValue;
00178 }
00179 
00180 Data& 
00181 Aor::scheme()
00182 {
00183    return mScheme;
00184 }
00185 
00186 const Data& 
00187 Aor::scheme() const
00188 {
00189    return mScheme;
00190 }
00191 
00192 Data& 
00193 Aor::host()
00194 {
00195    return mHost;
00196 }
00197 
00198 const Data& 
00199 Aor::host() const
00200 {
00201    return mHost;
00202 }
00203 
00204 Data& 
00205 Aor::user()
00206 {
00207    return mUser;
00208 }
00209 
00210 const Data& 
00211 Aor::user() const
00212 {
00213    return mUser;
00214 }
00215 
00216 int& 
00217 Aor::port()
00218 {
00219    return mPort;
00220 }
00221 
00222 int 
00223 Aor::port() const
00224 {
00225    return mPort;
00226 }
00227       
00228 EncodeStream& 
00229 Aor::operator<<(EncodeStream& str) const
00230 {
00231    str << value();
00232    return str;
00233 }
00234 
00235 /* ====================================================================
00236  * The Vovida Software License, Version 1.0 
00237  * 
00238  * Copyright (c) 2000-2005 Vovida Networks, Inc.  All rights reserved.
00239  * 
00240  * Redistribution and use in source and binary forms, with or without
00241  * modification, are permitted provided that the following conditions
00242  * are met:
00243  * 
00244  * 1. Redistributions of source code must retain the above copyright
00245  *    notice, this list of conditions and the following disclaimer.
00246  * 
00247  * 2. Redistributions in binary form must reproduce the above copyright
00248  *    notice, this list of conditions and the following disclaimer in
00249  *    the documentation and/or other materials provided with the
00250  *    distribution.
00251  * 
00252  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00253  *    and "Vovida Open Communication Application Library (VOCAL)" must
00254  *    not be used to endorse or promote products derived from this
00255  *    software without prior written permission. For written
00256  *    permission, please contact vocal@vovida.org.
00257  *
00258  * 4. Products derived from this software may not be called "VOCAL", nor
00259  *    may "VOCAL" appear in their name, without prior written
00260  *    permission of Vovida Networks, Inc.
00261  * 
00262  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00263  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00264  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00265  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00266  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00267  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00268  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00269  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00270  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00271  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00272  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00273  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00274  * DAMAGE.
00275  * 
00276  * ====================================================================
00277  * 
00278  * This software consists of voluntary contributions made by Vovida
00279  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00280  * Inc.  For more information on Vovida Networks, Inc., please see
00281  * <http://www.vovida.org/>.
00282  *
00283  */