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