1 //------------------------------------------------------------------------------ 2 // Copyright (c) 2001-2005, Haiku, Inc. 3 // 4 // Permission is hereby granted, free of charge, to any person obtaining a 5 // copy of this software and associated documentation files (the "Software"), 6 // to deal in the Software without restriction, including without limitation 7 // the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 // and/or sell copies of the Software, and to permit persons to whom the 9 // Software is furnished to do so, subject to the following conditions: 10 // 11 // The above copyright notice and this permission notice shall be included in 12 // all copies or substantial portions of the Software. 13 // 14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 // DEALINGS IN THE SOFTWARE. 21 // 22 // File Name: DataIO.cpp 23 // Author(s): Stefano Ceccherini (burton666@libero.it) 24 // The Storage Team 25 // Description: Pure virtual BDataIO and BPositioIO classes provide 26 // the protocol for Read()/Write()/Seek(). 27 // 28 // BMallocIO and BMemoryIO classes implement the protocol, 29 // as does BFile in the Storage Kit. 30 //------------------------------------------------------------------------------ 31 #include <algorithm> 32 #include <stdio.h> 33 #include <string.h> 34 #include <stdlib.h> 35 36 #include <DataIO.h> 37 38 39 // *** BDataIO *** 40 41 // Construction 42 BDataIO::BDataIO() 43 { 44 } 45 46 47 // Destruction 48 BDataIO::~BDataIO() 49 { 50 } 51 52 53 // Private or Reserved 54 BDataIO::BDataIO(const BDataIO &) 55 { 56 //Copying not allowed 57 } 58 59 60 BDataIO & 61 BDataIO::operator=(const BDataIO &) 62 { 63 //Copying not allowed 64 return *this; 65 } 66 67 68 // FBC 69 void BDataIO::_ReservedDataIO1(){} 70 void BDataIO::_ReservedDataIO2(){} 71 void BDataIO::_ReservedDataIO3(){} 72 void BDataIO::_ReservedDataIO4(){} 73 74 #if !_PR3_COMPATIBLE_ 75 void BDataIO::_ReservedDataIO5(){} 76 void BDataIO::_ReservedDataIO6(){} 77 void BDataIO::_ReservedDataIO7(){} 78 void BDataIO::_ReservedDataIO8(){} 79 void BDataIO::_ReservedDataIO9(){} 80 void BDataIO::_ReservedDataIO10(){} 81 void BDataIO::_ReservedDataIO11(){} 82 void BDataIO::_ReservedDataIO12(){} 83 #endif 84 85 86 // *** BPositionIO *** 87 88 // Construction 89 BPositionIO::BPositionIO() 90 { 91 } 92 93 94 // Destruction 95 BPositionIO::~BPositionIO() 96 { 97 } 98 99 100 // Read 101 ssize_t 102 BPositionIO::Read(void *buffer, size_t size) 103 { 104 off_t curPos = Position(); 105 ssize_t result = ReadAt(curPos, buffer, size); 106 if (result > 0) 107 Seek(result, SEEK_CUR); 108 109 return result; 110 } 111 112 113 // Write 114 ssize_t 115 BPositionIO::Write(const void *buffer, size_t size) 116 { 117 off_t curPos = Position(); 118 ssize_t result = WriteAt(curPos, buffer, size); 119 if (result > 0) 120 Seek(result, SEEK_CUR); 121 122 return result; 123 } 124 125 126 // SetSize 127 status_t 128 BPositionIO::SetSize(off_t size) 129 { 130 return B_ERROR; 131 } 132 133 134 // FBC 135 void BPositionIO::_ReservedPositionIO1(){} 136 void BPositionIO::_ReservedPositionIO2(){} 137 void BPositionIO::_ReservedPositionIO3(){} 138 void BPositionIO::_ReservedPositionIO4(){} 139 140 #if !_PR3_COMPATIBLE_ 141 void BPositionIO::_ReservedPositionIO5(){} 142 void BPositionIO::_ReservedPositionIO6(){} 143 void BPositionIO::_ReservedPositionIO7(){} 144 void BPositionIO::_ReservedPositionIO8(){} 145 void BPositionIO::_ReservedPositionIO9(){} 146 void BPositionIO::_ReservedPositionIO10(){} 147 void BPositionIO::_ReservedPositionIO11(){} 148 void BPositionIO::_ReservedPositionIO12(){} 149 #endif 150 151 152 // *** BMemoryIO *** 153 154 // Construction 155 BMemoryIO::BMemoryIO(void *p, size_t len) 156 :fReadOnly(false), 157 fBuf(static_cast<char*>(p)), 158 fLen(len), 159 fPhys(len), 160 fPos(0) 161 162 { 163 } 164 165 166 BMemoryIO::BMemoryIO(const void *p, size_t len) 167 :fReadOnly(true), 168 fBuf(const_cast<char*>(static_cast<const char*>(p))), 169 fLen(len), 170 fPhys(len), 171 fPos(0) 172 { 173 } 174 175 176 // Destruction 177 BMemoryIO::~BMemoryIO() 178 { 179 } 180 181 182 // ReadAt 183 ssize_t 184 BMemoryIO::ReadAt(off_t pos, void *buffer, size_t size) 185 { 186 if (buffer == NULL || pos < 0) 187 return B_BAD_VALUE; 188 189 ssize_t sizeRead = 0; 190 if (pos < fLen) { 191 sizeRead = min_c(static_cast<off_t>(size), fLen - pos); 192 memcpy(buffer, fBuf + pos, sizeRead); 193 } 194 return sizeRead; 195 } 196 197 198 // WriteAt 199 ssize_t 200 BMemoryIO::WriteAt(off_t pos, const void *buffer, size_t size) 201 { 202 if (fReadOnly) 203 return B_NOT_ALLOWED; 204 205 if (buffer == NULL || pos < 0) 206 return B_BAD_VALUE; 207 208 ssize_t sizeWritten = 0; 209 if (pos < fPhys) { 210 sizeWritten = min_c(static_cast<off_t>(size), fPhys - pos); 211 memcpy(fBuf + pos, buffer, sizeWritten); 212 } 213 214 if (pos + sizeWritten > fLen) 215 fLen = pos + sizeWritten; 216 217 return sizeWritten; 218 } 219 220 221 // Seek 222 off_t 223 BMemoryIO::Seek(off_t position, uint32 seek_mode) 224 { 225 switch (seek_mode) { 226 case SEEK_SET: 227 fPos = position; 228 break; 229 case SEEK_CUR: 230 fPos += position; 231 break; 232 case SEEK_END: 233 fPos = fLen + position; 234 break; 235 default: 236 break; 237 } 238 return fPos; 239 } 240 241 242 // Position 243 off_t 244 BMemoryIO::Position() const 245 { 246 return fPos; 247 } 248 249 250 // SetSize 251 status_t 252 BMemoryIO::SetSize(off_t size) 253 { 254 status_t err = B_ERROR; 255 256 if (fReadOnly) 257 return B_NOT_ALLOWED; 258 259 if (size <= fPhys) { 260 err = B_OK; 261 fLen = size; 262 } 263 264 return err; 265 } 266 267 268 // Private or Reserved 269 BMemoryIO::BMemoryIO(const BMemoryIO &) 270 { 271 //Copying not allowed 272 } 273 274 275 BMemoryIO & 276 BMemoryIO::operator=(const BMemoryIO &) 277 { 278 //Copying not allowed 279 return *this; 280 } 281 282 283 // FBC 284 void BMemoryIO::_ReservedMemoryIO1(){} 285 void BMemoryIO::_ReservedMemoryIO2(){} 286 287 288 // *** BMallocIO *** 289 290 // Construction 291 BMallocIO::BMallocIO() 292 : fBlockSize(256), 293 fMallocSize(0), 294 fLength(0), 295 fData(NULL), 296 fPosition(0) 297 { 298 } 299 300 301 // Destruction 302 BMallocIO::~BMallocIO() 303 { 304 free(fData); 305 } 306 307 308 // ReadAt 309 ssize_t 310 BMallocIO::ReadAt(off_t pos, void *buffer, size_t size) 311 { 312 if (buffer == NULL) 313 return B_BAD_VALUE; 314 315 ssize_t sizeRead = 0; 316 if (pos < fLength) { 317 sizeRead = min_c(static_cast<off_t>(size), fLength - pos); 318 memcpy(buffer, fData + pos, sizeRead); 319 } 320 return sizeRead; 321 } 322 323 324 // WriteAt 325 ssize_t 326 BMallocIO::WriteAt(off_t pos, const void *buffer, size_t size) 327 { 328 if (buffer == NULL) 329 return B_BAD_VALUE; 330 331 size_t newSize = max_c(pos + size, static_cast<off_t>(fLength)); 332 333 status_t error = B_OK; 334 335 if (newSize > fMallocSize) 336 error = SetSize(newSize); 337 338 if (error == B_OK) { 339 memcpy(fData + pos, buffer, size); 340 if (pos + size > fLength) 341 fLength = pos + size; 342 } 343 return error != B_OK ? error : size; 344 } 345 346 347 // Seek 348 off_t 349 BMallocIO::Seek(off_t position, uint32 seekMode) 350 { 351 switch (seekMode) { 352 case SEEK_SET: 353 fPosition = position; 354 break; 355 case SEEK_END: 356 fPosition = fLength + position; 357 break; 358 case SEEK_CUR: 359 fPosition += position; 360 break; 361 default: 362 break; 363 } 364 return fPosition; 365 } 366 367 368 // Position 369 off_t 370 BMallocIO::Position() const 371 { 372 return fPosition; 373 } 374 375 376 // SetSize 377 status_t 378 BMallocIO::SetSize(off_t size) 379 { 380 status_t error = B_OK; 381 if (size == 0) { 382 // size == 0, free the memory 383 free(fData); 384 fData = NULL; 385 fMallocSize = 0; 386 } else { 387 // size != 0, see, if necessary to resize 388 size_t newSize = (size + fBlockSize - 1) / fBlockSize * fBlockSize; 389 if (size != fMallocSize) { 390 // we need to resize 391 if (char *newData = static_cast<char*>(realloc(fData, newSize))) { 392 // set the new area to 0 393 if (newSize > fMallocSize) 394 memset(newData + fMallocSize, 0, newSize - fMallocSize); 395 fData = newData; 396 fMallocSize = newSize; 397 } else // couldn't alloc the memory 398 error = B_NO_MEMORY; 399 } 400 } 401 402 if (error == B_OK) 403 fLength = size; 404 405 return error; 406 } 407 408 409 // SetBlockSize 410 void 411 BMallocIO::SetBlockSize(size_t blockSize) 412 { 413 if (blockSize == 0) 414 blockSize = 1; 415 if (blockSize != fBlockSize) 416 fBlockSize = blockSize; 417 } 418 419 420 // Buffer 421 const void * 422 BMallocIO::Buffer() const 423 { 424 return fData; 425 } 426 427 428 // BufferLength 429 size_t 430 BMallocIO::BufferLength() const 431 { 432 return fLength; 433 } 434 435 436 // Private or Reserved 437 BMallocIO::BMallocIO(const BMallocIO &) 438 { 439 // copying not allowed... 440 } 441 442 443 BMallocIO & 444 BMallocIO::operator=(const BMallocIO &) 445 { 446 // copying not allowed... 447 return *this; 448 } 449 450 451 // FBC 452 void BMallocIO::_ReservedMallocIO1() {} 453 void BMallocIO::_ReservedMallocIO2() {} 454 455 456 /* 457 * $Log $ 458 * 459 * $Id $ 460 * 461 */ 462