reSIProcate/stack  9694
Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Member Functions | Protected Attributes | Private Attributes | Static Private Attributes
resip::Uri Class Reference

Represents the "SIP-URI" and "SIPS-URI" elements in the RFC 3261 grammar. More...

#include <Uri.hxx>

Inheritance diagram for resip::Uri:
Inheritance graph
[legend]
Collaboration diagram for resip::Uri:
Collaboration graph
[legend]

List of all members.

Public Types

typedef std::bitset
< Uri::uriEncodingTableSize
EncodingTable

Public Member Functions

 RESIP_HeapCount (Uri)
 Uri (PoolBase *pool=0)
 Uri (const HeaderFieldValue &hfv, Headers::Type type, PoolBase *pool=0)
 Uri (const Uri &orig, PoolBase *pool=0)
 Uri (const Data &data)
 ~Uri ()
Datahost ()
const Datahost () const
Datauser ()
const Datauser () const
DatauserParameters ()
const DatauserParameters () const
Dataopaque ()
const Dataopaque () const
Data getAor () const
Data getAorNoPort () const
Data getAorNoReally () const
Data getAOR (bool addPort) const
Uri getAorAsUri (TransportType transportTypeToRemoveDefaultPort=UNKNOWN_TRANSPORT) const
bool userIsTelephoneSubscriber () const
 Returns true if the user appears to fit the BNF for the 'telephone-subscriber' element in the RFC 3261 (and by extension, RFC 3966) grammar.
Token getUserAsTelephoneSubscriber () const
 Returns the user-part as a 'telephone-subscriber' grammar element (in other words, this parses the user-part into a dial string and parameters, with the dial-string accessible with Token::value(), and the parameters accessible with the various Token::param() and Token::exists() interfaces).
void setUserAsTelephoneSubscriber (const Token &telephoneSubscriber)
 Sets the user-part of this URI using the dial-string and parameters stored in telephoneSubscriber.
Datascheme ()
const Datascheme () const
int & port ()
int port () const
Datapassword ()
const Datapassword () const
Data toString () const
bool isEnumSearchable () const
 Returns true if the uri can be converted into a string that can be used as an enum lookup.
std::vector< DatagetEnumLookups (const std::vector< Data > &suffixes) const
 Return a vector of domains to do a NAPTR lookup for enum.
bool hasEmbedded () const
SipMessageembedded ()
const SipMessageembedded () const
void removeEmbedded ()
virtual void parse (ParseBuffer &pb)
virtual ParserCategoryclone () const
virtual ParserCategoryclone (void *location) const
virtual ParserCategoryclone (PoolBase *pool) const
virtual EncodeStreamencodeParsed (EncodeStream &str) const
void parseEmbeddedHeaders (ParseBuffer &pb)
EncodeStreamencodeEmbeddedHeaders (EncodeStream &str) const
Urioperator= (const Uri &rhs)
bool operator== (const Uri &other) const
bool operator!= (const Uri &other) const
bool operator< (const Uri &other) const
bool aorEqual (const Uri &rhs) const
virtual ParametercreateParam (ParameterTypes::Type type, ParseBuffer &pb, const std::bitset< 256 > &terminators, PoolBase *pool)
bool exists (const Param< Uri > &paramType) const
void remove (const Param< Uri > &paramType)
 defineParam (ob,"ob", ExistsParameter,"RFC 5626")
 defineParam (gr,"gr", ExistsOrDataParameter,"RFC 5627")
 defineParam (comp,"comp", DataParameter,"RFC 3486")
 defineParam (duration,"duration", UInt32Parameter,"RFC 4240")
 defineParam (lr,"lr", ExistsParameter,"RFC 3261")
 defineParam (maddr,"maddr", DataParameter,"RFC 3261")
 defineParam (method,"method", DataParameter,"RFC 3261")
 defineParam (transport,"transport", DataParameter,"RFC 3261")
 defineParam (ttl,"ttl", UInt32Parameter,"RFC 3261")
 defineParam (user,"user", DataParameter,"RFC 3261, 4967")
 defineParam (extension,"ext", DataParameter,"RFC 3966")
 defineParam (sigcompId,"sigcomp-id", QuotedDataParameter,"RFC 5049")
 defineParam (rinstance,"rinstance", DataParameter,"proprietary (resip)")
 defineParam (addTransport,"addTransport", ExistsParameter,"RESIP INTERNAL")

Static Public Member Functions

static Uri fromTel (const Uri &, const Uri &hostUri)
static void setUriUserEncoding (unsigned char c, bool encode)
 Modifies the default URI encoding character sets.
static void setUriPasswordEncoding (unsigned char c, bool encode)
static EncodingTablegetUserEncodingTable ()
static EncodingTablegetPasswordEncodingTable ()
static EncodingTablegetLocalNumberTable ()
static EncodingTablegetGlobalNumberTable ()

Static Public Attributes

static const size_t uriEncodingTableSize = 256

Protected Member Functions

void getAorInternal (bool dropScheme, bool addPort, Data &aor) const

Protected Attributes

Data mScheme
Data mHost
Data mUser
Data mUserParameters
int mPort
Data mPassword
bool mHostCanonicalized

Private Attributes

std::auto_ptr< DatamEmbeddedHeadersText
std::auto_ptr< SipMessagemEmbeddedHeaders

Static Private Attributes

static ParameterTypes::Factory ParameterFactories [ParameterTypes::MAX_PARAMETER] = {0}
static const bool tablesMightBeInitialized
 Dummy static initialization variable, for ensuring that the encoding tables are initialized sometime during static initialization, preventing the scenario where multiple threads try to runtime init the same table at the same time.

Detailed Description

Represents the "SIP-URI" and "SIPS-URI" elements in the RFC 3261 grammar.

Also can be made to represent other URI types (like tel URIs)

Definition at line 21 of file Uri.hxx.


Member Typedef Documentation

Definition at line 184 of file Uri.hxx.


Constructor & Destructor Documentation

Uri::Uri ( PoolBase pool = 0)

Definition at line 36 of file Uri.cxx.

Referenced by clone().

Uri::Uri ( const HeaderFieldValue hfv,
Headers::Type  type,
PoolBase pool = 0 
)

Definition at line 44 of file Uri.cxx.

                                                                      :
   ParserCategory(hfv, type, pool),
   mPort(0),
   mHostCanonicalized(false)
{}
Uri::Uri ( const Uri orig,
PoolBase pool = 0 
)

