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-DUAL appears on the first line, falls
9 // under this license. See the file COPYING.txt for more information.
10 //
11 // This file is dual licensed. You may use and distribute it providing that you
12 // comply EITHER with the terms of the BSD license, OR the GPL license. It is
13 // not necessary to comply with both licenses, only one.
14 //
15 // The BSD license option follows:
16 //
17 // Redistribution and use in source and binary forms, with or without
18 // modification, are permitted provided that the following conditions are met:
19 //
20 // 1. Redistributions of source code must retain the above copyright
21 //    notice, this list of conditions and the following disclaimer.
22 //
23 // 2. Redistributions in binary form must reproduce the above copyright
24 //    notice, this list of conditions and the following disclaimer in the
25 //    documentation and/or other materials provided with the distribution.
26 //
27 // 3. Neither the name of the Box Backup nor the names of its contributors may
28 //    be used to endorse or promote products derived from this software without
29 //    specific prior written permission.
30 //
31 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
34 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
35 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
38 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
40 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41 //
42 // [http://en.wikipedia.org/wiki/BSD_licenses#3-clause_license_.28.22New_BSD_License.22.29]
43 //
44 // The GPL license option follows:
45 //
46 // This program is free software; you can redistribute it and/or
47 // modify it under the terms of the GNU General Public License
48 // as published by the Free Software Foundation; either version 2
49 // of the License, or (at your option) any later version.
50 //
51 // This program is distributed in the hope that it will be useful,
52 // but WITHOUT ANY WARRANTY; without even the implied warranty of
53 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
54 // GNU General Public License for more details.
55 //
56 // You should have received a copy of the GNU General Public License
57 // along with this program; if not, write to the Free Software
58 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
59 //
60 // [http://www.gnu.org/licenses/old-licenses/gpl-2.0.html#SEC4]
61 // --------------------------------------------------------------------------
62 //
63 // File
64 //		Name:    IOStream.cpp
65 //		Purpose: I/O Stream abstraction
66 //		Created: 2003/07/31
67 //
68 // --------------------------------------------------------------------------
69 
70 #include "Box.h"
71 #include "IOStream.h"
72 #include "CommonException.h"
73 #include "Guards.h"
74 
75 #include "MemLeakFindOn.h"
76 
77 // --------------------------------------------------------------------------
78 //
79 // Function
80 //		Name:    IOStream::IOStream()
81 //		Purpose: Constructor
82 //		Created: 2003/07/31
83 //
84 // --------------------------------------------------------------------------
IOStream()85 IOStream::IOStream()
86 {
87 }
88 
89 // --------------------------------------------------------------------------
90 //
91 // Function
92 //		Name:    IOStream::~IOStream()
93 //		Purpose: Destructor
94 //		Created: 2003/07/31
95 //
96 // --------------------------------------------------------------------------
~IOStream()97 IOStream::~IOStream()
98 {
99 }
100 
101 // --------------------------------------------------------------------------
102 //
103 // Function
104 //		Name:    IOStream::Close()
105 //		Purpose: Close the stream
106 //		Created: 2003/07/31
107 //
108 // --------------------------------------------------------------------------
Close()109 void IOStream::Close()
110 {
111 	// Do nothing by default -- let the destructor clear everything up.
112 }
113 
114 // --------------------------------------------------------------------------
115 //
116 // Function
117 //		Name:    IOStream::Seek(int, int)
118 //		Purpose: Seek in stream (if supported)
119 //		Created: 2003/07/31
120 //
121 // --------------------------------------------------------------------------
Seek(IOStream::pos_type Offset,int SeekType)122 void IOStream::Seek(IOStream::pos_type Offset, int SeekType)
123 {
124 	THROW_EXCEPTION(CommonException, NotSupported)
125 }
126 
127 
128 // --------------------------------------------------------------------------
129 //
130 // Function
131 //		Name:    IOStream::GetPosition()
132 //		Purpose: Returns current position in stream (if supported)
133 //		Created: 2003/08/21
134 //
135 // --------------------------------------------------------------------------
GetPosition() const136 IOStream::pos_type IOStream::GetPosition() const
137 {
138 	THROW_EXCEPTION(CommonException, NotSupported)
139 }
140 
141 // --------------------------------------------------------------------------
142 //
143 // Function
144 //		Name:    IOStream::ConvertSeekTypeToOSWhence(int)
145 //		Purpose: Return an whence arg for lseek given a IOStream seek type
146 //		Created: 2003/08/21
147 //
148 // --------------------------------------------------------------------------
ConvertSeekTypeToOSWhence(int SeekType)149 int IOStream::ConvertSeekTypeToOSWhence(int SeekType)
150 {
151 	// Should be nicely optimised out as values are choosen in header file to match OS values.
152 	int ostype = SEEK_SET;
153 	switch(SeekType)
154 	{
155 #ifdef WIN32
156 	case SeekType_Absolute:
157 		ostype = FILE_BEGIN;
158 		break;
159 	case SeekType_Relative:
160 		ostype = FILE_CURRENT;
161 		break;
162 	case SeekType_End:
163 		ostype = FILE_END;
164 		break;
165 #else // ! WIN32
166 	case SeekType_Absolute:
167 		ostype = SEEK_SET;
168 		break;
169 	case SeekType_Relative:
170 		ostype = SEEK_CUR;
171 		break;
172 	case SeekType_End:
173 		ostype = SEEK_END;
174 		break;
175 #endif // WIN32
176 
177 	default:
178 		THROW_EXCEPTION(CommonException, IOStreamBadSeekType)
179 	}
180 
181 	return ostype;
182 }
183 
184 
185 // --------------------------------------------------------------------------
186 //
187 // Function
188 //		Name:    IOStream::ReadFullBuffer(void *, int, int)
189 //		Purpose: Reads bytes into buffer, returning whether or not it managed to
190 //				 get all the bytes required. Exception and abort use of stream
191 //				 if this returns false.
192 //		Created: 2003/08/26
193 //
194 // --------------------------------------------------------------------------
ReadFullBuffer(void * pBuffer,int NBytes,int * pNBytesRead,int Timeout)195 bool IOStream::ReadFullBuffer(void *pBuffer, int NBytes, int *pNBytesRead, int Timeout)
196 {
197 	int bytesToGo = NBytes;
198 	char *buffer = (char*)pBuffer;
199 	if(pNBytesRead) (*pNBytesRead) = 0;
200 
201 	while(bytesToGo > 0)
202 	{
203 		int bytesRead = Read(buffer, bytesToGo, Timeout);
204 		if(bytesRead == 0)
205 		{
206 			// Timeout or something
207 			return false;
208 		}
209 		// Increment things
210 		bytesToGo -= bytesRead;
211 		buffer += bytesRead;
212 		if(pNBytesRead) (*pNBytesRead) += bytesRead;
213 	}
214 
215 	// Got everything
216 	return true;
217 }
218 
219 
220 // --------------------------------------------------------------------------
221 //
222 // Function
223 //		Name:    IOStream::WriteAllBuffered()
224 //		Purpose: Ensures that any data which has been buffered is written to the stream
225 //		Created: 2003/08/26
226 //
227 // --------------------------------------------------------------------------
WriteAllBuffered()228 void IOStream::WriteAllBuffered()
229 {
230 }
231 
232 
233 // --------------------------------------------------------------------------
234 //
235 // Function
236 //		Name:    IOStream::BytesLeftToRead()
237 //		Purpose: Numbers of bytes left to read in the stream, or
238 //				 IOStream::SizeOfStreamUnknown if this isn't known.
239 //		Created: 2003/08/26
240 //
241 // --------------------------------------------------------------------------
BytesLeftToRead()242 IOStream::pos_type IOStream::BytesLeftToRead()
243 {
244 	return IOStream::SizeOfStreamUnknown;
245 }
246 
247 // --------------------------------------------------------------------------
248 //
249 // Function
250 //		Name:    IOStream::CopyStreamTo(IOStream &, int Timeout)
251 //		Purpose: Copies the entire stream to another stream (reading from this,
252 //				 writing to rCopyTo). Returns whether the copy completed (ie
253 //				 StreamDataLeft() returns false)
254 //		Created: 2003/08/26
255 //
256 // --------------------------------------------------------------------------
CopyStreamTo(IOStream & rCopyTo,int Timeout,int BufferSize)257 bool IOStream::CopyStreamTo(IOStream &rCopyTo, int Timeout, int BufferSize)
258 {
259 	// Make sure there's something to do before allocating that buffer
260 	if(!StreamDataLeft())
261 	{
262 		return true;	// complete, even though nothing happened
263 	}
264 
265 	// Buffer
266 	MemoryBlockGuard<char*> buffer(BufferSize);
267 
268 	// Get copying!
269 	while(StreamDataLeft())
270 	{
271 		// Read some data
272 		int bytes = Read(buffer, BufferSize, Timeout);
273 		if(bytes == 0 && StreamDataLeft())
274 		{
275 			return false;	// incomplete, timed out
276 		}
277 
278 		// Write some data
279 		if(bytes != 0)
280 		{
281 			rCopyTo.Write(buffer, bytes);
282 		}
283 	}
284 
285 	return true;	// completed
286 }
287 
288 // --------------------------------------------------------------------------
289 //
290 // Function
291 //		Name:    IOStream::Flush(int Timeout)
292 //		Purpose: Read and discard all remaining data in stream.
293 //			 Useful for protocol streams which must be flushed
294 //			 to avoid breaking the protocol.
295 //		Created: 2008/08/20
296 //
297 // --------------------------------------------------------------------------
Flush(int Timeout)298 void IOStream::Flush(int Timeout)
299 {
300 	char buffer[4096];
301 
302 	while(StreamDataLeft())
303 	{
304 		Read(buffer, sizeof(buffer), Timeout);
305 	}
306 }
307 
Write(const char * pBuffer)308 void IOStream::Write(const char *pBuffer)
309 {
310 	Write(pBuffer, strlen(pBuffer));
311 }
312