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