| 307 | } |
| 308 | |
| 309 | void CheckedFile::read( char *buf, size_t nRead, size_t /*bufSize*/ ) |
| 310 | { |
| 311 | //??? what if read past logical end?, or physical end? |
| 312 | //??? need to keep track of logical length? |
| 313 | //??? check bufSize OK |
| 314 | |
| 315 | const uint64_t end = position( Logical ) + nRead; |
| 316 | const uint64_t logicalLength = length( Logical ); |
| 317 | |
| 318 | if ( end > logicalLength ) |
| 319 | { |
| 320 | throw E57_EXCEPTION2( ErrorInternal, "fileName=" + fileName_ + " end=" + toString( end ) + |
| 321 | " length=" + toString( logicalLength ) ); |
| 322 | } |
| 323 | |
| 324 | uint64_t page = 0; |
| 325 | size_t pageOffset = 0; |
| 326 | |
| 327 | getCurrentPageAndOffset( page, pageOffset ); |
| 328 | |
| 329 | size_t n = std::min( nRead, logicalPageSize - pageOffset ); |
| 330 | |
| 331 | // Allocate temp page buffer |
| 332 | std::vector<char> page_buffer_v( physicalPageSize ); |
| 333 | char *page_buffer = page_buffer_v.data(); |
| 334 | |
| 335 | while ( nRead > 0 ) |
| 336 | { |
| 337 | readPhysicalPage( page_buffer, page ); |
| 338 | |
| 339 | switch ( checkSumPolicy_ ) |
| 340 | { |
| 341 | case ChecksumPolicy::ChecksumNone: |
| 342 | break; |
| 343 | |
| 344 | case ChecksumPolicy::ChecksumAll: |
| 345 | verifyChecksum( page_buffer, page ); |
| 346 | break; |
| 347 | |
| 348 | default: |
| 349 | { |
| 350 | const auto checksumMod = |
| 351 | static_cast<unsigned int>( std::nearbyint( 100.0 / checkSumPolicy_ ) ); |
| 352 | |
| 353 | if ( !( page % checksumMod ) || ( nRead < physicalPageSize ) ) |
| 354 | { |
| 355 | verifyChecksum( page_buffer, page ); |
| 356 | } |
| 357 | } |
| 358 | break; |
| 359 | } |
| 360 | |
| 361 | memcpy( buf, page_buffer + pageOffset, n ); |
| 362 | |
| 363 | buf += n; |
| 364 | nRead -= n; |
| 365 | pageOffset = 0; |
| 366 | ++page; |
no test coverage detected