⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sbineturl.cpp

📁 sloedgy open sip stack source code
💻 CPP
📖 第 1 页 / 共 3 页
字号:
 #else /* not WIN32 */
 
 struct URLInfo
 {
   SBinetString protocol;
   SBinetString fragment;
   SBinetString query;
   SBinetString path;
   SBinetString host;
   int port;
 };
 
 static VXIinetResult parseURL(const VXIchar* const url, URLInfo& urlInfo)
 {
   // Initialize the URLInfo structure.
   urlInfo.port = -1;
 
   // Check to see if the URL is invalid.
   if (!url || (url[0] == 0))
     return VXIinet_RESULT_NON_FATAL_ERROR;
 
   VXIchar* tmpUrl = new VXIchar [wcslen(url) + 1];
   wcscpy(tmpUrl, url);
   const VXIchar* tmpUrlOriginal = tmpUrl;
 
   // Check for the protocol part.
   bool needToCanonicalize = false;
   VXIchar* protocolEndPtr = wcschr(tmpUrl, L':');
   if (protocolEndPtr && (!wcsncmp(tmpUrl, L"file", 4) || !wcsncmp(tmpUrl, L"http", 4)))
   {
     // Found the protocol.  Copy it to the URLInfo structure.
     int protLen = protocolEndPtr - tmpUrl;
     urlInfo.protocol.append(tmpUrl, protLen);
 
     // Advance past the protocol part of the URL.
     if (0 == wcsncmp(protocolEndPtr + 1, L"//", 2))
     {
       tmpUrl = protocolEndPtr + 3;
     }
     else
     {
       tmpUrl = protocolEndPtr + 1;
       needToCanonicalize = 1;
     }
   }
   else
   {
     // The default protocol is the file protocol.
     urlInfo.protocol = L"file";
   }
 
   if (!wcscmp(urlInfo.protocol.c_str(), L"file"))
   {
     // If the URL uses the file protocol, the rest of the URL is the path.
 
     // The path needs to be canonicalized.  It could still be an absolute
     // path if it starts with a '/'.  If it does not, create the absolute
     // path by prepending the current path with the current directory.
     if (needToCanonicalize && tmpUrl[0] != '/')
     {
       char buf[1024];
       urlInfo.path = getcwd(buf, 1024);
       urlInfo.path += '/';
     }
     VXIchar* endPtr = wcschr(tmpUrl, L'?');
     VXIchar* fragmentPtr = wcschr(tmpUrl, L'#');
     if (endPtr)
     {
       if (fragmentPtr && (fragmentPtr < endPtr))
         endPtr = fragmentPtr;
     }
     else if (fragmentPtr)
     {
       endPtr = fragmentPtr;
     }
 
     // Strip the query and/or fragment part of the file URI if
     // there is any.
     if (endPtr)
       *endPtr = L'\0';
 
     urlInfo.path += tmpUrl;
   }
   else
   {
     // Check for the fragment part.
     VXIchar* fragmentPtr = wcsrchr(tmpUrl, L'#');
     if (fragmentPtr)
     {
       // Found the fragment.  Copy it to the URLInfo structure.
       *fragmentPtr = L'\0';
       urlInfo.fragment = ++fragmentPtr;
     }
 
     // Check for the query part.
     VXIchar* queryPtr = wcsrchr(tmpUrl, L'?');
     if (queryPtr)
     {
       // Found the query.  Copy it to the URLInfo structure.
       *queryPtr = L'\0';
       urlInfo.query = ++queryPtr;
     }
 
     // Check for the path part.
     VXIchar* pathPtr = wcschr(tmpUrl, L'/');
     if (pathPtr)
     {
       // Found the path.  Copy it to the URLInfo structure.
       // First, we need to UTF-8 encode it and then escape it.
       SBinetNString utfPath, escapedPath;
       SBinetHttpUtils::utf8encode(pathPtr, utfPath);
       SBinetHttpUtils::escapeString(utfPath.c_str(),
                                     SBinetHttpUtils::URL_PATH,
                                     escapedPath);
 
       urlInfo.path = escapedPath;
 
       // Append the query to the path.
       if (queryPtr)
       {
         // Add the query to the path.
         urlInfo.path += L'?';
         urlInfo.path += urlInfo.query;
       }
 
       *pathPtr = L'\0';
     }
     else
     {
       // No path was specified so set the path to root ("/").
       urlInfo.path = "/";
     }
 
     // Check for the username:password part.
     VXIchar* userpassEndPtr = wcschr(tmpUrl, L'@');
     if (userpassEndPtr)
     {
       // For now, just ignore username and password.
       tmpUrl = userpassEndPtr + 1;
     }
 
     // Check for the port part.
     VXIchar* portPtr = wcsrchr(tmpUrl, L':');
     if (portPtr)
     {
       *portPtr = L'\0';
       ++portPtr;
 
       // Check if the port is valid (all digits).
       VXIchar* end = NULL;
       long port = wcstol(portPtr, &end, 10);
 
       if ((end) && (*end == L'\0'))
         urlInfo.port = (int) port;
     }
 
     // The rest is the host part.
     urlInfo.host = tmpUrl;
 
     if (urlInfo.host[0] == 0)
     {
       delete [] tmpUrlOriginal;
       return VXIinet_RESULT_NON_FATAL_ERROR;
     }
   }
 
   delete [] tmpUrlOriginal;
 
   return VXIinet_RESULT_SUCCESS;
 }
 
 typedef std::basic_string<VXIchar> vxistring;
 
 static VXIinetResult combineURL(const VXIchar* const baseUrl,
                                 const VXIchar* const relativeUrl,
                                 SBinetString& absoluteUrl)
 {
   // Check to see if the relative URL is referencing another host
   //    (i.e. the protocol is specified).
   const VXIchar* protocolEndPtr = wcschr(relativeUrl, L':');
   if (!baseUrl || (protocolEndPtr && (!wcsncmp(relativeUrl, L"file", 4) || !wcsncmp(relativeUrl, L"http", 4))))
   {
     // HACK to allow OSR to load absolute local URLs
     if (wcsstr(relativeUrl, L"/file://"))
       absoluteUrl = relativeUrl + 1;
     else
       absoluteUrl = relativeUrl;
   }
   else
   {
     absoluteUrl = baseUrl;
 
     const VXIchar* absoluteUrlStr = absoluteUrl.c_str();
     const VXIchar* pathPtr = wcsstr(absoluteUrlStr, L"://");
     if (pathPtr)
       pathPtr += 3;
     else
       pathPtr = absoluteUrlStr;
 
     if (relativeUrl[0] == L'/' && relativeUrl[1] != L'/')
     {
       // The relative URL is an absolute path.
 
       // Find the pointer to the beginning of the path in the absoluteUrl.
       pathPtr = wcschr(pathPtr, L'/');
       if (pathPtr)
         absoluteUrl.resize(pathPtr - absoluteUrlStr);
     }
     else
     {
       // The relative URL is a relative path.
 
       // Find the pointer to the end of the path.
       pathPtr = wcsrchr(pathPtr, L'/');
       if (pathPtr)
       {
         // Clear anything after the last slash in the path part of the
         //    absolute URL.
         ++pathPtr;
         absoluteUrl.resize(pathPtr - absoluteUrlStr);
       }
       else
       {
         // Add a slash at the end of the absolute URL if it didn't have one.
         absoluteUrl += L"/";
       }
     }
 
     // Remove the ../ and move up
     // the abs. url accordingly
     // Remove .. from relative url and go up one level in absolute url
     // Remove the last '/' from the abs. url    
     vxistring absUrl = absoluteUrl.c_str();
     if( absUrl[absUrl.length() - 1] == L'/' )
       absUrl.erase(absUrl.length() - 1 );
     
     // find the first "../" string from rel. url
     vxistring relUrl = relativeUrl;
     vxistring::size_type pos = 0;
     vxistring::size_type idx, i;
     idx = relUrl.find(L"../", pos);
 
     while( idx != vxistring::npos )
     {
       // first remove the ../ from rel. url
       relUrl.erase(idx, idx+3);
       // go up one level from the abs. url
       i = absUrl.rfind(L"/");
       if( i != vxistring::npos )
         absUrl.erase(i);
       idx = relUrl.find(L"../", idx - 2);
     }
     
     // take care of '//' 
     if( relUrl.substr(0,2) == L"//" ) {
       idx = absUrl.find(L"://");
       if ( idx != vxistring::npos )
         absUrl.erase(idx+1);  
     }
     
     // insert the last '/' to abs. url
     if( relUrl[0] != L'/' )
       absUrl.push_back(L'/');
     absUrl += relUrl.c_str();
     absoluteUrl = absUrl.c_str();
   }
 
   return VXIinet_RESULT_SUCCESS;
 }
 
 VXIinetResult
 SBinetURL::parse(const VXIchar* pszUrl,
                  const VXIchar* pszUrlBase)
 {
   // TBD: Must apply SPR 7530 fix here too, for now only in WinInetResolveUrl,
   // support for relative URL starting with / as specified by the RFC that
   // defines file:// access
   VXIinetResult eResult( VXIinet_RESULT_SUCCESS );
 
   if( !pszUrl || !pszUrl[0])
   {
     //Error(200, L"%s%s", L"Operation", L"parse URL");
     return VXIinet_RESULT_INVALID_ARGUMENT;
   }
 
   if (pszUrlBase != NULL)
     _baseURL = pszUrlBase;
   else
     _baseURL = L"";
 
   // Combine the base and relative URLs to get an absolute URL.
   eResult = combineURL(pszUrlBase, pszUrl, _absoluteURL);
 
   if (eResult == VXIinet_RESULT_SUCCESS)
   {
     // Parse the absolute URL into its components.
     URLInfo urlInfo;
     eResult = parseURL(_absoluteURL.c_str(), urlInfo);
 
     if (eResult == VXIinet_RESULT_SUCCESS)
     {
       if (!wcscmp(urlInfo.protocol.c_str(), L"file"))
       {
         _protocol = FILE_PROTOCOL;
       }
       else if (!wcscmp(urlInfo.protocol.c_str(), L"http"))
       {
         _protocol = HTTP_PROTOCOL;
         _host = urlInfo.host;
         _port = urlInfo.port == -1 ? 80 : urlInfo.port;
       }
       else if (!wcscmp(urlInfo.protocol.c_str(), L"https"))
       {
         _protocol = HTTPS_PROTOCOL;
         _host = urlInfo.host;
         _port = urlInfo.port == -1 ? 443 : urlInfo.port;
       }
       else
       {
         eResult = VXIinet_RESULT_NON_FATAL_ERROR;
       }
     }
 
     if (eResult == VXIinet_RESULT_SUCCESS)
     {
       _strPath = urlInfo.path;
 
       // Remove trailing / in absolute URL to ensure that www.speechworks.com
       // and www.speechworks.com/ are seen as the same URL.
       int idx = _absoluteURL.length() - 1;
       if (_absoluteURL[idx] == L'/')
         _absoluteURL.resize(idx);
     }
   }
 
   N_absoluteURL = _absoluteURL;
   N_baseURL = _baseURL;
   N_host = _host;
   N_strPath = _strPath;
 
   return eResult;
 }
 
 #endif /* WIN32 */
 
 
 
 SBinetNString SBinetURL::valueToNString(const VXIValue* value)
 {
   // Convert numeric types using a narrow character buffer in order to
   // avoid the need for swprintf( ) which doesn't exist in the GNU
   // GCC C library for GCC 2.x and earlier.
   char tempBuf[32];
   *tempBuf = '\0';
   switch (VXIValueGetType(value))
   {
    case VALUE_BOOLEAN:
      {
        VXIbool valBool = VXIBooleanValue( (const VXIBoolean *)value );
        sprintf (tempBuf, "%s", valBool ? "true" : "false");
      }
      break;
    case VALUE_INTEGER:
      {
        VXIint32 valInt = VXIIntegerValue( (const VXIInteger *)value );
        sprintf (tempBuf, "%d", valInt);
      }
      break;
    case VALUE_FLOAT:
      {
        VXIflt32 valFloat = VXIFloatValue( (const VXIFloat *)value );
        sprintf (tempBuf, "%f", valFloat);
      }
      break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -