summaryrefslogtreecommitdiff
path: root/comphelper
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2016-09-23 18:21:54 +0200
committerArmin Le Grand <Armin.Le.Grand@cib.de>2016-10-11 13:56:22 +0200
commit7db23b6346ff601449e8017fd585e9fbc295ed34 (patch)
tree696b232a1a372d13bbaf605586a9c9f4637744d2 /comphelper
parent9fa4eff9be5e440099517a522a83e20debaf2955 (diff)
profilesafe: Collect copies in single *.pack file
Enhanced helper classes for BackupFileHelper to allow writing a stack of rescued last valid configuration files to a single file package. Added configuration values for enabling this and defining the number of entries, added max entry limitation. Using FileSize and CRC32 now to dectect if config file did change. To make this work I added sorting to writing the configuration so that with no change the same configuration file is written. Use std::vector for better mem performance for sorting, defined static const for buffer size of manipulation, prepare inflate/deflate usages. Fixes to setPos, warnings Change-Id: Ib286e2a3f25b0085a1e3ae4f50c9ff1ff3a5dcf5
Diffstat (limited to 'comphelper')
-rw-r--r--comphelper/source/misc/backupfilehelper.cxx714
1 files changed, 576 insertions, 138 deletions
diff --git a/comphelper/source/misc/backupfilehelper.cxx b/comphelper/source/misc/backupfilehelper.cxx
index 7a353b8e90bb..8fed178faa44 100644
--- a/comphelper/source/misc/backupfilehelper.cxx
+++ b/comphelper/source/misc/backupfilehelper.cxx
@@ -9,232 +9,670 @@
#include <sal/config.h>
-#include <comphelper/backupfilehelper.hxx>
#include <rtl/ustring.hxx>
+#include <rtl/bootstrap.hxx>
+#include <comphelper/backupfilehelper.hxx>
+#include <rtl/crc.h>
+#include <deque>
-namespace comphelper
-{
- sal_uInt16 BackupFileHelper::mnMaxAllowedBackups = 10;
- bool BackupFileHelper::mbExitWasCalled = false;
+typedef std::shared_ptr< osl::File > FileSharedPtr;
+static const sal_uInt32 BACKUP_FILE_HELPER_BLOCK_SIZE = 1024;
- BackupFileHelper::BackupFileHelper(
- const OUString& rBaseURL,
- sal_uInt16 nNumBackups)
- : mrBaseURL(rBaseURL),
- mnNumBackups(::std::min(::std::max(nNumBackups, sal_uInt16(1)), mnMaxAllowedBackups)),
- maBase(),
- maExt(),
- maBaseFile(rBaseURL),
- mbBaseFileIsOpen(false)
+namespace
+{
+ OUString splitAtLastToken(const OUString& rSrc, sal_Unicode aToken, OUString& rRight)
{
- }
+ const sal_Int32 nIndex(rSrc.lastIndexOf(aToken));
+ OUString aRetval;
- void BackupFileHelper::setExitWasCalled()
- {
- mbExitWasCalled = true;
- }
+ if (-1 == nIndex)
+ {
+ aRetval = rSrc;
+ }
+ else if (nIndex > 0)
+ {
+ aRetval = rSrc.copy(0, nIndex);
+ }
- bool BackupFileHelper::getExitWasCalled()
- {
- return mbExitWasCalled;
+ if (rSrc.getLength() > nIndex + 1)
+ {
+ rRight = rSrc.copy(nIndex + 1);
+ }
+
+ return aRetval;
}
- bool BackupFileHelper::tryPush()
+ sal_uInt32 createCrc32(FileSharedPtr& rCandidate, sal_uInt32 nOffset)
{
- if (isDifferentOrNew())
+ sal_uInt32 nCrc32(0);
+
+ if (rCandidate && osl::File::E_None == rCandidate->open(osl_File_OpenFlag_Read))
{
- // the new file is different or new, create a new first backup
- // rename/move/cleanup other backup files, make space for new first backup
- push();
+ sal_uInt8 aArray[BACKUP_FILE_HELPER_BLOCK_SIZE];
+ sal_uInt64 nBytesTransfer(0);
+ sal_uInt64 nSize(0);
- // copy new one to now free 1st position
- osl::File::copy(mrBaseURL, getName(1));
+ rCandidate->getSize(nSize);
- return true;
- }
+ // set offset in source file - should be zero due to crc32 should
+ // only be needed to be created for new entries, gets loaded with old
+ // ones
+ if (osl::File::E_None == rCandidate->setPos(osl_Pos_Absolut, sal_Int64(nOffset)))
+ {
+ while (nSize != 0)
+ {
+ const sal_uInt64 nToTransfer(std::min(nSize, (sal_uInt64)BACKUP_FILE_HELPER_BLOCK_SIZE));
+
+ if (osl::File::E_None == rCandidate->read(static_cast<void*>(aArray), nToTransfer, nBytesTransfer) && nBytesTransfer == nToTransfer)
+ {
+ // add to crc and reduce size
+ nCrc32 = rtl_crc32(nCrc32, static_cast<void*>(aArray), static_cast<sal_uInt32>(nBytesTransfer));
+ nSize -= nToTransfer;
+ }
+ else
+ {
+ // error - reset to zero again
+ nSize = nCrc32 = 0;
+ }
+ }
+ }
- return false;
- }
+ rCandidate->close();
+ }
- bool BackupFileHelper::isPopPossible()
- {
- return firstExists();
+ return nCrc32;
}
+}
- bool BackupFileHelper::tryPop()
+namespace
+{
+ struct PackedFileEntry
{
- if (firstExists())
+ private:
+ sal_uInt32 mnSize; // size in bytes
+ sal_uInt32 mnOffset; // offset in File (zero identifies new file)
+ sal_uInt32 mnCrc32; // checksum
+ FileSharedPtr maFile; // file where to find the data (at offset)
+
+ public:
+ PackedFileEntry(
+ sal_uInt32 nSize,
+ sal_uInt32 nOffset,
+ sal_uInt32 nCrc32,
+ FileSharedPtr& rFile)
+ : mnSize(nSize),
+ mnOffset(nOffset),
+ mnCrc32(nCrc32),
+ maFile(rFile)
{
- // first copy exists, copy over original and delete
- const OUString aOneName(getName(1));
- maBaseFile.close();
- osl::File::copy(aOneName, mrBaseURL);
- osl::File::remove(aOneName);
+ }
- // rename/move/cleanup other backup files
- pop();
+ PackedFileEntry()
+ : mnSize(0),
+ mnOffset(0),
+ mnCrc32(0),
+ maFile()
+ {
+ }
- return true;
+ sal_uInt32 getSize() const
+ {
+ return mnSize;
}
- return false;
- }
+ sal_uInt32 getOffset() const
+ {
+ return mnOffset;
+ }
- rtl::OUString BackupFileHelper::getName(sal_uInt16 n)
- {
- if (maExt.isEmpty())
+ sal_uInt32 getCrc32() const
{
- return OUString(maBase + "_" + OUString::number(n));
+ return mnCrc32;
}
- return OUString(maBase + "_" + OUString::number(n) + "." + maExt);
- }
+ bool read_header(
+ FileSharedPtr& rFile,
+ sal_uInt32 nOffset)
+ {
+ mnOffset = nOffset;
+ maFile = rFile;
- bool BackupFileHelper::firstExists()
- {
- if (baseFileOpen() && splitBaseURL())
+ if (maFile)
+ {
+ sal_uInt8 aArray[4];
+ sal_uInt64 nBaseRead(0);
+
+ // read and compute entry size
+ if (osl::File::E_None == maFile->read(static_cast<void*>(aArray), 4, nBaseRead) && 4 == nBaseRead)
+ {
+ mnSize = (sal_uInt32(aArray[0]) << 24) + (sal_uInt32(aArray[1]) << 16) + (sal_uInt32(aArray[2]) << 8) + sal_uInt32(aArray[3]);
+ }
+ else
+ {
+ return false;
+ }
+
+ // read and compute entry crc32
+ if (osl::File::E_None == maFile->read(static_cast<void*>(aArray), 4, nBaseRead) && 4 == nBaseRead)
+ {
+ mnCrc32 = (sal_uInt32(aArray[0]) << 24) + (sal_uInt32(aArray[1]) << 16) + (sal_uInt32(aArray[2]) << 8) + sal_uInt32(aArray[3]);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ bool write_header(oslFileHandle& rHandle)
{
- // check if 1st copy exists
- osl::File aOneFile(getName(1));
- const osl::FileBase::RC aResult(aOneFile.open(osl_File_OpenFlag_Read));
+ sal_uInt8 aArray[4];
+ sal_uInt64 nBaseWritten(0);
+
+ // write size
+ aArray[0] = sal_uInt8((mnSize & 0xff000000) >> 24);
+ aArray[1] = sal_uInt8((mnSize & 0x00ff0000) >> 16);
+ aArray[2] = sal_uInt8((mnSize & 0x0000ff00) >> 8);
+ aArray[3] = sal_uInt8(mnSize & 0x000000ff);
+
+ if (osl_File_E_None != osl_writeFile(rHandle, static_cast<const void*>(aArray), 4, &nBaseWritten) || 4 != nBaseWritten)
+ {
+ return false;
+ }
+
+ // for each entry, write crc32
+ aArray[0] = sal_uInt8((mnCrc32 & 0xff000000) >> 24);
+ aArray[1] = sal_uInt8((mnCrc32 & 0x00ff0000) >> 16);
+ aArray[2] = sal_uInt8((mnCrc32 & 0x0000ff00) >> 8);
+ aArray[3] = sal_uInt8(mnCrc32 & 0x000000ff);
+
+ if (osl_File_E_None != osl_writeFile(rHandle, static_cast<const void*>(aArray), 4, &nBaseWritten) || 4 != nBaseWritten)
+ {
+ return false;
+ }
- return (osl::File::E_None == aResult);
+ return true;
}
- return false;
- }
+ bool copy_content(oslFileHandle& rTargetHandle, bool bInflate)
+ {
+ if (maFile && osl::File::E_None == maFile->open(osl_File_OpenFlag_Read))
+ {
+ sal_uInt8 aArray[BACKUP_FILE_HELPER_BLOCK_SIZE];
+ sal_uInt64 nBytesTransfer(0);
+ sal_uInt64 nSize(getSize());
+ const bool bNewFile(0 == getOffset());
+
+ // set offset in source file - when this is zero, a new file is to be added
+ if (osl::File::E_None == maFile->setPos(osl_Pos_Absolut, sal_Int64(getOffset())))
+ {
+ if (!bInflate)
+ {
+ // copy-back, deflate file
+ }
+ else if (bNewFile)
+ {
+ // new file gets added, inflate initially
+ }
+
+ while (nSize != 0)
+ {
+ const sal_uInt64 nToTransfer(std::min(nSize, (sal_uInt64)BACKUP_FILE_HELPER_BLOCK_SIZE));
+
+ if (osl::File::E_None != maFile->read(static_cast<void*>(aArray), nToTransfer, nBytesTransfer) || nBytesTransfer != nToTransfer)
+ {
+ break;
+ }
+
+ if (osl_File_E_None != osl_writeFile(rTargetHandle, static_cast<const void*>(aArray), nToTransfer, &nBytesTransfer) || nBytesTransfer != nToTransfer)
+ {
+ break;
+ }
+
+ nSize -= nToTransfer;
+ }
+ }
+
+ maFile->close();
+
+ return (0 == nSize);
+ }
+ else
+ {
+ return false;
+ }
+ }
+ };
+}
+
+namespace
+{
+ typedef ::std::deque< PackedFileEntry > PackedFileEntryVector;
- void BackupFileHelper::pop()
+ class PackedFile
{
- for (sal_uInt16 a(2); a < mnMaxAllowedBackups + 1; a++)
+ private:
+ const OUString maURL;
+ PackedFileEntryVector maPackedFileEntryVector;
+ bool mbChanged;
+
+ public:
+ PackedFile(const OUString& rURL)
+ : maURL(rURL),
+ maPackedFileEntryVector(),
+ mbChanged(false)
{
- const OUString aSourceName(getName(a));
+ FileSharedPtr aSourceFile(new osl::File(rURL));
- if (a > mnNumBackups + 1)
+ if (osl::File::E_None == aSourceFile->open(osl_File_OpenFlag_Read))
{
- // try to delete that file, it is out of scope
- osl::File::remove(aSourceName);
+ sal_uInt64 nBaseLen(0);
+ aSourceFile->getSize(nBaseLen);
+
+ // we need at least File_ID and num entries -> 8byte
+ if (8 < nBaseLen)
+ {
+ sal_uInt8 aArray[4];
+ sal_uInt64 nBaseRead(0);
+
+ // read and check File_ID
+ if (osl::File::E_None == aSourceFile->read(static_cast< void* >(aArray), 4, nBaseRead) && 4 == nBaseRead)
+ {
+ if ('P' == aArray[0] && 'A' == aArray[1] && 'C' == aArray[2] && 'K' == aArray[3])
+ {
+ // read and compute num entries in this file
+ if (osl::File::E_None == aSourceFile->read(static_cast<void*>(aArray), 4, nBaseRead) && 4 == nBaseRead)
+ {
+ sal_uInt32 nEntries((sal_uInt32(aArray[0]) << 24) + (sal_uInt32(aArray[1]) << 16) + (sal_uInt32(aArray[2]) << 8) + sal_uInt32(aArray[3]));
+
+ // if there are entries (and less than max), read them
+ if (nEntries >= 1 && nEntries <= 10)
+ {
+ // offset in souce file starts with 8Byte for header+numEntries and
+ // 8byte for each entry (size and crc32)
+ sal_uInt32 nOffset(8 + (8 * nEntries));
+
+ for (sal_uInt32 a(0); a < nEntries; a++)
+ {
+ // create new entry, read header (size and crc) and
+ // set offset and source file
+ PackedFileEntry aEntry;
+
+ if (aEntry.read_header(aSourceFile, nOffset))
+ {
+ // add to local data
+ maPackedFileEntryVector.push_back(aEntry);
+
+ // increase offset for next entry
+ nOffset += aEntry.getSize();
+ }
+ else
+ {
+ // error
+ nEntries = 0;
+ }
+ }
+
+ if (0 == nEntries)
+ {
+ // on read error clear local data
+ maPackedFileEntryVector.clear();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ aSourceFile->close();
}
- else
+
+ if (maPackedFileEntryVector.empty())
{
- // rename that file by decreasing index by one
- osl::File::move(aSourceName, getName(a - 1));
+ // on error or no data get rid of pack file
+ osl::File::remove(maURL);
}
}
- }
- void BackupFileHelper::push()
- {
- for (sal_uInt16 a(0); a < mnMaxAllowedBackups; a++)
+ bool flush()
+ {
+ bool bRetval(true);
+
+ if (maPackedFileEntryVector.empty())
+ {
+ // get rid of (now?) empty pack file
+ osl::File::remove(maURL);
+ }
+ else if (mbChanged)
+ {
+ // need to create a new pack file, do this in a temp file to which data
+ // will be copied from local file (so keep it here until this is done)
+ oslFileHandle aHandle;
+ OUString aTempURL;
+
+ // open target temp file
+ if (osl::File::E_None == osl::FileBase::createTempFile(nullptr, &aHandle, &aTempURL))
+ {
+ sal_uInt8 aArray[4];
+ sal_uInt64 nBaseWritten(0);
+
+ aArray[0] = 'P';
+ aArray[1] = 'A';
+ aArray[2] = 'C';
+ aArray[3] = 'K';
+
+ // write File_ID
+ if (osl_File_E_None == osl_writeFile(aHandle, static_cast<const void*>(aArray), 4, &nBaseWritten) && 4 == nBaseWritten)
+ {
+ const sal_uInt32 nSize(maPackedFileEntryVector.size());
+ aArray[0] = sal_uInt8((nSize & 0xff000000) >> 24);
+ aArray[1] = sal_uInt8((nSize & 0x00ff0000) >> 16);
+ aArray[2] = sal_uInt8((nSize & 0x0000ff00) >> 8);
+ aArray[3] = sal_uInt8(nSize & 0x000000ff);
+
+ // write number of entries
+ if (osl_File_E_None == osl_writeFile(aHandle, static_cast<const void*>(aArray), 4, &nBaseWritten) && 4 == nBaseWritten)
+ {
+ // write headers
+ for (auto& candidateA : maPackedFileEntryVector)
+ {
+ if (!candidateA.write_header(aHandle))
+ {
+ // error
+ bRetval = false;
+ break;
+ }
+ }
+
+ if (bRetval)
+ {
+ // write contents
+ for (auto& candidateB : maPackedFileEntryVector)
+ {
+ if (!candidateB.copy_content(aHandle, true))
+ {
+ bRetval = false;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // close temp file (in all cases)
+ osl_closeFile(aHandle);
+
+ if (bRetval)
+ {
+ // copy over existing file by first deleting original
+ // and moving the temp file to old original
+ osl::File::remove(maURL);
+ osl::File::move(aTempURL, maURL);
+ }
+
+ // delete temp file (in all cases - it may be moved already)
+ osl::File::remove(aTempURL);
+ }
+
+ return bRetval;
+ }
+
+ bool tryPush(FileSharedPtr& rFileCandidate)
{
- const sal_uInt16 nIndex(mnMaxAllowedBackups - a);
- const OUString aSourceName(getName(nIndex));
+ sal_uInt64 nFileSize(0);
+
+ if (rFileCandidate && osl::File::E_None == rFileCandidate->open(osl_File_OpenFlag_Read))
+ {
+ rFileCandidate->getSize(nFileSize);
+ rFileCandidate->close();
+ }
+
+ if (0 == nFileSize)
+ {
+ // empty file offered
+ return false;
+ }
- if (nIndex >= mnNumBackups)
+ bool bNeedToAdd(false);
+ sal_uInt32 nCrc32(0);
+
+ if (!maPackedFileEntryVector.empty())
{
- // try to delete that file, it is out of scope
- osl::File::remove(aSourceName);
+ // already backups there, check if different from last entry
+ const PackedFileEntry& aLastEntry = maPackedFileEntryVector.back();
+
+ if (aLastEntry.getSize() != static_cast<sal_uInt32>(nFileSize))
+ {
+ // different size, different file
+ bNeedToAdd = true;
+ }
+ else
+ {
+ // same size, check crc32
+ nCrc32 = createCrc32(rFileCandidate, 0);
+
+ if (nCrc32 != aLastEntry.getCrc32())
+ {
+ // different crc, different file
+ bNeedToAdd = true;
+ }
+ }
}
else
{
- // rename that file by increasing index by one
- osl::File::move(aSourceName, getName(nIndex + 1));
+ // no backup yet, add
+ bNeedToAdd = true;
+ }
+
+ if (bNeedToAdd)
+ {
+ // create crc32 if not yet done
+ if (0 == nCrc32)
+ {
+ nCrc32 = createCrc32(rFileCandidate, 0);
+ }
+
+ // create a file entry for a new file. Offset is set to 0 to mark
+ // the entry as new file entry
+ maPackedFileEntryVector.push_back(
+ PackedFileEntry(
+ static_cast< sal_uInt32 >(nFileSize),
+ 0,
+ nCrc32,
+ rFileCandidate));
+
+ mbChanged = true;
}
+
+ return bNeedToAdd;
}
- }
- bool BackupFileHelper::isDifferentOrNew()
- {
- if (baseFileOpen() && splitBaseURL())
+ bool tryPop(oslFileHandle& rHandle)
{
- osl::File aLastFile(getName(1));
- const osl::FileBase::RC aResult(aLastFile.open(osl_File_OpenFlag_Read));
- bool bDifferentOrNew(false);
+ bool bRetval(false);
- if (osl::File::E_None == aResult)
+ if (!maPackedFileEntryVector.empty())
{
- // exists, check for being equal
- bDifferentOrNew = !equalsBase(aLastFile);
+ // already backups there, check if different from last entry
+ PackedFileEntry& aLastEntry = maPackedFileEntryVector.back();
+
+ bRetval = aLastEntry.copy_content(rHandle, false);
+
+ if (bRetval)
+ {
+ maPackedFileEntryVector.pop_back();
+ mbChanged = true;
+ }
+
+ return bRetval;
}
- else if (osl::File::E_NOENT == aResult)
+
+ return false;
+ }
+
+ void tryReduceToNumBackups(sal_uInt16 nNumBackups)
+ {
+ while (maPackedFileEntryVector.size() > nNumBackups)
{
- // does not exist - also copy
- bDifferentOrNew = true;
+ maPackedFileEntryVector.pop_front();
+ mbChanged = true;
}
+ }
- return bDifferentOrNew;
+ bool empty()
+ {
+ return maPackedFileEntryVector.empty();
}
+ };
+}
- return false;
+namespace comphelper
+{
+ sal_uInt16 BackupFileHelper::mnMaxAllowedBackups = 10;
+ bool BackupFileHelper::mbExitWasCalled = false;
+
+ BackupFileHelper::BackupFileHelper(
+ const OUString& rBaseURL,
+ sal_uInt16 nNumBackups)
+ : mrBaseURL(rBaseURL),
+ mnNumBackups(::std::min(::std::max(nNumBackups, sal_uInt16(1)), mnMaxAllowedBackups)),
+ maBase(),
+ maName(),
+ maExt()
+ {
+ }
+
+ void BackupFileHelper::setExitWasCalled()
+ {
+ mbExitWasCalled = true;
+ }
+
+ bool BackupFileHelper::getExitWasCalled()
+ {
+ return mbExitWasCalled;
}
- bool BackupFileHelper::equalsBase(osl::File& rLastFile)
+ bool BackupFileHelper::getSecureUserConfig(sal_uInt16& rnSecureUserConfigNumCopies)
{
- sal_uInt64 nBaseLen(0);
- sal_uInt64 nLastLen(0);
- maBaseFile.getSize(nBaseLen);
- rLastFile.getSize(nLastLen);
+ // init to not active
+ bool bRetval(false);
+ rnSecureUserConfigNumCopies = 0;
+ OUString sTokenOut;
- if (nBaseLen == nLastLen)
+ if (rtl::Bootstrap::get("SecureUserConfig", sTokenOut))
{
- // same filesize -> need to check content
- sal_uInt8 aArrayOld[1024];
- sal_uInt8 aArrayLast[1024];
- sal_uInt64 nBytesReadBase(0);
- sal_uInt64 nBytesReadLast(0);
- bool bDiffers(false);
+ bRetval = sTokenOut.toBoolean();
+ }
+
+ if (bRetval && rtl::Bootstrap::get("SecureUserConfigNumCopies", sTokenOut))
+ {
+ rnSecureUserConfigNumCopies = static_cast< sal_uInt16 >(sTokenOut.toUInt32());
+ }
+
+ return bRetval;
+ }
- // both rewind on start
- maBaseFile.setPos(0, 0);
- rLastFile.setPos(0, 0);
+ rtl::OUString BackupFileHelper::getName()
+ {
+ return OUString(maBase + "/." + maName + ".pack");
+ }
- while (!bDiffers
- && osl::File::E_None == maBaseFile.read(static_cast<void*>(aArrayOld), 1024, nBytesReadBase)
- && osl::File::E_None == rLastFile.read(static_cast<void*>(aArrayLast), 1024, nBytesReadLast)
- && 0 != nBytesReadBase
- && nBytesReadBase == nBytesReadLast)
+ bool BackupFileHelper::tryPush()
+ {
+ if (splitBaseURL() && baseFileExists())
+ {
+ PackedFile aPackedFile(getName());
+ FileSharedPtr aBaseFile(new osl::File(mrBaseURL));
+
+ if (aPackedFile.tryPush(aBaseFile))
{
- bDiffers = memcmp(aArrayOld, aArrayLast, nBytesReadBase);
+ // reduce to allowed number and flush
+ aPackedFile.tryReduceToNumBackups(mnNumBackups);
+ aPackedFile.flush();
+
+ return true;
}
+ }
+
+ return false;
+ }
+
+ bool BackupFileHelper::isPopPossible()
+ {
+ if (splitBaseURL() && baseFileExists())
+ {
+ PackedFile aPackedFile(getName());
- return !bDiffers;
+ return !aPackedFile.empty();
}
return false;
}
- bool BackupFileHelper::splitBaseURL()
+ bool BackupFileHelper::tryPop()
{
- if (maBase.isEmpty() && !mrBaseURL.isEmpty())
+ if (splitBaseURL() && baseFileExists())
{
- const sal_Int32 nIndex(mrBaseURL.lastIndexOf('.'));
+ PackedFile aPackedFile(getName());
- if (-1 == nIndex)
+ if (!aPackedFile.empty())
{
- maBase = mrBaseURL;
- }
- else if (nIndex > 0)
- {
- maBase = mrBaseURL.copy(0, nIndex);
+ oslFileHandle aHandle;
+ OUString aTempURL;
+
+ // open target temp file
+ if (osl::File::E_None == osl::FileBase::createTempFile(nullptr, &aHandle, &aTempURL))
+ {
+ bool bRetval(aPackedFile.tryPop(aHandle));
+
+ // close temp file (in all cases)
+ osl_closeFile(aHandle);
+
+ if (bRetval)
+ {
+ // copy over existing file by first deleting original
+ // and moving the temp file to old original
+ osl::File::remove(mrBaseURL);
+ osl::File::move(aTempURL, mrBaseURL);
+
+ // reduce to allowed number and flush
+ aPackedFile.tryReduceToNumBackups(mnNumBackups);
+ aPackedFile.flush();
+ }
+
+ // delete temp file (in all cases - it may be moved already)
+ osl::File::remove(aTempURL);
+
+ return bRetval;
+ }
}
+ }
- if (mrBaseURL.getLength() > nIndex + 1)
- {
- maExt = mrBaseURL.copy(nIndex + 1);
- }
+ return false;
+ }
+
+ bool BackupFileHelper::splitBaseURL()
+ {
+ if (maBase.isEmpty() && !mrBaseURL.isEmpty())
+ {
+ // split URL at extension and at last path separator
+ maBase = splitAtLastToken(splitAtLastToken(mrBaseURL, '.', maExt), '/', maName);
}
- return !maBase.isEmpty();
+ return !maBase.isEmpty() && !maName.isEmpty();
}
- bool BackupFileHelper::baseFileOpen()
+ bool BackupFileHelper::baseFileExists()
{
- if (!mbBaseFileIsOpen && !mrBaseURL.isEmpty())
+ if (!mrBaseURL.isEmpty())
{
- mbBaseFileIsOpen = (osl::File::E_None == maBaseFile.open(osl_File_OpenFlag_Read));
+ FileSharedPtr aBaseFile(new osl::File(mrBaseURL));
+
+ return (osl::File::E_None == aBaseFile->open(osl_File_OpenFlag_Read));
}
- return mbBaseFileIsOpen;
+ return false;
}
}