29 #if defined( _MSC_VER )
32 #elif defined( __GNUC__ )
33 #define _LARGEFILE64_SOURCE
34 #define __LARGE64_FILES
36 #include <sys/types.h>
39 #error "no supported compiler defined"
41 #elif defined( __linux__ )
42 #define _LARGEFILE64_SOURCE
43 #define __LARGE64_FILES
45 #include <sys/types.h>
47 #elif defined( __APPLE__ )
48 #include <sys/types.h>
51 #error "no supported OS platform defined"
64 #ifdef E57_CHECK_FILE_DEBUG
69 #define O_BINARY ( 0 )
111 cursorStream_ = streamSize_ -
offset;
114 if ( cursorStream_ > streamSize_ )
116 cursorStream_ = streamSize_;
125 const uint64_t start = cursorStream_;
126 for ( uint64_t i = 0; i <
count; ++i )
128 buffer[i] = stream_[start + i];
134 const uint64_t streamSize_;
135 uint64_t cursorStream_ = 0;
140 fileName_( fileName ), checkSumPolicy_( policy )
145 fd_ = open64( fileName_, O_RDONLY |
O_BINARY, 0 );
149 physicalLength_ = lseek64( 0LL,
SEEK_END );
157 fd_ = open64( fileName_, O_RDWR | O_CREAT | O_TRUNC |
O_BINARY, S_IWRITE | S_IREAD );
161 fd_ = open64( fileName_, O_RDWR |
O_BINARY, 0 );
169 fileName_(
"<StreamBuffer>" ), checkSumPolicy_( policy )
175 physicalLength_ = lseek64( 0LL,
SEEK_END );
181 int CheckedFile::open64(
const ustring &fileName,
int flags,
int mode )
183 #if defined( _MSC_VER )
185 std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
186 std::wstring widePath = converter.from_bytes(
fileName );
189 int err = _wsopen_s( &handle, widePath.c_str(), flags, _SH_DENYNO, mode );
196 #elif defined( __GNUC__ )
197 int result = open( fileName_.c_str(), flags, mode );
205 #error "no supported compiler defined"
230 if ( end > logicalLength )
233 " length=" +
toString( logicalLength ) );
237 size_t pageOffset = 0;
239 getCurrentPageAndOffset( page, pageOffset );
245 char *page_buffer = &page_buffer_v[0];
247 auto checksumMod =
static_cast<const unsigned int>( std::nearbyint( 100.0 / checkSumPolicy_ ) );
251 readPhysicalPage( page_buffer, page );
253 switch ( checkSumPolicy_ )
259 verifyChecksum( page_buffer, page );
265 verifyChecksum( page_buffer, page );
270 memcpy( buf, page_buffer + pageOffset, n );
286 #ifdef E57_MAX_VERBOSE
298 size_t pageOffset = 0;
300 getCurrentPageAndOffset( page, pageOffset );
306 char *page_buffer = &page_buffer_v[0];
314 readPhysicalPage( page_buffer, page );
317 #ifdef E57_MAX_VERBOSE
323 memcpy( page_buffer + pageOffset, buf, n );
324 writePhysicalPage( page_buffer, page );
325 #ifdef E57_MAX_VERBOSE
336 if ( end > logicalLength_ )
338 logicalLength_ = end;
347 write( s.c_str(), s.length() );
353 std::stringstream ss;
355 return ( *
this << ss.str() );
360 std::stringstream ss;
362 return ( *
this << ss.str() );
368 return writeFloatingPoint( f, 7 );
374 return writeFloatingPoint( d, 17 );
377 template <
class FTYPE>
CheckedFile &CheckedFile::writeFloatingPoint( FTYPE value,
int precision )
379 #ifdef E57_MAX_VERBOSE
380 std::cout <<
"CheckedFile::writeFloatingPoint, value=" << value <<
" precision=" << precision <<
std::endl;
383 std::stringstream ss;
384 ss << std::scientific << std::setprecision( precision ) << value;
391 const size_t len = s.length();
399 ustring mantissa = s.substr( 0, len - 5 );
400 ustring exponent = s.substr( len - 5, 5 );
403 if ( exponent[0] ==
'e' )
406 while ( mantissa[mantissa.length() - 1] ==
'0' )
408 mantissa = mantissa.substr( 0, mantissa.length() - 1 );
412 if ( mantissa[mantissa.length() - 1] ==
'.' )
414 mantissa = mantissa.substr( 0, mantissa.length() - 1 );
419 if ( exponent ==
"e+000" )
425 s = mantissa + exponent;
433 FTYPE old_value = static_cast<FTYPE>(atof(old_s.c_str()));
434 FTYPE new_value =
static_cast<FTYPE
>(atof(s.c_str()));
435 if (old_value != new_value)
437 if (new_value != value)
441 return ( *
this << s );
449 #ifdef E57_MAX_VERBOSE
456 uint64_t CheckedFile::lseek64( int64_t
offset,
int whence )
458 if ( ( fd_ < 0 ) && ( bufView_ !=
nullptr ) )
460 const auto uoffset =
static_cast<uint64_t
>(
offset );
462 if ( bufView_->
seek( uoffset, whence ) )
464 return bufView_->
pos();
471 #if defined( _WIN32 )
472 #if defined( _MSC_VER ) || defined( __MINGW32__ )
474 #elif defined( __GNUC__ )
477 if (
sizeof( off_t ) !=
sizeof(
offset ) )
482 #error "no supported compiler defined"
484 #elif defined( __linux__ )
486 #elif defined( __APPLE__ )
489 #error "no supported OS platform defined"
499 return static_cast<uint64_t
>(
result );
505 const uint64_t pos = lseek64( 0LL,
SEEK_CUR );
521 return physicalLength_;
525 uint64_t original_pos = lseek64( 0LL,
SEEK_CUR );
528 uint64_t end_pos = lseek64( 0LL,
SEEK_END );
536 return logicalLength_;
541 #ifdef E57_MAX_VERBOSE
550 uint64_t newLogicalLength = 0;
558 newLogicalLength = newLength;
564 if ( newLogicalLength < currentLogicalLength )
567 " currentLength=" +
toString( currentLogicalLength ) );
571 uint64_t nWrite = newLogicalLength - currentLogicalLength;
577 size_t pageOffset = 0;
579 getCurrentPageAndOffset( page, pageOffset );
587 n =
static_cast<size_t>( nWrite );
596 char *page_buffer = &page_buffer_v[0];
604 readPhysicalPage( page_buffer, page );
607 #ifdef E57_MAX_VERBOSE
612 memset( page_buffer + pageOffset, 0, n );
613 writePhysicalPage( page_buffer, page );
621 n =
static_cast<size_t>( nWrite );
630 logicalLength_ = newLogicalLength;
640 #if defined( _MSC_VER )
641 int result = ::_close( fd_ );
642 #elif defined( __GNUC__ )
645 #error "no supported compiler defined"
655 if ( bufView_ !=
nullptr )
670 int result = std::remove( fileName_.c_str() );
672 #ifdef E57_MAX_VERBOSE
682 val = ( ( val << 8 ) & 0xFF00FF00 ) | ( ( val >> 8 ) & 0xFF00FF );
684 return ( val << 16 ) | ( val >> 16 );
688 uint32_t CheckedFile::checksum(
char *buf,
size_t size )
const
694 auto crc = CRC::Calculate<crcpp_uint32, 32>( buf,
size, sCRCTable );
702 void CheckedFile::verifyChecksum(
char *page_buffer,
size_t page )
705 const uint32_t check_sum_in_page = *
reinterpret_cast<uint32_t *
>( &page_buffer[
logicalPageSize] );
707 if ( check_sum_in_page != check_sum )
712 "fileName=" + fileName_ +
" computedChecksum=" +
toString( check_sum ) +
713 " storedChecksum=" +
toString( check_sum_in_page ) +
" page=" +
toString( page ) +
714 " length=" +
toString( physicalLength ) );
718 void CheckedFile::getCurrentPageAndOffset( uint64_t &page,
size_t &pageOffset, OffsetMode omode )
720 const uint64_t pos =
position( omode );
734 void CheckedFile::readPhysicalPage(
char *page_buffer, uint64_t page )
736 #ifdef E57_MAX_VERBOSE
740 #ifdef E57_CHECK_FILE_DEBUG
749 if ( ( fd_ < 0 ) && ( bufView_ !=
nullptr ) )
755 #if defined( _MSC_VER )
757 #elif defined( __GNUC__ )
760 #error "no supported compiler defined"
769 void CheckedFile::writePhysicalPage(
char *page_buffer, uint64_t page )
771 #ifdef E57_MAX_VERBOSE
777 *
reinterpret_cast<uint32_t *
>( &page_buffer[
logicalPageSize] ) = check_sum;
782 #if defined( _MSC_VER )
784 #elif defined( __GNUC__ )
787 #error "no supported compiler defined"
uint32_t swap_uint32(uint32_t val)
void read(char *buffer, uint64_t count)
bool seek(uint64_t offset, int whence)
BufferView(const char *input, uint64_t size)
void write(const char *buf, size_t nWrite)
static constexpr uint64_t physicalPageSizeMask
CheckedFile & operator<<(const e57::ustring &s)
static constexpr size_t physicalPageSize
void read(char *buf, size_t nRead, size_t bufSize=0)
void extend(uint64_t newLength, OffsetMode omode=Logical)
uint64_t position(OffsetMode omode=Logical)
static uint64_t logicalToPhysical(uint64_t logicalOffset)
static uint64_t physicalToLogical(uint64_t physicalOffset)
CheckedFile(const e57::ustring &fileName, Mode mode, ReadChecksumPolicy policy)
static constexpr size_t physicalPageSizeLog2
e57::ustring fileName() const
static constexpr size_t logicalPageSize
uint64_t length(OffsetMode omode=Logical)
void seek(uint64_t offset, OffsetMode omode=Logical)
QTextStream & endl(QTextStream &stream)
constexpr ReadChecksumPolicy CHECKSUM_POLICY_ALL
Only verify 50% of the checksums. The last block is always verified.
int ReadChecksumPolicy
Specifies the percentage of checksums which are verified when reading an ImageFile (0-100%).
@ E57_ERROR_FILE_IS_READ_ONLY
can't modify read only file
@ E57_ERROR_READ_FAILED
read() failed
@ E57_ERROR_INTERNAL
An unrecoverable inconsistent internal state was detected.
@ E57_ERROR_OPEN_FAILED
open() failed
@ E57_ERROR_WRITE_FAILED
write() failed
@ E57_ERROR_BAD_CHECKSUM
checksum mismatch, file is corrupted
@ E57_ERROR_CLOSE_FAILED
close() failed
@ E57_ERROR_LSEEK_FAILED
lseek() failed
std::string ustring
UTF-8 encodeded Unicode string.
std::string toString(T x)
constexpr ReadChecksumPolicy CHECKSUM_POLICY_NONE
CRC lookup table. After construction, the CRC parameters are fixed.