Definition at line 65 of file Uri.cxx.

   : ParserCategory(rhs, pool),
     mScheme(rhs.mScheme),
     mHost(rhs.mHost),
     mUser(rhs.mUser),
     mUserParameters(rhs.mUserParameters),
     mPort(rhs.mPort),
     mPassword(rhs.mPassword),
     mHostCanonicalized(rhs.mHostCanonicalized),
     mEmbeddedHeadersText(rhs.mEmbeddedHeadersText.get() ? new Data(*rhs.mEmbeddedHeadersText) : 0),
     mEmbeddedHeaders(rhs.mEmbeddedHeaders.get() ? new SipMessage(*rhs.mEmbeddedHeaders) : 0)
{}
Uri::Uri ( const Data data) [explicit]

Definition at line 52 of file Uri.cxx.

References resip::Data::data(), resip::Data::size(), and resip::Headers::UNKNOWN.

   : ParserCategory(), 
     mScheme(Symbols::DefaultSipScheme),
     mPort(0),
     mHostCanonicalized(false)
{
   HeaderFieldValue hfv(data.data(), data.size());
   // must copy because parse creates overlays
   Uri tmp(hfv, Headers::UNKNOWN);
   tmp.checkParsed();
   *this = tmp;
}

Here is the call graph for this function:

Uri::~Uri ( )

Definition at line 80 of file Uri.cxx.

{}

Member Function Documentation

bool Uri::aorEqual ( const Uri rhs) const
ParserCategory * Uri::clone ( ) const [virtual]

Implements resip::ParserCategory.

Definition at line 1071 of file Uri.cxx.

References Uri().

{
   return new Uri(*this);
}

Here is the call graph for this function:

ParserCategory * Uri::clone ( void *  location) const [virtual]

Implements resip::ParserCategory.

Definition at line 1077 of file Uri.cxx.

References Uri().

{
   return new (location) Uri(*this);
}

Here is the call graph for this function:

ParserCategory * Uri::clone ( PoolBase pool) const [virtual]

Implements resip::ParserCategory.

Definition at line 1083 of file Uri.cxx.

References Uri().

{
   return new (pool) Uri(*this);
}

Here is the call graph for this function:

Parameter * Uri::createParam ( ParameterTypes::Type  type,
ParseBuffer pb,
const std::bitset< 256 > &  terminators,
PoolBase pool 
) [virtual]
resip::Uri::defineParam ( ob  ,
"ob"  ,
ExistsParameter  ,
"RFC 5626"   
)
resip::Uri::defineParam ( gr  ,
"gr"  ,
ExistsOrDataParameter  ,
"RFC 5627"   
)
resip::Uri::defineParam ( comp  ,
"comp"  ,
DataParameter  ,
"RFC 3486"   
)
resip::Uri::defineParam ( duration  ,
"duration"  ,
UInt32Parameter  ,
"RFC 4240"   
)
resip::Uri::defineParam ( lr  ,
"lr"  ,
ExistsParameter  ,
"RFC 3261"   
)
resip::Uri::defineParam ( maddr  ,
"maddr"  ,
DataParameter  ,
"RFC 3261"   
)
resip::Uri::defineParam ( method  ,
"method"  ,
DataParameter  ,
"RFC 3261"   
)
resip::Uri::defineParam ( transport  ,
"transport"  ,
DataParameter  ,
"RFC 3261"   
)
resip::Uri::defineParam ( ttl  ,
"ttl"  ,
UInt32Parameter  ,
"RFC 3261"   
)
resip::Uri::defineParam ( user  ,
"user"  ,
DataParameter  ,
"RFC  3261,
4967"   
)
resip::Uri::defineParam ( extension  ,
"ext"  ,
DataParameter  ,
"RFC 3966"   
)
resip::Uri::defineParam ( sigcompId  ,
"sigcomp-id"  ,
QuotedDataParameter  ,
"RFC 5049"   
)
resip::Uri::defineParam ( rinstance  ,
"rinstance"  ,
DataParameter  ,
"proprietary (resip)"   
)
resip::Uri::defineParam ( addTransport  ,
"addTransport"  ,
ExistsParameter  ,
"RESIP INTERNAL"   
)
SipMessage & Uri::embedded ( )

Definition at line 1150 of file Uri.cxx.

References resip::LazyParser::checkParsed(), mEmbeddedHeaders, mEmbeddedHeadersText, and parseEmbeddedHeaders().

Referenced by embedded(), main(), and resip::SipMessage::mergeUri().

{
   checkParsed();
   if (mEmbeddedHeaders.get() == 0)
   {
      this->mEmbeddedHeaders.reset(new SipMessage());
      if (mEmbeddedHeadersText.get() && !mEmbeddedHeadersText->empty())
      {
         ParseBuffer pb(mEmbeddedHeadersText->data(), mEmbeddedHeadersText->size());
         this->parseEmbeddedHeaders(pb);
      }
   }

   return *mEmbeddedHeaders;
}

Here is the call graph for this function:

const SipMessage & Uri::embedded ( ) const

Definition at line 1167 of file Uri.cxx.

References embedded().

{
   Uri* ncthis = const_cast<Uri*>(this);
   return ncthis->embedded();
}

Here is the call graph for this function:

EncodeStream & Uri::encodeEmbeddedHeaders ( EncodeStream str) const

Definition at line 1227 of file Uri.cxx.

References mEmbeddedHeaders, and mEmbeddedHeadersText.

Referenced by encodeParsed().

{
   if (mEmbeddedHeaders.get())
   {
      mEmbeddedHeaders->encodeEmbedded(str);
   }
   else if(mEmbeddedHeadersText.get())
   {
      // never decoded
      str << *mEmbeddedHeadersText;
   }
   return str;
}
EncodeStream & Uri::encodeParsed ( EncodeStream str) const [virtual]

Implements resip::LazyParser.

Definition at line 1100 of file Uri.cxx.

References resip::Symbols::AT_SIGN, resip::Symbols::COLON, resip::Data::empty(), encodeEmbeddedHeaders(), resip::ParserCategory::encodeParameters(), resip::Data::escapeToStream(), getPasswordEncodingTable(), getUserEncodingTable(), resip::DnsUtil::isIpV6Address(), mHost, mPassword, mPort, mScheme, mUser, mUserParameters, and resip::Symbols::SEMI_COLON.

Referenced by resip::RequestLine::encodeParsed(), resip::NameAddr::encodeParsed(), and toString().

