1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
// distribution boxbackup-0.11rc2 (svn version: 2072)
//
// Copyright (c) 2003 - 2008
// Ben Summers and contributors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. All use of this software and associated advertising materials must
// display the following acknowledgment:
// This product includes software developed by Ben Summers.
// 4. The names of the Authors may not be used to endorse or promote
// products derived from this software without specific prior written
// permission.
//
// [Where legally impermissible the Authors do not disclaim liability for
// direct physical injury or death caused solely by defects in the software
// unless it is modified by a third party.]
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT,
// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//
//
// --------------------------------------------------------------------------
//
// File
// Name: BackupStoreFileEncodeStream.h
// Purpose: Implement stream-based file encoding for the backup store
// Created: 12/1/04
//
// --------------------------------------------------------------------------
#ifndef BACKUPSTOREFILEENCODESTREAM__H
#define BACKUPSTOREFILEENCODESTREAM__H
#include <vector>
#include "IOStream.h"
#include "BackupStoreFilename.h"
#include "CollectInBufferStream.h"
#include "MD5Digest.h"
#include "BackupStoreFile.h"
#include "ReadLoggingStream.h"
namespace BackupStoreFileCreation
{
// Diffing and creation of files share some implementation details.
typedef struct _BlocksAvailableEntry
{
struct _BlocksAvailableEntry *mpNextInHashList;
int32_t mSize; // size in clear
uint32_t mWeakChecksum; // weak, rolling checksum
uint8_t mStrongChecksum[MD5Digest::DigestLength]; // strong digest based checksum
} BlocksAvailableEntry;
}
// --------------------------------------------------------------------------
//
// Class
// Name: BackupStoreFileEncodeStream
// Purpose: Encode a file into a stream
// Created: 8/12/03
//
// --------------------------------------------------------------------------
class BackupStoreFileEncodeStream : public IOStream
{
public:
BackupStoreFileEncodeStream();
~BackupStoreFileEncodeStream();
typedef struct
{
int64_t mSpaceBefore; // amount of bytes which aren't taken out of blocks which go
int32_t mBlocks; // number of block to reuse, starting at this one
BackupStoreFileCreation::BlocksAvailableEntry *mpStartBlock; // may be null
} RecipeInstruction;
class Recipe : public std::vector<RecipeInstruction>
{
// NOTE: This class is rather tied in with the implementation of diffing.
public:
Recipe(BackupStoreFileCreation::BlocksAvailableEntry *pBlockIndex, int64_t NumBlocksInIndex,
int64_t OtherFileID = 0);
~Recipe();
int64_t GetOtherFileID() {return mOtherFileID;}
int64_t BlockPtrToIndex(BackupStoreFileCreation::BlocksAvailableEntry *pBlock)
{
return pBlock - mpBlockIndex;
}
private:
BackupStoreFileCreation::BlocksAvailableEntry *mpBlockIndex;
int64_t mNumBlocksInIndex;
int64_t mOtherFileID;
};
void Setup(const char *Filename, Recipe *pRecipe, int64_t ContainerID, const BackupStoreFilename &rStoreFilename, int64_t *pModificationTime);
virtual int Read(void *pBuffer, int NBytes, int Timeout);
virtual void Write(const void *pBuffer, int NBytes);
virtual bool StreamDataLeft();
virtual bool StreamClosed();
private:
enum
{
Status_Header = 0,
Status_Blocks = 1,
Status_BlockListing = 2,
Status_Finished = 3
};
private:
void EncodeCurrentBlock();
void CalculateBlockSizes(int64_t DataSize, int64_t &rNumBlocksOut, int32_t &rBlockSizeOut, int32_t &rLastBlockSizeOut);
void SkipPreviousBlocksInInstruction();
void SetForInstruction();
void StoreBlockIndexEntry(int64_t WncSizeOrBlkIndex, int32_t ClearSize, uint32_t WeakChecksum, uint8_t *pStrongChecksum);
private:
Recipe *mpRecipe;
IOStream *mpFile; // source file
CollectInBufferStream mData; // buffer for header and index entries
ReadLoggingStream *mpLogging;
int mStatus;
bool mSendData; // true if there's file data to send (ie not a symlink)
int64_t mTotalBlocks; // Total number of blocks in the file
int64_t mAbsoluteBlockNumber; // The absolute block number currently being output
// Instruction number
int64_t mInstructionNumber;
// All the below are within the current instruction
int64_t mNumBlocks; // number of blocks. Last one will be a different size to the rest in most cases
int64_t mCurrentBlock;
int32_t mCurrentBlockEncodedSize;
int32_t mPositionInCurrentBlock; // for reading out
int32_t mBlockSize; // Basic block size of most of the blocks in the file
int32_t mLastBlockSize; // the size (unencoded) of the last block in the file
// Buffers
uint8_t *mpRawBuffer; // buffer for raw data
BackupStoreFile::EncodingBuffer mEncodedBuffer;
// buffer for encoded data
int32_t mAllocatedBufferSize; // size of above two allocated blocks
uint64_t mEntryIVBase; // base for block entry IV
};
#endif // BACKUPSTOREFILEENCODESTREAM__H
|