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