diff --git a/file.cc b/file.cc index aa4a51f5..fd68d6df 100644 --- a/file.cc +++ b/file.cc @@ -18,6 +18,7 @@ #endif #include "ufile.hh" +#include "fsencoding.hh" namespace File { @@ -69,9 +70,31 @@ bool exists( char const * filename ) throw() void Class::open( char const * filename, char const * mode ) throw( exCantOpen ) { - f = gd_fopen( filename, mode ); + QFile::OpenMode openMode = QIODevice::Text; + const char * pch = mode; + while( *pch ) + { + switch( *pch ) + { + case 'r': openMode |= QIODevice::ReadOnly; + break; + case 'w': openMode |= QIODevice::WriteOnly; + break; + case '+': openMode &= ~( QIODevice::ReadOnly | QIODevice::WriteOnly ); + openMode |= QIODevice::ReadWrite; + break; + case 'a': openMode |= QIODevice::Append; + break; + case 'b': openMode &= ~QIODevice::Text; + break; + default: break; + } + ++pch; + } - if ( !f ) + f.setFileName( FsEncoding::decode( filename ) ); + + if ( !f.open( openMode ) ) throw exCantOpen( std::string( filename ) + ": " + strerror( errno ) ); } @@ -87,7 +110,7 @@ Class::Class( std::string const & filename, char const * mode ) open( filename.c_str(), mode ); } -void Class::read( void * buf, size_t size ) throw( exReadError, exWriteError ) +void Class::read( void * buf, qint64 size ) throw( exReadError, exWriteError ) { if ( !size ) return; @@ -95,21 +118,22 @@ void Class::read( void * buf, size_t size ) throw( exReadError, exWriteError ) if ( writeBuffer ) flushWriteBuffer(); - size_t result = fread( buf, size, 1, f ); + qint64 result = f.read( reinterpret_cast( buf ), size ); - if ( result != 1 ) + if ( result != size ) throw exReadError(); } -size_t Class::readRecords( void * buf, size_t size, size_t count ) throw( exWriteError ) +size_t Class::readRecords( void * buf, qint64 size, size_t count ) throw( exWriteError ) { if ( writeBuffer ) flushWriteBuffer(); - return fread( buf, size, count, f ); + qint64 result = f.read( reinterpret_cast( buf ), size * count ); + return result < 0 ? result : result / size; } -void Class::write( void const * buf, size_t size ) throw( exWriteError ) +void Class::write( void const * buf, qint64 size ) throw( exWriteError ) { if ( !size ) return; @@ -119,9 +143,9 @@ void Class::write( void const * buf, size_t size ) throw( exWriteError ) // If the write is large, there's not much point in buffering flushWriteBuffer(); - size_t result = fwrite( buf, size, 1, f ); + size_t result = f.write( reinterpret_cast( buf ), size ); - if ( result != 1 ) + if ( result != size ) throw exWriteError(); return; @@ -154,12 +178,13 @@ void Class::write( void const * buf, size_t size ) throw( exWriteError ) } } -size_t Class::writeRecords( void const * buf, size_t size, size_t count ) +size_t Class::writeRecords( void const * buf, qint64 size, size_t count ) throw( exWriteError ) { flushWriteBuffer(); - return fwrite( buf, size, count, f ); + qint64 result = f.write( reinterpret_cast( buf ), size * count ); + return result < 0 ? result : result / size; } char * Class::gets( char * s, int size, bool stripNl ) @@ -168,11 +193,11 @@ char * Class::gets( char * s, int size, bool stripNl ) if ( writeBuffer ) flushWriteBuffer(); - char * result = fgets( s, size, f ); + qint64 len = f.readLine( s, size ); + char * result = len > 0 ? s : NULL; if ( result && stripNl ) { - size_t len = strlen( result ); char * last = result + len; @@ -205,7 +230,7 @@ void Class::seek( long offset ) throw( exSeekError, exWriteError ) if ( writeBuffer ) flushWriteBuffer(); - if ( fseek( f, offset, SEEK_SET ) != 0 ) + if ( !f.seek( offset ) ) throw exSeekError(); } @@ -214,7 +239,7 @@ void Class::seekCur( long offset ) throw( exSeekError, exWriteError ) if ( writeBuffer ) flushWriteBuffer(); - if ( fseek( f, offset, SEEK_CUR ) != 0 ) + if( !f.seek( f.pos() + offset ) ) throw exSeekError(); } @@ -223,7 +248,7 @@ void Class::seekEnd( long offset ) throw( exSeekError, exWriteError ) if ( writeBuffer ) flushWriteBuffer(); - if ( fseek( f, offset, SEEK_END ) != 0 ) + if( !f.seek( f.size() + offset ) ) throw exSeekError(); } @@ -234,7 +259,7 @@ void Class::rewind() throw( exSeekError, exWriteError ) size_t Class::tell() throw( exSeekError ) { - long result = ftell( f ); + qint64 result = f.pos(); if ( result == -1 ) throw exSeekError(); @@ -250,35 +275,25 @@ bool Class::eof() throw( exWriteError ) if ( writeBuffer ) flushWriteBuffer(); - return feof( f ) != 0; + return f.atEnd(); } -FILE * Class::file() throw( exWriteError ) +QFile & Class::file() throw( exWriteError ) { flushWriteBuffer(); return f; } -FILE * Class::release() throw( exWriteError ) -{ - releaseWriteBuffer(); - - FILE * c = f; - - f = 0; - - return c; -} - void Class::close() throw( exWriteError ) { - fclose( release() ); + releaseWriteBuffer(); + f.close(); } Class::~Class() throw() { - if ( f ) + if ( f.isOpen() ) { try { @@ -287,7 +302,7 @@ Class::~Class() throw() catch( exWriteError & ) { } - fclose( f ); + f.close(); } } @@ -295,9 +310,9 @@ void Class::flushWriteBuffer() throw( exWriteError ) { if ( writeBuffer && writeBufferLeft != WriteBufferSize ) { - size_t result = fwrite( writeBuffer, WriteBufferSize - writeBufferLeft, 1, f ); + size_t result = f.write( writeBuffer, WriteBufferSize - writeBufferLeft ); - if ( result != 1 ) + if ( result != WriteBufferSize - writeBufferLeft ) throw exWriteError(); writeBufferLeft = WriteBufferSize; diff --git a/file.hh b/file.hh index 97d5514a..adb407cd 100644 --- a/file.hh +++ b/file.hh @@ -7,6 +7,7 @@ #include #include #include +#include #include "ex.hh" /// A simple wrapper over FILE * operations with added write-buffering, @@ -33,7 +34,7 @@ inline bool exists( std::string const & filename ) throw() class Class { - FILE * f; + QFile f; char * writeBuffer; size_t writeBufferLeft; @@ -47,7 +48,7 @@ public: /// Reads the number of bytes to the buffer, throws an error if it /// failed to fill the whole buffer (short read, i/o error etc). - void read( void * buf, size_t size ) throw( exReadError, exWriteError ); + void read( void * buf, qint64 size ) throw( exReadError, exWriteError ); template< typename T > void read( T & value ) throw( exReadError, exWriteError ) @@ -59,7 +60,7 @@ public: /// Attempts reading at most 'count' records sized 'size'. Returns /// the number of records it managed to read, up to 'count'. - size_t readRecords( void * buf, size_t size, size_t count ) throw( exWriteError ); + size_t readRecords( void * buf, qint64 size, size_t count ) throw( exWriteError ); /// Writes the number of bytes from the buffer, throws an error if it /// failed to write the whole buffer (short write, i/o error etc). @@ -67,7 +68,7 @@ public: /// end up on disk immediately, or a short write may occur later /// than it really did. If you don't want write buffering, use /// writeRecords() function instead. - void write( void const * buf, size_t size ) throw( exWriteError ); + void write( void const * buf, qint64 size ) throw( exWriteError ); template< typename T > void write( T const & value ) throw( exWriteError ) @@ -77,7 +78,7 @@ public: /// the number of records it managed to write, up to 'count'. /// This function does not employ buffering, but flushes the buffer if it /// was used before. - size_t writeRecords( void const * buf, size_t size, size_t count ) + size_t writeRecords( void const * buf, qint64 size, size_t count ) throw( exWriteError ); /// Reads a string from the file. Unlike the normal fgets(), this one @@ -107,11 +108,7 @@ public: /// Returns the underlying FILE * record, so other operations can be /// performed on it. - FILE * file() throw( exWriteError ); - - /// Releases the file handle out of the control of the class. No further - /// operations are valid. The file will not be closed on destruction. - FILE * release() throw( exWriteError ); + QFile & file() throw( exWriteError ); /// Closes the file. No further operations are valid. void close() throw( exWriteError ); diff --git a/lsa.cc b/lsa.cc index f4e8a0af..78d0f662 100644 --- a/lsa.cc +++ b/lsa.cc @@ -24,6 +24,7 @@ #include #include #include +#include namespace Lsa { @@ -316,10 +317,10 @@ sptr< Dictionary::DataRequest > LsaDictionary::getArticle( wstring const & word, /// This wraps around file operations struct ShiftedVorbis { - FILE * f; + QFile & f; size_t shift; - ShiftedVorbis( FILE * f_, size_t shift_ ): f( f_ ), shift( shift_ ) + ShiftedVorbis( QFile & f_, size_t shift_ ): f( f_ ), shift( shift_ ) {} static size_t read( void * ptr, size_t size, size_t nmemb, void * datasource ); @@ -334,7 +335,7 @@ size_t ShiftedVorbis::read( void * ptr, size_t size, size_t nmemb, { ShiftedVorbis * sv = ( ShiftedVorbis * ) datasource; - return fread( ptr, size, nmemb, sv->f ); + return sv->f.read( reinterpret_cast( ptr ), size * nmemb ); } int ShiftedVorbis::seek( void * datasource, ogg_int64_t offset, int whence ) @@ -344,13 +345,19 @@ int ShiftedVorbis::seek( void * datasource, ogg_int64_t offset, int whence ) if ( whence == SEEK_SET ) offset += sv->shift; - return fseek( sv->f, offset, whence ); + if( whence == SEEK_CUR ) + offset += sv->f.pos(); + + if( whence == SEEK_END ) + offset += sv->f.size(); + + return sv->f.seek( offset ); } long ShiftedVorbis::tell( void * datasource ) { ShiftedVorbis * sv = ( ShiftedVorbis * ) datasource; - long result = ftell( sv->f ); + long result = sv->f.pos(); if ( result != -1 ) result -= sv->shift;