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