1 /* 2 * Copyright 2005-2014 Haiku, Inc. All rights reserved. 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 #include <Errors.h> 17 18 19 BDataIO::BDataIO() 20 { 21 } 22 23 24 BDataIO::~BDataIO() 25 { 26 } 27 28 29 ssize_t 30 BDataIO::Read(void* buffer, size_t size) 31 { 32 return B_NOT_SUPPORTED; 33 } 34 35 36 ssize_t 37 BDataIO::Write(const void* buffer, size_t size) 38 { 39 return B_NOT_SUPPORTED; 40 } 41 42 43 status_t 44 BDataIO::Flush() 45 { 46 return B_OK; 47 } 48 49 50 status_t 51 BDataIO::ReadExactly(void* buffer, size_t size, size_t* _bytesRead) 52 { 53 uint8* out = (uint8*)buffer; 54 size_t bytesRemaining = size; 55 status_t error = B_OK; 56 57 while (bytesRemaining > 0) { 58 ssize_t bytesRead = Read(out, bytesRemaining); 59 if (bytesRead < 0) { 60 error = bytesRead; 61 break; 62 } 63 64 if (bytesRead == 0) { 65 error = B_PARTIAL_READ; 66 break; 67 } 68 69 out += bytesRead; 70 bytesRemaining -= bytesRead; 71 } 72 73 if (_bytesRead != NULL) 74 *_bytesRead = size - bytesRemaining; 75 76 return error; 77 } 78 79 80 status_t 81 BDataIO::WriteExactly(const void* buffer, size_t size, size_t* _bytesWritten) 82 { 83 const uint8* in = (const uint8*)buffer; 84 size_t bytesRemaining = size; 85 status_t error = B_OK; 86 87 while (bytesRemaining > 0) { 88 ssize_t bytesWritten = Write(in, bytesRemaining); 89 if (bytesWritten < 0) { 90 error = bytesWritten; 91 break; 92 } 93 94 if (bytesWritten == 0) { 95 error = B_PARTIAL_WRITE; 96 break; 97 } 98 99 in += bytesWritten; 100 bytesRemaining -= bytesWritten; 101 } 102 103 if (_bytesWritten != NULL) 104 *_bytesWritten = size - bytesRemaining; 105 106 return error; 107 } 108 109 110 // Private or Reserved 111 112 BDataIO::BDataIO(const BDataIO &) 113 { 114 // Copying not allowed 115 } 116 117 118 BDataIO & 119 BDataIO::operator=(const BDataIO &) 120 { 121 // Copying not allowed 122 return *this; 123 } 124 125 126 #if __GNUC__ == 2 127 128 129 extern "C" status_t 130 _ReservedDataIO1__7BDataIO(BDataIO* self) 131 { 132 return self->BDataIO::Flush(); 133 } 134 135 136 #else 137 138 139 // TODO: RELEASE: Remove! 140 141 extern "C" status_t 142 _ZN7BDataIO16_ReservedDataIO1Ev(BDataIO* self) 143 { 144 return self->BDataIO::Flush(); 145 } 146 147 148 #endif 149 150 151 // FBC 152 void BDataIO::_ReservedDataIO2(){} 153 void BDataIO::_ReservedDataIO3(){} 154 void BDataIO::_ReservedDataIO4(){} 155 void BDataIO::_ReservedDataIO5(){} 156 void BDataIO::_ReservedDataIO6(){} 157 void BDataIO::_ReservedDataIO7(){} 158 void BDataIO::_ReservedDataIO8(){} 159 void BDataIO::_ReservedDataIO9(){} 160 void BDataIO::_ReservedDataIO10(){} 161 void BDataIO::_ReservedDataIO11(){} 162 void BDataIO::_ReservedDataIO12(){} 163 164 165 // #pragma mark - 166 167 168 BPositionIO::BPositionIO() 169 { 170 } 171 172 173 BPositionIO::~BPositionIO() 174 { 175 } 176 177 178 ssize_t 179 BPositionIO::Read(void* buffer, size_t size) 180 { 181 off_t curPos = Position(); 182 ssize_t result = ReadAt(curPos, buffer, size); 183 if (result > 0) 184 Seek(result, SEEK_CUR); 185 186 return result; 187 } 188 189 190 ssize_t 191 BPositionIO::Write(const void* buffer, size_t size) 192 { 193 off_t curPos = Position(); 194 ssize_t result = WriteAt(curPos, buffer, size); 195 if (result > 0) 196 Seek(result, SEEK_CUR); 197 198 return result; 199 } 200 201 202 status_t 203 BPositionIO::ReadAtExactly(off_t position, void* buffer, size_t size, 204 size_t* _bytesRead) 205 { 206 uint8* out = (uint8*)buffer; 207 size_t bytesRemaining = size; 208 status_t error = B_OK; 209 210 while (bytesRemaining > 0) { 211 ssize_t bytesRead = ReadAt(position, out, bytesRemaining); 212 if (bytesRead < 0) { 213 error = bytesRead; 214 break; 215 } 216 217 if (bytesRead == 0) { 218 error = B_PARTIAL_READ; 219 break; 220 } 221 222 out += bytesRead; 223 bytesRemaining -= bytesRead; 224 position += bytesRead; 225 } 226 227 if (_bytesRead != NULL) 228 *_bytesRead = size - bytesRemaining; 229 230 return error; 231 } 232 233 234 status_t 235 BPositionIO::WriteAtExactly(off_t position, const void* buffer, size_t size, 236 size_t* _bytesWritten) 237 { 238 const uint8* in = (const uint8*)buffer; 239 size_t bytesRemaining = size; 240 status_t error = B_OK; 241 242 while (bytesRemaining > 0) { 243 ssize_t bytesWritten = WriteAt(position, in, bytesRemaining); 244 if (bytesWritten < 0) { 245 error = bytesWritten; 246 break; 247 } 248 249 if (bytesWritten == 0) { 250 error = B_PARTIAL_WRITE; 251 break; 252 } 253 254 in += bytesWritten; 255 bytesRemaining -= bytesWritten; 256 position += bytesWritten; 257 } 258 259 if (_bytesWritten != NULL) 260 *_bytesWritten = size - bytesRemaining; 261 262 return error; 263 } 264 265 266 status_t 267 BPositionIO::SetSize(off_t size) 268 { 269 return B_ERROR; 270 } 271 272 273 status_t 274 BPositionIO::GetSize(off_t* size) const 275 { 276 if (!size) 277 return B_BAD_VALUE; 278 279 off_t currentPos = Position(); 280 if (currentPos < 0) 281 return (status_t)currentPos; 282 283 *size = const_cast<BPositionIO*>(this)->Seek(0, SEEK_END); 284 if (*size < 0) 285 return (status_t)*size; 286 287 off_t pos = const_cast<BPositionIO*>(this)->Seek(currentPos, SEEK_SET); 288 289 if (pos != currentPos) 290 return pos < 0 ? (status_t)pos : B_ERROR; 291 292 return B_OK; 293 } 294 295 296 // FBC 297 extern "C" void _ReservedPositionIO1__11BPositionIO() {} 298 void BPositionIO::_ReservedPositionIO2(){} 299 void BPositionIO::_ReservedPositionIO3(){} 300 void BPositionIO::_ReservedPositionIO4(){} 301 void BPositionIO::_ReservedPositionIO5(){} 302 void BPositionIO::_ReservedPositionIO6(){} 303 void BPositionIO::_ReservedPositionIO7(){} 304 void BPositionIO::_ReservedPositionIO8(){} 305 void BPositionIO::_ReservedPositionIO9(){} 306 void BPositionIO::_ReservedPositionIO10(){} 307 void BPositionIO::_ReservedPositionIO11(){} 308 void BPositionIO::_ReservedPositionIO12(){} 309 310 311 // #pragma mark - 312 313 314 BMemoryIO::BMemoryIO(void* buffer, size_t length) 315 : 316 fReadOnly(false), 317 fBuffer(static_cast<char*>(buffer)), 318 fLength(length), 319 fBufferSize(length), 320 fPosition(0) 321 { 322 } 323 324 325 BMemoryIO::BMemoryIO(const void* buffer, size_t length) 326 : 327 fReadOnly(true), 328 fBuffer(const_cast<char*>(static_cast<const char*>(buffer))), 329 fLength(length), 330 fBufferSize(length), 331 fPosition(0) 332 { 333 } 334 335 336 BMemoryIO::~BMemoryIO() 337 { 338 } 339 340 341 ssize_t 342 BMemoryIO::ReadAt(off_t pos, void* buffer, size_t size) 343 { 344 if (buffer == NULL || pos < 0) 345 return B_BAD_VALUE; 346 347 ssize_t sizeRead = 0; 348 if (pos < (off_t)fLength) { 349 sizeRead = min_c((off_t)size, (off_t)fLength - pos); 350 memcpy(buffer, fBuffer + pos, sizeRead); 351 } 352 353 return sizeRead; 354 } 355 356 357 ssize_t 358 BMemoryIO::WriteAt(off_t pos, const void* buffer, size_t size) 359 { 360 if (fReadOnly) 361 return B_NOT_ALLOWED; 362 363 if (buffer == NULL || pos < 0) 364 return B_BAD_VALUE; 365 366 ssize_t sizeWritten = 0; 367 if (pos < (off_t)fBufferSize) { 368 sizeWritten = min_c((off_t)size, (off_t)fBufferSize - pos); 369 memcpy(fBuffer + pos, buffer, sizeWritten); 370 } 371 372 if (pos + sizeWritten > (off_t)fLength) 373 fLength = pos + sizeWritten; 374 375 return sizeWritten; 376 } 377 378 379 off_t 380 BMemoryIO::Seek(off_t position, uint32 seek_mode) 381 { 382 switch (seek_mode) { 383 case SEEK_SET: 384 fPosition = position; 385 break; 386 case SEEK_CUR: 387 fPosition += position; 388 break; 389 case SEEK_END: 390 fPosition = fLength + position; 391 break; 392 default: 393 break; 394 } 395 396 return fPosition; 397 } 398 399 400 off_t 401 BMemoryIO::Position() const 402 { 403 return fPosition; 404 } 405 406 407 status_t 408 BMemoryIO::SetSize(off_t size) 409 { 410 if (fReadOnly) 411 return B_NOT_ALLOWED; 412 413 if (size > (off_t)fBufferSize) 414 return B_ERROR; 415 416 fLength = size; 417 418 return B_OK; 419 } 420 421 422 // Private or Reserved 423 424 BMemoryIO::BMemoryIO(const BMemoryIO &) 425 { 426 //Copying not allowed 427 } 428 429 430 BMemoryIO & 431 BMemoryIO::operator=(const BMemoryIO &) 432 { 433 //Copying not allowed 434 return *this; 435 } 436 437 438 // FBC 439 void BMemoryIO::_ReservedMemoryIO1(){} 440 void BMemoryIO::_ReservedMemoryIO2(){} 441 442 443 // #pragma mark - 444 445 446 BMallocIO::BMallocIO() 447 : 448 fBlockSize(256), 449 fMallocSize(0), 450 fLength(0), 451 fData(NULL), 452 fPosition(0) 453 { 454 } 455 456 457 BMallocIO::~BMallocIO() 458 { 459 free(fData); 460 } 461 462 463 ssize_t 464 BMallocIO::ReadAt(off_t pos, void* buffer, size_t size) 465 { 466 if (buffer == NULL) 467 return B_BAD_VALUE; 468 469 ssize_t sizeRead = 0; 470 if (pos < (off_t)fLength) { 471 sizeRead = min_c((off_t)size, (off_t)fLength - pos); 472 memcpy(buffer, fData + pos, sizeRead); 473 } 474 475 return sizeRead; 476 } 477 478 479 ssize_t 480 BMallocIO::WriteAt(off_t pos, const void* buffer, size_t size) 481 { 482 if (buffer == NULL) 483 return B_BAD_VALUE; 484 485 size_t newSize = max_c(pos + (off_t)size, (off_t)fLength); 486 status_t error = B_OK; 487 488 if (newSize > fMallocSize) 489 error = SetSize(newSize); 490 491 if (error == B_OK) { 492 memcpy(fData + pos, buffer, size); 493 if (pos + size > fLength) 494 fLength = pos + size; 495 } 496 497 return error != B_OK ? error : size; 498 } 499 500 501 off_t 502 BMallocIO::Seek(off_t position, uint32 seekMode) 503 { 504 switch (seekMode) { 505 case SEEK_SET: 506 fPosition = position; 507 break; 508 case SEEK_END: 509 fPosition = fLength + position; 510 break; 511 case SEEK_CUR: 512 fPosition += position; 513 break; 514 default: 515 break; 516 } 517 return fPosition; 518 } 519 520 521 off_t 522 BMallocIO::Position() const 523 { 524 return fPosition; 525 } 526 527 528 status_t 529 BMallocIO::SetSize(off_t size) 530 { 531 status_t error = B_OK; 532 if (size == 0) { 533 // size == 0, free the memory 534 free(fData); 535 fData = NULL; 536 fMallocSize = 0; 537 } else { 538 // size != 0, see, if necessary to resize 539 size_t newSize = (size + fBlockSize - 1) / fBlockSize * fBlockSize; 540 if (size != (off_t)fMallocSize) { 541 // we need to resize 542 if (char* newData = static_cast<char*>(realloc(fData, newSize))) { 543 // set the new area to 0 544 if (newSize > fMallocSize) 545 memset(newData + fMallocSize, 0, newSize - fMallocSize); 546 fData = newData; 547 fMallocSize = newSize; 548 } else // couldn't alloc the memory 549 error = B_NO_MEMORY; 550 } 551 } 552 553 if (error == B_OK) 554 fLength = size; 555 556 return error; 557 } 558 559 560 void 561 BMallocIO::SetBlockSize(size_t blockSize) 562 { 563 if (blockSize == 0) 564 blockSize = 1; 565 566 if (blockSize != fBlockSize) 567 fBlockSize = blockSize; 568 } 569 570 571 const void* 572 BMallocIO::Buffer() const 573 { 574 return fData; 575 } 576 577 578 size_t 579 BMallocIO::BufferLength() const 580 { 581 return fLength; 582 } 583 584 585 // Private or Reserved 586 587 BMallocIO::BMallocIO(const BMallocIO &) 588 { 589 // copying not allowed... 590 } 591 592 593 BMallocIO & 594 BMallocIO::operator=(const BMallocIO &) 595 { 596 // copying not allowed... 597 return *this; 598 } 599 600 601 // FBC 602 void BMallocIO::_ReservedMallocIO1() {} 603 void BMallocIO::_ReservedMallocIO2() {} 604