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