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