1 /* This file is (c) 2017 Abs62 2 * Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */ 3 4 #include "splitfile.hh" 5 #include "fsencoding.hh" 6 7 namespace SplitFile 8 { 9 SplitFile()10SplitFile::SplitFile() : 11 currentFile( 0 ) 12 { 13 } 14 ~SplitFile()15SplitFile::~SplitFile() 16 { 17 close(); 18 } 19 appendFile(const QString & name)20void SplitFile::appendFile( const QString & name ) 21 { 22 if( offsets.isEmpty() ) 23 offsets.append( 0 ); 24 else 25 offsets.append( offsets.last() + files.last()->size() ); 26 files.append( new QFile( name ) ); 27 } 28 close()29void SplitFile::close() 30 { 31 for( QVector< QFile * >::const_iterator i = files.begin(); i != files.end(); ++i ) 32 { 33 (*i)->close(); 34 delete (*i); 35 } 36 37 files.clear(); 38 offsets.clear(); 39 40 currentFile = 0; 41 } 42 getFilenames(vector<string> & names) const43void SplitFile::getFilenames( vector< string > &names ) const 44 { 45 for( QVector< QFile const * >::const_iterator i = files.begin(); i != files.end(); ++i ) 46 names.push_back( FsEncoding::encode( (*i)->fileName() ) ); 47 } 48 open(QFile::OpenMode mode)49bool SplitFile::open( QFile::OpenMode mode ) 50 { 51 for( QVector< QFile * >::iterator i = files.begin(); i != files.end(); ++i ) 52 if( !(*i)->open( mode ) ) 53 { 54 close(); 55 return false; 56 } 57 58 return true; 59 } 60 seek(quint64 pos)61bool SplitFile::seek( quint64 pos ) 62 { 63 if( offsets.isEmpty() ) 64 return false; 65 66 int fileNom; 67 68 for( fileNom = 0; fileNom < offsets.size() - 1; fileNom++ ) 69 if( pos < offsets.at( fileNom + 1 ) ) 70 break; 71 72 pos -= offsets.at( fileNom ); 73 74 currentFile = fileNom; 75 return files.at( fileNom )->seek( pos ); 76 } 77 read(char * data,qint64 maxSize)78qint64 SplitFile::read( char *data, qint64 maxSize ) 79 { 80 if( offsets.isEmpty() ) 81 return 0; 82 83 quint64 bytesReaded = 0; 84 for( int i = currentFile; i < files.size(); i++ ) 85 { 86 if( i != currentFile ) 87 { 88 files.at( i )->seek( 0 ); 89 currentFile = i; 90 } 91 92 qint64 ret = files.at( i )->read( data + bytesReaded, maxSize ); 93 if( ret < 0 ) 94 break; 95 96 bytesReaded += ret; 97 maxSize -= ret; 98 99 if( maxSize <= 0 ) 100 break; 101 } 102 return bytesReaded; 103 } 104 read(qint64 maxSize)105QByteArray SplitFile::read( qint64 maxSize ) 106 { 107 QByteArray data; 108 data.resize( maxSize ); 109 110 qint64 ret = read( data.data(), maxSize ); 111 112 if( ret != maxSize ) 113 data.resize( ret ); 114 115 return data; 116 } 117 getChar(char * c)118bool SplitFile::getChar( char *c ) 119 { 120 char ch; 121 return read( c ? c : &ch, 1 ) == 1; 122 } 123 pos() const124qint64 SplitFile::pos() const 125 { 126 if( offsets.isEmpty() ) 127 return 0; 128 129 return offsets.at( currentFile ) + files.at( currentFile )->pos(); 130 } 131 132 } // namespace SplitFile 133