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