📄 uri.cxx
字号:
++b; } } return true;}bool Uri::operator!=(const Uri& other) const{ return !(*this == other);}boolUri::operator<(const Uri& other) const{ 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; } if (mHost < other.mHost) { return true; } if (mHost > other.mHost) { return false; } return mPort < other.mPort;}bool Uri::GreaterQ::operator()(const Uri& lhs, const Uri& rhs) const{ if (lhs.exists(p_q) && rhs.exists(p_q)) { return lhs.param(p_q) > rhs.param(p_q); } if (lhs.exists(p_q)) { return lhs.param(p_q) > 1000; // > 1.0 } if (rhs.exists(p_q)) { return rhs.param(p_q) < 1000; // < 1.0 } return false;}const DataUri::getAorNoPort() const{ // CJ - TODO - check this in inline with the getAor code (see v6 stuff) checkParsed(); getAor(); Data aor; aor.reserve(mUser.size() + mCanonicalHost.size() + 2 /* for @ */ ); if (mUser.empty()) { aor += mCanonicalHost; } else { aor += mUser; if (!mCanonicalHost.empty()) { aor += Symbols::AT_SIGN; aor += mCanonicalHost; } } return aor;}const Data&Uri::getAor() const{ checkParsed(); // did anything change? if (mOldUser != mUser || mOldHost != mHost || mOldPort != mPort) { bool hostIsIpV6Address = false; mOldHost = mHost; // canonicalize host if (DnsUtil::isIpV6Address(mOldHost)) { mCanonicalHost = DnsUtil::canonicalizeIpV6Address(mHost); hostIsIpV6Address = true; } else { mCanonicalHost = mHost; mCanonicalHost.lowercase(); } mOldUser = mUser; mOldPort = mPort; mAor.clear(); // @:10000 mAor.reserve(mUser.size() + mCanonicalHost.size() + 10); if (mOldUser.empty()) { mAor += mCanonicalHost; } else { mAor += mOldUser; if (!mCanonicalHost.empty()) { mAor += Symbols::AT_SIGN; if (hostIsIpV6Address && mPort != 0) { mAor += Symbols::LS_BRACKET + mCanonicalHost + Symbols::RS_BRACKET; } else { mAor += mCanonicalHost; } } } if (mPort != 0) { mAor += Symbols::COLON; mAor += Data(mPort); } } return mAor;}Uri Uri::getAorAsUri() const{ //.dcm. -- tel conversion? checkParsed(); Uri ret; ret.scheme() = mScheme; ret.user() = mUser; ret.host() = mHost; ret.port() = mPort; return ret;}voidUri::parse(ParseBuffer& pb){ pb.skipWhitespace(); const char* start = pb.position(); pb.skipToOneOf(":@"); // make sure the colon precedes pb.assertNotEof(); pb.data(mScheme, start); pb.skipChar(Symbols::COLON[0]); mScheme.lowercase(); if (isEqualNoCase(mScheme, Symbols::Tel)) { const char* anchor = pb.position(); pb.skipToOneOf(ParseBuffer::Whitespace, ";>"); 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(); pb.skipToChar(Symbols::AT_SIGN[0]); if (!pb.eof()) { pb.reset(start); start = pb.position(); pb.skipToOneOf(":@");#ifdef HANDLE_CHARACTER_ESCAPING pb.dataUnescaped(mUser, start);#else pb.data(mUser, start);#endif if (!pb.eof() && *pb.position() == Symbols::COLON[0]) { start = pb.skipChar(); pb.skipToChar(Symbols::AT_SIGN[0]);#ifdef HANDLE_CHARACTER_ESCAPING pb.dataUnescaped(mPassword, start);#else pb.data(mPassword, start);#endif } start = pb.skipChar(); } else { pb.reset(start); } 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(); } else { pb.skipToOneOf(ParseBuffer::Whitespace, ":;?>"); pb.data(mHost, start); } pb.skipToOneOf(ParseBuffer::Whitespace, ":;?>"); if (!pb.eof() && *pb.position() == ':') { start = pb.skipChar(); mPort = pb.integer(); pb.skipToOneOf(ParseBuffer::Whitespace, ";?>"); } else { mPort = 0; } parseParameters(pb); if (!pb.eof() && *pb.position() == Symbols::QUESTION[0]) { const char* anchor = pb.position(); pb.skipToOneOf(Symbols::RA_QUOTE, Symbols::SEMI_COLON); pb.data(mEmbeddedHeadersText, anchor); }}ParserCategory*Uri::clone() const{ return new Uri(*this);}void Uri::setUriUserEncoding(char c, bool encode) { if(!mEncodingReady) { // if we don't init first, the changes we make will be lost when // init is invoked initialiseEncodingTables(); } if(c < 0) { ErrLog(<< "unable to change encoding for character '" << c << "', table size = " << URI_ENCODING_TABLE_SIZE); return; } mUriEncodingUserTable[c] = encode; }void Uri::setUriPasswordEncoding(char c, bool encode){ if(!mEncodingReady) { // if we don't init first, the changes we make will be lost when // init is invoked initialiseEncodingTables(); } if(c < 0) { ErrLog(<< "unable to change encoding for character '" << c << "', table size = " << URI_ENCODING_TABLE_SIZE); return; } mUriEncodingPasswordTable[c] = encode;}void Uri::initialiseEncodingTables() { // set all bits mUriEncodingUserTable.set(); mUriEncodingPasswordTable.set(); for(Data::size_type i = 0; i < mUriNonEncodingUserChars.size(); i++) { char& c = mUriNonEncodingUserChars.at(i); if(c >= 0) { mUriEncodingUserTable[c] = false; } } for(Data::size_type i = 0; i < mUriNonEncodingPasswordChars.size(); i++) { char& c = mUriNonEncodingPasswordChars.at(i); if(c >= 0) { mUriEncodingPasswordTable[c] = false; } } mEncodingReady = true;}inline bool Uri::shouldEscapeUserChar(char c){ if(!mEncodingReady) { initialiseEncodingTables(); } if(c < 0) { return false; } return mUriEncodingUserTable[c];}inline bool Uri::shouldEscapePasswordChar(char c){ if(!mEncodingReady) { initialiseEncodingTables(); } if(c < 0) { return false; } return mUriEncodingPasswordTable[c];} // should not encode user parameters unless its a tel?std::ostream& Uri::encodeParsed(std::ostream& str) const{ str << mScheme << Symbols::COLON; if (!mUser.empty()) {#ifdef HANDLE_CHARACTER_ESCAPING mUser.escapeToStream(str, shouldEscapeUserChar); #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, shouldEscapePasswordChar);#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;}SipMessage&Uri::embedded(){ checkParsed(); if (mEmbeddedHeaders == 0) { this->mEmbeddedHeaders = new SipMessage(); if (!mEmbeddedHeadersText.empty()) { ParseBuffer pb(mEmbeddedHeadersText.data(), mEmbeddedHeadersText.size()); this->parseEmbeddedHeaders(pb); } } return *mEmbeddedHeaders;}const SipMessage&Uri::embedded() const{ Uri* ncthis = const_cast<Uri*>(this); return ncthis->embedded();}voidUri::parseEmbeddedHeaders(ParseBuffer& pb){ 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); static const Data body("Body"); if (isEqualNoCase(body, headerName)) { mEmbeddedHeaders->setBody(decodedContents, len); } else { DebugLog(<< "Uri::parseEmbeddedHeaders(" << headerName << ", " << Data(decodedContents, len) << ")"); mEmbeddedHeaders->addHeader(Headers::getType(headerName.data(), headerName.size()), headerName.data(), headerName.size(), decodedContents, len); } }}std::ostream& Uri::encodeEmbeddedHeaders(std::ostream& str) const{ if (mEmbeddedHeaders) { mEmbeddedHeaders->encodeEmbedded(str); } else { // never decoded str << mEmbeddedHeadersText; } return str;}Data Uri::toString() const{ Data out; { oDataStream dataStream(out); this->encodeParsed(dataStream); } return out;}HashValueImp(resip::Uri, resip::Data::from(data).hash());/* ==================================================================== * The Vovida Software License, Version 1.0 * * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The names "VOCAL", "Vovida Open Communication Application Library", * and "Vovida Open Communication Application Library (VOCAL)" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor * may "VOCAL" appear in their name, without prior written * permission of Vovida Networks, Inc. * * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. * * ==================================================================== * * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc. For more information on Vovida Networks, Inc., please see * <http://www.vovida.org/>. * */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -