2017-04-24 14:42:01 +00:00
|
|
|
/* This file is (c) 2017 Abs62
|
|
|
|
* Part of GoldenDict. Licensed under GPLv3 or later, see the LICENSE file */
|
|
|
|
|
|
|
|
#include "splitfile.hh"
|
|
|
|
#include "fsencoding.hh"
|
|
|
|
|
|
|
|
namespace SplitFile
|
|
|
|
{
|
|
|
|
|
|
|
|
SplitFile::SplitFile() :
|
|
|
|
currentFile( 0 )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
SplitFile::~SplitFile()
|
|
|
|
{
|
|
|
|
close();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SplitFile::appendFile( const QString & name )
|
|
|
|
{
|
|
|
|
if( offsets.isEmpty() )
|
|
|
|
offsets.append( 0 );
|
|
|
|
else
|
|
|
|
offsets.append( offsets.last() + files.last()->size() );
|
|
|
|
files.append( new QFile( name ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
void SplitFile::close()
|
|
|
|
{
|
|
|
|
for( QVector< QFile * >::const_iterator i = files.begin(); i != files.end(); ++i )
|
|
|
|
{
|
|
|
|
(*i)->close();
|
|
|
|
delete (*i);
|
|
|
|
}
|
|
|
|
|
|
|
|
files.clear();
|
|
|
|
offsets.clear();
|
|
|
|
|
|
|
|
currentFile = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SplitFile::getFilenames( vector< string > &names ) const
|
|
|
|
{
|
2022-02-27 05:17:37 +00:00
|
|
|
for( QVector< QFile * >::const_iterator i = files.begin(); i != files.end(); ++i )
|
2017-04-24 14:42:01 +00:00
|
|
|
names.push_back( FsEncoding::encode( (*i)->fileName() ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SplitFile::open( QFile::OpenMode mode )
|
|
|
|
{
|
|
|
|
for( QVector< QFile * >::iterator i = files.begin(); i != files.end(); ++i )
|
|
|
|
if( !(*i)->open( mode ) )
|
|
|
|
{
|
|
|
|
close();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SplitFile::seek( quint64 pos )
|
|
|
|
{
|
2017-04-27 15:02:44 +00:00
|
|
|
if( offsets.isEmpty() )
|
|
|
|
return false;
|
|
|
|
|
2017-04-24 14:42:01 +00:00
|
|
|
int fileNom;
|
|
|
|
|
|
|
|
for( fileNom = 0; fileNom < offsets.size() - 1; fileNom++ )
|
|
|
|
if( pos < offsets.at( fileNom + 1 ) )
|
|
|
|
break;
|
|
|
|
|
|
|
|
pos -= offsets.at( fileNom );
|
|
|
|
|
|
|
|
currentFile = fileNom;
|
|
|
|
return files.at( fileNom )->seek( pos );
|
|
|
|
}
|
|
|
|
|
|
|
|
qint64 SplitFile::read( char *data, qint64 maxSize )
|
|
|
|
{
|
2017-04-27 15:02:44 +00:00
|
|
|
if( offsets.isEmpty() )
|
|
|
|
return 0;
|
|
|
|
|
2017-04-24 14:42:01 +00:00
|
|
|
quint64 bytesReaded = 0;
|
|
|
|
for( int i = currentFile; i < files.size(); i++ )
|
|
|
|
{
|
|
|
|
if( i != currentFile )
|
|
|
|
{
|
|
|
|
files.at( i )->seek( 0 );
|
|
|
|
currentFile = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
qint64 ret = files.at( i )->read( data + bytesReaded, maxSize );
|
|
|
|
if( ret < 0 )
|
|
|
|
break;
|
|
|
|
|
|
|
|
bytesReaded += ret;
|
|
|
|
maxSize -= ret;
|
|
|
|
|
|
|
|
if( maxSize <= 0 )
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return bytesReaded;
|
|
|
|
}
|
|
|
|
|
|
|
|
QByteArray SplitFile::read( qint64 maxSize )
|
|
|
|
{
|
|
|
|
QByteArray data;
|
|
|
|
data.resize( maxSize );
|
|
|
|
|
|
|
|
qint64 ret = read( data.data(), maxSize );
|
|
|
|
|
|
|
|
if( ret != maxSize )
|
|
|
|
data.resize( ret );
|
|
|
|
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SplitFile::getChar( char *c )
|
|
|
|
{
|
|
|
|
char ch;
|
|
|
|
return read( c ? c : &ch, 1 ) == 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
qint64 SplitFile::pos() const
|
|
|
|
{
|
2017-04-27 15:02:44 +00:00
|
|
|
if( offsets.isEmpty() )
|
2017-04-24 14:42:01 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
return offsets.at( currentFile ) + files.at( currentFile )->pos();
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace SplitFile
|