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::SetSize(off_t size) 204 { 205 return B_ERROR; 206 } 207 208 209 status_t 210 BPositionIO::GetSize(off_t* size) const 211 { 212 if (!size) 213 return B_BAD_VALUE; 214 215 off_t currentPos = Position(); 216 if (currentPos < 0) 217 return (status_t)currentPos; 218 219 *size = const_cast<BPositionIO*>(this)->Seek(0, SEEK_END); 220 if (*size < 0) 221 return (status_t)*size; 222 223 off_t pos = const_cast<BPositionIO*>(this)->Seek(currentPos, SEEK_SET); 224 225 if (pos != currentPos) 226 return pos < 0 ? (status_t)pos : B_ERROR; 227 228 return B_OK; 229 } 230 231 232 // FBC 233 extern "C" void _ReservedPositionIO1__11BPositionIO() {} 234 void BPositionIO::_ReservedPositionIO2(){} 235 void BPositionIO::_ReservedPositionIO3(){} 236 void BPositionIO::_ReservedPositionIO4(){} 237 void BPositionIO::_ReservedPositionIO5(){} 238 void BPositionIO::_ReservedPositionIO6(){} 239 void BPositionIO::_ReservedPositionIO7(){} 240 void BPositionIO::_ReservedPositionIO8(){} 241 void BPositionIO::_ReservedPositionIO9(){} 242 void BPositionIO::_ReservedPositionIO10(){} 243 void BPositionIO::_ReservedPositionIO11(){} 244 void BPositionIO::_ReservedPositionIO12(){} 245 246 247 // #pragma mark - 248 249 250 BMemoryIO::BMemoryIO(void* buffer, size_t length) 251 : 252 fReadOnly(false), 253 fBuffer(static_cast<char*>(buffer)), 254 fLength(length), 255 fBufferSize(length), 256 fPosition(0) 257 { 258 } 259 260 261 BMemoryIO::BMemoryIO(const void* buffer, size_t length) 262 : 263 fReadOnly(true), 264 fBuffer(const_cast<char*>(static_cast<const char*>(buffer))), 265 fLength(length), 266 fBufferSize(length), 267 fPosition(0) 268 { 269 } 270 271 272 BMemoryIO::~BMemoryIO() 273 { 274 } 275 276 277 ssize_t 278 BMemoryIO::ReadAt(off_t pos, void* buffer, size_t size) 279 { 280 if (buffer == NULL || pos < 0) 281 return B_BAD_VALUE; 282 283 ssize_t sizeRead = 0; 284 if (pos < (off_t)fLength) { 285 sizeRead = min_c((off_t)size, (off_t)fLength - pos); 286 memcpy(buffer, fBuffer + pos, sizeRead); 287 } 288 289 return sizeRead; 290 } 291 292 293 ssize_t 294 BMemoryIO::WriteAt(off_t pos, const void* buffer, size_t size) 295 { 296 if (fReadOnly) 297 return B_NOT_ALLOWED; 298 299 if (buffer == NULL || pos < 0) 300 return B_BAD_VALUE; 301 302 ssize_t sizeWritten = 0; 303 if (pos < (off_t)fBufferSize) { 304 sizeWritten = min_c((off_t)size, (off_t)fBufferSize - pos); 305 memcpy(fBuffer + pos, buffer, sizeWritten); 306 } 307 308 if (pos + sizeWritten > (off_t)fLength) 309 fLength = pos + sizeWritten; 310 311 return sizeWritten; 312 } 313 314 315 off_t 316 BMemoryIO::Seek(off_t position, uint32 seek_mode) 317 { 318 switch (seek_mode) { 319 case SEEK_SET: 320 fPosition = position; 321 break; 322 case SEEK_CUR: 323 fPosition += position; 324 break; 325 case SEEK_END: 326 fPosition = fLength + position; 327 break; 328 default: 329 break; 330 } 331 332 return fPosition; 333 } 334 335 336 off_t 337 BMemoryIO::Position() const 338 { 339 return fPosition; 340 } 341 342 343 status_t 344 BMemoryIO::SetSize(off_t size) 345 { 346 if (fReadOnly) 347 return B_NOT_ALLOWED; 348 349 if (size > (off_t)fBufferSize) 350 return B_ERROR; 351 352 fLength = size; 353 354 return B_OK; 355 } 356 357 358 // Private or Reserved 359 360 BMemoryIO::BMemoryIO(const BMemoryIO &) 361 { 362 //Copying not allowed 363 } 364 365 366 BMemoryIO & 367 BMemoryIO::operator=(const BMemoryIO &) 368 { 369 //Copying not allowed 370 return *this; 371 } 372 373 374 // FBC 375 void BMemoryIO::_ReservedMemoryIO1(){} 376 void BMemoryIO::_ReservedMemoryIO2(){} 377 378 379 // #pragma mark - 380 381 382 BMallocIO::BMallocIO() 383 : 384 fBlockSize(256), 385 fMallocSize(0), 386 fLength(0), 387 fData(NULL), 388 fPosition(0) 389 { 390 } 391 392 393 BMallocIO::~BMallocIO() 394 { 395 free(fData); 396 } 397 398 399 ssize_t 400 BMallocIO::ReadAt(off_t pos, void* buffer, size_t size) 401 { 402 if (buffer == NULL) 403 return B_BAD_VALUE; 404 405 ssize_t sizeRead = 0; 406 if (pos < (off_t)fLength) { 407 sizeRead = min_c((off_t)size, (off_t)fLength - pos); 408 memcpy(buffer, fData + pos, sizeRead); 409 } 410 411 return sizeRead; 412 } 413 414 415 ssize_t 416 BMallocIO::WriteAt(off_t pos, const void* buffer, size_t size) 417 { 418 if (buffer == NULL) 419 return B_BAD_VALUE; 420 421 size_t newSize = max_c(pos + (off_t)size, (off_t)fLength); 422 status_t error = B_OK; 423 424 if (newSize > fMallocSize) 425 error = SetSize(newSize); 426 427 if (error == B_OK) { 428 memcpy(fData + pos, buffer, size); 429 if (pos + size > fLength) 430 fLength = pos + size; 431 } 432 433 return error != B_OK ? error : size; 434 } 435 436 437 off_t 438 BMallocIO::Seek(off_t position, uint32 seekMode) 439 { 440 switch (seekMode) { 441 case SEEK_SET: 442 fPosition = position; 443 break; 444 case SEEK_END: 445 fPosition = fLength + position; 446 break; 447 case SEEK_CUR: 448 fPosition += position; 449 break; 450 default: 451 break; 452 } 453 return fPosition; 454 } 455 456 457 off_t 458 BMallocIO::Position() const 459 { 460 return fPosition; 461 } 462 463 464 status_t 465 BMallocIO::SetSize(off_t size) 466 { 467 status_t error = B_OK; 468 if (size == 0) { 469 // size == 0, free the memory 470 free(fData); 471 fData = NULL; 472 fMallocSize = 0; 473 } else { 474 // size != 0, see, if necessary to resize 475 size_t newSize = (size + fBlockSize - 1) / fBlockSize * fBlockSize; 476 if (size != (off_t)fMallocSize) { 477 // we need to resize 478 if (char* newData = static_cast<char*>(realloc(fData, newSize))) { 479 // set the new area to 0 480 if (newSize > fMallocSize) 481 memset(newData + fMallocSize, 0, newSize - fMallocSize); 482 fData = newData; 483 fMallocSize = newSize; 484 } else // couldn't alloc the memory 485 error = B_NO_MEMORY; 486 } 487 } 488 489 if (error == B_OK) 490 fLength = size; 491 492 return error; 493 } 494 495 496 void 497 BMallocIO::SetBlockSize(size_t blockSize) 498 { 499 if (blockSize == 0) 500 blockSize = 1; 501 502 if (blockSize != fBlockSize) 503 fBlockSize = blockSize; 504 } 505 506 507 const void* 508 BMallocIO::Buffer() const 509 { 510 return fData; 511 } 512 513 514 size_t 515 BMallocIO::BufferLength() const 516 { 517 return fLength; 518 } 519 520 521 // Private or Reserved 522 523 BMallocIO::BMallocIO(const BMallocIO &) 524 { 525 // copying not allowed... 526 } 527 528 529 BMallocIO & 530 BMallocIO::operator=(const BMallocIO &) 531 { 532 // copying not allowed... 533 return *this; 534 } 535 536 537 // FBC 538 void BMallocIO::_ReservedMallocIO1() {} 539 void BMallocIO::_ReservedMallocIO2() {} 540 541