chxavutil.cpp

来自「symbian 下的helix player源代码」· C++ 代码 · 共 344 行

CPP
344
字号
/************************************************************************
 * chxavutil.cpp
 * -------------
 *
 * Synopsis:
 * URL Utility namespace implementation.
 *
 * Target:
 * Symbian OS
 *
 *
 * (c) 1995-2003 RealNetworks, Inc. Patents pending. All rights reserved.
 *
 *****************************************************************************/

// Symbian includes...
#include <aknpopup.h>
#include <akntitle.h>
#include <eikenv.h>
#include <stdlib.h>
#include <coemain.h>

// Helix includes...
#include "hxtypes.h"
#include "hxassert.h"
#include "unkimp.h"
#include "ihxpckts.h"
#include "hxstring.h"
#include "hxurl.h"
#include "chxpckts.h"
#include "hlxclib/string.h"

// Includes from this project...
#include "realplayer.rsg"
#include "chxavutil.h"
#include "realplayer.hrh"
#include "chxavstringutils.h"
#include "chxavnamedisplaytrait.h"
#include "chxavcleanstring.h"
#include "chxavcleanupstack.h"
#include "chxavescapedstring.h"
#include "chxavstringutils.h"
#include "hxdebug_hxapi.h"
#include "hxapihelp.h"
#include "chxavmisc.h"
#include "comptr.h"
#include "chxavthread.h"
#include "chxavconfignames.h"

////////////////////////////////////////////////////
//
// return true if url prefix matches "{scheme}://"
//
bool CHXAvUtil::HasValidNetworkURLSchemePrefix(const TDesC& url)
{
    bool bHasValidPrefix = false;

    TInt idx = ScanPastURLSchemePrefix(url);
    if( -1 != idx)
    {
        _LIT(KExpected, "//");
        const TInt cchExpected = litSize(KExpected);

        if( idx + cchExpected <= url.Length() )
        {

            TPtrC ptr(url.Mid(idx, cchExpected));
            bHasValidPrefix = (0 == ptr.Compare(KExpected));
        }
    }

    return bHasValidPrefix;
}


//////////////////////////////////////////////////////////
//
// return idx to position past url scheme prefix "{scheme}:"
//
// return -1 if invalid scheme
//
TInt CHXAvUtil::ScanPastURLSchemePrefix(const TDesC& url)
{
    const TInt cchUrl = url.Length();
    
    const char* const pValidSchemeChars = "+.-"; // RFC 1738 2.1

    // scan up to first non-scheme character
    TInt idx = 0;
    for( ; idx < cchUrl; ++idx)
    {
        const char ch = url[idx];
        bool bIsValidSchemeChar = (isalnum(ch) || strchr(pValidSchemeChars, ch));
        if(!bIsValidSchemeChar)
        {
            break;
        }
    }

    // now we expect a colon
    if( idx > 0 && idx < cchUrl && url[idx] == ':')
    {
        ++idx;
    }
    else
    {
        idx = -1;
    }
        
    return idx;
}


//////////////////////////////////////
// test url for correct syntax
CHXAvUtil::ValidateUrlResult CHXAvUtil::ValidateUrl(const TDesC& url) 
{
    ValidateUrlResult res = vuGood;

    if (url.Length() == 0)
    {
	res = vuEmpty;
    }
    else if(!HasValidNetworkURLSchemePrefix(url))
    {
        // this check is done because it's hard to detect via CHXAvURLRep
        res = vuMissingScheme;
    }
    else
    {
        CHXString str;
        CHXAvStringUtils::DesToString(url, str);
        CHXAvURLRep rep(str);

        if(rep.Protocol() == "")
        {
            res = vuMissingScheme;
        }
        else if (strcasecmp(rep.Protocol(), "rtsp") && strcasecmp(rep.Protocol(), "file") && strcasecmp(rep.Protocol(), "http"))
        {
            res = vuUnsupportedScheme;
        }
        else if (!strcasecmp(rep.Protocol(), "rtsp") && (rep.Host() == ""))
        {
	    res = vuMissingHost;
        }
        else if (!strcasecmp(rep.Protocol(), "file") && (rep.Host() != ""))
        {
            res = vuHostUnexpected;
        }
        else if (rep.Path() == "")
        {
	    res = vuMissingPath;
        }
        else if (CHXAvUtil::ExtractFilename(rep.Path()) == "")
        {
	    res = vuMissingFile;
        }
        // XXXLCM check host length < 256 ? (see rfc)
    }
    return res;
}

////////////////////////////////////
// 
CHXString
CHXAvUtil::ExtractFilename(const CHXString& path)
{
    const char* pBegin = static_cast<const char*>(path);
    const char* p = pBegin + path.GetLength();
    
    // scan back to begin or first slash
    for( /*null*/; p > pBegin; --p)
    {
	if (*p == '/' || *p == '\\')
        {
            break;
        }
    }

    // advance past path sep if that's what we ended on
    if (*p == '/' || *p == '\\')
    {
        ++p;
    }

    return CHXString(p);
}