{
   str << mScheme << Symbols::COLON; 
   if (!mUser.empty())
   {
#ifdef HANDLE_CHARACTER_ESCAPING
      mUser.escapeToStream(str, getUserEncodingTable()); 
#else
      str << mUser;
#endif
      if (!mUserParameters.empty())
      {
         str << Symbols::SEMI_COLON[0] << mUserParameters;
      }
      if (!mPassword.empty())
      {
         str << Symbols::COLON;
#ifdef HANDLE_CHARACTER_ESCAPING
         mPassword.escapeToStream(str, getPasswordEncodingTable());
#else
         str << mPassword;
#endif
      }
   }
   if (!mHost.empty())
   {
     if (!mUser.empty())
     {
       str << Symbols::AT_SIGN;
     }
     if (DnsUtil::isIpV6Address(mHost))
     {
        str << '[' << mHost << ']';
     }
     else
     {
        str << mHost;
     }
   }
   if (mPort != 0)
   {
      str << Symbols::COLON << mPort;
   }
   encodeParameters(str);
   encodeEmbeddedHeaders(str);

   return str;
}

Here is the call graph for this function:

bool Uri::exists ( const Param< Uri > &  paramType) const
Uri Uri::fromTel ( const Uri tel,
const Uri hostUri 
) [static]

Definition at line 169 of file Uri.cxx.

References resip::Data::data(), DebugLog, resip::Data::empty(), resip::Symbols::Isub, resip::Data::lowercase(), resip::ParserCategory::param(), resip::Symbols::Phone, resip::ParseBuffer::position(), resip::Symbols::Postd, resip::Data::prefix(), resip::Data::reserve(), scheme(), resip::Symbols::SEMI_COLON, resip::Symbols::Sip, resip::Data::size(), resip::Symbols::Tel, user(), and userParameters().

Referenced by main().

{
   assert(tel.scheme() == Symbols::Tel);

   Uri u(hostUri);
   u.scheme() = Symbols::Sip;
   u.user() = tel.user();
   u.param(p_user) = Symbols::Phone;

   // need to sort the user parameters
   if (!tel.userParameters().empty())
   {
      DebugLog(<< "Uri::fromTel: " << tel.userParameters());
      Data isub;
      Data postd;

      int totalSize  = 0;
      std::set<Data> userParameters;

      ParseBuffer pb(tel.userParameters().data(), tel.userParameters().size());
      while (true)
      {
         const char* anchor = pb.position();
         pb.skipToChar(Symbols::SEMI_COLON[0]);
         Data param = pb.data(anchor);
         // !dlb! not supposed to lowercase extension parameters
         param.lowercase();
         totalSize += (int)param.size() + 1;

         if (param.prefix(Symbols::Isub))
         {
            isub = param;
         }
         else if (param.prefix(Symbols::Postd))
         {
            postd = param;
         }
         else
         {
            userParameters.insert(param);
         }
         if (pb.eof())
         {
            break;
         }
         else
         {
            pb.skipChar();
         }
      }

      u.userParameters().reserve(totalSize);
      if (!isub.empty())
      {
         u.userParameters() = isub;
      }
      if (!postd.empty())
      {
         if (!u.userParameters().empty())
         {
            u.userParameters() += Symbols::SEMI_COLON[0];
         }
         u.userParameters() += postd;
      }
      
      for(std::set<Data>::const_iterator i = userParameters.begin();
          i != userParameters.end(); ++i)
      {
         DebugLog(<< "Adding param: " << *i);
         if (!u.userParameters().empty())
         {
            u.userParameters() += Symbols::SEMI_COLON[0];
         }
         u.userParameters() += *i;
      }
   }

   return u;
}

Here is the call graph for this function:

Data Uri::getAor ( ) const
Data Uri::getAOR ( bool  addPort) const

Definition at line 802 of file Uri.cxx.

References getAorInternal().

Referenced by getAorNoReally().

{
   Data result;
   getAorInternal(false, addPort, result);
   return result;
}

Here is the call graph for this function:

Uri Uri::getAorAsUri ( TransportType  transportTypeToRemoveDefaultPort = UNKNOWN_TRANSPORT) const

Definition at line 905 of file Uri.cxx.

References resip::LazyParser::checkParsed(), resip::Symbols::DefaultSipPort, resip::Symbols::DefaultSipsPort, resip::DTLS, host(), mHost, mPort, mScheme, mUser, port(), scheme(), resip::TCP, resip::TLS, resip::UDP, and user().

Referenced by main().

{   
   //.dcm. -- tel conversion?
   checkParsed();
   Uri ret;
   ret.scheme() = mScheme;   
   ret.user() = mUser;
   ret.host() = mHost;

   // Remove any default ports (if required)
   if(transportTypeToRemoveDefaultPort == UDP || 
       transportTypeToRemoveDefaultPort == TCP)
   {
      if(mPort != Symbols::DefaultSipPort)
      {
         ret.port() = mPort;
      }
   }
   else if (transportTypeToRemoveDefaultPort == TLS || 
            transportTypeToRemoveDefaultPort == DTLS)
   {
      if(mPort != Symbols::DefaultSipsPort)
      {
         ret.port() = mPort;
      }
   }
   else
   {
      ret.port() = mPort;
   }

   return ret;
}

Here is the call graph for this function:

void Uri::getAorInternal ( bool  dropScheme,
bool  addPort,
Data aor 
) const [protected]

Definition at line 734 of file Uri.cxx.

References resip::Symbols::AT_SIGN, resip::DnsUtil::canonicalizeIpV6Address(), resip::LazyParser::checkParsed(), resip::Data::clear(), resip::Symbols::COLON, resip::Data::empty(), resip::Data::escapeToStream(), getUserEncodingTable(), resip::DnsUtil::isIpV6Address(), resip::Data::lowercase(), resip::Symbols::LS_BRACKET, mHost, mHostCanonicalized, mPort, mScheme, mUser, resip::Data::reserve(), resip::Symbols::RS_BRACKET, and resip::Data::size().

Referenced by getAor(), getAOR(), and getAorNoPort().

{
   checkParsed();
   // canonicalize host

   addPort = addPort && mPort!=0;

   bool hostIsIpV6Address = false;
   if(!mHostCanonicalized)
   {
      if (DnsUtil::isIpV6Address(mHost))
      {
         mHost = DnsUtil::canonicalizeIpV6Address(mHost);
         hostIsIpV6Address = true;
      }
      else
      {
         mHost.lowercase();
      }
   }

   // !bwc! Maybe reintroduce caching of aor. (Would use a bool instead of the
   // mOldX cruft)
   //                                                  @:10000
   aor.clear();
   aor.reserve((dropScheme ? 0 : mScheme.size()+1)
               + mUser.size() + mHost.size() + 7);
   if(!dropScheme)
   {
      aor += mScheme;
      aor += ':';
   }

   if (!mUser.empty())
   {
#ifdef HANDLE_CHARACTER_ESCAPING
      {
         oDataStream str(aor);
         mUser.escapeToStream(str, getUserEncodingTable()); 
      }
#else
      aor += mUser;
#endif
      if(!mHost.empty())
      {
         aor += Symbols::AT_SIGN;
      }
   }

   if(hostIsIpV6Address && addPort)
   {
      aor += Symbols::LS_BRACKET;
      aor += mHost;
      aor += Symbols::RS_BRACKET;
   }
   else
   {
      aor += mHost;
   }

   if(addPort)
   {
      aor += Symbols::COLON;
      aor += Data(mPort);
   }
}

