xref: /haiku/src/kits/support/DataIO.cpp (revision 8cd531a9babbc69c2bfd302dec4ff5a3573e9d35)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2005, Haiku, Inc.
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 #include <stdio.h>
32 #include <string.h>
33 #include <stdlib.h>
34 
35 #include <DataIO.h>
36 
37 
38 // *** BDataIO ***
39 
40 // Construction
41 BDataIO::BDataIO()
42 {
43 }
44 
45 
46 // Destruction
47 BDataIO::~BDataIO()
48 {
49 }
50 
51 
52 // Private or Reserved
53 BDataIO::BDataIO(const BDataIO &)
54 {
55 	//Copying not allowed
56 }
57 
58 
59 BDataIO &
60 BDataIO::operator=(const BDataIO &)
61 {
62 	//Copying not allowed
63 	return *this;
64 }
65 
66 
67 // FBC
68 void BDataIO::_ReservedDataIO1(){}
69 void BDataIO::_ReservedDataIO2(){}
70 void BDataIO::_ReservedDataIO3(){}
71 void BDataIO::_ReservedDataIO4(){}
72 
73 #if !_PR3_COMPATIBLE_
74 void BDataIO::_ReservedDataIO5(){}
75 void BDataIO::_ReservedDataIO6(){}
76 void BDataIO::_ReservedDataIO7(){}
77 void BDataIO::_ReservedDataIO8(){}
78 void BDataIO::_ReservedDataIO9(){}
79 void BDataIO::_ReservedDataIO10(){}
80 void BDataIO::_ReservedDataIO11(){}
81 void BDataIO::_ReservedDataIO12(){}
82 #endif
83 
84 
85 // *** BPositionIO ***
86 
87 // Construction
88 BPositionIO::BPositionIO()
89 {
90 }
91 
92 
93 // Destruction
94 BPositionIO::~BPositionIO()
95 {
96 }
97 
98 
99 // Read
100 ssize_t
101 BPositionIO::Read(void *buffer, size_t size)
102 {
103 	off_t curPos = Position();
104 	ssize_t result = ReadAt(curPos, buffer, size);
105 	if (result > 0)
106 		Seek(result, SEEK_CUR);
107 
108 	return result;
109 }
110 
111 
112 // Write
113 ssize_t
114 BPositionIO::Write(const void *buffer, size_t size)
115 {
116 	off_t curPos = Position();
117 	ssize_t result = WriteAt(curPos, buffer, size);
118 	if (result > 0)
119 		Seek(result, SEEK_CUR);
120 
121 	return result;
122 }
123 
124 
125 // SetSize
126 status_t
127 BPositionIO::SetSize(off_t size)
128 {
129 	return B_ERROR;
130 }
131 
132 // GetSize
133 status_t
134 BPositionIO::GetSize(off_t* size) const
135 {
136 	if (!size)
137 		return B_BAD_VALUE;
138 
139 	off_t currentPos = Position();
140 	if (currentPos < 0)
141 		return (status_t)currentPos;
142 
143 	*size = const_cast<BPositionIO*>(this)->Seek(0, SEEK_END);
144 	if (*size < 0)
145 		return (status_t)*size;
146 
147 	off_t pos = const_cast<BPositionIO*>(this)->Seek(currentPos, SEEK_SET);
148 
149 	if (pos != currentPos)
150 		return pos < 0 ? (status_t)pos : B_ERROR;
151 
152 	return B_OK;
153 }
154 
155 
156 // FBC
157 extern "C" void _ReservedPositionIO1__11BPositionIO() {}
158 void BPositionIO::_ReservedPositionIO2(){}
159 void BPositionIO::_ReservedPositionIO3(){}
160 void BPositionIO::_ReservedPositionIO4(){}
161 
162 #if !_PR3_COMPATIBLE_
163 void BPositionIO::_ReservedPositionIO5(){}
164 void BPositionIO::_ReservedPositionIO6(){}
165 void BPositionIO::_ReservedPositionIO7(){}
166 void BPositionIO::_ReservedPositionIO8(){}
167 void BPositionIO::_ReservedPositionIO9(){}
168 void BPositionIO::_ReservedPositionIO10(){}
169 void BPositionIO::_ReservedPositionIO11(){}
170 void BPositionIO::_ReservedPositionIO12(){}
171 #endif
172 
173 
174 // *** BMemoryIO ***
175 
176 // Construction
177 BMemoryIO::BMemoryIO(void *p, size_t len)
178 		:fReadOnly(false),
179 		fBuf(static_cast<char*>(p)),
180 		fLen(len),
181 		fPhys(len),
182 		fPos(0)
183 
184 {
185 }
186 
187 
188 BMemoryIO::BMemoryIO(const void *p, size_t len)
189 		:fReadOnly(true),
190 		fBuf(const_cast<char*>(static_cast<const char*>(p))),
191 		fLen(len),
192 		fPhys(len),
193 		fPos(0)
194 {
195 }
196 
197 
198 // Destruction
199 BMemoryIO::~BMemoryIO()
200 {
201 }
202 
203 
204 // ReadAt
205 ssize_t
206 BMemoryIO::ReadAt(off_t pos, void *buffer, size_t size)
207 {
208 	if (buffer == NULL || pos < 0)
209 		return B_BAD_VALUE;
210 
211 	ssize_t sizeRead = 0;
212 	if (pos < fLen) {
213 		sizeRead = min_c(static_cast<off_t>(size), fLen - pos);
214 		memcpy(buffer, fBuf + pos, sizeRead);
215 	}
216 	return sizeRead;
217 }
218 
219 
220 // WriteAt
221 ssize_t
222 BMemoryIO::WriteAt(off_t pos, const void *buffer, size_t size)
223 {
224 	if (fReadOnly)
225 		return B_NOT_ALLOWED;
226 
227 	if (buffer == NULL || pos < 0)
228 		return B_BAD_VALUE;
229 
230 	ssize_t sizeWritten = 0;
231 	if (pos < fPhys) {
232 		sizeWritten = min_c(static_cast<off_t>(size), fPhys - pos);
233 		memcpy(fBuf + pos, buffer, sizeWritten);
234 	}
235 
236 	if (pos + sizeWritten > fLen)
237 		fLen = pos + sizeWritten;
238 
239 	return sizeWritten;
240 }
241 
242 
243 // Seek
244 off_t
245 BMemoryIO::Seek(off_t position, uint32 seek_mode)
246 {
247 	switch (seek_mode) {
248 		case SEEK_SET:
249 			fPos = position;
250 			break;
251 		case SEEK_CUR:
252 			fPos += position;
253 			break;
254 		case SEEK_END:
255 			fPos = fLen + position;
256 			break;
257 		default:
258 			break;
259 	}
260 	return fPos;
261 }
262 
263 
264 // Position
265 off_t
266 BMemoryIO::Position() const
267 {
268 	return fPos;
269 }
270 
271 
272 // SetSize
273 status_t
274 BMemoryIO::SetSize(off_t size)
275 {
276 	if (fReadOnly)
277 		return B_NOT_ALLOWED;
278 
279 	if (size > fPhys)
280 		return B_ERROR;
281 
282 	fLen = size;
283 
284 	return B_OK;
285 }
286 
287 
288 // Private or Reserved
289 BMemoryIO::BMemoryIO(const BMemoryIO &)
290 {
291 	//Copying not allowed
292 }
293 
294 
295 BMemoryIO &
296 BMemoryIO::operator=(const BMemoryIO &)
297 {
298 	//Copying not allowed
299 	return *this;
300 }
301 
302 
303 // FBC
304 void BMemoryIO::_ReservedMemoryIO1(){}
305 void BMemoryIO::_ReservedMemoryIO2(){}
306 
307 
308 // *** BMallocIO ***
309 
310 // Construction
311 BMallocIO::BMallocIO()
312 		 : fBlockSize(256),
313 		   fMallocSize(0),
314 		   fLength(0),
315 		   fData(NULL),
316 		   fPosition(0)
317 {
318 }
319 
320 
321 // Destruction
322 BMallocIO::~BMallocIO()
323 {
324 	free(fData);
325 }
326 
327 
328 // ReadAt
329 ssize_t
330 BMallocIO::ReadAt(off_t pos, void *buffer, size_t size)
331 {
332 	if (buffer == NULL)
333 		return B_BAD_VALUE;
334 
335 	ssize_t sizeRead = 0;
336 	if (pos < fLength) {
337 		sizeRead = min_c(static_cast<off_t>(size), fLength - pos);
338 		memcpy(buffer, fData + pos, sizeRead);
339 	}
340 	return sizeRead;
341 }
342 
343 
344 // WriteAt
345 ssize_t
346 BMallocIO::WriteAt(off_t pos, const void *buffer, size_t size)
347 {
348 	if (buffer == NULL)
349 		return B_BAD_VALUE;
350 
351 	size_t newSize = max_c(pos + size, static_cast<off_t>(fLength));
352 
353 	status_t error = B_OK;
354 
355 	if (newSize > fMallocSize)
356 		error = SetSize(newSize);
357 
358 	if (error == B_OK) {
359 		memcpy(fData + pos, buffer, size);
360 		if (pos + size > fLength)
361 			fLength = pos + size;
362 	}
363 	return error != B_OK ? error : size;
364 }
365 
366 
367 // Seek
368 off_t
369 BMallocIO::Seek(off_t position, uint32 seekMode)
370 {
371 	switch (seekMode) {
372 		case SEEK_SET:
373 			fPosition = position;
374 			break;
375 		case SEEK_END:
376 			fPosition = fLength + position;
377 			break;
378 		case SEEK_CUR:
379 			fPosition += position;
380 			break;
381 		default:
382 			break;
383 	}
384 	return fPosition;
385 }
386 
387 
388 // Position
389 off_t
390 BMallocIO::Position() const
391 {
392 	return fPosition;
393 }
394 
395 
396 // SetSize
397 status_t
398 BMallocIO::SetSize(off_t size)
399 {
400 	status_t error = B_OK;
401 	if (size == 0) {
402 		// size == 0, free the memory
403 		free(fData);
404 		fData = NULL;
405 		fMallocSize = 0;
406 	} else {
407 		// size != 0, see, if necessary to resize
408 		size_t newSize = (size + fBlockSize - 1) / fBlockSize * fBlockSize;
409 		if (size != fMallocSize) {
410 			// we need to resize
411 			if (char *newData = static_cast<char*>(realloc(fData, newSize))) {
412 				// set the new area to 0
413 				if (newSize > fMallocSize)
414 					memset(newData + fMallocSize, 0, newSize - fMallocSize);
415 				fData = newData;
416 				fMallocSize = newSize;
417 			} else	// couldn't alloc the memory
418 				error = B_NO_MEMORY;
419 		}
420 	}
421 
422 	if (error == B_OK)
423 		fLength = size;
424 
425 	return error;
426 }
427 
428 
429 // SetBlockSize
430 void
431 BMallocIO::SetBlockSize(size_t blockSize)
432 {
433 	if (blockSize == 0)
434 		blockSize = 1;
435 	if (blockSize != fBlockSize)
436 		fBlockSize = blockSize;
437 }
438 
439 
440 // Buffer
441 const void *
442 BMallocIO::Buffer() const
443 {
444 	return fData;
445 }
446 
447 
448 // BufferLength
449 size_t
450 BMallocIO::BufferLength() const
451 {
452 	return fLength;
453 }
454 
455 
456 // Private or Reserved
457 BMallocIO::BMallocIO(const BMallocIO &)
458 {
459 	// copying not allowed...
460 }
461 
462 
463 BMallocIO &
464 BMallocIO::operator=(const BMallocIO &)
465 {
466 	// copying not allowed...
467 	return *this;
468 }
469 
470 
471 // FBC
472 void BMallocIO::_ReservedMallocIO1() {}
473 void BMallocIO::_ReservedMallocIO2() {}
474 
475 
476 /*
477  * $Log $
478  *
479  * $Id  $
480  *
481  */
482