28#include <osl/file.hxx>
68 if( rPath.startsWith(
"file://"))
72 else if( ::osl::FileBase::getFileURLFromSystemPath( rPath, aFileURL ) != ::osl::FileBase::E_None )
81 sal_uInt32 nTimeStamp = 0;
82 ::osl::DirectoryItem aItem;
83 ::osl::FileStatus aStatus( osl_FileStatus_Mask_ModifyTime );
85 if( ::osl::DirectoryItem::get( rFileName, aItem ) == ::osl::FileBase::E_None &&
86 aItem.getFileStatus( aStatus ) == ::osl::FileBase::E_None )
88 nTimeStamp = aStatus.getModifyTime().Seconds;
95 sal_uInt64& rRead,
bool& rbRead,
bool& rbIsUTF8BOM, sal_uInt32& rTimeStamp )
97 std::unique_ptr<sal_uInt8[]> pBuf;
98 ::osl::File aFile( rFileName );
100 if( aFile.open( osl_File_OpenFlag_Read ) == ::osl::FileBase::E_None )
103 if( aFile.getSize(
nPos ) == ::osl::FileBase::E_None )
105 if (
nPos > SAL_MAX_SIZE) {
110 sal_uInt64 nRead = 0;
111 if( aFile.read( pBuf.get(),
nPos, nRead ) == ::osl::FileBase::E_None && nRead ==
nPos )
114 unsigned char const BOM[3] = {0xEF, 0xBB, 0xBF};
115 if (nRead > 2 && memcmp(pBuf.get(), BOM, 3) == 0)
118 memmove(pBuf.get(), pBuf.get() + 3, sal::static_int_cast<std::size_t>(nRead *
sizeof(
sal_uInt8)) );
138 const sal_uInt8* pBuf, sal_uInt32 nBufLen,
bool rbIsUTF8BOM, sal_uInt32& rTimeStamp )
140 bool bSuccess =
false;
141 bool bUTF8BOMSuccess =
false;
143 ::osl::File aFile( rFileName );
144 ::osl::FileBase::RC eError = aFile.open( osl_File_OpenFlag_Write | osl_File_OpenFlag_Create );
145 if( eError != ::osl::FileBase::E_None )
146 eError = aFile.open( osl_File_OpenFlag_Write );
147 if( eError == ::osl::FileBase::E_None )
156 unsigned char const BOM[3] = {0xEF, 0xBB, 0xBF};
157 sal_uInt64 nUTF8BOMWritten;
158 if( aFile.write( BOM, 3, nUTF8BOMWritten ) == ::osl::FileBase::E_None && 3 == nUTF8BOMWritten )
160 bUTF8BOMSuccess =
true;
164 if( aFile.write( pBuf, nBufLen, nWritten ) == ::osl::FileBase::E_None && nWritten == nBufLen )
168 if ( rbIsUTF8BOM ? bSuccess && bUTF8BOMSuccess : bSuccess )
174 return rbIsUTF8BOM ? bSuccess && bUTF8BOMSuccess : bSuccess;
178OString makeOString(
const sal_uInt8* p, sal_uInt64 n)
180 if (n > SAL_MAX_INT32)
189 reinterpret_cast< char const *
>(p),
190 sal::static_int_cast< sal_Int32 >(n));
207 ImplKeyData* pPrevKey =
nullptr;
215 if ( pBuf[
i] == 0x1A )
219 while ( (pBuf[
i] ==
' ') || (pBuf[
i] ==
'\t') )
227 while ( (
i < nLen) && pBuf[
i] && (pBuf[
i] !=
'\r') && (pBuf[
i] !=
'\n') &&
235 (pBuf[
i] != pBuf[
i+1]) &&
236 ((pBuf[
i+1] ==
'\r') || (pBuf[
i+1] ==
'\n')) )
248 pPrevGroup->
mpNext = pGroup;
250 pData->mpFirstGroup = pGroup;
259 while ( (*pLine ==
' ') || (*pLine ==
'\t') )
265 while ( (nNameLen < nLineLen) && (pLine[nNameLen] !=
']') )
269 while ( (pLine[nNameLen-1] ==
' ') || (pLine[nNameLen-1] ==
'\t') )
272 pGroup->
maGroupName = makeOString(pLine, nNameLen);
285 pData->mpFirstGroup = pGroup;
295 pKey =
new ImplKeyData;
296 pKey->mbIsComment =
true;
304 pKey =
new ImplKeyData;
305 pKey->mpNext =
nullptr;
307 pPrevKey->mpNext = pKey;
311 if ( pLine[0] ==
';' )
313 pKey->maValue = makeOString(pLine, nLineLen);
314 pKey->mbIsComment =
true;
318 pKey->mbIsComment =
false;
320 while ( (nNameLen < nLineLen) && (pLine[nNameLen] !=
'=') )
326 while ( (pLine[nNameLen-1] ==
' ') || (pLine[nNameLen-1] ==
'\t') )
329 pKey->maKey = makeOString(pLine, nNameLen);
331 if ( nKeyLen < nLineLen )
336 while ( (*pLine ==
' ') || (*pLine ==
'\t') )
343 while ( (pLine[nLineLen-1] ==
' ') || (pLine[nLineLen-1] ==
'\t') )
345 pKey->maValue = makeOString(pLine, nLineLen);
363 std::unique_ptr<sal_uInt8[]> pWriteBuf;
369 sal_uInt32 nValueLen;
371 sal_uInt32 nLineEndLen;
373 aLineEndBuf[0] =
'\r';
374 aLineEndBuf[1] =
'\n';
378 pGroup =
pData->mpFirstGroup;
384 nBufLen += pGroup->
maGroupName.getLength() + nLineEndLen + 2;
388 nValueLen = pKey->maValue.getLength();
389 if ( pKey->mbIsComment )
390 nBufLen += nValueLen + nLineEndLen;
392 nBufLen += pKey->maKey.getLength() + nValueLen + nLineEndLen + 1;
410 pWriteBuf.reset(
new sal_uInt8[nLineEndLen]);
411 pWriteBuf[0] = aLineEndBuf[0];
412 if ( nLineEndLen == 2 )
413 pWriteBuf[1] = aLineEndBuf[1];
421 pBuf = pWriteBuf.get();
422 pGroup =
pData->mpFirstGroup;
432 *pBuf = aLineEndBuf[0]; pBuf++;
433 if ( nLineEndLen == 2 )
435 *pBuf = aLineEndBuf[1]; pBuf++;
440 nValueLen = pKey->maValue.getLength();
441 if ( pKey->mbIsComment )
445 memcpy( pBuf, pKey->maValue.getStr(), nValueLen );
448 *pBuf = aLineEndBuf[0]; pBuf++;
449 if ( nLineEndLen == 2 )
451 *pBuf = aLineEndBuf[1]; pBuf++;
456 nKeyLen = pKey->maKey.getLength();
457 memcpy( pBuf, pKey->maKey.getStr(), nKeyLen );
460 memcpy( pBuf, pKey->maValue.getStr(), nValueLen );
462 *pBuf = aLineEndBuf[0]; pBuf++;
463 if ( nLineEndLen == 2 )
465 *pBuf = aLineEndBuf[1]; pBuf++;
474 while ( nEmptyLines )
476 *pBuf = aLineEndBuf[0]; pBuf++;
477 if ( nLineEndLen == 2 )
479 *pBuf = aLineEndBuf[1]; pBuf++;
493 sal_uInt32 nTimeStamp = 0;
494 sal_uInt64 nRead = 0;
496 bool bIsUTF8BOM =
false;
497 std::unique_ptr<sal_uInt8[]> pBuf =
ImplSysReadConfig(
pData->maFileName, nRead, bRead, bIsUTF8BOM, nTimeStamp );
505 pData->mnTimeStamp = nTimeStamp;
506 pData->mbModified =
false;
508 pData->mbRead =
true;
510 pData->mbIsUTF8BOM =
true;
516 "tools.generic",
"Config overwrites modified configfile: " <<
pData->maFileName );
524 pData->mbModified =
false;
527 pData->mbModified =
false;
532 ImplKeyData* pTempKey;
538 pTempGroup = pGroup->
mpNext;
544 pTempKey = pKey->mpNext;
554 pData->mpFirstGroup =
nullptr;
560 pData->maFileName = rFileName;
561 pData->mpFirstGroup =
nullptr;
562 pData->mnDataUpdateId = 0;
563 pData->mbRead =
false;
564 pData->mbIsUTF8BOM =
false;
607 pPrevGroup->
mpNext = pGroup;
609 mpData->mpFirstGroup = pGroup;
634 SAL_INFO(
"tools.generic",
"Config::~Config()" );
663 if ( pGroup->
maGroupName.equalsIgnoreAsciiCase(rGroup) )
674 ImplKeyData* pTempKey;
678 pTempKey = pKey->mpNext;
691 mpData->mbModified =
true;
700 sal_uInt16 nGroupCount = 0;
704 if ( nGroup == nGroupCount )
720 sal_uInt16 nGroupCount = 0;
737 if( pGroup->
maGroupName.equalsIgnoreAsciiCase(rGroup) )
751 return ReadKey(rKey, OString());
756 SAL_INFO(
"tools.generic",
"Config::ReadKey( " << rKey <<
" ) from " <<
GetGroup()
766 if ( !pKey->mbIsComment && pKey->maKey.equalsIgnoreAsciiCase(rKey) )
767 return pKey->maValue;
778 SAL_INFO(
"tools.generic",
"Config::WriteKey( " << rKey <<
", " << rStr <<
" ) to "
793 ImplKeyData* pPrevKey =
nullptr;
797 if ( !pKey->mbIsComment && pKey->maKey.equalsIgnoreAsciiCase(rKey) )
807 pKey =
new ImplKeyData;
808 pKey->mpNext =
nullptr;
810 pKey->mbIsComment =
false;
812 pPrevKey->mpNext = pKey;
818 bNewValue = pKey->maValue != rStr;
822 pKey->maValue = rStr;
824 mpData->mbModified =
true;
842 ImplKeyData* pPrevKey =
nullptr;
846 if ( !pKey->mbIsComment && pKey->maKey.equalsIgnoreAsciiCase(rKey) )
857 pPrevKey->mpNext = pKey->mpNext;
862 mpData->mbModified =
true;
878 if ( !pKey->mbIsComment )
890 SAL_INFO(
"tools.generic",
"Config::GetKeyName( " << OString::number(
static_cast<sal_Int32
>(nKey))
900 if ( !pKey->mbIsComment )
916 SAL_INFO(
"tools.generic",
"Config::ReadKey( " << OString::number(
static_cast<sal_Int32
>(nKey))
926 if ( !pKey->mbIsComment )
929 return pKey->maValue;
const OString & GetGroup() const
void DeleteKey(std::string_view rKey)
OString GetKeyName(sal_uInt16 nKey) const
Config(const OUString &rFileName)
void SetGroup(const OString &rGroup)
void DeleteGroup(std::string_view rGroup)
OString GetGroupName(sal_uInt16 nGroup) const
sal_uInt16 GetKeyCount() const
TOOLS_DLLPRIVATE bool ImplUpdateConfig() const
sal_uInt32 mnDataUpdateId
OString ReadKey(const OString &rKey) const
bool HasGroup(std::string_view rGroup) const
sal_uInt16 GetGroupCount() const
std::unique_ptr< ImplConfigData > mpData
ImplGroupData * mpActGroup
void WriteKey(const OString &rKey, const OString &rValue)
TOOLS_DLLPRIVATE ImplGroupData * ImplGetGroup() const
static std::unique_ptr< ImplConfigData > ImplGetConfigData(const OUString &rFileName)
static void ImplMakeConfigList(ImplConfigData *pData, const sal_uInt8 *pBuf, sal_uInt64 nLen)
static OUString toUncPath(const OUString &rPath)
static void ImplWriteConfig(ImplConfigData *pData)
static std::unique_ptr< sal_uInt8[]> ImplSysReadConfig(const OUString &rFileName, sal_uInt64 &rRead, bool &rbRead, bool &rbIsUTF8BOM, sal_uInt32 &rTimeStamp)
static std::unique_ptr< sal_uInt8[]> ImplGetConfigBuffer(const ImplConfigData *pData, sal_uInt32 &rLen)
static void ImplReadConfig(ImplConfigData *pData)
static bool ImplSysWriteConfig(const OUString &rFileName, const sal_uInt8 *pBuf, sal_uInt32 nBufLen, bool rbIsUTF8BOM, sal_uInt32 &rTimeStamp)
static void ImplDeleteConfigData(ImplConfigData *pData)
static sal_uInt32 ImplSysGetConfigTimeStamp(const OUString &rFileName)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_INFO(area, stream)
std::unique_ptr< sal_Int32[]> pData
sal_uInt32 mnDataUpdateId
ImplGroupData * mpFirstGroup