chxavutil.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:8k
源码类别:

Symbian

开发平台:

C/C++

  1. /************************************************************************
  2.  * chxavutil.cpp
  3.  * -------------
  4.  *
  5.  * Synopsis:
  6.  * URL Utility namespace implementation.
  7.  *
  8.  * Target:
  9.  * Symbian OS
  10.  *
  11.  *
  12.  * (c) 1995-2003 RealNetworks, Inc. Patents pending. All rights reserved.
  13.  *
  14.  *****************************************************************************/
  15. // Symbian includes...
  16. #include <aknpopup.h>
  17. #include <akntitle.h>
  18. #include <eikenv.h>
  19. #include <stdlib.h>
  20. #include <coemain.h>
  21. // Helix includes...
  22. #include "hxtypes.h"
  23. #include "hxassert.h"
  24. #include "unkimp.h"
  25. #include "ihxpckts.h"
  26. #include "hxstring.h"
  27. #include "hxurl.h"
  28. #include "chxpckts.h"
  29. #include "hlxclib/string.h"
  30. // Includes from this project...
  31. #include "realplayer.rsg"
  32. #include "chxavutil.h"
  33. #include "realplayer.hrh"
  34. #include "chxavstringutils.h"
  35. #include "chxavnamedisplaytrait.h"
  36. #include "chxavcleanstring.h"
  37. #include "chxavcleanupstack.h"
  38. #include "chxavescapedstring.h"
  39. #include "chxavstringutils.h"
  40. #include "hxdebug_hxapi.h"
  41. #include "hxapihelp.h"
  42. #include "chxavmisc.h"
  43. #include "comptr.h"
  44. #include "chxavthread.h"
  45. #include "chxavconfignames.h"
  46. ////////////////////////////////////////////////////
  47. //
  48. // return true if url prefix matches "{scheme}://"
  49. //
  50. bool CHXAvUtil::HasValidNetworkURLSchemePrefix(const TDesC& url)
  51. {
  52.     bool bHasValidPrefix = false;
  53.     TInt idx = ScanPastURLSchemePrefix(url);
  54.     if( -1 != idx)
  55.     {
  56.         _LIT(KExpected, "//");
  57.         const TInt cchExpected = litSize(KExpected);
  58.         if( idx + cchExpected <= url.Length() )
  59.         {
  60.             TPtrC ptr(url.Mid(idx, cchExpected));
  61.             bHasValidPrefix = (0 == ptr.Compare(KExpected));
  62.         }
  63.     }
  64.     return bHasValidPrefix;
  65. }
  66. //////////////////////////////////////////////////////////
  67. //
  68. // return idx to position past url scheme prefix "{scheme}:"
  69. //
  70. // return -1 if invalid scheme
  71. //
  72. TInt CHXAvUtil::ScanPastURLSchemePrefix(const TDesC& url)
  73. {
  74.     const TInt cchUrl = url.Length();
  75.     
  76.     const char* const pValidSchemeChars = "+.-"; // RFC 1738 2.1
  77.     // scan up to first non-scheme character
  78.     TInt idx = 0;
  79.     for( ; idx < cchUrl; ++idx)
  80.     {
  81.         const char ch = url[idx];
  82.         bool bIsValidSchemeChar = (isalnum(ch) || strchr(pValidSchemeChars, ch));
  83.         if(!bIsValidSchemeChar)
  84.         {
  85.             break;
  86.         }
  87.     }
  88.     // now we expect a colon
  89.     if( idx > 0 && idx < cchUrl && url[idx] == ':')
  90.     {
  91.         ++idx;
  92.     }
  93.     else
  94.     {
  95.         idx = -1;
  96.     }
  97.         
  98.     return idx;
  99. }
  100. //////////////////////////////////////
  101. // test url for correct syntax
  102. CHXAvUtil::ValidateUrlResult CHXAvUtil::ValidateUrl(const TDesC& url) 
  103. {
  104.     ValidateUrlResult res = vuGood;
  105.     if (url.Length() == 0)
  106.     {
  107. res = vuEmpty;
  108.     }
  109.     else if(!HasValidNetworkURLSchemePrefix(url))
  110.     {
  111.         // this check is done because it's hard to detect via CHXAvURLRep
  112.         res = vuMissingScheme;
  113.     }
  114.     else
  115.     {
  116.         CHXString str;
  117.         CHXAvStringUtils::DesToString(url, str);
  118.         CHXAvURLRep rep(str);
  119.         if(rep.Protocol() == "")
  120.         {
  121.             res = vuMissingScheme;
  122.         }
  123.         else if (strcasecmp(rep.Protocol(), "rtsp") && strcasecmp(rep.Protocol(), "file") && strcasecmp(rep.Protocol(), "http"))
  124.         {
  125.             res = vuUnsupportedScheme;
  126.         }
  127.         else if (!strcasecmp(rep.Protocol(), "rtsp") && (rep.Host() == ""))
  128.         {
  129.     res = vuMissingHost;
  130.         }
  131.         else if (!strcasecmp(rep.Protocol(), "file") && (rep.Host() != ""))
  132.         {
  133.             res = vuHostUnexpected;
  134.         }
  135.         else if (rep.Path() == "")
  136.         {
  137.     res = vuMissingPath;
  138.         }
  139.         else if (CHXAvUtil::ExtractFilename(rep.Path()) == "")
  140.         {
  141.     res = vuMissingFile;
  142.         }
  143.         // XXXLCM check host length < 256 ? (see rfc)
  144.     }
  145.     return res;
  146. }
  147. ////////////////////////////////////
  148. // 
  149. CHXString
  150. CHXAvUtil::ExtractFilename(const CHXString& path)
  151. {
  152.     const char* pBegin = static_cast<const char*>(path);
  153.     const char* p = pBegin + path.GetLength();
  154.     
  155.     // scan back to begin or first slash
  156.     for( /*null*/; p > pBegin; --p)
  157.     {
  158. if (*p == '/' || *p == '\')
  159.         {
  160.             break;
  161.         }
  162.     }
  163.     // advance past path sep if that's what we ended on
  164.     if (*p == '/' || *p == '\')
  165.     {
  166.         ++p;
  167.     }
  168.     return CHXString(p);
  169. }
  170. ////////////////////////////////////////////////////////////
  171. //
  172. // return path-only part of file URL; does not fix escaped URLs
  173. //
  174. TPtrC 
  175. CHXAvUtil::PathFromFileURL(const TDesC& fileURL)
  176. {
  177.     // return path portion only if url begins with 'file:///'
  178.     TPtrC proto = fileURL.Left(litSize(KFileProtocolPrefix));
  179.     if(0 == proto.CompareF(KFileProtocolPrefix) )
  180.     {
  181. return fileURL.Mid(litSize(KFileProtocolPrefix));
  182.     }
  183.     // doesn't start with 'file:///'
  184.     return TPtrC(fileURL);
  185. }
  186. ////////////////////////////////////////////////////////////
  187. // like PathFromFileURL, but allocates a copy that ensures
  188. // back slashes (i.e., Epoc-style path separators) are used
  189. // 
  190. // epURL is in (possibly escaped) ep player format:
  191. //
  192. // file:///c:/folder/file.rm 
  193. // file:///c:%5Cfolder%5Cfile.rm
  194. // rtsp:///server/path/foo.rm <-- also ok
  195. //
  196. // returns something like:
  197. //
  198. // c:folderfile.rm
  199. //
  200. HBufC* 
  201. CHXAvUtil::AllocStdPathFromPlayerUrlL(const CHXString& strBadPath)
  202. {
  203.     // pass through CHXURL to get path
  204.     CHXURL url(strBadPath);
  205.     comptr<IHXValues> headers;
  206.     headers.Take(url.GetProperties());
  207.     HX_ASSERT(headers);
  208.     
  209.     //dbg::DumpObject(headers);
  210.     CHXString strPath;
  211.     val::GetString(headers, PROPERTY_FULLPATH, strPath, val::buffer);
  212.     // possibly unescape (so it is more readable)
  213.     CHXAvEscapedString escapedString(strPath);
  214.     strPath = escapedString.GetUnEscapedStr();
  215.     // skip '//' at beginning; PROPERTY_FULLPATH looks like:
  216.     //
  217.     //          '//c:/RealNetworks/Root/8khz-shrek-RV200_160x120_5fps_cook0_CBR_45kbps.rm'
  218.     //
  219.     const char* psz = strPath;
  220.     
  221.     while(*psz == '/')
  222.     {
  223.         ++psz;
  224.     }
  225.     
  226.     HBufC* pPath = CHXAvStringUtils::AllocTextL(psz);
  227.     TPtr ptr = pPath->Des();
  228.     
  229.     // fix it (e.g., c:folderfile.rm)
  230.     CHXAvUtil::ForwardToBackSlash(ptr);
  231.     return pPath;
  232.     
  233. }
  234. HBufC* 
  235. CHXAvUtil::AllocHostFromPlayerUrlL(const CHXString& strUrl)
  236. {
  237.     // pass through CHXURL to get path
  238.     CHXURL url(strUrl);
  239.     comptr<IHXValues> headers;
  240.     headers.Take(url.GetProperties());
  241.     HX_ASSERT(headers);
  242.     
  243.     //dbg::DumpObject(headers);
  244.     CHXString strHost;
  245.     val::GetString(headers, PROPERTY_HOST, strHost, val::buffer);
  246.     // possibly unescape (so it is more readable)
  247.     CHXAvEscapedString escapedString(strHost);
  248.     strHost = escapedString.GetUnEscapedStr();
  249.     
  250.     HBufC* pPath = CHXAvStringUtils::AllocTextL(strHost);
  251.     return pPath;
  252.     
  253. }
  254. //////////////////////////////////////////////////////
  255. // wait a bit and process some active objects
  256. //
  257. void 
  258. CHXAvUtil::ActiveWait(TInt msTotalWait, TInt msPerSleep)
  259. {
  260.     HX_ASSERT(msTotalWait >= msPerSleep);
  261.     const TInt tries = msTotalWait/msPerSleep;
  262.     for(TInt idx = 0; idx < tries; ++idx)
  263.     {
  264.         CHXAvThread::ProcessPendingRequests();
  265.         User::After(msPerSleep * 1000);
  266.     }
  267. }
  268. ////////////////////////////////////////////
  269. // AllocStdPathFromPlayerUrlL() override
  270. HBufC* 
  271. CHXAvUtil::AllocStdPathFromPlayerUrlL(const TDesC& url)
  272. {
  273.     return AllocStdPathFromPlayerUrlL(CHXAvStringUtils::DescToString(url));
  274. }
  275. ////////////////////////////////////////////////
  276. //
  277. HBufC* 
  278. CHXAvUtil::AllocDisplayTextForPlayerUrlL(const TDesC& url, bool bHideExt)
  279. {
  280.     // ensure url is not escaped
  281.     CHXString strOrigUrl = CHXAvStringUtils::DescToString(url);
  282.     HBufC* pGoodPath = AllocStdPathFromPlayerUrlL(strOrigUrl);
  283.     if( 0 == pGoodPath->Length() )
  284.     {
  285.         // some urls (e.g. http with query params) don't have  a path; use host in that case
  286.         HX_DELETE(pGoodPath);
  287.         pGoodPath = AllocHostFromPlayerUrlL(strOrigUrl);
  288.         return pGoodPath;
  289.     }
  290.     AUTO_PUSH_POP_DEL(pGoodPath);
  291.     CHXAvNameDisplayTrait fixer(bHideExt);
  292.     HBufC* pOut = fixer.GetDisplayText(*pGoodPath).first.AllocL();
  293.     TPtr ptr = pOut->Des();
  294.     CHXAvMisc::MakeDisplayFriendly(ptr);
  295.     return pOut;
  296. }