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