xref: /haiku/src/kits/support/DataIO.cpp (revision 95bac3fda53a4cb21880712d7b43f8c21db32a2e)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2005, Haiku, Inc.
3 //
4 //	Permission is hereby granted, free of charge, to any person obtaining a
5 //	copy of this software and associated documentation files (the "Software"),
6 //	to deal in the Software without restriction, including without limitation
7 //	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 //	and/or sell copies of the Software, and to permit persons to whom the
9 //	Software is furnished to do so, subject to the following conditions:
10 //
11 //	The above copyright notice and this permission notice shall be included in
12 //	all copies or substantial portions of the Software.
13 //
14 //	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 //	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 //	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 //	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 //	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 //	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 //	DEALINGS IN THE SOFTWARE.
21 //
22 //	File Name:		DataIO.cpp
23 //	Author(s):		Stefano Ceccherini (burton666@libero.it)
24 //					The Storage Team
25 //	Description:	Pure virtual BDataIO and BPositioIO classes provide
26 //					the protocol for Read()/Write()/Seek().
27 //
28 //					BMallocIO and BMemoryIO classes implement the protocol,
29 //					as does BFile in the Storage Kit.
30 //------------------------------------------------------------------------------
31 #include <algorithm>
32 #include <stdio.h>
33 #include <string.h>
34 #include <stdlib.h>
35 
36 #include <DataIO.h>
37 
38 
39 // *** BDataIO ***
40 
41 // Construction
42 BDataIO::BDataIO()
43 {
44 }
45 
46 
47 // Destruction
48 BDataIO::~BDataIO()
49 {
50 }
51 
52 
53 // Private or Reserved
54 BDataIO::BDataIO(const BDataIO &)
55 {
56 	//Copying not allowed
57 }
58 
59 
60 BDataIO &
61 BDataIO::operator=(const BDataIO &)
62 {
63 	//Copying not allowed
64 	return *this;
65 }
66 
67 
68 // FBC
69 void BDataIO::_ReservedDataIO1(){}
70 void BDataIO::_ReservedDataIO2(){}
71 void BDataIO::_ReservedDataIO3(){}
72 void BDataIO::_ReservedDataIO4(){}
73 
74 #if !_PR3_COMPATIBLE_
75 void BDataIO::_ReservedDataIO5(){}
76 void BDataIO::_ReservedDataIO6(){}
77 void BDataIO::_ReservedDataIO7(){}
78 void BDataIO::_ReservedDataIO8(){}
79 void BDataIO::_ReservedDataIO9(){}
80 void BDataIO::_ReservedDataIO10(){}
81 void BDataIO::_ReservedDataIO11(){}
82 void BDataIO::_ReservedDataIO12(){}
83 #endif
84 
85 
86 // *** BPositionIO ***
87 
88 // Construction
89 BPositionIO::BPositionIO()
90 {
91 }
92 
93 
94 // Destruction
95 BPositionIO::~BPositionIO()
96 {
97 }
98 
99 
100 // Read
101 ssize_t
102 BPositionIO::Read(void *buffer, size_t size)
103 {
104 	off_t curPos = Position();
105 	ssize_t result = ReadAt(curPos, buffer, size);
106 	if (result > 0)
107 		Seek(result, SEEK_CUR);
108 
109 	return result;
110 }
111 
112 
113 // Write
114 ssize_t
115 BPositionIO::Write(const void *buffer, size_t size)
116 {
117 	off_t curPos = Position();
118 	ssize_t result = WriteAt(curPos, buffer, size);
119 	if (result > 0)
120 		Seek(result, SEEK_CUR);
121 
122 	return result;
123 }
124 
125 
126 // SetSize
127 status_t
128 BPositionIO::SetSize(off_t size)
129 {
130 	return B_ERROR;
131 }
132 
133 
134 // FBC
135 void BPositionIO::_ReservedPositionIO1(){}
136 void BPositionIO::_ReservedPositionIO2(){}
137 void BPositionIO::_ReservedPositionIO3(){}
138 void BPositionIO::_ReservedPositionIO4(){}
139 
140 #if !_PR3_COMPATIBLE_
141 void BPositionIO::_ReservedPositionIO5(){}
142 void BPositionIO::_ReservedPositionIO6(){}
143 void BPositionIO::_ReservedPositionIO7(){}
144 void BPositionIO::_ReservedPositionIO8(){}
145 void BPositionIO::_ReservedPositionIO9(){}
146 void BPositionIO::_ReservedPositionIO10(){}
147 void BPositionIO::_ReservedPositionIO11(){}
148 void BPositionIO::_ReservedPositionIO12(){}
149 #endif
150 
151 
152 // *** BMemoryIO ***
153 
154 // Construction
155 BMemoryIO::BMemoryIO(void *p, size_t len)
156 		:fReadOnly(false),
157 		fBuf(static_cast<char*>(p)),
158 		fLen(len),
159 		fPhys(len),
160 		fPos(0)
161 
162 {
163 }
164 
165 
166 BMemoryIO::BMemoryIO(const void *p, size_t len)
167 		:fReadOnly(true),
168 		fBuf(const_cast<char*>(static_cast<const char*>(p))),
169 		fLen(len),
170 		fPhys(len),
171 		fPos(0)
172 {
173 }
174 
175 
176 // Destruction
177 BMemoryIO::~BMemoryIO()
178 {
179 }
180 
181 
182 // ReadAt
183 ssize_t
184 BMemoryIO::ReadAt(off_t pos, void *buffer, size_t size)
185 {
186 	if (buffer == NULL || pos < 0)
187 		return B_BAD_VALUE;
188 
189 	ssize_t sizeRead = 0;
190 	if (pos < fLen) {
191 		sizeRead = min_c(static_cast<off_t>(size), fLen - pos);
192 		memcpy(buffer, fBuf + pos, sizeRead);
193 	}
194 	return sizeRead;
195 }
196 
197 
198 // WriteAt
199 ssize_t
200 BMemoryIO::WriteAt(off_t pos, const void *buffer, size_t size)
201 {
202 	if (fReadOnly)
203 		return B_NOT_ALLOWED;
204 
205 	if (buffer == NULL || pos < 0)
206 		return B_BAD_VALUE;
207 
208 	ssize_t sizeWritten = 0;
209 	if (pos < fPhys) {
210 		sizeWritten = min_c(static_cast<off_t>(size), fPhys - pos);
211 		memcpy(fBuf + pos, buffer, sizeWritten);
212 	}
213 
214 	if (pos + sizeWritten > fLen)
215 		fLen = pos + sizeWritten;
216 
217 	return sizeWritten;
218 }
219 
220 
221 // Seek
222 off_t
223 BMemoryIO::Seek(off_t position, uint32 seek_mode)
224 {
225 	switch (seek_mode) {
226 		case SEEK_SET:
227 			fPos = position;
228 			break;
229 		case SEEK_CUR:
230 			fPos += position;
231 			break;
232 		case SEEK_END:
233 			fPos = fLen + position;
234 			break;
235 		default:
236 			break;
237 	}
238 	return fPos;
239 }
240 
241 
242 // Position
243 off_t
244 BMemoryIO::Position() const
245 {
246 	return fPos;
247 }
248 
249 
250 // SetSize
251 status_t
252 BMemoryIO::SetSize(off_t size)
253 {
254 	status_t err = B_ERROR;
255 
256 	if (fReadOnly)
257 		return B_NOT_ALLOWED;
258 
259 	if (size <= fPhys) {
260 		err = B_OK;
261 		fLen = size;
262 	}
263 
264 	return err;
265 }
266 
267 
268 // Private or Reserved
269 BMemoryIO::BMemoryIO(const BMemoryIO &)
270 {
271 	//Copying not allowed
272 }
273 
274 
275 BMemoryIO &
276 BMemoryIO::operator=(const BMemoryIO &)
277 {
278 	//Copying not allowed
279 	return *this;
280 }
281 
282 
283 // FBC
284 void BMemoryIO::_ReservedMemoryIO1(){}
285 void BMemoryIO::_ReservedMemoryIO2(){}
286 
287 
288 // *** BMallocIO ***
289 
290 // Construction
291 BMallocIO::BMallocIO()
292 		 : fBlockSize(256),
293 		   fMallocSize(0),
294 		   fLength(0),
295 		   fData(NULL),
296 		   fPosition(0)
297 {
298 }
299 
300 
301 // Destruction
302 BMallocIO::~BMallocIO()
303 {
304 	free(fData);
305 }
306 
307 
308 // ReadAt
309 ssize_t
310 BMallocIO::ReadAt(off_t pos, void *buffer, size_t size)
311 {
312 	if (buffer == NULL)
313 		return B_BAD_VALUE;
314 
315 	ssize_t sizeRead = 0;
316 	if (pos < fLength) {
317 		sizeRead = min_c(static_cast<off_t>(size), fLength - pos);
318 		memcpy(buffer, fData + pos, sizeRead);
319 	}
320 	return sizeRead;
321 }
322 
323 
324 // WriteAt
325 ssize_t
326 BMallocIO::WriteAt(off_t pos, const void *buffer, size_t size)
327 {
328 	if (buffer == NULL)
329 		return B_BAD_VALUE;
330 
331 	size_t newSize = max_c(pos + size, static_cast<off_t>(fLength));
332 
333 	status_t error = B_OK;
334 
335 	if (newSize > fMallocSize)
336 		error = SetSize(newSize);
337 
338 	if (error == B_OK) {
339 		memcpy(fData + pos, buffer, size);
340 		if (pos + size > fLength)
341 			fLength = pos + size;
342 	}
343 	return error != B_OK ? error : size;
344 }
345 
346 
347 // Seek
348 off_t
349 BMallocIO::Seek(off_t position, uint32 seekMode)
350 {
351 	switch (seekMode) {
352 		case SEEK_SET:
353 			fPosition = position;
354 			break;
355 		case SEEK_END:
356 			fPosition = fLength + position;
357 			break;
358 		case SEEK_CUR:
359 			fPosition += position;
360 			break;
361 		default:
362 			break;
363 	}
364 	return fPosition;
365 }
366 
367 
368 // Position
369 off_t
370 BMallocIO::Position() const
371 {
372 	return fPosition;
373 }
374 
375 
376 // SetSize
377 status_t
378 BMallocIO::SetSize(off_t size)
379 {
380 	status_t error = B_OK;
381 	if (size == 0) {
382 		// size == 0, free the memory
383 		free(fData);
384 		fData = NULL;
385 		fMallocSize = 0;
386 	} else {
387 		// size != 0, see, if necessary to resize
388 		size_t newSize = (size + fBlockSize - 1) / fBlockSize * fBlockSize;
389 		if (size != fMallocSize) {
390 			// we need to resize
391 			if (char *newData = static_cast<char*>(realloc(fData, newSize))) {
392 				// set the new area to 0
393 				if (newSize > fMallocSize)
394 					memset(newData + fMallocSize, 0, newSize - fMallocSize);
395 				fData = newData;
396 				fMallocSize = newSize;
397 			} else	// couldn't alloc the memory
398 				error = B_NO_MEMORY;
399 		}
400 	}
401 
402 	if (error == B_OK)
403 		fLength = size;
404 
405 	return error;
406 }
407 
408 
409 // SetBlockSize
410 void
411 BMallocIO::SetBlockSize(size_t blockSize)
412 {
413 	if (blockSize == 0)
414 		blockSize = 1;
415 	if (blockSize != fBlockSize)
416 		fBlockSize = blockSize;
417 }
418 
419 
420 // Buffer
421 const void *
422 BMallocIO::Buffer() const
423 {
424 	return fData;
425 }
426 
427 
428 // BufferLength
429 size_t
430 BMallocIO::BufferLength() const
431 {
432 	return fLength;
433 }
434 
435 
436 // Private or Reserved
437 BMallocIO::BMallocIO(const BMallocIO &)
438 {
439 	// copying not allowed...
440 }
441 
442 
443 BMallocIO &
444 BMallocIO::operator=(const BMallocIO &)
445 {
446 	// copying not allowed...
447 	return *this;
448 }
449 
450 
451 // FBC
452 void BMallocIO::_ReservedMallocIO1() {}
453 void BMallocIO::_ReservedMallocIO2() {}
454 
455 
456 /*
457  * $Log $
458  *
459  * $Id  $
460  *
461  */
462