xref: /haiku/src/kits/support/DataIO.cpp (revision e79e4e7c9e432c90415f79809b7160e864f79001)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2002, OpenBeOS
3 //
4 //	Permission is hereby granted, free of charge, to any person obtaining a
5 //	copy of this software and associated documentation files (the "Software"),
6 //	to deal in the Software without restriction, including without limitation
7 //	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 //	and/or sell copies of the Software, and to permit persons to whom the
9 //	Software is furnished to do so, subject to the following conditions:
10 //
11 //	The above copyright notice and this permission notice shall be included in
12 //	all copies or substantial portions of the Software.
13 //
14 //	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 //	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 //	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 //	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 //	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 //	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 //	DEALINGS IN THE SOFTWARE.
21 //
22 //	File Name:		DataIO.cpp
23 //	Author(s):		Stefano Ceccherini (burton666@libero.it)
24 //					The Storage Team
25 //	Description:	Pure virtual BDataIO and BPositioIO classes provide
26 //					the protocol for Read()/Write()/Seek().
27 //
28 //					BMallocIO and BMemoryIO classes implement the protocol,
29 //					as does BFile in the Storage Kit.
30 //------------------------------------------------------------------------------
31 
32 // Standard Includes -----------------------------------------------------------
33 #include <algorithm>
34 #include <stdio.h>
35 #include <string.h>
36 #include <stdlib.h>
37 
38 // System Includes -------------------------------------------------------------
39 #include <DataIO.h>
40 
41 // Project Includes ------------------------------------------------------------
42 
43 // Local Includes --------------------------------------------------------------
44 
45 // Local Defines ---------------------------------------------------------------
46 
47 // Globals ---------------------------------------------------------------------
48 
49 
50 // *** BDataIO ***
51 
52 // Construction
53 BDataIO::BDataIO()
54 {
55 }
56 
57 
58 // Destruction
59 BDataIO::~BDataIO()
60 {
61 }
62 
63 
64 // Private or Reserved
65 BDataIO::BDataIO(const BDataIO &)
66 {
67 	//Copying not allowed
68 }
69 
70 
71 BDataIO &
72 BDataIO::operator=(const BDataIO &)
73 {
74 	//Copying not allowed
75 	return *this;
76 }
77 
78 
79 // FBC
80 void BDataIO::_ReservedDataIO1(){}
81 void BDataIO::_ReservedDataIO2(){}
82 void BDataIO::_ReservedDataIO3(){}
83 void BDataIO::_ReservedDataIO4(){}
84 
85 #if !_PR3_COMPATIBLE_
86 void BDataIO::_ReservedDataIO5(){}
87 void BDataIO::_ReservedDataIO6(){}
88 void BDataIO::_ReservedDataIO7(){}
89 void BDataIO::_ReservedDataIO8(){}
90 void BDataIO::_ReservedDataIO9(){}
91 void BDataIO::_ReservedDataIO10(){}
92 void BDataIO::_ReservedDataIO11(){}
93 void BDataIO::_ReservedDataIO12(){}
94 #endif
95 
96 
97 // *** BPositionIO ***
98 
99 // Construction
100 BPositionIO::BPositionIO()
101 {
102 }
103 
104 
105 // Destruction
106 BPositionIO::~BPositionIO()
107 {
108 }
109 
110 
111 // Read
112 ssize_t
113 BPositionIO::Read(void *buffer, size_t size)
114 {
115 	off_t curPos = Position();
116 	ssize_t result = ReadAt(curPos, buffer, size);
117 	if (result > 0)
118 		Seek(result, SEEK_CUR);
119 
120 	return result;
121 }
122 
123 
124 // Write
125 ssize_t
126 BPositionIO::Write(const void *buffer, size_t size)
127 {
128 	off_t curPos = Position();
129 	ssize_t result = WriteAt(curPos, buffer, size);
130 	if (result > 0)
131 		Seek(result, SEEK_CUR);
132 
133 	return result;
134 }
135 
136 
137 // SetSize
138 status_t
139 BPositionIO::SetSize(off_t size)
140 {
141 	return B_ERROR;
142 }
143 
144 
145 // FBC
146 void BPositionIO::_ReservedPositionIO1(){}
147 void BPositionIO::_ReservedPositionIO2(){}
148 void BPositionIO::_ReservedPositionIO3(){}
149 void BPositionIO::_ReservedPositionIO4(){}
150 
151 #if !_PR3_COMPATIBLE_
152 void BPositionIO::_ReservedPositionIO5(){}
153 void BPositionIO::_ReservedPositionIO6(){}
154 void BPositionIO::_ReservedPositionIO7(){}
155 void BPositionIO::_ReservedPositionIO8(){}
156 void BPositionIO::_ReservedPositionIO9(){}
157 void BPositionIO::_ReservedPositionIO10(){}
158 void BPositionIO::_ReservedPositionIO11(){}
159 void BPositionIO::_ReservedPositionIO12(){}
160 #endif
161 
162 
163 // *** BMemoryIO ***
164 
165 // Construction
166 BMemoryIO::BMemoryIO(void *p, size_t len)
167 		:fReadOnly(false),
168 		fBuf(static_cast<char*>(p)),
169 		fLen(len),
170 		fPhys(len),
171 		fPos(0)
172 
173 {
174 }
175 
176 
177 BMemoryIO::BMemoryIO(const void *p, size_t len)
178 		:fReadOnly(true),
179 		fBuf(const_cast<char*>(static_cast<const char*>(p))),
180 		fLen(len),
181 		fPhys(len),
182 		fPos(0)
183 {
184 }
185 
186 
187 // Destruction
188 BMemoryIO::~BMemoryIO()
189 {
190 }
191 
192 
193 // ReadAt
194 ssize_t
195 BMemoryIO::ReadAt(off_t pos, void *buffer, size_t size)
196 {
197 	if (buffer == NULL || pos < 0)
198 		return B_BAD_VALUE;
199 
200 	ssize_t sizeRead = 0;
201 	if (pos < fLen) {
202 		sizeRead = min_c(static_cast<off_t>(size), fLen - pos);
203 		memcpy(buffer, fBuf + pos, sizeRead);
204 	}
205 	return sizeRead;
206 }
207 
208 
209 // WriteAt
210 ssize_t
211 BMemoryIO::WriteAt(off_t pos, const void *buffer, size_t size)
212 {
213 	if (fReadOnly)
214 		return B_NOT_ALLOWED;
215 
216 	if (buffer == NULL || pos < 0)
217 		return B_BAD_VALUE;
218 
219 	ssize_t sizeWritten = 0;
220 	if (pos < fPhys) {
221 		sizeWritten = min_c(static_cast<off_t>(size), fPhys - pos);
222 		memcpy(fBuf + pos, buffer, sizeWritten);
223 	}
224 
225 	if (pos + sizeWritten > fLen)
226 		fLen = pos + sizeWritten;
227 
228 	return sizeWritten;
229 }
230 
231 
232 // Seek
233 off_t
234 BMemoryIO::Seek(off_t position, uint32 seek_mode)
235 {
236 	switch (seek_mode) {
237 		case SEEK_SET:
238 			fPos = position;
239 			break;
240 		case SEEK_CUR:
241 			fPos += position;
242 			break;
243 		case SEEK_END:
244 			fPos = fLen + position;
245 			break;
246 		default:
247 			break;
248 	}
249 	return fPos;
250 }
251 
252 
253 // Position
254 off_t
255 BMemoryIO::Position() const
256 {
257 	return fPos;
258 }
259 
260 
261 // SetSize
262 status_t
263 BMemoryIO::SetSize(off_t size)
264 {
265 	status_t err = B_ERROR;
266 
267 	if (fReadOnly)
268 		return B_NOT_ALLOWED;
269 
270 	if (size <= fPhys) {
271 		err = B_OK;
272 		fLen = size;
273 	}
274 
275 	return err;
276 }
277 
278 
279 // Private or Reserved
280 BMemoryIO::BMemoryIO(const BMemoryIO &)
281 {
282 	//Copying not allowed
283 }
284 
285 
286 BMemoryIO &
287 BMemoryIO::operator=(const BMemoryIO &)
288 {
289 	//Copying not allowed
290 	return *this;
291 }
292 
293 
294 // FBC
295 void BMemoryIO::_ReservedMemoryIO1(){}
296 void BMemoryIO::_ReservedMemoryIO2(){}
297 
298 
299 // *** BMallocIO ***
300 
301 // Construction
302 BMallocIO::BMallocIO()
303 		 : fBlockSize(256),
304 		   fMallocSize(0),
305 		   fLength(0),
306 		   fData(NULL),
307 		   fPosition(0)
308 {
309 }
310 
311 
312 // Destruction
313 BMallocIO::~BMallocIO()
314 {
315 	if (fData)
316 		free(fData);
317 }
318 
319 
320 // ReadAt
321 ssize_t
322 BMallocIO::ReadAt(off_t pos, void *buffer, size_t size)
323 {
324 	if (buffer == NULL)
325 		return B_BAD_VALUE;
326 
327 	ssize_t sizeRead = 0;
328 	if (pos < fLength) {
329 		sizeRead = min_c(static_cast<off_t>(size), fLength - pos);
330 		memcpy(buffer, fData + pos, sizeRead);
331 	}
332 	return sizeRead;
333 }
334 
335 
336 // WriteAt
337 ssize_t
338 BMallocIO::WriteAt(off_t pos, const void *buffer, size_t size)
339 {
340 	if (buffer == NULL)
341 		return B_BAD_VALUE;
342 
343 	size_t newSize = max_c(pos + size, static_cast<off_t>(fLength));
344 
345 	status_t error = B_OK;
346 
347 	if (newSize > fMallocSize)
348 		error = SetSize(newSize);
349 
350 	if (error == B_OK) {
351 		memcpy(fData + pos, buffer, size);
352 		if (pos + size > fLength)
353 			fLength = pos + size;
354 	}
355 	return error != B_OK ? error : size;
356 }
357 
358 
359 // Seek
360 off_t
361 BMallocIO::Seek(off_t position, uint32 seekMode)
362 {
363 	switch (seekMode) {
364 		case SEEK_SET:
365 			fPosition = position;
366 			break;
367 		case SEEK_END:
368 			fPosition = fLength + position;
369 			break;
370 		case SEEK_CUR:
371 			fPosition += position;
372 			break;
373 		default:
374 			break;
375 	}
376 	return fPosition;
377 }
378 
379 
380 // Position
381 off_t
382 BMallocIO::Position() const
383 {
384 	return fPosition;
385 }
386 
387 
388 // SetSize
389 status_t
390 BMallocIO::SetSize(off_t size)
391 {
392 	status_t error = B_OK;
393 	if (size == 0) {
394 		// size == 0, free the memory
395 		free(fData);
396 		fData = NULL;
397 		fMallocSize = 0;
398 	} else {
399 		// size != 0, see, if necessary to resize
400 		size_t newSize = (size + fBlockSize - 1) / fBlockSize * fBlockSize;
401 		if (size != fMallocSize) {
402 			// we need to resize
403 			if (char *newData = static_cast<char*>(realloc(fData, newSize))) {
404 				// set the new area to 0
405 				if (newSize > fMallocSize)
406 					memset(newData + fMallocSize, 0, newSize - fMallocSize);
407 				fData = newData;
408 				fMallocSize = newSize;
409 			} else	// couldn't alloc the memory
410 				error = B_NO_MEMORY;
411 		}
412 	}
413 
414 	if (error == B_OK)
415 		fLength = size;
416 
417 	return error;
418 }
419 
420 
421 // SetBlockSize
422 void
423 BMallocIO::SetBlockSize(size_t blockSize)
424 {
425 	if (blockSize == 0)
426 		blockSize = 1;
427 	if (blockSize != fBlockSize)
428 		fBlockSize = blockSize;
429 }
430 
431 
432 // Buffer
433 const void *
434 BMallocIO::Buffer() const
435 {
436 	return fData;
437 }
438 
439 
440 // BufferLength
441 size_t
442 BMallocIO::BufferLength() const
443 {
444 	return fLength;
445 }
446 
447 
448 // Private or Reserved
449 BMallocIO::BMallocIO(const BMallocIO &)
450 {
451 	// copying not allowed...
452 }
453 
454 
455 BMallocIO &
456 BMallocIO::operator=(const BMallocIO &)
457 {
458 	// copying not allowed...
459 	return *this;
460 }
461 
462 
463 // FBC
464 void BMallocIO::_ReservedMallocIO1() {}
465 void BMallocIO::_ReservedMallocIO2() {}
466 
467 
468 /*
469  * $Log $
470  *
471  * $Id  $
472  *
473  */
474