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

📄 chxliteprefs.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "chxliteprefs.h"
#include "hlxclib/fcntl.h"
#include "chxdataf.h"
#include "hxslist.h"
#include "hxstring.h"
#include "hxdir.h"
#include "hxccf.h"
#include "ihxpckts.h"
#include <ctype.h>
#include "hlxclib/stdlib.h"
#include "pathutil.h"
#include "hxthread.h"


BEGIN_INTERFACE_LIST(CHXLitePrefs)
    INTERFACE_LIST_ENTRY_SIMPLE(IHXPreferences)
    INTERFACE_LIST_ENTRY_SIMPLE(IHXPreferences3)
END_INTERFACE_LIST


// for keeping track of a pref value
class Pref
{
public:
    Pref(const char* pStr): m_bChanged(FALSE), m_strValue(pStr){}

    BOOL HasChanged() const { return m_bChanged;}
    void SetChanged(BOOL bChanged) { m_bChanged = bChanged;}
    void SetValue(const char* pStr) { m_strValue = pStr;}
    
    const char* Buffer() const { return m_strValue;}
    UINT32 Size() const {return m_strValue.GetLength() + 1;}

private:
    BOOL    m_bChanged;
    CHXString m_strValue;
};

// helpers local to this module
namespace LitePrefs
{
void ClearPrefs(CHXMapStringToOb* pPrefs);
CHXDataFile* OpenPrefFile(const char* pPath, UINT16 mode);
HX_RESULT WritePrefFile(const char* pPath, CHXStringList& shadows, const CHXMapStringToOb& prefs);
HX_RESULT WritePrefs(const CHXMapStringToOb* pPrefs, const char* pPath);
HX_RESULT ReadPrefs(const char* pPath,
			      CHXMapStringToOb* pPrefs);
HX_RESULT ParsePrefs(CHXDataFile* pFile,
			       CHXMapStringToOb* pPrefs,
			       CHXStringList* pShadows);
HX_RESULT StorePref(CHXMapStringToOb* pPrefs,
			      const char* pName,
			      const char* pValue,
			      BOOL bChanged = TRUE);
HX_RESULT RetrievePref(IHXCommonClassFactory* pFactory,
				 const CHXMapStringToOb* pPrefs,
				 const char* pName,
				 REF(IHXBuffer*) pValue);
void FindNewOrAlteredPrefs(const CHXMapStringToOb& memPrefs, 
                  const CHXMapStringToOb& origPrefs, 
                  CHXMapStringToOb& prefsOut);

BOOL SkipToken(char*& pos, INT32& nCount, char term);
BOOL ParseToken(char*& pos, INT32& nCount, char term, CHXString& token);
CHXString GetBasePath(const CHXString& strPath);
}


//
// get base path part of full filename path (strip off filename)
//
inline
CHXString LitePrefs::GetBasePath(const CHXString& strPath)
{
    CHXString strBase;
    INT32 idxSep = strPath.ReverseFind(OS_SEPARATOR_CHAR);
    if( idxSep != -1 )
    {
        strBase = strPath.Left(idxSep + 1);
    }
    return strBase;
}

//
// go through current prefs (in memory) and determine which entries
// are: a) set in a shadow but now have a different value; or b) not
// in a shadow to begin with
//
inline void
LitePrefs::FindNewOrAlteredPrefs(const CHXMapStringToOb& memPrefs, 
                  const CHXMapStringToOb& origPrefs, 
                  CHXMapStringToOb& prefsOut)
{
    // for each current pref setting (cast away const to work around deficiency in map inteface)...
    CHXMapStringToOb& memPrefs_ = (CHXMapStringToOb&)memPrefs;
    CHXMapStringToOb::Iterator iterEnd = memPrefs_.End();
    for(CHXMapStringToOb::Iterator iter = memPrefs_.Begin(); iter != iterEnd; ++iter)
    {
        Pref* pPref = (Pref*)*iter;
        const char* pKey = iter.get_key();
        HX_ASSERT(pPref);
        HX_ASSERT(pKey);
    
        // transfer this pref if is new or altered
        if( pPref->HasChanged() || (0 != origPrefs.Lookup(pKey)) )
        {
            prefsOut.SetAt(pKey, pPref);
        }
    }
}

//
// Prefs are read from primary file, then shadows. Settings in primary file override
// those in shadows (which are essentially defaults). Therefore the first value that 
// is found for a given pref is the value that remains in effect.
//
HX_RESULT 
LitePrefs::ReadPrefs(const char* pPath,
			CHXMapStringToOb* pPrefs)
{
    HX_RESULT res = HXR_FAIL;
    CHXDataFile* pFile = LitePrefs::OpenPrefFile(pPath, O_RDONLY);
    if (pFile)
    {
        CHXStringList shadows;
        res = LitePrefs::ParsePrefs(pFile, pPrefs, &shadows);
        pFile->Close();

        // use base path from current pref file to locate regerenced shadow file
        CHXString strBase = LitePrefs::GetBasePath(pPath);
    
        LISTPOSITION i = shadows.GetHeadPosition();
        while(i)
        {
	    const CHXString& strShadowFile = *((CHXString*) shadows.GetNext(i));
            CHXString strPath = HXPathUtil::CombinePath(strBase, strShadowFile);
	    res = LitePrefs::ReadPrefs(strPath, pPrefs);
        }
	    
        HX_DELETE(pFile);
    }
    return res;
}


// helper
CHXDataFile*
LitePrefs::OpenPrefFile(const char* pPath, UINT16 mode)
{
    CHXDataFile* pFile = CHXDataFile::Construct();
    if (pFile)
    {
	HX_RESULT res = pFile->Open(pPath, mode, TRUE);
	if (FAILED(res))
	{
            HX_DELETE(pFile);
	}
    }
    return pFile;
}

