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