2000-11-08 12:11:22 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
2008-04-11 12:46:49 +00:00
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
2000-11-08 12:11:22 +00:00
|
|
|
*
|
2010-02-12 15:01:35 +01:00
|
|
|
* Copyright 2000, 2010 Oracle and/or its affiliates.
|
2000-11-08 12:11:22 +00:00
|
|
|
*
|
2008-04-11 12:46:49 +00:00
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
2000-11-08 12:11:22 +00:00
|
|
|
*
|
2008-04-11 12:46:49 +00:00
|
|
|
* This file is part of OpenOffice.org.
|
2000-11-08 12:11:22 +00:00
|
|
|
*
|
2008-04-11 12:46:49 +00:00
|
|
|
* OpenOffice.org is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Lesser General Public License version 3
|
|
|
|
* only, as published by the Free Software Foundation.
|
2000-11-08 12:11:22 +00:00
|
|
|
*
|
2008-04-11 12:46:49 +00:00
|
|
|
* OpenOffice.org is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU Lesser General Public License version 3 for more details
|
|
|
|
* (a copy is included in the LICENSE file that accompanied this code).
|
2000-11-08 12:11:22 +00:00
|
|
|
*
|
2008-04-11 12:46:49 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
* version 3 along with OpenOffice.org. If not, see
|
|
|
|
* <http://www.openoffice.org/license.html>
|
|
|
|
* for a copy of the LGPLv3 License.
|
2000-11-08 12:11:22 +00:00
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
2006-09-16 23:55:29 +00:00
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
|
|
#include "precompiled_tools.hxx"
|
|
|
|
|
2000-11-08 12:11:22 +00:00
|
|
|
#define _CONFIG_CXX
|
|
|
|
|
2006-06-19 12:44:30 +00:00
|
|
|
#include <cstddef>
|
|
|
|
#include <cstdlib>
|
|
|
|
#include <limits>
|
|
|
|
#include <new>
|
2000-11-08 12:11:22 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
2006-06-19 12:44:30 +00:00
|
|
|
#ifdef WNT
|
|
|
|
#include "stdlib.h"
|
|
|
|
#endif
|
2000-11-08 12:11:22 +00:00
|
|
|
#include <osl/file.hxx>
|
2007-06-27 21:13:15 +00:00
|
|
|
#include <tools/stream.hxx>
|
|
|
|
#include <tools/debug.hxx>
|
|
|
|
#include <tools/config.hxx>
|
2001-03-16 15:34:11 +00:00
|
|
|
#include <osl/security.h>
|
2000-11-08 12:11:22 +00:00
|
|
|
|
|
|
|
#define MAXBUFLEN 1024 // Fuer Buffer bei VOS-Funktionen
|
|
|
|
|
|
|
|
// -----------------
|
|
|
|
// - ImplConfigData -
|
|
|
|
// -----------------
|
|
|
|
|
|
|
|
struct ImplKeyData
|
|
|
|
{
|
|
|
|
ImplKeyData* mpNext;
|
|
|
|
ByteString maKey;
|
|
|
|
ByteString maValue;
|
|
|
|
BOOL mbIsComment;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ImplGroupData
|
|
|
|
{
|
|
|
|
ImplGroupData* mpNext;
|
|
|
|
ImplKeyData* mpFirstKey;
|
|
|
|
ByteString maGroupName;
|
|
|
|
USHORT mnEmptyLines;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ImplConfigData
|
|
|
|
{
|
|
|
|
ImplGroupData* mpFirstGroup;
|
|
|
|
XubString maFileName;
|
|
|
|
ULONG mnDataUpdateId;
|
|
|
|
ULONG mnTimeStamp;
|
|
|
|
LineEnd meLineEnd;
|
|
|
|
USHORT mnRefCount;
|
|
|
|
BOOL mbModified;
|
|
|
|
BOOL mbRead;
|
2007-07-03 12:58:34 +00:00
|
|
|
BOOL mbIsUTF8BOM;
|
2000-11-08 12:11:22 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
|
|
|
|
static ByteString& getEmptyByteString()
|
|
|
|
{
|
|
|
|
static ByteString aEmpty;
|
|
|
|
return aEmpty;
|
|
|
|
}
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
|
|
|
|
static String toUncPath( const String& rPath )
|
|
|
|
{
|
2001-05-10 09:36:29 +00:00
|
|
|
::rtl::OUString aFileURL;
|
|
|
|
|
2001-06-13 14:32:25 +00:00
|
|
|
// check if rFileName is already a URL; if not make it so
|
2001-05-22 14:42:49 +00:00
|
|
|
if( rPath.CompareToAscii( "file://", 7 ) == COMPARE_EQUAL )
|
|
|
|
aFileURL = rPath;
|
|
|
|
else if( ::osl::FileBase::getFileURLFromSystemPath( rPath, aFileURL ) != ::osl::FileBase::E_None )
|
2001-05-10 09:36:29 +00:00
|
|
|
aFileURL = rPath;
|
|
|
|
|
|
|
|
return aFileURL;
|
2000-11-08 12:11:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static ULONG ImplSysGetConfigTimeStamp( const XubString& rFileName )
|
|
|
|
{
|
|
|
|
ULONG nTimeStamp = 0;
|
|
|
|
::osl::DirectoryItem aItem;
|
|
|
|
::osl::FileStatus aStatus( osl_FileStatus_Mask_ModifyTime );
|
|
|
|
|
|
|
|
int nError = 0;
|
|
|
|
if( ( nError = ::osl::DirectoryItem::get( rFileName, aItem ) ) == ::osl::FileBase::E_None &&
|
|
|
|
aItem.getFileStatus( aStatus ) == ::osl::FileBase::E_None )
|
|
|
|
{
|
|
|
|
nTimeStamp = aStatus.getModifyTime().Seconds;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nTimeStamp;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
static BYTE* ImplSysReadConfig( const XubString& rFileName,
|
2007-07-03 12:58:34 +00:00
|
|
|
sal_uInt64& rRead, BOOL& rbRead, BOOL& rbIsUTF8BOM, ULONG& rTimeStamp )
|
2000-11-08 12:11:22 +00:00
|
|
|
{
|
|
|
|
BYTE* pBuf = NULL;
|
|
|
|
::osl::File aFile( rFileName );
|
|
|
|
|
|
|
|
if( aFile.open( osl_File_OpenFlag_Read ) == ::osl::FileBase::E_None )
|
|
|
|
{
|
|
|
|
sal_uInt64 nPos = 0, nRead = 0;
|
2004-09-08 15:11:44 +00:00
|
|
|
if( aFile.getSize( nPos ) == ::osl::FileBase::E_None )
|
2000-11-08 12:11:22 +00:00
|
|
|
{
|
2006-06-19 12:44:30 +00:00
|
|
|
if (nPos > std::numeric_limits< std::size_t >::max()) {
|
|
|
|
aFile.close();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
pBuf = new BYTE[static_cast< std::size_t >(nPos)];
|
2000-11-08 12:11:22 +00:00
|
|
|
if( aFile.read( pBuf, nPos, nRead ) == ::osl::FileBase::E_None && nRead == nPos )
|
|
|
|
{
|
2007-07-03 12:58:34 +00:00
|
|
|
//skip the byte-order-mark 0xEF 0xBB 0xBF, if it was UTF8 files
|
|
|
|
unsigned char BOM[3] = {0xEF, 0xBB, 0xBF};
|
|
|
|
if (nRead > 2 && memcmp(pBuf, BOM, 3) == 0)
|
|
|
|
{
|
|
|
|
nRead -= 3;
|
|
|
|
rtl_moveMemory(pBuf, pBuf + 3, sal::static_int_cast<sal_Size>(nRead * sizeof(BYTE)) );
|
|
|
|
rbIsUTF8BOM = TRUE;
|
|
|
|
}
|
|
|
|
|
2000-11-08 12:11:22 +00:00
|
|
|
rTimeStamp = ImplSysGetConfigTimeStamp( rFileName );
|
|
|
|
rbRead = TRUE;
|
|
|
|
rRead = nRead;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-06-19 12:44:30 +00:00
|
|
|
delete[] pBuf;
|
2000-11-08 12:11:22 +00:00
|
|
|
pBuf = NULL;
|
|
|
|
}
|
|
|
|
}
|
2006-06-19 12:44:30 +00:00
|
|
|
aFile.close();
|
2000-11-08 12:11:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return pBuf;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
static BOOL ImplSysWriteConfig( const XubString& rFileName,
|
2007-07-03 12:58:34 +00:00
|
|
|
const BYTE* pBuf, ULONG nBufLen, BOOL rbIsUTF8BOM, ULONG& rTimeStamp )
|
2000-11-08 12:11:22 +00:00
|
|
|
{
|
|
|
|
BOOL bSuccess = FALSE;
|
2007-07-03 12:58:34 +00:00
|
|
|
BOOL bUTF8BOMSuccess = FALSE;
|
2000-11-08 12:11:22 +00:00
|
|
|
|
|
|
|
::osl::File aFile( rFileName );
|
|
|
|
::osl::FileBase::RC eError = aFile.open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create );
|
|
|
|
if( eError != ::osl::FileBase::E_None )
|
|
|
|
eError = aFile.open( osl_File_OpenFlag_Write );
|
|
|
|
if( eError == ::osl::FileBase::E_None )
|
|
|
|
{
|
|
|
|
// truncate
|
|
|
|
aFile.setSize( 0 );
|
|
|
|
sal_uInt64 nWritten;
|
2007-07-03 12:58:34 +00:00
|
|
|
|
|
|
|
//write the the byte-order-mark 0xEF 0xBB 0xBF first , if it was UTF8 files
|
|
|
|
if ( rbIsUTF8BOM )
|
|
|
|
{
|
|
|
|
unsigned char BOM[3] = {0xEF, 0xBB, 0xBF};
|
|
|
|
sal_uInt64 nUTF8BOMWritten;
|
|
|
|
if( aFile.write( BOM, 3, nUTF8BOMWritten ) == ::osl::FileBase::E_None && 3 == nUTF8BOMWritten )
|
|
|
|
{
|
|
|
|
bUTF8BOMSuccess = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-11-08 12:11:22 +00:00
|
|
|
if( aFile.write( pBuf, nBufLen, nWritten ) == ::osl::FileBase::E_None && nWritten == nBufLen )
|
|
|
|
{
|
|
|
|
bSuccess = TRUE;
|
2007-07-03 12:58:34 +00:00
|
|
|
}
|
|
|
|
if ( rbIsUTF8BOM ? bSuccess && bUTF8BOMSuccess : bSuccess )
|
|
|
|
{
|
2000-11-08 12:11:22 +00:00
|
|
|
rTimeStamp = ImplSysGetConfigTimeStamp( rFileName );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-07-03 12:58:34 +00:00
|
|
|
return rbIsUTF8BOM ? bSuccess && bUTF8BOMSuccess : bSuccess;
|
2000-11-08 12:11:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
static String ImplMakeConfigName( const XubString* pFileName,
|
|
|
|
const XubString* pPathName )
|
|
|
|
{
|
|
|
|
::rtl::OUString aFileName;
|
|
|
|
::rtl::OUString aPathName;
|
|
|
|
if ( pFileName )
|
2001-03-23 08:22:44 +00:00
|
|
|
{
|
|
|
|
#ifdef UNX
|
|
|
|
aFileName = ::rtl::OUString::createFromAscii( "." );
|
|
|
|
aFileName += *pFileName;
|
|
|
|
aFileName += ::rtl::OUString::createFromAscii( "rc" );
|
|
|
|
#else
|
2000-11-08 12:11:22 +00:00
|
|
|
aFileName = *pFileName;
|
2001-03-23 08:22:44 +00:00
|
|
|
aFileName += ::rtl::OUString::createFromAscii( ".ini" );
|
|
|
|
#endif
|
|
|
|
}
|
2001-03-16 15:34:11 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
#ifdef UNX
|
2001-03-23 08:22:44 +00:00
|
|
|
aFileName = ::rtl::OUString::createFromAscii( ".sversionrc" );
|
2001-03-16 15:34:11 +00:00
|
|
|
#else
|
2001-03-23 08:22:44 +00:00
|
|
|
aFileName = ::rtl::OUString::createFromAscii( "sversion.ini" );
|
2001-03-16 15:34:11 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2001-06-13 14:32:25 +00:00
|
|
|
// #88208# in case pPathName is set but empty and pFileName is set
|
|
|
|
// and not empty just return the filename; on the default case
|
|
|
|
// prepend default path as usual
|
|
|
|
if ( pPathName && pPathName->Len() )
|
2000-11-08 12:11:22 +00:00
|
|
|
aPathName = toUncPath( *pPathName );
|
2001-06-13 14:32:25 +00:00
|
|
|
else if( pPathName && pFileName && pFileName->Len() )
|
|
|
|
return aFileName;
|
2001-03-16 15:34:11 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
oslSecurity aSec = osl_getCurrentSecurity();
|
|
|
|
osl_getConfigDir( aSec, &aPathName.pData );
|
|
|
|
osl_freeSecurityHandle( aSec );
|
|
|
|
}
|
|
|
|
|
|
|
|
::rtl::OUString aName( aPathName );
|
|
|
|
aName += ::rtl::OUString::createFromAscii( "/" );
|
|
|
|
aName += aFileName;
|
|
|
|
|
2000-11-08 12:11:22 +00:00
|
|
|
return aName;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
2006-06-19 12:44:30 +00:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
ByteString makeByteString(BYTE const * p, sal_uInt64 n) {
|
|
|
|
if (n > STRING_MAXLEN) {
|
|
|
|
#ifdef WNT
|
|
|
|
abort();
|
|
|
|
#else
|
|
|
|
::std::abort(); //TODO: handle this gracefully
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
return ByteString(
|
|
|
|
reinterpret_cast< char const * >(p),
|
|
|
|
sal::static_int_cast< xub_StrLen >(n));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2000-11-08 12:11:22 +00:00
|
|
|
static void ImplMakeConfigList( ImplConfigData* pData,
|
2006-06-19 12:44:30 +00:00
|
|
|
const BYTE* pBuf, sal_uInt64 nLen )
|
2000-11-08 12:11:22 +00:00
|
|
|
{
|
|
|
|
// kein Buffer, keine Daten
|
|
|
|
if ( !nLen )
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Buffer parsen und Liste zusammenbauen
|
2006-06-19 12:44:30 +00:00
|
|
|
sal_uInt64 nStart;
|
|
|
|
sal_uInt64 nLineLen;
|
|
|
|
xub_StrLen nNameLen;
|
|
|
|
xub_StrLen nKeyLen;
|
|
|
|
sal_uInt64 i;
|
2000-11-08 12:11:22 +00:00
|
|
|
const BYTE* pLine;
|
2004-02-04 12:45:02 +00:00
|
|
|
ImplKeyData* pPrevKey = NULL;
|
2000-11-08 12:11:22 +00:00
|
|
|
ImplKeyData* pKey;
|
|
|
|
ImplGroupData* pPrevGroup = NULL;
|
|
|
|
ImplGroupData* pGroup = NULL;
|
|
|
|
i = 0;
|
|
|
|
while ( i < nLen )
|
|
|
|
{
|
|
|
|
// Ctrl+Z
|
|
|
|
if ( pBuf[i] == 0x1A )
|
|
|
|
break;
|
|
|
|
|
|
|
|
// Spaces und Tabs entfernen
|
|
|
|
while ( (pBuf[i] == ' ') || (pBuf[i] == '\t') )
|
|
|
|
i++;
|
|
|
|
|
|
|
|
// Zeilenanfang merken
|
|
|
|
nStart = i;
|
|
|
|
pLine = pBuf+i;
|
|
|
|
|
|
|
|
// Zeilenende suchen
|
|
|
|
while ( (i < nLen) && pBuf[i] && (pBuf[i] != '\r') && (pBuf[i] != '\n') &&
|
|
|
|
(pBuf[i] != 0x1A) )
|
|
|
|
i++;
|
|
|
|
|
|
|
|
nLineLen = i-nStart;
|
|
|
|
|
|
|
|
// Wenn Zeilenende (CR/LF), dann noch einen weiterschalten
|
|
|
|
if ( (i+1 < nLen) &&
|
|
|
|
(pBuf[i] != pBuf[i+1]) &&
|
|
|
|
((pBuf[i+1] == '\r') || (pBuf[i+1] == '\n')) )
|
|
|
|
i++;
|
|
|
|
i++;
|
|
|
|
|
|
|
|
// Zeile auswerten
|
|
|
|
if ( *pLine == '[' )
|
|
|
|
{
|
|
|
|
pGroup = new ImplGroupData;
|
|
|
|
pGroup->mpNext = NULL;
|
|
|
|
pGroup->mpFirstKey = NULL;
|
|
|
|
pGroup->mnEmptyLines = 0;
|
|
|
|
if ( pPrevGroup )
|
|
|
|
pPrevGroup->mpNext = pGroup;
|
|
|
|
else
|
|
|
|
pData->mpFirstGroup = pGroup;
|
|
|
|
pPrevGroup = pGroup;
|
|
|
|
pPrevKey = NULL;
|
|
|
|
pKey = NULL;
|
|
|
|
|
|
|
|
// Gruppennamen rausfiltern
|
|
|
|
pLine++;
|
|
|
|
nLineLen--;
|
|
|
|
// Spaces und Tabs entfernen
|
|
|
|
while ( (*pLine == ' ') || (*pLine == '\t') )
|
|
|
|
{
|
|
|
|
nLineLen--;
|
|
|
|
pLine++;
|
|
|
|
}
|
|
|
|
nNameLen = 0;
|
|
|
|
while ( (nNameLen < nLineLen) && (pLine[nNameLen] != ']') )
|
|
|
|
nNameLen++;
|
|
|
|
if ( nNameLen )
|
|
|
|
{
|
|
|
|
while ( (pLine[nNameLen-1] == ' ') || (pLine[nNameLen-1] == '\t') )
|
|
|
|
nNameLen--;
|
|
|
|
}
|
|
|
|
pGroup->maGroupName = ByteString( (const sal_Char*)pLine, nNameLen );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( nLineLen )
|
|
|
|
{
|
|
|
|
// Wenn noch keine Gruppe existiert, dann alle Keys in die
|
|
|
|
// Default-Gruppe
|
|
|
|
if ( !pGroup )
|
|
|
|
{
|
|
|
|
pGroup = new ImplGroupData;
|
|
|
|
pGroup->mpNext = NULL;
|
|
|
|
pGroup->mpFirstKey = NULL;
|
|
|
|
pGroup->mnEmptyLines = 0;
|
|
|
|
if ( pPrevGroup )
|
|
|
|
pPrevGroup->mpNext = pGroup;
|
|
|
|
else
|
|
|
|
pData->mpFirstGroup = pGroup;
|
|
|
|
pPrevGroup = pGroup;
|
|
|
|
pPrevKey = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Falls Leerzeile vorhanden, dann anhaengen
|
|
|
|
if ( pPrevKey )
|
|
|
|
{
|
|
|
|
while ( pGroup->mnEmptyLines )
|
|
|
|
{
|
|
|
|
pKey = new ImplKeyData;
|
|
|
|
pKey->mbIsComment = TRUE;
|
|
|
|
pPrevKey->mpNext = pKey;
|
|
|
|
pPrevKey = pKey;
|
|
|
|
pGroup->mnEmptyLines--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Neuen Key erzeugen
|
|
|
|
pKey = new ImplKeyData;
|
|
|
|
pKey->mpNext = NULL;
|
|
|
|
if ( pPrevKey )
|
|
|
|
pPrevKey->mpNext = pKey;
|
|
|
|
else
|
|
|
|
pGroup->mpFirstKey = pKey;
|
|
|
|
pPrevKey = pKey;
|
|
|
|
if ( pLine[0] == ';' )
|
|
|
|
{
|
2006-06-19 12:44:30 +00:00
|
|
|
pKey->maValue = makeByteString(pLine, nLineLen);
|
2000-11-08 12:11:22 +00:00
|
|
|
pKey->mbIsComment = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pKey->mbIsComment = FALSE;
|
|
|
|
nNameLen = 0;
|
|
|
|
while ( (nNameLen < nLineLen) && (pLine[nNameLen] != '=') )
|
|
|
|
nNameLen++;
|
|
|
|
nKeyLen = nNameLen;
|
|
|
|
// Spaces und Tabs entfernen
|
|
|
|
if ( nNameLen )
|
|
|
|
{
|
|
|
|
while ( (pLine[nNameLen-1] == ' ') || (pLine[nNameLen-1] == '\t') )
|
|
|
|
nNameLen--;
|
|
|
|
}
|
|
|
|
pKey->maKey = ByteString( (const sal_Char*)pLine, nNameLen );
|
|
|
|
nKeyLen++;
|
|
|
|
if ( nKeyLen < nLineLen )
|
|
|
|
{
|
|
|
|
pLine += nKeyLen;
|
|
|
|
nLineLen -= nKeyLen;
|
|
|
|
// Spaces und Tabs entfernen
|
|
|
|
while ( (*pLine == ' ') || (*pLine == '\t') )
|
|
|
|
{
|
|
|
|
nLineLen--;
|
|
|
|
pLine++;
|
|
|
|
}
|
|
|
|
if ( nLineLen )
|
|
|
|
{
|
|
|
|
while ( (pLine[nLineLen-1] == ' ') || (pLine[nLineLen-1] == '\t') )
|
|
|
|
nLineLen--;
|
2006-06-19 12:44:30 +00:00
|
|
|
pKey->maValue = makeByteString(pLine, nLineLen);
|
2000-11-08 12:11:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Leerzeilen werden nur gezaehlt und beim Erzeugen des
|
|
|
|
// naechsten Keys angehaengt, da wir Leerzeilen am Ende
|
|
|
|
// einer Gruppe auch nach hinzufuegen von neuen Keys nur
|
|
|
|
// am Ende der Gruppe wieder speichern wollen
|
|
|
|
if ( pGroup )
|
|
|
|
pGroup->mnEmptyLines++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
static BYTE* ImplGetConfigBuffer( const ImplConfigData* pData, ULONG& rLen )
|
|
|
|
{
|
|
|
|
BYTE* pWriteBuf;
|
|
|
|
BYTE* pBuf;
|
2006-08-29 10:13:49 +00:00
|
|
|
BYTE aLineEndBuf[2] = {0, 0};
|
2000-11-08 12:11:22 +00:00
|
|
|
ImplKeyData* pKey;
|
|
|
|
ImplGroupData* pGroup;
|
|
|
|
unsigned int nBufLen;
|
|
|
|
USHORT nValueLen;
|
|
|
|
USHORT nKeyLen;
|
|
|
|
USHORT nLineEndLen;
|
|
|
|
|
|
|
|
if ( pData->meLineEnd == LINEEND_CR )
|
|
|
|
{
|
|
|
|
aLineEndBuf[0] = _CR;
|
|
|
|
nLineEndLen = 1;
|
|
|
|
}
|
|
|
|
else if ( pData->meLineEnd == LINEEND_LF )
|
|
|
|
{
|
|
|
|
aLineEndBuf[0] = _LF;
|
|
|
|
nLineEndLen = 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
aLineEndBuf[0] = _CR;
|
|
|
|
aLineEndBuf[1] = _LF;
|
|
|
|
nLineEndLen = 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Buffergroesse ermitteln
|
|
|
|
nBufLen = 0;
|
|
|
|
pGroup = pData->mpFirstGroup;
|
|
|
|
while ( pGroup )
|
|
|
|
{
|
|
|
|
// Leere Gruppen werden nicht geschrieben
|
|
|
|
if ( pGroup->mpFirstKey )
|
|
|
|
{
|
|
|
|
nBufLen += pGroup->maGroupName.Len() + nLineEndLen + 2;
|
|
|
|
pKey = pGroup->mpFirstKey;
|
|
|
|
while ( pKey )
|
|
|
|
{
|
|
|
|
nValueLen = pKey->maValue.Len();
|
|
|
|
if ( pKey->mbIsComment )
|
|
|
|
nBufLen += nValueLen + nLineEndLen;
|
|
|
|
else
|
|
|
|
nBufLen += pKey->maKey.Len() + nValueLen + nLineEndLen + 1;
|
|
|
|
|
|
|
|
pKey = pKey->mpNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Leerzeile nach jeder Gruppe auch wieder speichern
|
|
|
|
if ( !pGroup->mnEmptyLines )
|
|
|
|
pGroup->mnEmptyLines = 1;
|
|
|
|
nBufLen += nLineEndLen * pGroup->mnEmptyLines;
|
|
|
|
}
|
|
|
|
|
|
|
|
pGroup = pGroup->mpNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Laenge dem Aufrufer mitteilen
|
|
|
|
rLen = nBufLen;
|
|
|
|
if ( !nBufLen )
|
|
|
|
{
|
2006-06-19 12:44:30 +00:00
|
|
|
pWriteBuf = new BYTE[nLineEndLen];
|
2000-11-08 12:11:22 +00:00
|
|
|
if ( pWriteBuf )
|
|
|
|
{
|
|
|
|
pWriteBuf[0] = aLineEndBuf[0];
|
|
|
|
if ( nLineEndLen == 2 )
|
|
|
|
pWriteBuf[1] = aLineEndBuf[1];
|
|
|
|
return pWriteBuf;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Schreibbuffer anlegen (wird vom Aufrufer zerstoert)
|
2006-06-19 12:44:30 +00:00
|
|
|
pWriteBuf = new BYTE[nBufLen];
|
2000-11-08 12:11:22 +00:00
|
|
|
if ( !pWriteBuf )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
// Buffer fuellen
|
|
|
|
pBuf = pWriteBuf;
|
|
|
|
pGroup = pData->mpFirstGroup;
|
|
|
|
while ( pGroup )
|
|
|
|
{
|
|
|
|
// Leere Gruppen werden nicht geschrieben
|
|
|
|
if ( pGroup->mpFirstKey )
|
|
|
|
{
|
|
|
|
*pBuf = '['; pBuf++;
|
|
|
|
memcpy( pBuf, pGroup->maGroupName.GetBuffer(), pGroup->maGroupName.Len() );
|
|
|
|
pBuf += pGroup->maGroupName.Len();
|
|
|
|
*pBuf = ']'; pBuf++;
|
|
|
|
*pBuf = aLineEndBuf[0]; pBuf++;
|
|
|
|
if ( nLineEndLen == 2 )
|
|
|
|
{
|
|
|
|
*pBuf = aLineEndBuf[1]; pBuf++;
|
|
|
|
}
|
|
|
|
pKey = pGroup->mpFirstKey;
|
|
|
|
while ( pKey )
|
|
|
|
{
|
|
|
|
nValueLen = pKey->maValue.Len();
|
|
|
|
if ( pKey->mbIsComment )
|
|
|
|
{
|
|
|
|
if ( nValueLen )
|
|
|
|
{
|
|
|
|
memcpy( pBuf, pKey->maValue.GetBuffer(), nValueLen );
|
|
|
|
pBuf += nValueLen;
|
|
|
|
}
|
|
|
|
*pBuf = aLineEndBuf[0]; pBuf++;
|
|
|
|
if ( nLineEndLen == 2 )
|
|
|
|
{
|
|
|
|
*pBuf = aLineEndBuf[1]; pBuf++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nKeyLen = pKey->maKey.Len();
|
|
|
|
memcpy( pBuf, pKey->maKey.GetBuffer(), nKeyLen );
|
|
|
|
pBuf += nKeyLen;
|
|
|
|
*pBuf = '='; pBuf++;
|
|
|
|
memcpy( pBuf, pKey->maValue.GetBuffer(), nValueLen );
|
|
|
|
pBuf += nValueLen;
|
|
|
|
*pBuf = aLineEndBuf[0]; pBuf++;
|
|
|
|
if ( nLineEndLen == 2 )
|
|
|
|
{
|
|
|
|
*pBuf = aLineEndBuf[1]; pBuf++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pKey = pKey->mpNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Leerzeile nach jeder Gruppe auch wieder speichern
|
|
|
|
USHORT nEmptyLines = pGroup->mnEmptyLines;
|
|
|
|
while ( nEmptyLines )
|
|
|
|
{
|
|
|
|
*pBuf = aLineEndBuf[0]; pBuf++;
|
|
|
|
if ( nLineEndLen == 2 )
|
|
|
|
{
|
|
|
|
*pBuf = aLineEndBuf[1]; pBuf++;
|
|
|
|
}
|
|
|
|
nEmptyLines--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pGroup = pGroup->mpNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
return pWriteBuf;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
static void ImplReadConfig( ImplConfigData* pData )
|
|
|
|
{
|
|
|
|
ULONG nTimeStamp = 0;
|
2006-06-19 12:44:30 +00:00
|
|
|
sal_uInt64 nRead = 0;
|
2000-11-08 12:11:22 +00:00
|
|
|
BOOL bRead = FALSE;
|
2007-07-03 12:58:34 +00:00
|
|
|
BOOL bIsUTF8BOM =FALSE;
|
|
|
|
BYTE* pBuf = ImplSysReadConfig( pData->maFileName, nRead, bRead, bIsUTF8BOM, nTimeStamp );
|
2000-11-08 12:11:22 +00:00
|
|
|
|
|
|
|
// Aus dem Buffer die Config-Verwaltungsliste aufbauen
|
|
|
|
if ( pBuf )
|
|
|
|
{
|
|
|
|
ImplMakeConfigList( pData, pBuf, nRead );
|
2006-06-19 12:44:30 +00:00
|
|
|
delete[] pBuf;
|
2000-11-08 12:11:22 +00:00
|
|
|
}
|
|
|
|
pData->mnTimeStamp = nTimeStamp;
|
|
|
|
pData->mbModified = FALSE;
|
|
|
|
if ( bRead )
|
|
|
|
pData->mbRead = TRUE;
|
2007-07-03 12:58:34 +00:00
|
|
|
if ( bIsUTF8BOM )
|
|
|
|
pData->mbIsUTF8BOM = TRUE;
|
2000-11-08 12:11:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
static void ImplWriteConfig( ImplConfigData* pData )
|
|
|
|
{
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
if ( DbgIsAssert() )
|
|
|
|
{
|
|
|
|
if ( pData->mnTimeStamp != ImplSysGetConfigTimeStamp( pData->maFileName ) )
|
|
|
|
{
|
|
|
|
DBG_ERROR1( "Config overwrites modified configfile:\n %s", ByteString( pData->maFileName, RTL_TEXTENCODING_UTF8 ).GetBuffer() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Aus der Config-Liste einen Buffer zusammenbauen
|
|
|
|
ULONG nBufLen;
|
|
|
|
BYTE* pBuf = ImplGetConfigBuffer( pData, nBufLen );
|
|
|
|
if ( pBuf )
|
|
|
|
{
|
2007-07-03 12:58:34 +00:00
|
|
|
if ( ImplSysWriteConfig( pData->maFileName, pBuf, nBufLen, pData->mbIsUTF8BOM, pData->mnTimeStamp ) )
|
2000-11-08 12:11:22 +00:00
|
|
|
pData->mbModified = FALSE;
|
2006-06-19 12:44:30 +00:00
|
|
|
delete[] pBuf;
|
2000-11-08 12:11:22 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
pData->mbModified = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
static void ImplDeleteConfigData( ImplConfigData* pData )
|
|
|
|
{
|
|
|
|
ImplKeyData* pTempKey;
|
|
|
|
ImplKeyData* pKey;
|
|
|
|
ImplGroupData* pTempGroup;
|
|
|
|
ImplGroupData* pGroup = pData->mpFirstGroup;
|
|
|
|
while ( pGroup )
|
|
|
|
{
|
|
|
|
pTempGroup = pGroup->mpNext;
|
|
|
|
|
|
|
|
// Alle Keys loeschen
|
|
|
|
pKey = pGroup->mpFirstKey;
|
|
|
|
while ( pKey )
|
|
|
|
{
|
|
|
|
pTempKey = pKey->mpNext;
|
|
|
|
delete pKey;
|
|
|
|
pKey = pTempKey;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Gruppe loeschen und weiterschalten
|
|
|
|
delete pGroup;
|
|
|
|
pGroup = pTempGroup;
|
|
|
|
}
|
|
|
|
|
|
|
|
pData->mpFirstGroup = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
|
|
|
|
static ImplConfigData* ImplGetConfigData( const XubString& rFileName )
|
|
|
|
{
|
|
|
|
ImplConfigData* pData;
|
|
|
|
|
|
|
|
pData = new ImplConfigData;
|
|
|
|
pData->maFileName = rFileName;
|
|
|
|
pData->mpFirstGroup = NULL;
|
|
|
|
pData->mnDataUpdateId = 0;
|
|
|
|
pData->meLineEnd = LINEEND_CRLF;
|
|
|
|
pData->mnRefCount = 0;
|
|
|
|
pData->mbRead = FALSE;
|
2007-07-03 12:58:34 +00:00
|
|
|
pData->mbIsUTF8BOM = FALSE;
|
2000-11-08 12:11:22 +00:00
|
|
|
ImplReadConfig( pData );
|
|
|
|
|
|
|
|
return pData;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
static void ImplFreeConfigData( ImplConfigData* pDelData )
|
|
|
|
{
|
|
|
|
ImplDeleteConfigData( pDelData );
|
|
|
|
delete pDelData;
|
|
|
|
}
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
|
|
|
|
BOOL Config::ImplUpdateConfig() const
|
|
|
|
{
|
|
|
|
// Wenn sich TimeStamp unterscheidet, dann Datei neu einlesen
|
|
|
|
if ( mpData->mnTimeStamp != ImplSysGetConfigTimeStamp( maFileName ) )
|
|
|
|
{
|
|
|
|
ImplDeleteConfigData( mpData );
|
|
|
|
ImplReadConfig( mpData );
|
|
|
|
mpData->mnDataUpdateId++;
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
ImplGroupData* Config::ImplGetGroup() const
|
|
|
|
{
|
|
|
|
if ( !mpActGroup || (mnDataUpdateId != mpData->mnDataUpdateId) )
|
|
|
|
{
|
|
|
|
ImplGroupData* pPrevGroup = NULL;
|
|
|
|
ImplGroupData* pGroup = mpData->mpFirstGroup;
|
|
|
|
while ( pGroup )
|
|
|
|
{
|
|
|
|
if ( pGroup->maGroupName.EqualsIgnoreCaseAscii( maGroupName ) )
|
|
|
|
break;
|
|
|
|
|
|
|
|
pPrevGroup = pGroup;
|
|
|
|
pGroup = pGroup->mpNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Falls Gruppe noch nicht existiert, dann dazufuegen
|
|
|
|
if ( !pGroup )
|
|
|
|
{
|
|
|
|
pGroup = new ImplGroupData;
|
|
|
|
pGroup->mpNext = NULL;
|
|
|
|
pGroup->mpFirstKey = NULL;
|
|
|
|
pGroup->mnEmptyLines = 1;
|
|
|
|
if ( pPrevGroup )
|
|
|
|
pPrevGroup->mpNext = pGroup;
|
|
|
|
else
|
|
|
|
mpData->mpFirstGroup = pGroup;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Gruppenname immer uebernehmen, da er auch in dieser Form
|
|
|
|
// geschrieben werden soll. Ausserdem die Cache-Members der
|
|
|
|
// Config-Klasse updaten
|
|
|
|
pGroup->maGroupName = maGroupName;
|
|
|
|
((Config*)this)->mnDataUpdateId = mpData->mnDataUpdateId;
|
|
|
|
((Config*)this)->mpActGroup = pGroup;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mpActGroup;
|
|
|
|
}
|
|
|
|
|
|
|
|
// =======================================================================
|
|
|
|
|
|
|
|
Config::Config()
|
|
|
|
{
|
|
|
|
// Daten initialisieren und einlesen
|
|
|
|
maFileName = ImplMakeConfigName( NULL, NULL );
|
|
|
|
mpData = ImplGetConfigData( maFileName );
|
|
|
|
mpActGroup = NULL;
|
|
|
|
mnDataUpdateId = 0;
|
|
|
|
mnLockCount = 1;
|
|
|
|
mbPersistence = TRUE;
|
|
|
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
DBG_TRACE( "Config::Config()" );
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
Config::Config( const XubString& rFileName )
|
|
|
|
{
|
|
|
|
// Daten initialisieren und einlesen
|
|
|
|
maFileName = toUncPath( rFileName );
|
|
|
|
mpData = ImplGetConfigData( maFileName );
|
|
|
|
mpActGroup = NULL;
|
|
|
|
mnDataUpdateId = 0;
|
|
|
|
mnLockCount = 1;
|
|
|
|
mbPersistence = TRUE;
|
|
|
|
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
ByteString aTraceStr( "Config::Config( " );
|
|
|
|
aTraceStr += ByteString( maFileName, RTL_TEXTENCODING_UTF8 );
|
|
|
|
aTraceStr += " )";
|
|
|
|
DBG_TRACE( aTraceStr.GetBuffer() );
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
Config::~Config()
|
|
|
|
{
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
DBG_TRACE( "Config::~Config()" );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
Flush();
|
|
|
|
ImplFreeConfigData( mpData );
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
String Config::GetDefDirectory()
|
|
|
|
{
|
2001-05-22 14:42:49 +00:00
|
|
|
::rtl::OUString aDefConfig;
|
|
|
|
oslSecurity aSec = osl_getCurrentSecurity();
|
|
|
|
osl_getConfigDir( aSec, &aDefConfig.pData );
|
|
|
|
osl_freeSecurityHandle( aSec );
|
2000-11-08 12:11:22 +00:00
|
|
|
|
|
|
|
return aDefConfig;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
XubString Config::GetConfigName( const XubString& rPath,
|
|
|
|
const XubString& rBaseName )
|
|
|
|
{
|
|
|
|
return ImplMakeConfigName( &rBaseName, &rPath );
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
void Config::SetGroup( const ByteString& rGroup )
|
|
|
|
{
|
|
|
|
// Wenn neue Gruppe gesetzt wird, muss beim naechsten mal die
|
|
|
|
// Gruppe neu ermittelt werden
|
|
|
|
if ( maGroupName != rGroup )
|
|
|
|
{
|
|
|
|
maGroupName = rGroup;
|
|
|
|
mnDataUpdateId = mpData->mnDataUpdateId-1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
void Config::DeleteGroup( const ByteString& rGroup )
|
|
|
|
{
|
|
|
|
// Config-Daten evt. updaten
|
|
|
|
if ( !mnLockCount || !mpData->mbRead )
|
|
|
|
{
|
|
|
|
ImplUpdateConfig();
|
|
|
|
mpData->mbRead = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
ImplGroupData* pPrevGroup = NULL;
|
|
|
|
ImplGroupData* pGroup = mpData->mpFirstGroup;
|
|
|
|
while ( pGroup )
|
|
|
|
{
|
|
|
|
if ( pGroup->maGroupName.EqualsIgnoreCaseAscii( rGroup ) )
|
|
|
|
break;
|
|
|
|
|
|
|
|
pPrevGroup = pGroup;
|
|
|
|
pGroup = pGroup->mpNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( pGroup )
|
|
|
|
{
|
|
|
|
// Alle Keys loeschen
|
|
|
|
ImplKeyData* pTempKey;
|
|
|
|
ImplKeyData* pKey = pGroup->mpFirstKey;
|
|
|
|
while ( pKey )
|
|
|
|
{
|
|
|
|
pTempKey = pKey->mpNext;
|
|
|
|
delete pKey;
|
|
|
|
pKey = pTempKey;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Gruppe weiterschalten und loeschen
|
|
|
|
if ( pPrevGroup )
|
|
|
|
pPrevGroup->mpNext = pGroup->mpNext;
|
|
|
|
else
|
|
|
|
mpData->mpFirstGroup = pGroup->mpNext;
|
|
|
|
delete pGroup;
|
|
|
|
|
|
|
|
// Config-Datei neu schreiben
|
|
|
|
if ( !mnLockCount && mbPersistence )
|
|
|
|
ImplWriteConfig( mpData );
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mpData->mbModified = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Gruppen auf ungluetig setzen
|
|
|
|
mnDataUpdateId = mpData->mnDataUpdateId;
|
|
|
|
mpData->mnDataUpdateId++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
ByteString Config::GetGroupName( USHORT nGroup ) const
|
|
|
|
{
|
|
|
|
// Config-Daten evt. updaten
|
|
|
|
if ( !mnLockCount )
|
|
|
|
ImplUpdateConfig();
|
|
|
|
|
|
|
|
ImplGroupData* pGroup = mpData->mpFirstGroup;
|
|
|
|
USHORT nGroupCount = 0;
|
|
|
|
ByteString aGroupName;
|
|
|
|
while ( pGroup )
|
|
|
|
{
|
|
|
|
if ( nGroup == nGroupCount )
|
|
|
|
{
|
|
|
|
aGroupName = pGroup->maGroupName;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
nGroupCount++;
|
|
|
|
pGroup = pGroup->mpNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
return aGroupName;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
USHORT Config::GetGroupCount() const
|
|
|
|
{
|
|
|
|
// Config-Daten evt. updaten
|
|
|
|
if ( !mnLockCount )
|
|
|
|
ImplUpdateConfig();
|
|
|
|
|
|
|
|
ImplGroupData* pGroup = mpData->mpFirstGroup;
|
|
|
|
USHORT nGroupCount = 0;
|
|
|
|
while ( pGroup )
|
|
|
|
{
|
|
|
|
nGroupCount++;
|
|
|
|
pGroup = pGroup->mpNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
return nGroupCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
BOOL Config::HasGroup( const ByteString& rGroup ) const
|
|
|
|
{
|
|
|
|
// Config-Daten evt. updaten
|
|
|
|
if ( !mnLockCount )
|
|
|
|
ImplUpdateConfig();
|
|
|
|
|
|
|
|
ImplGroupData* pGroup = mpData->mpFirstGroup;
|
|
|
|
BOOL bRet = FALSE;
|
|
|
|
|
|
|
|
while( pGroup )
|
|
|
|
{
|
|
|
|
if( pGroup->maGroupName.EqualsIgnoreCaseAscii( rGroup ) )
|
|
|
|
{
|
|
|
|
bRet = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
pGroup = pGroup->mpNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
return bRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
ByteString Config::ReadKey( const ByteString& rKey ) const
|
|
|
|
{
|
|
|
|
return ReadKey( rKey, getEmptyByteString() );
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
UniString Config::ReadKey( const ByteString& rKey, rtl_TextEncoding eEncoding ) const
|
|
|
|
{
|
2007-07-03 12:58:34 +00:00
|
|
|
if ( mpData->mbIsUTF8BOM )
|
|
|
|
eEncoding = RTL_TEXTENCODING_UTF8;
|
2000-11-08 12:11:22 +00:00
|
|
|
return UniString( ReadKey( rKey ), eEncoding );
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
ByteString Config::ReadKey( const ByteString& rKey, const ByteString& rDefault ) const
|
|
|
|
{
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
ByteString aTraceStr( "Config::ReadKey( " );
|
|
|
|
aTraceStr += rKey;
|
|
|
|
aTraceStr += " ) from ";
|
|
|
|
aTraceStr += GetGroup();
|
|
|
|
aTraceStr += " in ";
|
|
|
|
aTraceStr += ByteString( maFileName, RTL_TEXTENCODING_UTF8 );
|
|
|
|
DBG_TRACE( aTraceStr.GetBuffer() );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Config-Daten evt. updaten
|
|
|
|
if ( !mnLockCount )
|
|
|
|
ImplUpdateConfig();
|
|
|
|
|
|
|
|
// Key suchen und Value zurueckgeben
|
|
|
|
ImplGroupData* pGroup = ImplGetGroup();
|
|
|
|
if ( pGroup )
|
|
|
|
{
|
|
|
|
ImplKeyData* pKey = pGroup->mpFirstKey;
|
|
|
|
while ( pKey )
|
|
|
|
{
|
|
|
|
if ( !pKey->mbIsComment && pKey->maKey.EqualsIgnoreCaseAscii( rKey ) )
|
|
|
|
return pKey->maValue;
|
|
|
|
|
|
|
|
pKey = pKey->mpNext;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return rDefault;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
void Config::WriteKey( const ByteString& rKey, const ByteString& rStr )
|
|
|
|
{
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
ByteString aTraceStr( "Config::WriteKey( " );
|
|
|
|
aTraceStr += rKey;
|
|
|
|
aTraceStr += ", ";
|
|
|
|
aTraceStr += rStr;
|
|
|
|
aTraceStr += " ) to ";
|
|
|
|
aTraceStr += GetGroup();
|
|
|
|
aTraceStr += " in ";
|
|
|
|
aTraceStr += ByteString( maFileName, RTL_TEXTENCODING_UTF8 );
|
|
|
|
DBG_TRACE( aTraceStr.GetBuffer() );
|
|
|
|
DBG_ASSERTWARNING( rStr != ReadKey( rKey ), "Config::WriteKey() with the same Value" );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Config-Daten evt. updaten
|
|
|
|
if ( !mnLockCount || !mpData->mbRead )
|
|
|
|
{
|
|
|
|
ImplUpdateConfig();
|
|
|
|
mpData->mbRead = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Key suchen und Value setzen
|
|
|
|
ImplGroupData* pGroup = ImplGetGroup();
|
|
|
|
if ( pGroup )
|
|
|
|
{
|
|
|
|
ImplKeyData* pPrevKey = NULL;
|
|
|
|
ImplKeyData* pKey = pGroup->mpFirstKey;
|
|
|
|
while ( pKey )
|
|
|
|
{
|
|
|
|
if ( !pKey->mbIsComment && pKey->maKey.EqualsIgnoreCaseAscii( rKey ) )
|
|
|
|
break;
|
|
|
|
|
|
|
|
pPrevKey = pKey;
|
|
|
|
pKey = pKey->mpNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL bNewValue;
|
|
|
|
if ( !pKey )
|
|
|
|
{
|
|
|
|
pKey = new ImplKeyData;
|
|
|
|
pKey->mpNext = NULL;
|
|
|
|
pKey->maKey = rKey;
|
|
|
|
pKey->mbIsComment = FALSE;
|
|
|
|
if ( pPrevKey )
|
|
|
|
pPrevKey->mpNext = pKey;
|
|
|
|
else
|
|
|
|
pGroup->mpFirstKey = pKey;
|
|
|
|
bNewValue = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
bNewValue = pKey->maValue != rStr;
|
|
|
|
|
|
|
|
if ( bNewValue )
|
|
|
|
{
|
|
|
|
pKey->maValue = rStr;
|
|
|
|
|
|
|
|
if ( !mnLockCount && mbPersistence )
|
|
|
|
ImplWriteConfig( mpData );
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mpData->mbModified = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
void Config::WriteKey( const ByteString& rKey, const UniString& rValue, rtl_TextEncoding eEncoding )
|
|
|
|
{
|
2007-07-03 12:58:34 +00:00
|
|
|
if ( mpData->mbIsUTF8BOM )
|
|
|
|
eEncoding = RTL_TEXTENCODING_UTF8;
|
2000-11-08 12:11:22 +00:00
|
|
|
WriteKey( rKey, ByteString( rValue, eEncoding ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
void Config::DeleteKey( const ByteString& rKey )
|
|
|
|
{
|
|
|
|
// Config-Daten evt. updaten
|
|
|
|
if ( !mnLockCount || !mpData->mbRead )
|
|
|
|
{
|
|
|
|
ImplUpdateConfig();
|
|
|
|
mpData->mbRead = TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Key suchen und Value setzen
|
|
|
|
ImplGroupData* pGroup = ImplGetGroup();
|
|
|
|
if ( pGroup )
|
|
|
|
{
|
|
|
|
ImplKeyData* pPrevKey = NULL;
|
|
|
|
ImplKeyData* pKey = pGroup->mpFirstKey;
|
|
|
|
while ( pKey )
|
|
|
|
{
|
|
|
|
if ( !pKey->mbIsComment && pKey->maKey.EqualsIgnoreCaseAscii( rKey ) )
|
|
|
|
break;
|
|
|
|
|
|
|
|
pPrevKey = pKey;
|
|
|
|
pKey = pKey->mpNext;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( pKey )
|
|
|
|
{
|
|
|
|
// Gruppe weiterschalten und loeschen
|
|
|
|
if ( pPrevKey )
|
|
|
|
pPrevKey->mpNext = pKey->mpNext;
|
|
|
|
else
|
|
|
|
pGroup->mpFirstKey = pKey->mpNext;
|
|
|
|
delete pKey;
|
|
|
|
|
|
|
|
// Config-Datei neu schreiben
|
|
|
|
if ( !mnLockCount && mbPersistence )
|
|
|
|
ImplWriteConfig( mpData );
|
|
|
|
else
|
|
|
|
{
|
|
|
|
mpData->mbModified = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
USHORT Config::GetKeyCount() const
|
|
|
|
{
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
ByteString aTraceStr( "Config::GetKeyCount()" );
|
|
|
|
aTraceStr += " from ";
|
|
|
|
aTraceStr += GetGroup();
|
|
|
|
aTraceStr += " in ";
|
|
|
|
aTraceStr += ByteString( maFileName, RTL_TEXTENCODING_UTF8 );
|
|
|
|
DBG_TRACE( aTraceStr.GetBuffer() );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Config-Daten evt. updaten
|
|
|
|
if ( !mnLockCount )
|
|
|
|
ImplUpdateConfig();
|
|
|
|
|
|
|
|
// Key suchen und Value zurueckgeben
|
|
|
|
USHORT nCount = 0;
|
|
|
|
ImplGroupData* pGroup = ImplGetGroup();
|
|
|
|
if ( pGroup )
|
|
|
|
{
|
|
|
|
ImplKeyData* pKey = pGroup->mpFirstKey;
|
|
|
|
while ( pKey )
|
|
|
|
{
|
|
|
|
if ( !pKey->mbIsComment )
|
|
|
|
nCount++;
|
|
|
|
|
|
|
|
pKey = pKey->mpNext;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
ByteString Config::GetKeyName( USHORT nKey ) const
|
|
|
|
{
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
ByteString aTraceStr( "Config::GetKeyName( " );
|
2004-02-26 12:20:06 +00:00
|
|
|
aTraceStr += ByteString::CreateFromInt32(nKey);
|
2000-11-08 12:11:22 +00:00
|
|
|
aTraceStr += " ) from ";
|
|
|
|
aTraceStr += GetGroup();
|
|
|
|
aTraceStr += " in ";
|
|
|
|
aTraceStr += ByteString( maFileName, RTL_TEXTENCODING_UTF8 );
|
|
|
|
DBG_TRACE( aTraceStr.GetBuffer() );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Key suchen und Name zurueckgeben
|
|
|
|
ImplGroupData* pGroup = ImplGetGroup();
|
|
|
|
if ( pGroup )
|
|
|
|
{
|
|
|
|
ImplKeyData* pKey = pGroup->mpFirstKey;
|
|
|
|
while ( pKey )
|
|
|
|
{
|
|
|
|
if ( !pKey->mbIsComment )
|
|
|
|
{
|
|
|
|
if ( !nKey )
|
|
|
|
return pKey->maKey;
|
|
|
|
nKey--;
|
|
|
|
}
|
|
|
|
|
|
|
|
pKey = pKey->mpNext;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return getEmptyByteString();
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
ByteString Config::ReadKey( USHORT nKey ) const
|
|
|
|
{
|
|
|
|
#ifdef DBG_UTIL
|
|
|
|
ByteString aTraceStr( "Config::ReadKey( " );
|
|
|
|
aTraceStr += ByteString::CreateFromInt32( nKey );
|
|
|
|
aTraceStr += " ) from ";
|
|
|
|
aTraceStr += GetGroup();
|
|
|
|
aTraceStr += " in ";
|
|
|
|
aTraceStr += ByteString( maFileName, RTL_TEXTENCODING_UTF8 );
|
|
|
|
DBG_TRACE( aTraceStr.GetBuffer() );
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Key suchen und Value zurueckgeben
|
|
|
|
ImplGroupData* pGroup = ImplGetGroup();
|
|
|
|
if ( pGroup )
|
|
|
|
{
|
|
|
|
ImplKeyData* pKey = pGroup->mpFirstKey;
|
|
|
|
while ( pKey )
|
|
|
|
{
|
|
|
|
if ( !pKey->mbIsComment )
|
|
|
|
{
|
|
|
|
if ( !nKey )
|
|
|
|
return pKey->maValue;
|
|
|
|
nKey--;
|
|
|
|
}
|
|
|
|
|
|
|
|
pKey = pKey->mpNext;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return getEmptyByteString();
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
void Config::EnterLock()
|
|
|
|
{
|
|
|
|
// Config-Daten evt. updaten
|
|
|
|
if ( !mnLockCount )
|
|
|
|
ImplUpdateConfig();
|
|
|
|
|
|
|
|
mnLockCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
void Config::LeaveLock()
|
|
|
|
{
|
|
|
|
DBG_ASSERT( mnLockCount, "Config::LeaveLook() without Config::EnterLook()" );
|
|
|
|
mnLockCount--;
|
|
|
|
|
|
|
|
if ( (mnLockCount == 0) && mpData->mbModified && mbPersistence )
|
|
|
|
ImplWriteConfig( mpData );
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
BOOL Config::Update()
|
|
|
|
{
|
|
|
|
return ImplUpdateConfig();
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
void Config::Flush()
|
|
|
|
{
|
|
|
|
if ( mpData->mbModified && mbPersistence )
|
|
|
|
ImplWriteConfig( mpData );
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
void Config::SetLineEnd( LineEnd eLineEnd )
|
|
|
|
{
|
|
|
|
mpData->meLineEnd = eLineEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
|
|
LineEnd Config::GetLineEnd() const
|
|
|
|
{
|
|
|
|
return mpData->meLineEnd;
|
|
|
|
}
|
|
|
|
|