Here is the call graph for this function:

Data Uri::getAorNoPort ( ) const

Definition at line 889 of file Uri.cxx.

References getAorInternal().

Referenced by main(), myMain(), resip::TuIM::processMessageRequest(), processStdin(), and resip::TuIM::processSubscribeRequest().

{
   Data result;
   getAorInternal(true, false, result);
   return result;
}

Here is the call graph for this function:

Data resip::Uri::getAorNoReally ( ) const [inline]

Definition at line 55 of file Uri.hxx.

References getAOR().

      {
         return getAOR(false);
      }

Here is the call graph for this function:

std::vector< Data > Uri::getEnumLookups ( const std::vector< Data > &  suffixes) const

Return a vector of domains to do a NAPTR lookup for enum.

Definition at line 257 of file Uri.cxx.

References resip::Data::begin(), resip::Symbols::DOT, isEnumSearchable(), and user().

Referenced by resip::DnsResult::lookup().

{
   std::vector<Data> results;
   Data prefix;
   if (isEnumSearchable())
   {
      // skip the leading +
      for (const char* i=user().end()-1 ; i!= user().begin(); --i)
      {
         if (isdigit(*i))
         {
            prefix += *i;
            prefix += Symbols::DOT;
         }
      }
      for (std::vector<Data>::const_iterator j=suffixes.begin(); j != suffixes.end(); ++j)
      {
         results.push_back(prefix + *j);
      }
   }
   return results;
}

Here is the call graph for this function:

static EncodingTable& resip::Uri::getGlobalNumberTable ( ) [inline, static]

Definition at line 215 of file Uri.hxx.

References resip::Data::toBitset().

Referenced by initAllTables(), and userIsTelephoneSubscriber().

      {
         static EncodingTable globalNumberTable(
               Data::toBitset("-.()0123456789"));
         return globalNumberTable;
      }

Here is the call graph for this function:

static EncodingTable& resip::Uri::getLocalNumberTable ( ) [inline, static]

Definition at line 206 of file Uri.hxx.

References resip::Data::toBitset().

Referenced by initAllTables(), and userIsTelephoneSubscriber().

      {
         // ?bwc? 'p' and 'w' are allowed in 2806, but have been removed in 
         // 3966. Should we support these or not?
         static EncodingTable localNumberTable(
               Data::toBitset("*#-.()0123456789ABCDEFpw"));
         return localNumberTable;
      }

Here is the call graph for this function:

static EncodingTable& resip::Uri::getPasswordEncodingTable ( ) [inline, static]

Definition at line 196 of file Uri.hxx.

References resip::Data::toBitset().

Referenced by encodeParsed(), initAllTables(), and setUriPasswordEncoding().

      {
         static EncodingTable passwordEncodingTable(
               Data::toBitset("abcdefghijklmnopqrstuvwxyz"
                              "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                              "0123456789"
                              "-_.!~*\\()&=+$").flip());
         return passwordEncodingTable;
      }

Here is the call graph for this function:

Token Uri::getUserAsTelephoneSubscriber ( ) const

Returns the user-part as a 'telephone-subscriber' grammar element (in other words, this parses the user-part into a dial string and parameters, with the dial-string accessible with Token::value(), and the parameters accessible with the various Token::param() and Token::exists() interfaces).

For example, suppose the following is in the Request-URI:

sip:5555551234;phone-context=+86@example.com;user=dialstring

The user-part of this SIP URI is "5555551234;phone-context=+86", and it fits the BNF for the 'telephone-subscriber' grammar element. To access the 'phone-context' parameter, do something like the following:

            Uri& reqUri(sip.header(h_RequestLine).uri());

            // !bwc! May add native support for this param later
            static ExtensionParameter p_phoneContext("phone-context");
            Data phoneContextValue;

            if(reqUri.isWellFormed())
            {
               if(reqUri.exists(p_phoneContext))
               {
                  // Phone context as URI param
                  phoneContextValue=reqUri.param(p_phoneContext);
               }
               else if(reqUri.scheme()=="sip" || reqUri.scheme()=="sips")
               {
                  // Might have phone-context as a user param (only happens 
                  // in a sip or sips URI)
                  // Technically, this userIsTelephoneSubscriber() check is 
                  // required: 
                  // sip:bob;phone-context=+86@example.com doesn't have a 
                  // phone-context param according to the BNF in 3261. But, 
                  // interop may require you to parse this as if it did have 
                  // such a param.
                  if(reqUri.userIsTelephoneSubscriber())
                  {
                     Token telSub(reqUri.getUserAsTelephoneSubscriber());
                     if(telSub.isWellFormed() && telSub.exists(p_phoneContext))
                     {
                        // Phone context as user param
                        phoneContextValue=telSub.param(p_phoneContext);
                     }
                  }
               }
            }

Definition at line 863 of file Uri.cxx.

References resip::Data::data(), mUser, resip::Headers::NONE, and resip::Data::size().

Referenced by main().

{
   // !bwc! Ugly. Someday, refactor all this lazy-parser stuff and make it 
   // possible to control ownership explicitly.
   // Set this up as lazy-parsed, to prevent exceptions from being thrown.
   HeaderFieldValue temp(mUser.data(), mUser.size());
   Token tempToken(temp, Headers::NONE);
   // tempToken does not own the HeaderFieldValue temp, and temp does not own 
   // its buffer.

   // Here's the voodoo; invoking operator= makes a deep copy of the stuff in
   // tempToken, with result owning the memory, and result is in the unparsed 
   // state.
   Token result = tempToken;
   return result;
}

Here is the call graph for this function:

static EncodingTable& resip::Uri::getUserEncodingTable ( ) [inline, static]

Definition at line 186 of file Uri.hxx.

References resip::Data::toBitset().

Referenced by encodeParsed(), getAorInternal(), initAllTables(), and setUriUserEncoding().

      {
         static EncodingTable userEncodingTable(
               Data::toBitset("abcdefghijklmnopqrstuvwxyz"
                              "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                              "0123456789"
                              "-_.!~*\\()&=+$,;?/").flip());
         return userEncodingTable;
      }

Here is the call graph for this function:

bool Uri::hasEmbedded ( ) const

Definition at line 282 of file Uri.cxx.

References resip::LazyParser::checkParsed(), mEmbeddedHeaders, and mEmbeddedHeadersText.

