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