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

📄 unix_pref.cpp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: RCSL 1.0/RPSL 1.0 
 *  
 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
 *      
 * The contents of this file, and the files included with this file, are 
 * subject to the current version of the RealNetworks Public Source License 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
 * in which case the RCSL will apply. You may also obtain the license terms 
 * directly from RealNetworks.  You may not use this file except in 
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
 * applicable to this file, the RCSL.  Please see the applicable RPSL or 
 * RCSL for the rights, obligations and limitations governing use of the 
 * contents of the file.  
 *  
 * This file is part of the Helix DNA Technology. RealNetworks is the 
 * developer of the Original Code and owns the copyrights in the portions 
 * it created. 
 *  
 * This file, and the files included with this file, is distributed and made 
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
 * 
 * Technology Compatibility Kit Test Suite(s) Location: 
 *    http://www.helixcommunity.org/content/tck 
 * 
 * Contributor(s): 
 *  
 * ***** END LICENSE BLOCK ***** */ 

#ifdef _BEOS
#include <Path.h>
#include <FindDirectory.h>
#endif

#include <string.h>
#include <unistd.h>
#ifndef _VXWORKS
#include <strings.h>
#include <sys/uio.h> 
#include <sys/file.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/stat.h>
#include <ctype.h>
#include <errno.h>

#include "hxslist.h"
#include "hxmap.h"
#include "hxtypes.h"
#include "hxresult.h"
#include "hxheap.h"
#include "hxstrutl.h"

#include "hxcom.h"
#include "ihxpckts.h"
#include "chxpckts.h"

#include "unix_pref.h"
#include "dbcs.h"  // HXReverseFindChar prototype
#include "unix_misc.h"
#include "cunixprefutils.h"
#define ARE_PREFS_LOADED_PREF "ArePrefsLoaded"

extern char** environ;

static CHXString FixupCompany (const char *pCompany)
{
    char *pTmpCompany = new_string(pCompany);
    char *pos  = strchr(pTmpCompany, ',');
    if (pos) *pos = 0;
    strlwr(pTmpCompany);
    CHXString ret = pTmpCompany;
    HX_VECTOR_DELETE(pTmpCompany);
    return ret;
}

static char *CIGetenv(const char *pKey)
{
    UINT32 keylen = strlen(pKey);
    char *pArr = new char[keylen + 2];
    sprintf(pArr, "%s=", pKey); /* Flawfinder: ignore */
    for (char **ppEnv = environ ; *ppEnv ; ++ppEnv)
    {
	if (!strnicmp(*ppEnv, pArr, keylen +1))
	{
	    HX_VECTOR_DELETE(pArr);
	    return *ppEnv + keylen + 1;
	}
    }
    HX_VECTOR_DELETE(pArr);
    return NULL;
}

static int CIPutenv(const char *pKey)
{
    char *pNewVal = new_string(pKey);
    char *pEquals = strchr(pNewVal, '=');
    HX_ASSERT(pEquals);
    if (pEquals)
    {
        *pEquals = '\0';
        strlwr(pNewVal);
        *pEquals = '=';
    }

    return putenv(pNewVal);
}

static void CIUnsetEnv(const char *pKey)
{
    unsigned int keylen = strlen(pKey);
    char *pArr = new char[keylen + 2];
    sprintf(pArr, "%s=", pKey); /* Flawfinder: ignore */

    for (char **ppEnv = environ ; *ppEnv ; ++ppEnv)
    {
        if (!strnicmp(*ppEnv, pArr, keylen +1))
        {
            //delete [] *ppEnv;  // pjg all uses of this delete the string
            while (*ppEnv)
            {
                *ppEnv = *(ppEnv+1);
                ppEnv++;
            }
            HX_VECTOR_DELETE(pArr);
            return;
        }
    }
    HX_VECTOR_DELETE(pArr);
}


void CUnixPref::ConstructFamily(CHXString &ret)
{
    HX_ASSERT(!strchr(m_pCompany, '\n'));
    HX_ASSERT(!strchr(m_pCompany, ' '));
    HX_ASSERT(!strchr(m_pCompany, '\t'));
    HX_ASSERT(!strchr(m_pCompany, '='));
    HX_ASSERT(!strchr(m_pProduct, '\n'));
    HX_ASSERT(!strchr(m_pProduct, ' '));
    HX_ASSERT(!strchr(m_pProduct, '\t'));
    HX_ASSERT(!strchr(m_pProduct, '='));
    
    UINT32 nEstimatedSize = strlen ("HXPref_") + 
	6 * 1 +   // for underscores
	strlen(m_pCompany) +
	strlen(m_pProduct) +
	30; // 2 ints + fudge;

    char *pTmp = new char[nEstimatedSize];

    SafeSprintf(pTmp, nEstimatedSize, "HXPref_%s_%s_%d_%d_", 
	    (const char *)m_pCompany, (const char *)m_pProduct, m_nMajor, m_nMinor);
    ret = pTmp;
    HX_VECTOR_DELETE(pTmp);
}

