diff options
Diffstat (limited to 'lib/backupclient/BackupStoreFileCombine.cpp')
-rw-r--r-- | lib/backupclient/BackupStoreFileCombine.cpp | 410 |
1 files changed, 0 insertions, 410 deletions
diff --git a/lib/backupclient/BackupStoreFileCombine.cpp b/lib/backupclient/BackupStoreFileCombine.cpp deleted file mode 100644 index baa331f0..00000000 --- a/lib/backupclient/BackupStoreFileCombine.cpp +++ /dev/null @@ -1,410 +0,0 @@ -// -------------------------------------------------------------------------- -// -// File -// Name: BackupStoreFileCombine.cpp -// Purpose: File combining for BackupStoreFile -// Created: 16/1/04 -// -// -------------------------------------------------------------------------- - -#include "Box.h" - -#include <new> - -#include "BackupStoreFile.h" -#include "BackupStoreFileWire.h" -#include "BackupStoreObjectMagic.h" -#include "BackupStoreException.h" -#include "BackupStoreConstants.h" -#include "BackupStoreFilename.h" -#include "FileStream.h" - -#include "MemLeakFindOn.h" - -typedef struct -{ - int64_t mFilePosition; -} FromIndexEntry; - -static void LoadFromIndex(IOStream &rFrom, FromIndexEntry *pIndex, int64_t NumEntries); -static void CopyData(IOStream &rDiffData, IOStream &rDiffIndex, int64_t DiffNumBlocks, IOStream &rFrom, FromIndexEntry *pFromIndex, int64_t FromNumBlocks, IOStream &rOut); -static void WriteNewIndex(IOStream &rDiff, int64_t DiffNumBlocks, FromIndexEntry *pFromIndex, int64_t FromNumBlocks, IOStream &rOut); - -// -------------------------------------------------------------------------- -// -// Function -// Name: BackupStoreFile::CombineFile(IOStream &, IOStream &, IOStream &) -// Purpose: Where rDiff is a store file which is incomplete as a result of a -// diffing operation, rFrom is the file it is diffed from, and -// rOut is the stream in which to place the result, the old file -// and new file are combined into a file containing all the data. -// rDiff2 is the same file as rDiff, opened again to get two -// independent streams to the same file. -// Created: 16/1/04 -// -// -------------------------------------------------------------------------- -void BackupStoreFile::CombineFile(IOStream &rDiff, IOStream &rDiff2, IOStream &rFrom, IOStream &rOut) -{ - // Read and copy the header. - file_StreamFormat hdr; - if(!rDiff.ReadFullBuffer(&hdr, sizeof(hdr), 0)) - { - THROW_EXCEPTION(BackupStoreException, FailedToReadBlockOnCombine) - } - if(ntohl(hdr.mMagicValue) != OBJECTMAGIC_FILE_MAGIC_VALUE_V1) - { - THROW_EXCEPTION(BackupStoreException, BadBackupStoreFile) - } - // Copy - rOut.Write(&hdr, sizeof(hdr)); - // Copy over filename and attributes - // BLOCK - { - BackupStoreFilename filename; - filename.ReadFromStream(rDiff, IOStream::TimeOutInfinite); - filename.WriteToStream(rOut); - StreamableMemBlock attr; - attr.ReadFromStream(rDiff, IOStream::TimeOutInfinite); - attr.WriteToStream(rOut); - } - - // Read the header for the From file - file_StreamFormat fromHdr; - if(!rFrom.ReadFullBuffer(&fromHdr, sizeof(fromHdr), 0)) - { - THROW_EXCEPTION(BackupStoreException, FailedToReadBlockOnCombine) - } - if(ntohl(fromHdr.mMagicValue) != OBJECTMAGIC_FILE_MAGIC_VALUE_V1) - { - THROW_EXCEPTION(BackupStoreException, BadBackupStoreFile) - } - // Skip over the filename and attributes of the From file - // BLOCK - { - BackupStoreFilename filename2; - filename2.ReadFromStream(rFrom, IOStream::TimeOutInfinite); - int32_t size_s; - if(!rFrom.ReadFullBuffer(&size_s, sizeof(size_s), 0 /* not interested in bytes read if this fails */)) - { - THROW_EXCEPTION(CommonException, StreamableMemBlockIncompleteRead) - } - int size = ntohl(size_s); - // Skip forward the size - rFrom.Seek(size, IOStream::SeekType_Relative); - } - - // Allocate memory for the block index of the From file - int64_t fromNumBlocks = box_ntoh64(fromHdr.mNumBlocks); - // NOTE: An extra entry is required so that the length of the last block can be calculated - FromIndexEntry *pFromIndex = (FromIndexEntry*)::malloc((fromNumBlocks+1) * sizeof(FromIndexEntry)); - if(pFromIndex == 0) - { - throw std::bad_alloc(); - } - - try - { - // Load the index from the From file, calculating the offsets in the - // file as we go along, and enforce that everything should be present. - LoadFromIndex(rFrom, pFromIndex, fromNumBlocks); - - // Read in the block index of the Diff file in small chunks, and output data - // for each block, either from this file, or the other file. - int64_t diffNumBlocks = box_ntoh64(hdr.mNumBlocks); - CopyData(rDiff /* positioned at start of data */, rDiff2, diffNumBlocks, rFrom, pFromIndex, fromNumBlocks, rOut); - - // Read in the block index again, and output the new block index, simply - // filling in the sizes of blocks from the old file. - WriteNewIndex(rDiff, diffNumBlocks, pFromIndex, fromNumBlocks, rOut); - - // Free buffers - ::free(pFromIndex); - pFromIndex = 0; - } - catch(...) - { - // Clean up - if(pFromIndex != 0) - { - ::free(pFromIndex); - pFromIndex = 0; - } - throw; - } -} - - -// -------------------------------------------------------------------------- -// -// Function -// Name: static LoadFromIndex(IOStream &, FromIndexEntry *, int64_t) -// Purpose: Static. Load the index from the From file -// Created: 16/1/04 -// -// -------------------------------------------------------------------------- -static void LoadFromIndex(IOStream &rFrom, FromIndexEntry *pIndex, int64_t NumEntries) -{ - ASSERT(pIndex != 0); - ASSERT(NumEntries >= 0); - - // Get the starting point in the file - int64_t filePos = rFrom.GetPosition(); - - // Jump to the end of the file to read the index - rFrom.Seek(0 - ((NumEntries * sizeof(file_BlockIndexEntry)) + sizeof(file_BlockIndexHeader)), IOStream::SeekType_End); - - // Read block index header - file_BlockIndexHeader blkhdr; - if(!rFrom.ReadFullBuffer(&blkhdr, sizeof(blkhdr), 0)) - { - THROW_EXCEPTION(BackupStoreException, FailedToReadBlockOnCombine) - } - if(ntohl(blkhdr.mMagicValue) != OBJECTMAGIC_FILE_BLOCKS_MAGIC_VALUE_V1 - || (int64_t)box_ntoh64(blkhdr.mNumBlocks) != NumEntries) - { - THROW_EXCEPTION(BackupStoreException, BadBackupStoreFile) - } - - // And then the block entries - for(int64_t b = 0; b < NumEntries; ++b) - { - // Read - file_BlockIndexEntry en; - if(!rFrom.ReadFullBuffer(&en, sizeof(en), 0)) - { - THROW_EXCEPTION(BackupStoreException, FailedToReadBlockOnCombine) - } - - // Add to list - pIndex[b].mFilePosition = filePos; - - // Encoded size? - int64_t encodedSize = box_ntoh64(en.mEncodedSize); - // Check that the block is actually there - if(encodedSize <= 0) - { - THROW_EXCEPTION(BackupStoreException, OnCombineFromFileIsIncomplete) - } - - // Move file pointer on - filePos += encodedSize; - } - - // Store the position in the very last entry, so the size of the last entry can be calculated - pIndex[NumEntries].mFilePosition = filePos; -} - - -// -------------------------------------------------------------------------- -// -// Function -// Name: static CopyData(IOStream &, IOStream &, int64_t, IOStream &, FromIndexEntry *, int64_t, IOStream &) -// Purpose: Static. Copy data from the Diff and From file to the out file. -// rDiffData is at beginning of data. -// rDiffIndex at any position. -// rFrom is at any position. -// rOut is after the header, ready for data -// Created: 16/1/04 -// -// -------------------------------------------------------------------------- -static void CopyData(IOStream &rDiffData, IOStream &rDiffIndex, int64_t DiffNumBlocks, - IOStream &rFrom, FromIndexEntry *pFromIndex, int64_t FromNumBlocks, IOStream &rOut) -{ - // Jump to the end of the diff file to read the index - rDiffIndex.Seek(0 - ((DiffNumBlocks * sizeof(file_BlockIndexEntry)) + sizeof(file_BlockIndexHeader)), IOStream::SeekType_End); - - // Read block index header - file_BlockIndexHeader diffBlkhdr; - if(!rDiffIndex.ReadFullBuffer(&diffBlkhdr, sizeof(diffBlkhdr), 0)) - { - THROW_EXCEPTION(BackupStoreException, FailedToReadBlockOnCombine) - } - if(ntohl(diffBlkhdr.mMagicValue) != OBJECTMAGIC_FILE_BLOCKS_MAGIC_VALUE_V1 - || (int64_t)box_ntoh64(diffBlkhdr.mNumBlocks) != DiffNumBlocks) - { - THROW_EXCEPTION(BackupStoreException, BadBackupStoreFile) - } - - // Record where the From file is - int64_t fromPos = rFrom.GetPosition(); - - // Buffer data - void *buffer = 0; - int bufferSize = 0; - - try - { - // Read the blocks in! - for(int64_t b = 0; b < DiffNumBlocks; ++b) - { - // Read - file_BlockIndexEntry en; - if(!rDiffIndex.ReadFullBuffer(&en, sizeof(en), 0)) - { - THROW_EXCEPTION(BackupStoreException, FailedToReadBlockOnCombine) - } - - // What's the size value stored in the entry - int64_t encodedSize = box_ntoh64(en.mEncodedSize); - - // How much data will be read? - int32_t blockSize = 0; - if(encodedSize > 0) - { - // The block is actually in the diff file - blockSize = encodedSize; - } - else - { - // It's in the from file. First, check to see if it's valid - int64_t blockIdx = (0 - encodedSize); - if(blockIdx > FromNumBlocks) - { - // References a block which doesn't actually exist - THROW_EXCEPTION(BackupStoreException, BadBackupStoreFile) - } - // Calculate size. This operation is safe because of the extra entry at the end - blockSize = pFromIndex[blockIdx + 1].mFilePosition - pFromIndex[blockIdx].mFilePosition; - } - ASSERT(blockSize > 0); - - // Make sure there's memory available to copy this - if(bufferSize < blockSize || buffer == 0) - { - // Free old block - if(buffer != 0) - { - ::free(buffer); - buffer = 0; - bufferSize = 0; - } - // Allocate new block - buffer = ::malloc(blockSize); - if(buffer == 0) - { - throw std::bad_alloc(); - } - bufferSize = blockSize; - } - ASSERT(bufferSize >= blockSize); - - // Load in data from one of the files - if(encodedSize > 0) - { - // Load from diff file - if(!rDiffData.ReadFullBuffer(buffer, blockSize, 0)) - { - THROW_EXCEPTION(BackupStoreException, FailedToReadBlockOnCombine) - } - } - else - { - // Locate and read the data from the from file - int64_t blockIdx = (0 - encodedSize); - // Seek if necessary - if(fromPos != pFromIndex[blockIdx].mFilePosition) - { - rFrom.Seek(pFromIndex[blockIdx].mFilePosition, IOStream::SeekType_Absolute); - fromPos = pFromIndex[blockIdx].mFilePosition; - } - // Read - if(!rFrom.ReadFullBuffer(buffer, blockSize, 0)) - { - THROW_EXCEPTION(BackupStoreException, FailedToReadBlockOnCombine) - } - - // Update fromPos to current position - fromPos += blockSize; - } - - // Write data to out file - rOut.Write(buffer, blockSize); - } - - // Free buffer, if allocated - if(buffer != 0) - { - ::free(buffer); - buffer = 0; - } - } - catch(...) - { - if(buffer != 0) - { - ::free(buffer); - buffer = 0; - } - throw; - } -} - - - -// -------------------------------------------------------------------------- -// -// Function -// Name: static WriteNewIndex(IOStream &, int64_t, FromIndexEntry *, int64_t, IOStream &) -// Purpose: Write the index to the out file, just copying from the diff file and -// adjusting the entries. -// Created: 16/1/04 -// -// -------------------------------------------------------------------------- -static void WriteNewIndex(IOStream &rDiff, int64_t DiffNumBlocks, FromIndexEntry *pFromIndex, int64_t FromNumBlocks, IOStream &rOut) -{ - // Jump to the end of the diff file to read the index - rDiff.Seek(0 - ((DiffNumBlocks * sizeof(file_BlockIndexEntry)) + sizeof(file_BlockIndexHeader)), IOStream::SeekType_End); - - // Read block index header - file_BlockIndexHeader diffBlkhdr; - if(!rDiff.ReadFullBuffer(&diffBlkhdr, sizeof(diffBlkhdr), 0)) - { - THROW_EXCEPTION(BackupStoreException, FailedToReadBlockOnCombine) - } - if(ntohl(diffBlkhdr.mMagicValue) != OBJECTMAGIC_FILE_BLOCKS_MAGIC_VALUE_V1 - || (int64_t)box_ntoh64(diffBlkhdr.mNumBlocks) != DiffNumBlocks) - { - THROW_EXCEPTION(BackupStoreException, BadBackupStoreFile) - } - - // Write it out with a blanked out other file ID - diffBlkhdr.mOtherFileID = box_hton64(0); - rOut.Write(&diffBlkhdr, sizeof(diffBlkhdr)); - - // Rewrite the index - for(int64_t b = 0; b < DiffNumBlocks; ++b) - { - file_BlockIndexEntry en; - if(!rDiff.ReadFullBuffer(&en, sizeof(en), 0)) - { - THROW_EXCEPTION(BackupStoreException, FailedToReadBlockOnCombine) - } - - // What's the size value stored in the entry - int64_t encodedSize = box_ntoh64(en.mEncodedSize); - - // Need to adjust it? - if(encodedSize <= 0) - { - // This actually refers to a block in the from file. So rewrite this. - int64_t blockIdx = (0 - encodedSize); - if(blockIdx > FromNumBlocks) - { - // References a block which doesn't actually exist - THROW_EXCEPTION(BackupStoreException, BadBackupStoreFile) - } - // Calculate size. This operation is safe because of the extra entry at the end - int32_t blockSize = pFromIndex[blockIdx + 1].mFilePosition - pFromIndex[blockIdx].mFilePosition; - // Then replace entry - en.mEncodedSize = box_hton64(((uint64_t)blockSize)); - } - - // Write entry - rOut.Write(&en, sizeof(en)); - } -} - - - - - |