Referenced by main(), and resip::SipMessage::mergeUri().

{
   checkParsed(); 
   return (mEmbeddedHeadersText.get() && !mEmbeddedHeadersText->empty()) || mEmbeddedHeaders.get() != 0;
}

Here is the call graph for this function:

Data& resip::Uri::host ( ) [inline]
const Data& resip::Uri::host ( ) const [inline]

Definition at line 41 of file Uri.hxx.

References resip::LazyParser::checkParsed(), and mHost.

{checkParsed(); return mHost;}

Here is the call graph for this function:

bool Uri::isEnumSearchable ( ) const

Returns true if the uri can be converted into a string that can be used as an enum lookup.

Definition at line 250 of file Uri.cxx.

References resip::LazyParser::checkParsed(), resip::Data::empty(), mUser, and resip::Data::size().

Referenced by getEnumLookups(), and resip::DnsResult::lookup().

{
   checkParsed();
   return (!mUser.empty() && mUser.size() >= 2 && mUser[0] == '+');
}

Here is the call graph for this function:

Data& resip::Uri::opaque ( ) [inline]

Definition at line 46 of file Uri.hxx.

References resip::LazyParser::checkParsed(), and mHost.

{checkParsed(); return mHost;}

Here is the call graph for this function:

const Data& resip::Uri::opaque ( ) const [inline]

Definition at line 47 of file Uri.hxx.

References resip::LazyParser::checkParsed(), and mHost.

{checkParsed(); return mHost;}

Here is the call graph for this function:

bool Uri::operator!= ( const Uri other) const

Definition at line 627 of file Uri.cxx.

{
   return !(*this == other);
}
bool Uri::operator< ( const Uri other) const

Definition at line 633 of file Uri.cxx.

References resip::DnsUtil::canonicalizeIpV6Address(), resip::LazyParser::checkParsed(), resip::DnsUtil::isIpV6Address(), resip::Data::lowercase(), mHost, mHostCanonicalized, mPort, mUser, and mUserParameters.

{
   other.checkParsed();
   checkParsed();
   if (mUser < other.mUser)
   {
      return true;
   }

   if (mUser > other.mUser)
   {
      return false;
   }

   if (mUserParameters < other.mUserParameters)
   {
      return true;
   }

   if (mUserParameters > other.mUserParameters)
   {
      return false;
   }

   // !bwc! Canonicalize before we compare! Jeez...
   if (!mHostCanonicalized)
   {
      if(DnsUtil::isIpV6Address(mHost))
      {
         mHost = DnsUtil::canonicalizeIpV6Address(mHost);
      }
      else
      {
         mHost.lowercase();
      }
      mHostCanonicalized=true;
   }
   
   if (!other.mHostCanonicalized)
   {
      if(DnsUtil::isIpV6Address(other.mHost))
      {
         other.mHost = DnsUtil::canonicalizeIpV6Address(other.mHost);
      }
      else
      {
         other.mHost.lowercase();
      }
      other.mHostCanonicalized=true;
   }

   if (mHost < other.mHost)
   {
      return true;
   }

   if (mHost > other.mHost)
   {
      return false;
   }

   return mPort < other.mPort;
}

Here is the call graph for this function:

Uri & Uri::operator= ( const Uri rhs)

Definition at line 299 of file Uri.cxx.

References mEmbeddedHeaders, mEmbeddedHeadersText, mHost, mHostCanonicalized, mPassword, mPort, mScheme, mUser, and mUserParameters.

{
   if (this != &rhs)
   {
      ParserCategory::operator=(rhs);
      mScheme = rhs.mScheme;
      mHost = rhs.mHost;
      mHostCanonicalized=rhs.mHostCanonicalized;
      mUser = rhs.mUser;
      mUserParameters = rhs.mUserParameters;
      mPort = rhs.mPort;
      mPassword = rhs.mPassword;
      if (rhs.mEmbeddedHeaders.get() != 0)
      {
         mEmbeddedHeaders.reset(new SipMessage(*rhs.mEmbeddedHeaders));
      }
      else if(rhs.mEmbeddedHeadersText.get() != 0)
      {
         if(!mEmbeddedHeadersText.get())
         {
            mEmbeddedHeadersText.reset(new Data(*rhs.mEmbeddedHeadersText));
         }
         else
         {
            // !bwc! Data::operator= is smart enough to handle this safely.
            *mEmbeddedHeadersText = *rhs.mEmbeddedHeadersText;
         }
      }
   }
   return *this;
}
bool Uri::operator== ( const Uri other) const

Definition at line 366 of file Uri.cxx.

References resip::DnsUtil::canonicalizeIpV6Address(), resip::LazyParser::checkParsed(), resip::ParserCategory::getParameterByEnum(), resip::isEqualNoCase(), resip::DnsUtil::isIpV6Address(), mHost, mHostCanonicalized, resip::ParserCategory::mParameters, mPassword, mPort, mScheme, resip::ParserCategory::mUnknownParameters, mUser, mUserParameters, resip::ParserCategory::param(), resip::Symbols::Sip, resip::Symbols::Sips, resip::UnknownParameter::value(), and value.