void CUnixPref::ConstructPref(const char *pref,
			      CHXString &ret)
{
    HX_ASSERT(!strchr(m_pCompany, '\n'));
    HX_ASSERT(!strchr(m_pCompany, ' '));
    HX_ASSERT(!strchr(m_pCompany, '\t'));
    HX_ASSERT(!strchr(m_pCompany, '='));
    HX_ASSERT(!strchr(m_pProduct, '\n'));
    HX_ASSERT(!strchr(m_pProduct, ' '));
    HX_ASSERT(!strchr(m_pProduct, '\t'));
    HX_ASSERT(!strchr(m_pProduct, '='));
    
    UINT32 nEstimatedSize = strlen ("HXPref_") + 
	6 * 1 +   // for underscores
	strlen(m_RootKeyName) +
	strlen(m_pCompany) +
	strlen(m_pProduct) +
	strlen(pref) + 
	30; // 2 ints + fudge;

    char *pTmp = new char[nEstimatedSize];

    if (strlen(m_RootKeyName))
    {
	SafeSprintf(pTmp, nEstimatedSize, "HXPref_%s_%s_%s_%d_%d_%s", 
		m_RootKeyName, (const char *)m_pCompany, (const char *)m_pProduct, 
		m_nMajor, m_nMinor, pref);
    }
    else
    {
	SafeSprintf(pTmp, nEstimatedSize, "HXPref_%s_%s_%d_%d_%s", 
		(const char *)m_pCompany, (const char *)m_pProduct, 
		m_nMajor, m_nMinor, pref);
    }
    ret = pTmp;
    HX_VECTOR_DELETE(pTmp);
}

void CUnixPref::ConstructPrefAssignment(const char *pref,
					const char *pValue,
					CHXString &ret,
                                        BOOL bEscapeValue)
{
    HX_ASSERT(!strchr(m_pCompany, '\n'));
    HX_ASSERT(!strchr(m_pCompany, ' '));
    HX_ASSERT(!strchr(m_pCompany, '\t'));
    HX_ASSERT(!strchr(m_pCompany, '='));
    HX_ASSERT(!strchr(m_pProduct, '\n'));
    HX_ASSERT(!strchr(m_pProduct, ' '));
    HX_ASSERT(!strchr(m_pProduct, '\t'));
    HX_ASSERT(!strchr(m_pProduct, '='));

    char *pEscapedValue = NULL;
    
    if (bEscapeValue)
    {
        EscapeNewLine(pValue, pEscapedValue);
    }

    UINT32 nEstimatedSize = strlen ("HXPref_") + 
	6 * 1 +   // for underscores
	strlen(m_RootKeyName) +
	strlen(m_pCompany) +
	strlen(m_pProduct) +
	strlen(pref) + 
	strlen(pEscapedValue ? pEscapedValue : pValue) +
	30; // 2 ints + fudge;

    char *pTmp = new char[nEstimatedSize];

    if (strlen (m_RootKeyName))
    {
	SafeSprintf(pTmp, nEstimatedSize, "HXPref_%s_%s_%s_%d_%d_%s=%s", 
		m_RootKeyName, (const char *)m_pCompany, (const char *)m_pProduct, 
		m_nMajor, m_nMinor, pref, 
		pEscapedValue? pEscapedValue :pValue);
    }
    else
    {
	SafeSprintf(pTmp, nEstimatedSize, "HXPref_%s_%s_%d_%d_%s=%s", 
		(const char *)m_pCompany, (const char *)m_pProduct, 
		m_nMajor, m_nMinor, pref, 
		pEscapedValue? pEscapedValue :pValue);
	
    }
    ret = pTmp;
    HX_VECTOR_DELETE(pTmp);
    HX_VECTOR_DELETE(pEscapedValue);
}

