unix_pref.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:21k
- /* ***** 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 = ' ';
- 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, "%sn", *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,
- int nProdMajorVer,
- int nProdMinorVer)
- {
- CUnixPref *cp = new CUnixPref(
- pCompanyName,
- pProductName,
- nProdMajorVer,
- nProdMinorVer);
- if (!SUCCEEDED(cp->last_error())) {
- delete cp;
- cp = NULL;
- }
- return cp;
- }
- /////////////////////////////////////////////////////////////////////////////
- // Constructor NOTE: use open_pref() to create an instance of this class
- //
- CUnixPref::CUnixPref(
- const char* pCompanyName,
- const char* pProductName,
- int nProdMajorVer,
- int nProdMinorVer)
- {
- m_pPath = NULL;
- mFile = NULL;
- mFileID = -1;
- mLastError = HXR_OK;
- m_bWrite = FALSE;
- m_RootKeyName[0] = ' ';
- init_pref( pCompanyName,pProductName,nProdMajorVer,nProdMinorVer);
- }
- /////////////////////////////////////////////////////////////////////////////
- // class destructor
- CUnixPref::~CUnixPref (void)
- {
- commit_prefs();
- HX_VECTOR_DELETE(m_pPath);
- }
- /* delete_pref deletes the preference specified by Key from the Buffer. */
- HX_RESULT CUnixPref::delete_pref(const char* pPrefKey)
- {
- return write_pref(pPrefKey, NULL);
- }
- /////////////////////////////////////////////////////////////////////////////
- // init opens pref file if found, otherwise it creates it;
- // reads the pref file into an internal buffer.
- //
- HX_RESULT CUnixPref::init_pref(
- const char* pCompanyName,
- const char* pProductName,
- int nProdMajorVer,
- int nProdMinorVer)
- {
- m_nMajor = nProdMajorVer;
- m_nMinor = nProdMinorVer;
- m_pCompany = FixupCompany(pCompanyName);
- m_pProduct = pProductName;
-
- HX_RESULT theErr = HXR_OK;
- char stmp[32]; /* Flawfinder: ignore */
- #if defined(_SUN) || defined(_HPUX)
- char rcPath[ _POSIX_PATH_MAX ]; /* Flawfinder: ignore */
- CUnixPrefUtils::GetPrefPath(rcPath, PATH_MAX, pCompanyName);
- #else
- char rcPath[ PATH_MAX ]; /* Flawfinder: ignore */
- CUnixPrefUtils::GetPrefPath(rcPath, PATH_MAX, pCompanyName);
- #endif
- #ifndef _VXWORKS
- #if defined(_BEOS)
- SafeStrCat( rcPath, "/", sizeof(rcPath));
- #else
- //::strcat( rcPath, "/." );
- SafeStrCat( rcPath, "/", sizeof(rcPath)); //Note that the "." has been removed. Files no longuer start with "."
- #endif /* _BEOS */
- if ( pProductName )
- {
- SafeStrCat( rcPath, pProductName, sizeof(rcPath));
- // remove any , or space
- char * pComa = (char*) HXFindChar(rcPath, ',');
- if(pComa)
- {
- *pComa = 0;
- }
- pComa = (char*) HXFindChar(rcPath, ' ');
- if(pComa)
- {
- *pComa = 0;
- }
- SafeStrCat( rcPath, "_", sizeof(rcPath));
- }
- ::sprintf(stmp, "%d_%d", nProdMajorVer,nProdMinorVer); /* Flawfinder: ignore */
- SafeStrCat(rcPath, stmp, sizeof(rcPath));
- m_pPath = new char[ ::strlen( rcPath ) + 1 ];
- strcpy( m_pPath, rcPath ); /* Flawfinder: ignore */
- // we're done now if the environment has been primed
- CHXString prefTester ;
- ConstructPref("ArePrefsLoaded", prefTester);
- if (CIGetenv(prefTester))
- {
- return HXR_OK; // already loaded :)
- }
- // open pref file for reading and writing; if it doesn't exist
- // create one.
- if ( (mFile = fopen ( m_pPath, "r")) == NULL )
- {
- #ifdef _DEBUG
- fprintf(stderr,"Can't open file: %s.n", m_pPath);
- #endif
- }
- else
- {
- mFileID = fileno(mFile);
- }
- #endif /* _VXWORKS */
-
- IHXBuffer* buf = new CHXBuffer((UCHAR*)(new_string("1")), 2);
- buf->AddRef();
- write_pref(ARE_PREFS_LOADED_PREF, buf);
- buf->Release();
- #ifndef _VXWORKS
- if (!theErr && mFile > 0)
- {
- // Read the contents of the file into memory.
- size_t lNumTotalRead = 0;
- struct stat stat_buf;
- char* pfile_data = 0;
- int err = stat(m_pPath, &stat_buf);
- if ( !err && stat_buf.st_size > 0 )
- {
- pfile_data = new char [ stat_buf.st_size + 10];
- size_t lNumRead = 1;
- while (!feof(mFile))
- {
- lNumRead = fread(pfile_data+lNumTotalRead, 1, 16000, mFile);
- if (lNumRead > 0)
- {
- lNumTotalRead += lNumRead;
- }
- else
- {
- break;
- }
- }
- pfile_data[lNumTotalRead] = ' ';
- HX_ASSERT(lNumTotalRead <= stat_buf.st_size);
- }
- // Now break the data into lines delimited by newlines, and then
- // break those strings up into name/value pairs.
- if ( lNumTotalRead > 0 && stat_buf.st_size > 0 )
- {
- char* snl = 0;
- char* seq = 0;
- char* sname= 0;
- char* svalue= 0;
- char* stmp = pfile_data;
- int name_len = 0;
- snl = strtok( stmp, "n");
- while( snl )
- {
- // now break up each line into name/value pairs...
- seq = strstr( snl, "=" );
- if(seq)
- {
- name_len = seq-snl;
- char* keyname = new char [name_len+1];
- strncpy( keyname, snl, name_len); /* Flawfinder: ignore */
- keyname[name_len] = ' ';
- char* lwr = new char[strlen(keyname) + 1];
- strcpy(lwr, keyname); /* Flawfinder: ignore */
- seq++;
-
- // if we find in environ already, ignore
- IHXBuffer *pBuffer = NULL;
- if (HXR_OK ==read_pref(lwr, pBuffer))
- {
- pBuffer->Release();
- }
- else
- {
- CHXString assn;
- ConstructPrefAssignment(lwr, seq, assn, FALSE);
- HX_VERIFY(-1 != CIPutenv(assn));
- }
- HX_VECTOR_DELETE(keyname);
- HX_VECTOR_DELETE(lwr);
- }
- snl = strtok( NULL, "n");
- }
- }
- HX_VECTOR_DELETE(pfile_data);
- }
- if ( mFile )
- {
- // unlock the file
- ::fclose( mFile );
- mFile = NULL;
- mFileID = -1;
- }
- #endif /* _VXWORKS */
- m_bWrite = FALSE; // we use write_pref internally, but we don't want to consider our
- // database to be modified at this point.
- mLastError = theErr;
- return theErr;
- }
- HX_RESULT CUnixPref::remove_pref(const char* pPrefKey)
- {
- return write_pref(pPrefKey, NULL);
- }
- HX_RESULT CUnixPref::remove_indexed_pref(const char* pPrefKey)
- {
- return HXR_NOTIMPL;
- }
- //
- // Access a preferences file subtree by appending a string to the Root
- // Key.
- //
- HX_RESULT CUnixPref::BeginSubPref(const char* szSubPref)
- {
- HX_ASSERT((strlen(m_RootKeyName) + 1 + strlen(szSubPref) + 1) <= _MAX_KEY);
- // Just add sub-pref to the root key name
- SafeStrCat(m_RootKeyName,"\", _MAX_KEY);
- SafeStrCat(m_RootKeyName,szSubPref, _MAX_KEY);
- return HXR_OK;
- }
- HX_RESULT CUnixPref::EndSubPref()
- {
- // Find the character from the end of the string
- char* pSlash = HXReverseFindChar(m_RootKeyName,'\');
- // if we find the character we NULL terminate at this point removing the last sub-pref added
- if (pSlash)
- {
- *pSlash = ' ';
- return HXR_OK;
- }
- else
- return HXR_FAIL;
- }
- //
- // Return the value of subkey number nIndex under the current m_RootKeyName.
- //
- HX_RESULT CUnixPref::GetPrefKey(UINT32 nIndex, IHXBuffer*& pBuffer)
- {
- UINT32 i; // index of the current subkey
- POSITION mapPosition = NULL;
- CHXString key;
- HX_RESULT result = HXR_FAIL;
- CHXString prefFamily;
- ConstructFamily(prefFamily);
- UINT32 nPrefFamilyLen = strlen(prefFamily);
-
- UINT32 counter = 0;
-
- for (char **ppEnv = environ ; *ppEnv ; ++ppEnv)
- {
- if (!strnicmp(prefFamily, *ppEnv, nPrefFamilyLen))
- {
- // make sure this isn't the head of the family
- if ('=' == (*ppEnv)[nPrefFamilyLen])
- continue;
-
- if (counter == nIndex)
- {
- char *value = (*ppEnv) + nPrefFamilyLen + 1;
- char *ueValue = NULL;
- UnescapeNewLine(value, ueValue);
- pBuffer = new CHXBuffer;
- pBuffer->AddRef();
- pBuffer->Set((UCHAR*)(ueValue? ueValue : value), strlen(ueValue ? ueValue : value) + 1);
- HX_VECTOR_DELETE(ueValue);
- return HXR_OK;
- }
- counter++;
- }
- }
-
- return HXR_FAIL;
- }
- BOOL
- CUnixPref::EscapeNewLine(const char* pLine, char*& pTmpOutLine)
- {
- char hexBuf[3] = {0}; /* Flawfinder: ignore */
- pTmpOutLine = NULL;
- char* pOutLine = NULL;
- const char* pInputLine = pLine;
- while (*pLine)
- {
- // escape n, = and %
- if (*pLine == 'n' || *pLine == '=' || *pLine == '%')
- {
- if (!pOutLine)
- {
- pTmpOutLine = pOutLine = new char[strlen(pInputLine) * 3 + 1];
- *pOutLine = ' ';
- strncpy(pOutLine, pInputLine, pLine - pInputLine); /* Flawfinder: ignore */
- pOutLine += pLine - pInputLine;
- }
- sprintf(hexBuf,"%02x", (UCHAR)*pLine); /* Flawfinder: ignore */
- *pOutLine++ = '%';
- *pOutLine++ = hexBuf[0];
- *pOutLine++ = hexBuf[1];
- }
- else if (pOutLine)
- {
- *pOutLine++ = *pLine;
- }
- pLine++;
- }
- if (pOutLine) *pOutLine = ' ';
- return (pOutLine ? TRUE : FALSE);
- }
- BOOL
- CUnixPref::UnescapeNewLine(const char* pLine, char*& pTmpOutLine)
- {
- char hexBuf[3] = {0}; /* Flawfinder: ignore */
- pTmpOutLine = NULL;
- char* pOutLine = NULL;
- const char* pInputLine = pLine;
- while (*pLine)
- {
- if (*pLine == '%')
- {
- if (!pOutLine)
- {
- pTmpOutLine = pOutLine = new char[strlen(pInputLine)+1];
- *pOutLine = ' ';
- strncpy(pOutLine, pInputLine, pLine - pInputLine); /* Flawfinder: ignore */
- pOutLine += pLine - pInputLine;
- }
- char hexBuf[3]; /* Flawfinder: ignore */
- if(pLine[1] && // check for overbound condition
- pLine[2])
- {
- pLine++; // walk past '%'
- hexBuf[0] = *pLine++;
- hexBuf[1] = *pLine;
- hexBuf[2] = ' ';
- *pOutLine++ = (char)strtol(hexBuf, NULL, 16);
- }
- }
- else if (pOutLine)
- {
- *pOutLine++ = *pLine;
- }
- pLine++;
- }
- if (pOutLine) *pOutLine = ' ';
- return (pOutLine ? TRUE : FALSE);
- }