{
   checkParsed();
   other.checkParsed();

   // compare hosts
   if (DnsUtil::isIpV6Address(mHost) &&
       DnsUtil::isIpV6Address(other.mHost))
   {

      // compare canonicalized IPV6 addresses

      // update canonicalized if host changed
      if (!mHostCanonicalized)
      {
         mHost = DnsUtil::canonicalizeIpV6Address(mHost);
         mHostCanonicalized=true;
      }

      // update canonicalized if host changed
      if (!other.mHostCanonicalized)
      {
         other.mHost = DnsUtil::canonicalizeIpV6Address(other.mHost);
         other.mHostCanonicalized=true;
      }

      if (mHost != other.mHost)
      {
         return false;
      }
   }
   else
   {
      if (!isEqualNoCase(mHost, other.mHost))
      {
         return false;
      }
   }
   
   if (isEqualNoCase(mScheme, other.mScheme) &&
       ((isEqualNoCase(mScheme, Symbols::Sip) || isEqualNoCase(mScheme, Symbols::Sips)) ? mUser == other.mUser : isEqualNoCase(mUser, other.mUser)) &&
       isEqualNoCase(mUserParameters,other.mUserParameters) &&
       mPassword == other.mPassword &&
       mPort == other.mPort)
   {
      for (ParameterList::const_iterator it = mParameters.begin(); it != mParameters.end(); ++it)
      {
         Parameter* otherParam = other.getParameterByEnum((*it)->getType());

         switch ((*it)->getType())
         {
            case ParameterTypes::user:
            {
               if (!(otherParam &&
                     isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(),
                                   dynamic_cast<DataParameter*>(otherParam)->value())))
               {
                  return false;
               }
            }
            break;
            case ParameterTypes::ttl:
            {
               if (!(otherParam &&
                     (dynamic_cast<UInt32Parameter*>(*it)->value() ==
                      dynamic_cast<UInt32Parameter*>(otherParam)->value())))
               {
                  return false;
               }
               break;
            }
            case ParameterTypes::method:
            {
               // this should possibly be case sensitive, but is allowed to be
               // case insensitive for robustness.  
               
               if (otherParam)
               {
                  DataParameter* dp1 = dynamic_cast<DataParameter*>(*it);
                  DataParameter* dp2 = dynamic_cast<DataParameter*>(otherParam);
                  (void)dp1;
                  (void)dp2;
                  // ?bwc? It looks like we're just assuming the dynamic_cast 
                  // will succeed everywhere else; why are we bothering to 
                  // assert()?
                  assert(dp1);
                  assert(dp2);
               }
               if (!(otherParam &&
                     isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(),
                                   dynamic_cast<DataParameter*>(otherParam)->value())))
               {
                  return false;
               }
               break;
            }
            case ParameterTypes::maddr:
            {               
               if (!(otherParam &&
                     isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(),
                                   dynamic_cast<DataParameter*>(otherParam)->value())))
               {
                  return false;
               }
            }
            break;
            case ParameterTypes::transport:
            {
               if (!(otherParam &&
                     isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(),
                                   dynamic_cast<DataParameter*>(otherParam)->value())))
               {
                  return false;
               }
            }
            break;
            // the parameters that follow don't affect comparison if only present
            // in one of the URI's
            case ParameterTypes::lr:
               break;
            default:
               break;
               //treat as unknown parameter?
         }
      }         

      // now check the other way, sigh
      for (ParameterList::const_iterator it = other.mParameters.begin(); it != other.mParameters.end(); ++it)
      {
         Parameter* param = getParameterByEnum((*it)->getType());
         switch ((*it)->getType())
         {
            case ParameterTypes::user:
            {
               if (!(param &&
                     isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(),
                                   dynamic_cast<DataParameter*>(param)->value())))
               {
                  return false;
               }
            }
            break;
            case ParameterTypes::ttl:
            {
               if (!(param &&
                     (dynamic_cast<UInt32Parameter*>(*it)->value() == 
                      dynamic_cast<UInt32Parameter*>(param)->value())))
               {
                  return false;
               }
               break;
            }
            case ParameterTypes::method:
            {
               // this should possilby be case sensitive, but is allowed to be
               // case insensitive for robustness.  
               if (!(param &&
                     isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(),
                                   dynamic_cast<DataParameter*>(param)->value())))
               {
                  return false;
               }
            }
            break;
            case ParameterTypes::maddr:
            {               
               if (!(param &&
                     isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(),
                                   dynamic_cast<DataParameter*>(param)->value())))
               {
                  return false;
               }
            }
            break;
            case ParameterTypes::transport:
            {
               if (!(param &&
                     isEqualNoCase(dynamic_cast<DataParameter*>(*it)->value(),
                                   dynamic_cast<DataParameter*>(param)->value())))
               {
                  return false;
               }
            }
            break;
            // the parameters that follow don't affect comparison if only present
            // in one of the URI's
            case ParameterTypes::lr:
               break;
            default:
               break;
               //treat as unknown parameter?
         }
      }
   }
   else
   {
      return false;
   }

   OrderUnknownParameters orderUnknown;

#if defined(__SUNPRO_CC) || defined(WIN32) || defined(__sun__)
   // The Solaris Forte STL implementation does not support the
   // notion of a list.sort() function taking a BinaryPredicate.
   // The hacky workaround is to load the Parameter pointers into
   // an STL set which does support an ordering function.

   typedef std::set<Parameter*, OrderUnknownParameters> ParameterSet;
   ParameterSet unA, unB;

   for (ParameterList::const_iterator i = mUnknownParameters.begin();
        i != mUnknownParameters.end(); ++i)
   {
      unA.insert(*i);
   }
   for (ParameterList::const_iterator i = other.mUnknownParameters.begin();
        i != other.mUnknownParameters.end(); ++i)
   {
      unB.insert(*i);
   }

   ParameterSet::iterator a = unA.begin();
   ParameterSet::iterator b = unB.begin();
#else
   // .dlb. more efficient to copy to vector for sorting?
   // Uri comparison is expensive; consider caching? ugh
   ParameterList unA = mUnknownParameters;
   ParameterList unB = other.mUnknownParameters;

   sort(unA.begin(), unA.end(), orderUnknown);
   sort(unB.begin(), unB.end(), orderUnknown);
 
   ParameterList::iterator a = unA.begin();
   ParameterList::iterator b = unB.begin();
#endif

   while(a != unA.end() && b != unB.end())
   {
      if (orderUnknown(*a, *b))
      {
         ++a;
      }
      else if (orderUnknown(*b, *a))
      {
         ++b;
      }
      else
      {
         if (!isEqualNoCase(dynamic_cast<UnknownParameter*>(*a)->value(),
                            dynamic_cast<UnknownParameter*>(*b)->value()))
         {
            return false;
         }
         ++a;
         ++b;
      }
   }
   return true;
}

Here is the call graph for this function:

void Uri::parse ( ParseBuffer pb) [virtual]

Implements resip::LazyParser.

Definition at line 940 of file Uri.cxx.

References resip::ParseBuffer::assertNotEof(), resip::Symbols::AT_SIGN, resip::DnsUtil::canonicalizeIpV6Address(), resip::Symbols::COLON, resip::ParseBuffer::data(), resip::ParseBuffer::dataUnescaped(), resip::Data::empty(), resip::ParseBuffer::eof(), mEmbeddedHeadersText, mHost, mHostCanonicalized, mPassword, mPort, mScheme, mUser, mUserParameters, resip::ParserCategory::parseParameters(), resip::ParseBuffer::position(), resip::Symbols::QUESTION, resip::Symbols::RA_QUOTE, resip::ParseBuffer::reset(), resip::Data::schemeLowercase(), resip::Symbols::SEMI_COLON, resip::ParseBuffer::skipChar(), resip::ParseBuffer::skipToChar(), resip::ParseBuffer::skipToOneOf(), resip::ParseBuffer::skipWhitespace(), resip::Symbols::Tel, resip::Data::toBitset(), resip::ParseBuffer::uInt32(), and resip::ParseBuffer::Whitespace.

Referenced by resip::RequestLine::parse(), resip::MessageWaitingContents::parse(), and resip::NameAddr::parse().

