2012-02-20 21:47:14 +00:00
|
|
|
/* This file is (c) 2008-2012 Konstantin Isakov <ikm@goldendict.org>
|
2009-01-28 20:55:45 +00:00
|
|
|
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
|
|
|
|
|
|
|
|
#ifndef __FILE_HH_INCLUDED__
|
|
|
|
#define __FILE_HH_INCLUDED__
|
|
|
|
|
|
|
|
#include <cstdio>
|
|
|
|
#include <string>
|
2012-01-30 13:11:41 +00:00
|
|
|
#include <vector>
|
2014-02-26 14:22:12 +00:00
|
|
|
#include <QFile>
|
2009-01-28 20:55:45 +00:00
|
|
|
#include "ex.hh"
|
2022-06-17 12:23:16 +00:00
|
|
|
#include "mutex.hh"
|
2009-01-28 20:55:45 +00:00
|
|
|
|
|
|
|
/// A simple wrapper over FILE * operations with added write-buffering,
|
|
|
|
/// used for non-Qt parts of code.
|
|
|
|
/// It is possible to ifdef implementation details for some platforms.
|
|
|
|
namespace File {
|
|
|
|
|
|
|
|
DEF_EX( Ex, "File exception", std::exception )
|
|
|
|
DEF_EX_STR( exCantOpen, "Can't open", Ex )
|
|
|
|
DEF_EX( exReadError, "Error reading from the file", Ex )
|
|
|
|
DEF_EX( exWriteError, "Error writing to the file", Ex )
|
|
|
|
DEF_EX( exSeekError, "File seek error", Ex )
|
2014-04-25 13:13:56 +00:00
|
|
|
DEF_EX( exAllocation, "Memory allocation error", Ex )
|
2009-01-28 20:55:45 +00:00
|
|
|
|
2009-05-17 22:22:10 +00:00
|
|
|
/// Checks if the file exists or not.
|
2012-01-30 13:11:41 +00:00
|
|
|
|
|
|
|
bool tryPossibleName( std::string const & name, std::string & copyTo );
|
|
|
|
|
2017-04-24 14:42:01 +00:00
|
|
|
bool tryPossibleZipName( std::string const & name, std::string & copyTo );
|
|
|
|
|
2012-01-30 13:11:41 +00:00
|
|
|
void loadFromFile( std::string const & n, std::vector< char > & data );
|
|
|
|
|
2022-06-03 13:28:41 +00:00
|
|
|
bool exists( char const * filename ) noexcept;
|
2009-05-17 22:22:10 +00:00
|
|
|
|
2022-06-03 13:28:41 +00:00
|
|
|
inline bool exists( std::string const & filename ) noexcept
|
2009-05-17 22:22:10 +00:00
|
|
|
{ return exists( filename.c_str() ); }
|
|
|
|
|
2009-01-28 20:55:45 +00:00
|
|
|
class Class
|
|
|
|
{
|
2014-02-26 14:22:12 +00:00
|
|
|
QFile f;
|
2009-01-28 20:55:45 +00:00
|
|
|
char * writeBuffer;
|
2014-05-12 13:43:02 +00:00
|
|
|
qint64 writeBufferLeft;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
2022-01-09 08:35:07 +00:00
|
|
|
void open( char const * filename, char const * mode ) ;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
|
|
|
public:
|
2022-06-18 01:09:40 +00:00
|
|
|
QMutex lock;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
2022-01-09 08:35:07 +00:00
|
|
|
Class( char const * filename, char const * mode ) ;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
2022-01-09 08:35:07 +00:00
|
|
|
Class( std::string const & filename, char const * mode ) ;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
|
|
|
/// 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).
|
2022-01-09 08:35:07 +00:00
|
|
|
void read( void * buf, qint64 size ) ;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
|
|
|
template< typename T >
|
2022-01-09 08:35:07 +00:00
|
|
|
void read( T & value )
|
2009-01-28 20:55:45 +00:00
|
|
|
{ read( &value, sizeof( value ) ); }
|
|
|
|
|
|
|
|
template< typename T >
|
2022-01-09 08:35:07 +00:00
|
|
|
T read()
|
2009-01-28 20:55:45 +00:00
|
|
|
{ T value; read( value ); return value; }
|
|
|
|
|
|
|
|
/// Attempts reading at most 'count' records sized 'size'. Returns
|
|
|
|
/// the number of records it managed to read, up to 'count'.
|
2022-01-09 08:35:07 +00:00
|
|
|
size_t readRecords( void * buf, qint64 size, size_t count ) ;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
|
|
|
/// 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).
|
|
|
|
/// This function employs write buffering, and as such, writes may not
|
|
|
|
/// 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.
|
2022-01-09 08:35:07 +00:00
|
|
|
void write( void const * buf, qint64 size ) ;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
|
|
|
template< typename T >
|
2022-01-09 08:35:07 +00:00
|
|
|
void write( T const & value )
|
2009-01-28 20:55:45 +00:00
|
|
|
{ write( &value, sizeof( value ) ); }
|
|
|
|
|
|
|
|
/// Attempts writing at most 'count' records sized 'size'. Returns
|
|
|
|
/// 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.
|
2014-02-26 14:22:12 +00:00
|
|
|
size_t writeRecords( void const * buf, qint64 size, size_t count )
|
2022-01-09 08:35:07 +00:00
|
|
|
;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
|
|
|
/// Reads a string from the file. Unlike the normal fgets(), this one
|
|
|
|
/// can strip the trailing newline character, if this was requested.
|
|
|
|
/// Returns either s or 0 if no characters were read.
|
2022-01-09 08:35:07 +00:00
|
|
|
char * gets( char * s, int size, bool stripNl = false ) ;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
|
|
|
/// Like the above, but uses its own local internal buffer (1024 bytes
|
|
|
|
/// currently), and strips newlines by default.
|
2022-01-09 08:35:07 +00:00
|
|
|
std::string gets( bool stripNl = true ) ;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
|
|
|
/// Seeks in the file, relative to its beginning.
|
2022-01-09 08:35:07 +00:00
|
|
|
void seek( qint64 offset ) ;
|
2022-06-13 14:12:03 +00:00
|
|
|
uchar * map( qint64 offset, qint64 size );
|
2009-01-28 20:55:45 +00:00
|
|
|
/// Seeks in the file, relative to the current position.
|
2022-01-09 08:35:07 +00:00
|
|
|
void seekCur( qint64 offset ) ;
|
2009-01-28 20:55:45 +00:00
|
|
|
/// Seeks in the file, relative to the end of file.
|
2022-01-09 08:35:07 +00:00
|
|
|
void seekEnd( qint64 offset = 0 ) ;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
|
|
|
/// Seeks to the beginning of file
|
2022-01-09 08:35:07 +00:00
|
|
|
void rewind() ;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
|
|
|
/// Tells the current position within the file, relative to its beginning.
|
2022-01-09 08:35:07 +00:00
|
|
|
qint64 tell() ;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
|
|
|
/// Returns true if end-of-file condition is set.
|
2022-01-09 08:35:07 +00:00
|
|
|
bool eof() ;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
|
|
|
/// Returns the underlying FILE * record, so other operations can be
|
|
|
|
/// performed on it.
|
2022-01-09 08:35:07 +00:00
|
|
|
QFile & file() ;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
|
|
|
/// Closes the file. No further operations are valid.
|
2022-01-09 08:35:07 +00:00
|
|
|
void close() ;
|
2009-01-28 20:55:45 +00:00
|
|
|
|
2022-06-03 13:28:41 +00:00
|
|
|
~Class() noexcept;
|
2022-06-13 14:12:03 +00:00
|
|
|
bool unmap( uchar * address );
|
2009-01-28 20:55:45 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
|
2022-01-09 08:35:07 +00:00
|
|
|
void flushWriteBuffer() ;
|
|
|
|
void releaseWriteBuffer() ;
|
2009-01-28 20:55:45 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|