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 // GetSize 133 status_t 134 BPositionIO::GetSize(off_t* size) const 135 { 136 if (!size) 137 return B_BAD_VALUE; 138 139 off_t currentPos = Position(); 140 if (currentPos < 0) 141 return (status_t)currentPos; 142 143 *size = const_cast<BPositionIO*>(this)->Seek(0, SEEK_END); 144 if (*size < 0) 145 return (status_t)*size; 146 147 off_t pos = const_cast<BPositionIO*>(this)->Seek(currentPos, SEEK_SET); 148 149 if (pos != currentPos) 150 return pos < 0 ? (status_t)pos : B_ERROR; 151 152 return B_OK; 153 } 154 155 156 // FBC 157 extern "C" void _ReservedPositionIO1__11BPositionIO() {} 158 void BPositionIO::_ReservedPositionIO2(){} 159 void BPositionIO::_ReservedPositionIO3(){} 160 void BPositionIO::_ReservedPositionIO4(){} 161 162 #if !_PR3_COMPATIBLE_ 163 void BPositionIO::_ReservedPositionIO5(){} 164 void BPositionIO::_ReservedPositionIO6(){} 165 void BPositionIO::_ReservedPositionIO7(){} 166 void BPositionIO::_ReservedPositionIO8(){} 167 void BPositionIO::_ReservedPositionIO9(){} 168 void BPositionIO::_ReservedPositionIO10(){} 169 void BPositionIO::_ReservedPositionIO11(){} 170 void BPositionIO::_ReservedPositionIO12(){} 171 #endif 172 173 174 // *** BMemoryIO *** 175 176 // Construction 177 BMemoryIO::BMemoryIO(void *p, size_t len) 178 :fReadOnly(false), 179 fBuf(static_cast<char*>(p)), 180 fLen(len), 181 fPhys(len), 182 fPos(0) 183 184 { 185 } 186 187 188 BMemoryIO::BMemoryIO(const void *p, size_t len) 189 :fReadOnly(true), 190 fBuf(const_cast<char*>(static_cast<const char*>(p))), 191 fLen(len), 192 fPhys(len), 193 fPos(0) 194 { 195 } 196 197 198 // Destruction 199 BMemoryIO::~BMemoryIO() 200 { 201 } 202 203 204 // ReadAt 205 ssize_t 206 BMemoryIO::ReadAt(off_t pos, void *buffer, size_t size) 207 { 208 if (buffer == NULL || pos < 0) 209 return B_BAD_VALUE; 210 211 ssize_t sizeRead = 0; 212 if (pos < fLen) { 213 sizeRead = min_c(static_cast<off_t>(size), fLen - pos); 214 memcpy(buffer, fBuf + pos, sizeRead); 215 } 216 return sizeRead; 217 } 218 219 220 // WriteAt 221 ssize_t 222 BMemoryIO::WriteAt(off_t pos, const void *buffer, size_t size) 223 { 224 if (fReadOnly) 225 return B_NOT_ALLOWED; 226 227 if (buffer == NULL || pos < 0) 228 return B_BAD_VALUE; 229 230 ssize_t sizeWritten = 0; 231 if (pos < fPhys) { 232 sizeWritten = min_c(static_cast<off_t>(size), fPhys - pos); 233 memcpy(fBuf + pos, buffer, sizeWritten); 234 } 235 236 if (pos + sizeWritten > fLen) 237 fLen = pos + sizeWritten; 238 239 return sizeWritten; 240 } 241 242 243 // Seek 244 off_t 245 BMemoryIO::Seek(off_t position, uint32 seek_mode) 246 { 247 switch (seek_mode) { 248 case SEEK_SET: 249 fPos = position; 250 break; 251 case SEEK_CUR: 252 fPos += position; 253 break; 254 case SEEK_END: 255 fPos = fLen + position; 256 break; 257 default: 258 break; 259 } 260 return fPos; 261 } 262 263 264 // Position 265 off_t 266 BMemoryIO::Position() const 267 { 268 return fPos; 269 } 270 271 272 // SetSize 273 status_t 274 BMemoryIO::SetSize(off_t size) 275 { 276 if (fReadOnly) 277 return B_NOT_ALLOWED; 278 279 if (size > fPhys) 280 return B_ERROR; 281 282 fLen = size; 283 284 return B_OK; 285 } 286 287 288 // Private or Reserved 289 BMemoryIO::BMemoryIO(const BMemoryIO &) 290 { 291 //Copying not allowed 292 } 293 294 295 BMemoryIO & 296 BMemoryIO::operator=(const BMemoryIO &) 297 { 298 //Copying not allowed 299 return *this; 300 } 301 302 303 // FBC 304 void BMemoryIO::_ReservedMemoryIO1(){} 305 void BMemoryIO::_ReservedMemoryIO2(){} 306 307 308 // *** BMallocIO *** 309 310 // Construction 311 BMallocIO::BMallocIO() 312 : fBlockSize(256), 313 fMallocSize(0), 314 fLength(0), 315 fData(NULL), 316 fPosition(0) 317 { 318 } 319 320 321 // Destruction 322 BMallocIO::~BMallocIO() 323 { 324 free(fData); 325 } 326 327 328 // ReadAt 329 ssize_t 330 BMallocIO::ReadAt(off_t pos, void *buffer, size_t size) 331 { 332 if (buffer == NULL) 333 return B_BAD_VALUE; 334 335 ssize_t sizeRead = 0; 336 if (pos < fLength) { 337 sizeRead = min_c(static_cast<off_t>(size), fLength - pos); 338 memcpy(buffer, fData + pos, sizeRead); 339 } 340 return sizeRead; 341 } 342 343 344 // WriteAt 345 ssize_t 346 BMallocIO::WriteAt(off_t pos, const void *buffer, size_t size) 347 { 348 if (buffer == NULL) 349 return B_BAD_VALUE; 350 351 size_t newSize = max_c(pos + size, static_cast<off_t>(fLength)); 352 353 status_t error = B_OK; 354 355 if (newSize > fMallocSize) 356 error = SetSize(newSize); 357 358 if (error == B_OK) { 359 memcpy(fData + pos, buffer, size); 360 if (pos + size > fLength) 361 fLength = pos + size; 362 } 363 return error != B_OK ? error : size; 364 } 365 366 367 // Seek 368 off_t 369 BMallocIO::Seek(off_t position, uint32 seekMode) 370 { 371 switch (seekMode) { 372 case SEEK_SET: 373 fPosition = position; 374 break; 375 case SEEK_END: 376 fPosition = fLength + position; 377 break; 378 case SEEK_CUR: 379 fPosition += position; 380 break; 381 default: 382 break; 383 } 384 return fPosition; 385 } 386 387 388 // Position 389 off_t 390 BMallocIO::Position() const 391 { 392 return fPosition; 393 } 394 395 396 // SetSize 397 status_t 398 BMallocIO::SetSize(off_t size) 399 { 400 status_t error = B_OK; 401 if (size == 0) { 402 // size == 0, free the memory 403 free(fData); 404 fData = NULL; 405 fMallocSize = 0; 406 } else { 407 // size != 0, see, if necessary to resize 408 size_t newSize = (size + fBlockSize - 1) / fBlockSize * fBlockSize; 409 if (size != fMallocSize) { 410 // we need to resize 411 if (char *newData = static_cast<char*>(realloc(fData, newSize))) { 412 // set the new area to 0 413 if (newSize > fMallocSize) 414 memset(newData + fMallocSize, 0, newSize - fMallocSize); 415 fData = newData; 416 fMallocSize = newSize; 417 } else // couldn't alloc the memory 418 error = B_NO_MEMORY; 419 } 420 } 421 422 if (error == B_OK) 423 fLength = size; 424 425 return error; 426 } 427 428 429 // SetBlockSize 430 void 431 BMallocIO::SetBlockSize(size_t blockSize) 432 { 433 if (blockSize == 0) 434 blockSize = 1; 435 if (blockSize != fBlockSize) 436 fBlockSize = blockSize; 437 } 438 439 440 // Buffer 441 const void * 442 BMallocIO::Buffer() const 443 { 444 return fData; 445 } 446 447 448 // BufferLength 449 size_t 450 BMallocIO::BufferLength() const 451 { 452 return fLength; 453 } 454 455 456 // Private or Reserved 457 BMallocIO::BMallocIO(const BMallocIO &) 458 { 459 // copying not allowed... 460 } 461 462 463 BMallocIO & 464 BMallocIO::operator=(const BMallocIO &) 465 { 466 // copying not allowed... 467 return *this; 468 } 469 470 471 // FBC 472 void BMallocIO::_ReservedMallocIO1() {} 473 void BMallocIO::_ReservedMallocIO2() {} 474 475 476 /* 477 * $Log $ 478 * 479 * $Id $ 480 * 481 */ 482