//
// write out the given file in our pref file format
//
HX_RESULT
LitePrefs::WritePrefFile(const char* pPath, CHXStringList& shadows, const CHXMapStringToOb& prefs)
{
    HX_RESULT hr = HXR_FAIL;
    CHXDataFile* pFile = LitePrefs::OpenPrefFile(pPath, O_WRONLY | O_CREAT | O_TRUNC);
    if (pFile)
    {
        //
        // write the shadow pref file references
        //
        LISTPOSITION j = shadows.GetHeadPosition();
        while(j)
	{
	    const CHXString& fileName = *((CHXString*) shadows.GetNext(j));
	    // format shadow, write to file
	    pFile->Write("[", 1);
	    pFile->Write(fileName, fileName.GetLength());
	    pFile->Write("]\n", 2);
	}

        //
        // write out preference name/value entries
        //

        // cast away const to work around deficiency in map interface...
        CHXMapStringToOb& prefs_ = (CHXMapStringToOb&)prefs;

        CHXMapStringToOb::Iterator iterEnd = prefs_.End();
        for(CHXMapStringToOb::Iterator iter = prefs_.Begin(); iter != iterEnd; ++iter)
        {
            const char* pPrefKey = iter.get_key();
            Pref* pPref = (Pref*)*iter;
            
	    pFile->Write(pPrefKey, strlen(pPrefKey));
	    pFile->Write("=", 1);

	    if (pPref->Size() > 1)
	    {
		// don't write the null terminator
		pFile->Write(pPref->Buffer(), pPref->Size()-1);
	    }
	    
	    pFile->Write("\n", 1);
	}
        HX_DELETE(pFile);
        hr = HXR_OK;
    }
    return hr;
}




HX_RESULT
LitePrefs::WritePrefs(const CHXMapStringToOb* pPrefs, const char* pPath)
{
    HX_RESULT res = HXR_FAIL;
    CHXDataFile* pFile = LitePrefs::OpenPrefFile(pPath, O_RDONLY);
    if (pFile)
    {
	// read current preference settings from files
	CHXStringList shadows;
	CHXMapStringToOb origPrefs;
	res = LitePrefs::ParsePrefs(pFile, &origPrefs, &shadows);
        HX_DELETE(pFile);
	if (SUCCEEDED(res))
	{
            // determine altered or new preferences
            CHXMapStringToOb newPrefs;
            FindNewOrAlteredPrefs(*pPrefs, origPrefs, newPrefs);

            // write out the prefs with our up-to-date values
            LitePrefs::WritePrefFile(pPath, shadows, newPrefs);
	}
        
	LitePrefs::ClearPrefs(&origPrefs);
    }
	
    return res;
}

HX_RESULT 
LitePrefs::StorePref(CHXMapStringToOb* pPrefs,
	const char* pName,
	const char* pValue,
	BOOL bChanged)
{
    Pref* pPref = NULL;
    if (pPrefs->Lookup(pName, (void*&)pPref))
    {
        // update existing pref
        pPref->SetValue(pValue);
    }
    else
    {   
        // create and add new pref
        pPref = new Pref(pValue);
        if(!pPref)
        {
            return HXR_OUTOFMEMORY;
        }
        pPrefs->SetAt(pName, pPref);
    }
    
    pPref->SetChanged(bChanged);
    return HXR_OK;
}


HX_RESULT
LitePrefs::ParsePrefs(CHXDataFile* pFile,
	 CHXMapStringToOb* pPrefs,
	 CHXStringList* pShadows)
{
    HX_ASSERT(pFile && pPrefs && pShadows);

    #define BUF_SZ	0x0400	// read file in 1k chunks

    ParseState eState = eParsingWhiteSpace;
    INT32 nCount = 0;
    CHXString strBuf;
    char* pos = 0;
    char* buf = strBuf.GetBuffer(BUF_SZ);

    CHXString sName;
    CHXString sValue;
    for (;;)
    {
	// read more data
	if (nCount == 0)
	{
	    nCount = (INT32)pFile->Read(buf, BUF_SZ);
	    if (nCount <= 0)
            {
                // end of file
		break;
            }
	    pos = buf;
	}
        switch(eState)
        {
        case eParsingValue:
        {
            if (LitePrefs::ParseToken(pos, nCount, '\n', sValue))
            {
                eState = eParsingWhiteSpace;
            
                // don't add this name value if name already exists in prefs
                if(0 ==  pPrefs->Lookup(sName))
                {
                    HX_RESULT res = LitePrefs::StorePref(pPrefs, sName, sValue, FALSE);
                    if (FAILED(res))
                    {
                        return res;
                    }
                }
                sName.Empty();
                sValue.Empty();
            }
            
        }
        break;
        case eParsingComment:
        {
            // skip to end of line
            if (LitePrefs::SkipToken(pos, nCount, '\n'))
            {
                eState = eParsingWhiteSpace;
            }
        }
        break;
        case eParsingName:
        {
            // name is everything up to '='
            if (LitePrefs::ParseToken(pos, nCount, '=', sName))
            {
                eState = eParsingValue;
            }
        }
        break;
        case eParsingShadow:
        {
            // shadow reference is everything up to closing ']'
            if (LitePrefs::ParseToken(pos, nCount, ']', sName))
            {
                eState = eParsingComment;
          
                // queue this up for parsing
                pShadows->AddTailString(sName);
                sName.Empty();
            }
        }
        break;
        case eParsingWhiteSpace:
        {
                // we're looking for something to parse
                switch (*pos)
                {
                    case '[':
                    {
                        eState = eParsingShadow;
                    }
                    break;

                    case '#':
                    case ';':

⌨️ 快捷键说明

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