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