{
   pb.skipWhitespace();
   const char* start = pb.position();
   pb.skipToOneOf(":@");

   pb.assertNotEof();

   pb.data(mScheme, start);
   pb.skipChar(Symbols::COLON[0]);
   mScheme.schemeLowercase();

   if (mScheme==Symbols::Tel)
   {
      const char* anchor = pb.position();
      static std::bitset<256> delimiter=Data::toBitset("\r\n\t ;>");
      pb.skipToOneOf(delimiter);
      pb.data(mUser, anchor);
      if (!pb.eof() && *pb.position() == Symbols::SEMI_COLON[0])
      {
         anchor = pb.skipChar();
         pb.skipToOneOf(ParseBuffer::Whitespace, Symbols::RA_QUOTE);
         pb.data(mUserParameters, anchor);
      }
      return;
   }
   
   start = pb.position();
   static std::bitset<256> userPortOrPasswordDelim(Data::toBitset("@:\""));
   // stop at double-quote to prevent matching an '@' in a quoted string param. 
   pb.skipToOneOf(userPortOrPasswordDelim);
   if (!pb.eof())
   {
      const char* atSign=0;
      if (*pb.position() == Symbols::COLON[0])
      {
         // Either a password, or a port
         const char* afterColon = pb.skipChar();
         pb.skipToOneOf("@\"");
         if(!pb.eof() && *pb.position() == Symbols::AT_SIGN[0])
         {
            atSign=pb.position();
            // password
#ifdef HANDLE_CHARACTER_ESCAPING
            pb.dataUnescaped(mPassword, afterColon);
#else
            pb.data(mPassword, afterColon);
#endif
            pb.reset(afterColon-1);
         }
         else
         {
            // port. No user part.
            pb.reset(start);
         }
      }
      else if(*pb.position() == Symbols::AT_SIGN[0])
      {
         atSign=pb.position();
      }
      else
      {
         // Only a hostpart
         pb.reset(start);
      }

      if(atSign)
      {
#ifdef HANDLE_CHARACTER_ESCAPING
         pb.dataUnescaped(mUser, start);
#else
         pb.data(mUser, start);
#endif
         pb.reset(atSign);
         start = pb.skipChar();
      }
   }
   else
   {
      pb.reset(start);
   }

   mHostCanonicalized=false;
   static std::bitset<256> hostDelimiter(Data::toBitset("\r\n\t :;?>"));
   if (*start == '[')
   {
      start = pb.skipChar();
      pb.skipToChar(']');
      pb.data(mHost, start);
      // .bwc. We do not save this canonicalization, since we weren't doing so
      // before. This may change soon.
      Data canonicalizedHost=DnsUtil::canonicalizeIpV6Address(mHost);
      if(canonicalizedHost.empty())
      {
         // .bwc. So the V6 addy is garbage.
         throw ParseException("Unparsable V6 address (note, this might"
                                    " be unparsable because IPV6 support is not"
                                    " enabled)","Uri",__FILE__,
                                       __LINE__);
      }
      pb.skipChar();
      pb.skipToOneOf(hostDelimiter);
   }
   else
   {
      pb.skipToOneOf(hostDelimiter);
      pb.data(mHost, start);
   }

   if (!pb.eof() && *pb.position() == ':')
   {
      start = pb.skipChar();
      mPort = pb.uInt32();
   }
   else
   {
      mPort = 0;
   }

   parseParameters(pb);

   if (!pb.eof() && *pb.position() == Symbols::QUESTION[0])
   {
      const char* anchor = pb.position();
      pb.skipToOneOf(">;", ParseBuffer::Whitespace);
      if(!mEmbeddedHeadersText.get()) mEmbeddedHeadersText.reset(new Data);
      pb.data(*mEmbeddedHeadersText, anchor);
   }
}

Here is the call graph for this function:

void Uri::parseEmbeddedHeaders ( ParseBuffer pb)

Definition at line 1175 of file Uri.cxx.

References resip::Symbols::AMPERSAND, bodyData, resip::ParseBuffer::data(), resip::Data::data(), DebugLog, resip::Embedded::decode(), resip::ParseBuffer::eof(), resip::Symbols::EQUALS, resip::Headers::getType(), resip::isEqualNoCase(), len, mEmbeddedHeaders, resip::ParseBuffer::position(), resip::Symbols::QUESTION, resip::Data::size(), resip::ParseBuffer::skipChar(), and resip::ParseBuffer::skipToChar().

Referenced by embedded().

{
   DebugLog(<< "Uri::parseEmbeddedHeaders");
   if (!pb.eof() && *pb.position() == Symbols::QUESTION[0])
   {
      pb.skipChar();
   }

   const char* anchor;
   Data headerName;
   Data headerContents;

   bool first = true;
   while (!pb.eof())
   {
      if (first)
      {
         first = false;
      }
      else
      {
         pb.skipChar(Symbols::AMPERSAND[0]);
      }

      anchor = pb.position();
      pb.skipToChar(Symbols::EQUALS[0]);
      pb.data(headerName, anchor);
      // .dlb. in theory, need to decode header name

      anchor = pb.skipChar(Symbols::EQUALS[0]);
      pb.skipToChar(Symbols::AMPERSAND[0]);
      pb.data(headerContents, anchor);

      unsigned int len;
      char* decodedContents = Embedded::decode(headerContents, len);
      mEmbeddedHeaders->addBuffer(decodedContents);

      if (isEqualNoCase(bodyData, headerName))
      {
         mEmbeddedHeaders->setBody(decodedContents, len); 
      }
      else
      {
         DebugLog(<< "Uri::parseEmbeddedHeaders(" << headerName << ", " << Data(decodedContents, len) << ")");
         mEmbeddedHeaders->addHeader(Headers::getType(headerName.data(), (int)headerName.size()),
                                     headerName.data(), (int)headerName.size(),
                                     decodedContents, len);
      }
   }
}

Here is the call graph for this function:

Data& resip::Uri::password ( ) [inline]

Definition at line 145 of file Uri.hxx.

References resip::LazyParser::checkParsed(), and mPassword.

Referenced by resip::SipMessage::compute2543TransactionHash(), and main().

{checkParsed(); return mPassword;}

Here is the call graph for this function:

const Data& resip::Uri::password ( ) const [inline]

Definition at line 146 of file Uri.hxx.

References resip::LazyParser::checkParsed(), and mPassword.

{checkParsed(); return mPassword;}

Here is the call graph for this function:

int& resip::Uri::port ( ) [inline]
int resip::Uri::port ( ) const [inline]

Definition at line 144 of file Uri.hxx.

References resip::LazyParser::checkParsed(), and mPort.