HX_RESULT CUnixPref::read_pref(const char* pPrefKey, IHXBuffer*& pBuffer)
{
    pBuffer = NULL;
    CHXString key;
    ConstructPref(pPrefKey, key);
    char *value;
    if ((value = (char*)CIGetenv(key)))
    {
	char *pUnescapedValue = NULL;
	UnescapeNewLine(value, pUnescapedValue);
	pBuffer = new CHXBuffer();
	pBuffer->AddRef();
	if (pUnescapedValue)
	{
	    pBuffer->Set((UCHAR*)pUnescapedValue, strlen(pUnescapedValue) + 1);
	}
	else
	{
	    pBuffer->Set((UCHAR*)value, strlen(value) + 1);
	}
	HX_VECTOR_DELETE(pUnescapedValue);
    }
    return pBuffer ? HXR_OK : HXR_FAIL;
}


HX_RESULT CUnixPref::write_pref(const char* pPrefKey, IHXBuffer* pBuffer)
{
    m_bWrite = TRUE;
    CHXString key;
    ConstructPref(pPrefKey, key);
    key += "=";
    char *pStringToBeDeleted = NULL;
    
    for (char ** ppEnv = environ ; *ppEnv ; ++ppEnv)
    {
	if (!strnicmp(*ppEnv, key, strlen(key)))
	{
	    pStringToBeDeleted = *ppEnv;
	    break;
	}
    }
    
    if (pBuffer)
    {
	CHXString pValue = (const char *)(pBuffer->GetBuffer());
	ConstructPrefAssignment(pPrefKey, pValue, key, TRUE);
        CIPutenv(key);
    }
    else
    {
	CHXString oldKey;
	ConstructPref(pPrefKey, oldKey);
	CIUnsetEnv(oldKey);  
    }
    
    if (pStringToBeDeleted)
    {
	HX_VECTOR_DELETE(pStringToBeDeleted);
    }
    return HXR_OK;
}
    


/* commit_prefs saves all changes to the prefs to disk (e.g. on Unix) */ 
HX_RESULT CUnixPref::commit_prefs()
{
    if (!m_bWrite)
    {
	return HXR_OK;
    }

#ifndef _VXWORKS
    // if any new prefs were written, write prefs
    // open for writing
    mFile =  ::fopen ( m_pPath, "w");
    if (!mFile)
    {
	mFile = ::fopen( m_pPath, "w+");
    }
    
    // try to create it
    if (mFile)
    {
	/* change permissions to allow everyone to read the file 
	 * and owner/group to write only if I have to create this file
	 */
	
	/* PJG:  why does everyone get the right to read my prefs?  What about my MRU list? :) */
#if !defined(_VXWORKS) && !defined(_BEOS)
	mFileID = fileno(mFile);
	fchmod( mFileID, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP );
#endif
    }
    
    if (mFile)
    {
	mFileID = fileno(mFile);
	CHXString prefFamily;
	CHXString areLoadedPref;
	ConstructPref(ARE_PREFS_LOADED_PREF, areLoadedPref);
	UINT32 nAreLoadedPrefLen = strlen(areLoadedPref);
	ConstructFamily(prefFamily);
	UINT32 nPrefFamilyLen = strlen(prefFamily);
	
	for (char **ppEnv = environ ; *ppEnv ; ++ppEnv)
	{
	    if (!strnicmp(prefFamily, *ppEnv, nPrefFamilyLen))
	    {
		if (strnicmp(areLoadedPref, *ppEnv, nAreLoadedPrefLen)) // don't write out the placeholder
		{
		    fprintf(mFile, "%s\n", *ppEnv + nPrefFamilyLen);
		}
	    }
	}
    }
    else
    {
#ifdef _DEBUG
	fprintf(stderr,"Can't open file to write prefs: %s.\n", m_pPath);
#endif
    }
    
    if (mFile > 0) 
    {
	::fclose(mFile);       
	mFile = NULL;
	mFileID = -1;
    }

    // Remove file if it has zero length
    struct stat stat_buf;
    int err = stat(m_pPath, &stat_buf);
    if ( !err && stat_buf.st_size == 0 )
    {
	// if file is empty, delete the file.
	unlink(m_pPath);
    }
#endif

    m_bWrite = FALSE;
    return HXR_OK;
}



/////////////////////////////////////////////////////////////////////////////
// 	call open_pref() to automatically create the correct UNIX specific 
//	preference object.    
//
CUnixPref * CUnixPref::open_pref(
			const char* pCompanyName, 
			const char* pProductName, 

⌨️ 快捷键说明

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