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