{checkParsed(); return mPort;}

Here is the call graph for this function:

void Uri::remove ( const Param< Uri > &  paramType)
void Uri::removeEmbedded ( )

Definition at line 289 of file Uri.cxx.

References resip::LazyParser::checkParsed(), mEmbeddedHeaders, and mEmbeddedHeadersText.

Referenced by resip::SipMessage::mergeUri().

Here is the call graph for this function:

resip::Uri::RESIP_HeapCount ( Uri  )
Data& resip::Uri::scheme ( ) [inline]
const Data& resip::Uri::scheme ( ) const [inline]

Definition at line 142 of file Uri.hxx.

References resip::LazyParser::checkParsed(), and mScheme.

{checkParsed(); return mScheme;}

Here is the call graph for this function:

void Uri::setUriPasswordEncoding ( unsigned char  c,
bool  encode 
) [static]

Definition at line 1093 of file Uri.cxx.

References resip::LazyParser::encode(), and getPasswordEncodingTable().

Here is the call graph for this function:

void Uri::setUriUserEncoding ( unsigned char  c,
bool  encode 
) [static]

Modifies the default URI encoding character sets.

Definition at line 1088 of file Uri.cxx.

References resip::LazyParser::encode(), and getUserEncodingTable().

Referenced by main().

Here is the call graph for this function:

void Uri::setUserAsTelephoneSubscriber ( const Token telephoneSubscriber)

Sets the user-part of this URI using the dial-string and parameters stored in telephoneSubscriber.

Parameters:
telephoneSubscriberThe user-part, as a 'telephone-subscriber' grammar element.

Definition at line 881 of file Uri.cxx.

References resip::Data::clear(), and mUser.

Referenced by main().

{
   mUser.clear();
   oDataStream str(mUser);
   str << telephoneSubscriber;
}

Here is the call graph for this function:

Data Uri::toString ( ) const

Definition at line 1242 of file Uri.cxx.

References encodeParsed().

{
   Data out;
   {
      oDataStream dataStream(out);
      this->encodeParsed(dataStream);
   }
   return out;
}

Here is the call graph for this function:

Data& resip::Uri::user ( ) [inline]
const Data& resip::Uri::user ( ) const [inline]

Definition at line 43 of file Uri.hxx.

References resip::LazyParser::checkParsed(), and mUser.

{checkParsed(); return mUser;}

Here is the call graph for this function:

bool Uri::userIsTelephoneSubscriber ( ) const

Returns true if the user appears to fit the BNF for the 'telephone-subscriber' element in the RFC 3261 (and by extension, RFC 3966) grammar.

This is important because 'telephone-subscriber' can have parameters, which you could then access easily through the getUserAsTelephoneSubscriber() and setUserAsTelephoneSubscriber() calls.

Definition at line 810 of file Uri.cxx.

References resip::ParseBuffer::assertNotEof(), resip::ParseBuffer::data(), resip::ParseBuffer::eof(), resip::ParseBuffer::fail(), getGlobalNumberTable(), getLocalNumberTable(), mUser, resip::ParseBuffer::position(), resip::ParseBuffer::skipChar(), and resip::ParseBuffer::skipChars().

Referenced by main().

{
   try
   {
      ParseBuffer pb(mUser);
      pb.assertNotEof();
      const char* anchor=pb.position();
      bool local=false;
      if(*pb.position()=='+')
      {
         // Might be a global phone number
         pb.skipChar();
         pb.skipChars(getGlobalNumberTable());
      }
      else
      {
         pb.skipChars(getLocalNumberTable());
         local=true;
      }

      Data dialString(pb.data(anchor));
      if(dialString.empty())
      {
         pb.fail(__FILE__, __LINE__, "Dial string is empty.");
      }

      // ?bwc? More dial-string checking? For instance, +/ (or simply /) is not 
      // a valid dial-string according to the BNF; the string must contain at 
      // least one actual digit (or in the local number case, one hex digit or 
      // '*' or '#'. Interestingly, this means that stuff like ///*/// is 
      // valid)

      // Dial string looks ok so far; now look for params (there must be a 
      // phone-context param if this is a local number, otherwise there might 
      // or might not be one)
      if(local || !pb.eof())
      {
         // The only thing that can be here is a ';'. If it does, we're going 
         // to say it is good enough for us. If something in the parameter 
         // string is malformed, it'll get caught when/if 
         // getUserAsTelephoneSubscriber() is called.
         pb.skipChar(';');
      }

      return true;
   }
   catch(ParseException& /*e*/)
   {
      return false;
   }
}

Here is the call graph for this function:

Data& resip::Uri::userParameters ( ) [inline]

Definition at line 44 of file Uri.hxx.

References resip::LazyParser::checkParsed(), and mUserParameters.

Referenced by fromTel(), and main().

Here is the call graph for this function:

const Data& resip::Uri::userParameters ( ) const [inline]

Definition at line 45 of file Uri.hxx.

References resip::LazyParser::checkParsed(), and mUserParameters.

Here is the call graph for this function:


Member Data Documentation

std::auto_ptr<SipMessage> resip::Uri::mEmbeddedHeaders [private]
std::auto_ptr<Data> resip::Uri::mEmbeddedHeadersText [private]

Definition at line 267 of file Uri.hxx.

Referenced by embedded(), encodeEmbeddedHeaders(), hasEmbedded(), operator=(), parse(), and removeEmbedded().

Data resip::Uri::mHost [mutable, protected]
bool resip::Uri::mHostCanonicalized [mutable, protected]

Definition at line 264 of file Uri.hxx.

Referenced by aorEqual(), getAorInternal(), host(), operator<(), operator=(), operator==(), and parse().

Definition at line 261 of file Uri.hxx.

Referenced by encodeParsed(), operator=(), operator==(), parse(), and password().

int resip::Uri::mPort [protected]
Data resip::Uri::mUser [protected]

Definition at line 259 of file Uri.hxx.

Referenced by encodeParsed(), operator<(), operator=(), operator==(), parse(), and userParameters().

Definition at line 270 of file Uri.hxx.

Referenced by createParam().

const bool Uri::tablesMightBeInitialized [static, private]

Dummy static initialization variable, for ensuring that the encoding tables are initialized sometime during static initialization, preventing the scenario where multiple threads try to runtime init the same table at the same time.

Note:
Prior to static initialization of this bool, it could be either true or false; you should not be using this variable to check whether the tables are initialized. Just call the getXTable() accessor function; it will init the table if it is not already.

Definition at line 282 of file Uri.hxx.

const size_t resip::Uri::uriEncodingTableSize = 256 [static]

Definition at line 26 of file Uri.hxx.


The documentation for this class was generated from the following files: