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