////////////////////////////////////////////////////////////
//
// return path-only part of file URL; does not fix escaped URLs
//
TPtrC 
CHXAvUtil::PathFromFileURL(const TDesC& fileURL)
{
    // return path portion only if url begins with 'file:///'
    TPtrC proto = fileURL.Left(litSize(KFileProtocolPrefix));
    if(0 == proto.CompareF(KFileProtocolPrefix) )
    {
	return fileURL.Mid(litSize(KFileProtocolPrefix));
    }

    // doesn't start with 'file:///'
    return TPtrC(fileURL);
}

////////////////////////////////////////////////////////////
// like PathFromFileURL, but allocates a copy that ensures
// back slashes (i.e., Epoc-style path separators) are used
// 
// epURL is in (possibly escaped) ep player format:
//
// file:///c:/folder/file.rm 
// file:///c:%5Cfolder%5Cfile.rm
// rtsp:///server/path/foo.rm <-- also ok
//
// returns something like:
//
// c:\folder\file.rm
//
HBufC* 
CHXAvUtil::AllocStdPathFromPlayerUrlL(const CHXString& strBadPath)
{
    // pass through CHXURL to get path
    CHXURL url(strBadPath);

    comptr<IHXValues> headers;
    headers.Take(url.GetProperties());
    HX_ASSERT(headers);
    
    //dbg::DumpObject(headers);

    CHXString strPath;
    val::GetString(headers, PROPERTY_FULLPATH, strPath, val::buffer);

    // possibly unescape (so it is more readable)
    CHXAvEscapedString escapedString(strPath);
    strPath = escapedString.GetUnEscapedStr();

    // skip '//' at beginning; PROPERTY_FULLPATH looks like:
    //
    //          '//c:/RealNetworks/Root/8khz-shrek-RV200_160x120_5fps_cook0_CBR_45kbps.rm'
    //
    const char* psz = strPath;
    
    while(*psz == '/')
    {
        ++psz;
    }
    
    HBufC* pPath = CHXAvStringUtils::AllocTextL(psz);
    TPtr ptr = pPath->Des();
    
    // fix it (e.g., c:\folder\file.rm)
    CHXAvUtil::ForwardToBackSlash(ptr);

    return pPath;
    
}

HBufC* 
CHXAvUtil::AllocHostFromPlayerUrlL(const CHXString& strUrl)
{
    // pass through CHXURL to get path
    CHXURL url(strUrl);

    comptr<IHXValues> headers;
    headers.Take(url.GetProperties());
    HX_ASSERT(headers);
    
    //dbg::DumpObject(headers);

    CHXString strHost;
    val::GetString(headers, PROPERTY_HOST, strHost, val::buffer);

    // possibly unescape (so it is more readable)
    CHXAvEscapedString escapedString(strHost);
    strHost = escapedString.GetUnEscapedStr();
    
    HBufC* pPath = CHXAvStringUtils::AllocTextL(strHost);

    return pPath;
    
}


//////////////////////////////////////////////////////
// wait a bit and process some active objects
//
void 
CHXAvUtil::ActiveWait(TInt msTotalWait, TInt msPerSleep)
{
    HX_ASSERT(msTotalWait >= msPerSleep);
    const TInt tries = msTotalWait/msPerSleep;

    for(TInt idx = 0; idx < tries; ++idx)
    {
        CHXAvThread::ProcessPendingRequests();
        User::After(msPerSleep * 1000);
    }
}


////////////////////////////////////////////
// AllocStdPathFromPlayerUrlL() override
HBufC* 
CHXAvUtil::AllocStdPathFromPlayerUrlL(const TDesC& url)
{
    return AllocStdPathFromPlayerUrlL(CHXAvStringUtils::DescToString(url));
}

////////////////////////////////////////////////
//
HBufC* 
CHXAvUtil::AllocDisplayTextForPlayerUrlL(const TDesC& url, bool bHideExt)
{
    // ensure url is not escaped
    CHXString strOrigUrl = CHXAvStringUtils::DescToString(url);
    HBufC* pGoodPath = AllocStdPathFromPlayerUrlL(strOrigUrl);
    if( 0 == pGoodPath->Length() )
    {
        // some urls (e.g. http with query params) don't have  a path; use host in that case
        HX_DELETE(pGoodPath);
        pGoodPath = AllocHostFromPlayerUrlL(strOrigUrl);
        return pGoodPath;
    }

    AUTO_PUSH_POP_DEL(pGoodPath);

    CHXAvNameDisplayTrait fixer(bHideExt);
    HBufC* pOut = fixer.GetDisplayText(*pGoodPath).first.AllocL();

    TPtr ptr = pOut->Des();
    CHXAvMisc::MakeDisplayFriendly(ptr);

    return pOut;
}





⌨️ 快捷键说明

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