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