1 // distribution boxbackup-0.11_trunk_2979 (svn version: 2979)
2 // Box Backup, http://www.boxbackup.org/
3 //
4 // Copyright (c) 2003-2010, Ben Summers and contributors.
5 // All rights reserved.
6 //
7 // Note that this project uses mixed licensing. Any file with this license
8 // attached, or where the code LICENSE-GPL appears on the first line, falls
9 // under the "Box Backup GPL" license. See the file COPYING.txt for more
10 // information about this license.
11 //
12 // ---------------------------------------------------------------------
13 // This program is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU General Public License
15 // as published by the Free Software Foundation; either version 2
16 // of the License, or (at your option) any later version.
17 //
18 // This program is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 // GNU General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with this program; if not, write to the Free Software
25 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
26 //
27 // [http://www.gnu.org/licenses/old-licenses/gpl-2.0.html#SEC4]
28 //
29 // As a special exception to the GPLv2, the Box Backup Project gives
30 // permission to link any code falling under this license (the Box Backup
31 // GPL) with any software that can be downloaded from
32 // the OpenSSL website [http://www.openssl.org] under either the
33 // "OpenSSL License" or the "Original SSLeay License", and to distribute
34 // the linked executables under the terms of the "Box Backup GPL" license.
35 //
36 // As a special exception to the GPLv2, the Box Backup Project gives
37 // permission to link any code falling under this license (the Box Backup
38 // GPL) with any version of Microsoft's Volume Shadow Copy Service 7.2 SDK
39 // or Microsoft Windows Software Development Kit (SDK), including
40 // vssapi.lib, that can be downloaded from the Microsoft website
41 // [*.microsoft.com], and to distribute the linked executables under the
42 // terms of the "Box Backup GPL" license.
43 // --------------------------------------------------------------------------
44 //
45 // File
46 //		Name:    BackupStoreFileEncodeStream.h
47 //		Purpose: Implement stream-based file encoding for the backup store
48 //		Created: 12/1/04
49 //
50 // --------------------------------------------------------------------------
51 
52 #ifndef BACKUPSTOREFILEENCODESTREAM__H
53 #define BACKUPSTOREFILEENCODESTREAM__H
54 
55 #include <vector>
56 
57 #include "IOStream.h"
58 #include "BackupStoreFilename.h"
59 #include "CollectInBufferStream.h"
60 #include "MD5Digest.h"
61 #include "BackupStoreFile.h"
62 #include "ReadLoggingStream.h"
63 #include "RunStatusProvider.h"
64 
65 namespace BackupStoreFileCreation
66 {
67 	// Diffing and creation of files share some implementation details.
68 	typedef struct _BlocksAvailableEntry
69 	{
70 		struct _BlocksAvailableEntry *mpNextInHashList;
71 		int32_t mSize;			// size in clear
72 		uint32_t mWeakChecksum;	// weak, rolling checksum
73 		uint8_t mStrongChecksum[MD5Digest::DigestLength];	// strong digest based checksum
74 	} BlocksAvailableEntry;
75 
76 }
77 
78 
79 // --------------------------------------------------------------------------
80 //
81 // Class
82 //		Name:    BackupStoreFileEncodeStream
83 //		Purpose: Encode a file into a stream
84 //		Created: 8/12/03
85 //
86 // --------------------------------------------------------------------------
87 class BackupStoreFileEncodeStream : public IOStream
88 {
89 public:
90 	BackupStoreFileEncodeStream();
91 	~BackupStoreFileEncodeStream();
92 
93 	typedef struct
94 	{
95 		int64_t mSpaceBefore;				// amount of bytes which aren't taken out of blocks which go
96 		int32_t mBlocks;					// number of block to reuse, starting at this one
97 		BackupStoreFileCreation::BlocksAvailableEntry *mpStartBlock;	// may be null
98 	} RecipeInstruction;
99 
100 	class Recipe : public std::vector<RecipeInstruction>
101 	{
102 		// NOTE: This class is rather tied in with the implementation of diffing.
103 	public:
104 		Recipe(BackupStoreFileCreation::BlocksAvailableEntry *pBlockIndex, int64_t NumBlocksInIndex,
105 			int64_t OtherFileID = 0);
106 		~Recipe();
107 
GetOtherFileID()108 		int64_t GetOtherFileID() {return mOtherFileID;}
BlockPtrToIndex(BackupStoreFileCreation::BlocksAvailableEntry * pBlock)109 		int64_t BlockPtrToIndex(BackupStoreFileCreation::BlocksAvailableEntry *pBlock)
110 		{
111 			return pBlock - mpBlockIndex;
112 		}
113 
114 	private:
115 		BackupStoreFileCreation::BlocksAvailableEntry *mpBlockIndex;
116 		int64_t mNumBlocksInIndex;
117 		int64_t mOtherFileID;
118 	};
119 
120 	void Setup(const char *Filename, Recipe *pRecipe, int64_t ContainerID,
121 		const BackupStoreFilename &rStoreFilename,
122 		int64_t *pModificationTime,
123 		ReadLoggingStream::Logger* pLogger = NULL,
124 		RunStatusProvider* pRunStatusProvider = NULL);
125 
126 	virtual int Read(void *pBuffer, int NBytes, int Timeout);
127 	virtual void Write(const void *pBuffer, int NBytes);
128 	virtual bool StreamDataLeft();
129 	virtual bool StreamClosed();
GetTotalBytesSent()130 	int64_t GetTotalBytesSent() { return mTotalBytesSent; }
131 
132 private:
133 	enum
134 	{
135 		Status_Header = 0,
136 		Status_Blocks = 1,
137 		Status_BlockListing = 2,
138 		Status_Finished = 3
139 	};
140 
141 private:
142 	void EncodeCurrentBlock();
143 	void CalculateBlockSizes(int64_t DataSize, int64_t &rNumBlocksOut, int32_t &rBlockSizeOut, int32_t &rLastBlockSizeOut);
144 	void SkipPreviousBlocksInInstruction();
145 	void SetForInstruction();
146 	void StoreBlockIndexEntry(int64_t WncSizeOrBlkIndex, int32_t ClearSize, uint32_t WeakChecksum, uint8_t *pStrongChecksum);
147 
148 private:
149 	Recipe *mpRecipe;
150 	IOStream *mpFile;					// source file
151 	CollectInBufferStream mData;		// buffer for header and index entries
152 	IOStream *mpLogging;
153 	RunStatusProvider* mpRunStatusProvider;
154 	int mStatus;
155 	bool mSendData;						// true if there's file data to send (ie not a symlink)
156 	int64_t mTotalBlocks;				// Total number of blocks in the file
157 	int64_t mAbsoluteBlockNumber;		// The absolute block number currently being output
158 	// Instruction number
159 	int64_t mInstructionNumber;
160 	// All the below are within the current instruction
161 	int64_t mNumBlocks;					// number of blocks. Last one will be a different size to the rest in most cases
162 	int64_t mCurrentBlock;
163 	int32_t mCurrentBlockEncodedSize;
164 	int32_t mPositionInCurrentBlock;	// for reading out
165 	int32_t mBlockSize;					// Basic block size of most of the blocks in the file
166 	int32_t mLastBlockSize;				// the size (unencoded) of the last block in the file
167 	int64_t mTotalBytesSent;
168 	// Buffers
169 	uint8_t *mpRawBuffer;				// buffer for raw data
170 	BackupStoreFile::EncodingBuffer mEncodedBuffer;
171 										// buffer for encoded data
172 	int32_t mAllocatedBufferSize;		// size of above two allocated blocks
173 	uint64_t mEntryIVBase;				// base for block entry IV
174 };
175 
176 
177 
178 #endif // BACKUPSTOREFILEENCODESTREAM__H
179 
180