Commit ed48a69f authored by Henrique Pinto's avatar Henrique Pinto
Browse files

* Move some things out of the way, so that we can implement a bk plugin

svn path=/branches/work/libarchive-based-ark/ark/; revision=676936
parent a429011e
......@@ -24,6 +24,7 @@
*/
#include "jobs.h"
#include "jobs_p.h"
#include <kdebug.h>
ListingJob::ListingJob( ReadOnlyArchiveInterface *archive, QObject *parent )
......@@ -39,7 +40,7 @@ ListingJob::~ListingJob()
void ListingJob::run()
{
m_helper = new ListingJobHelper( m_archive );
m_helper = new ArchiveJobHelper( m_archive );
connect( m_helper, SIGNAL( entry( const ArchiveEntry & ) ),
this, SIGNAL( entry( const ArchiveEntry & ) ) );
connect( m_helper, SIGNAL( progress( double ) ),
......@@ -47,16 +48,39 @@ void ListingJob::run()
m_success = m_helper->getTheListing();
}
ListingJobHelper::ListingJobHelper( ReadOnlyArchiveInterface *archive, QObject *parent )
ExtractionJob::ExtractionJob( ReadOnlyArchiveInterface *archive, const QStringList & files, const QString & destinationDirectory, QObject *parent )
: ThreadWeaver::Job( parent ), m_archive( archive ), m_files( files ), m_destinationDirectory( destinationDirectory ),
m_helper( 0 ), m_success( false )
{
}
ExtractionJob::~ExtractionJob()
{
delete m_helper;
m_helper = 0;
}
void ExtractionJob::run()
{
m_helper = new ArchiveJobHelper( m_archive );
connect( m_helper, SIGNAL( progress( double ) ),
this, SIGNAL( progress( double ) ) );
m_archive->registerObserver( m_helper );
m_success = m_archive->copyFiles( m_files, m_destinationDirectory );
m_archive->removeObserver( m_helper );
}
ArchiveJobHelper::ArchiveJobHelper( ReadOnlyArchiveInterface *archive, QObject *parent )
: QObject( parent ), m_archive( archive )
{
}
ListingJobHelper::~ListingJobHelper()
ArchiveJobHelper::~ArchiveJobHelper()
{
}
bool ListingJobHelper::getTheListing()
bool ArchiveJobHelper::getTheListing()
{
m_archive->registerObserver( this );
bool result = m_archive->list();
......@@ -64,25 +88,26 @@ bool ListingJobHelper::getTheListing()
return result;
}
void ListingJobHelper::onError( const QString & message, const QString & details )
void ArchiveJobHelper::onError( const QString & message, const QString & details )
{
// TODO: do something
}
void ListingJobHelper::onEntry( const ArchiveEntry & archiveEntry )
void ArchiveJobHelper::onEntry( const ArchiveEntry & archiveEntry )
{
emit entry( archiveEntry );
}
void ListingJobHelper::onProgress( double d )
void ArchiveJobHelper::onProgress( double d )
{
emit progress( d );
}
void ListingJobHelper::entryslot( const ArchiveEntry & e )
void ArchiveJobHelper::entryslot( const ArchiveEntry & e )
{
kDebug( 1601 ) << k_funcinfo << "Entry: " << e[ FileName ] << ", Owner = " << e[ Owner ] << endl;
}
#include "jobs.moc"
#include "jobs_p.moc"
......@@ -32,50 +32,51 @@
#include "archiveinterface.h"
#include <QList>
class ListingJobHelper: public QObject, public ArchiveObserver
class ArchiveJobHelper;
class ListingJob: public ThreadWeaver::Job
{
Q_OBJECT
public:
ListingJobHelper( ReadOnlyArchiveInterface *archive, QObject *parent = 0 );
~ListingJobHelper();
bool getTheListing();
ListingJob( ReadOnlyArchiveInterface *archive, QObject *parent = 0 );
~ListingJob();
void onError( const QString & message, const QString & details );
void onEntry( const ArchiveEntry & archiveEntry );
void onProgress( double );
bool success() const { return m_success; }
protected:
void run();
signals:
void entry( const ArchiveEntry & );
//void entries( const QList<ArchiveEntry & );
void progress( double );
private slots:
void entryslot( const ArchiveEntry & );
private:
QList<ArchiveEntry> m_entries;
ArchiveJobHelper *m_helper;
ReadOnlyArchiveInterface *m_archive;
bool m_success;
};
class ListingJob: public ThreadWeaver::Job
class ExtractionJob: public ThreadWeaver::Job
{
Q_OBJECT
public:
ListingJob( ReadOnlyArchiveInterface *archive, QObject *parent = 0 );
~ListingJob();
ExtractionJob( ReadOnlyArchiveInterface *archive, const QStringList & files, const QString & destinationDirectory, QObject *parent = 0 );
~ExtractionJob();
bool success() const { return m_success; }
protected:
void run();
signals:
void entry( const ArchiveEntry & );
//void entries( const QList<ArchiveEntry & );
void progress( double );
void progress( double p );
private:
QList<ArchiveEntry> m_entries;
ListingJobHelper *m_helper;
ReadOnlyArchiveInterface *m_archive;
QStringList m_files;
QString m_destinationDirectory;
ArchiveJobHelper *m_helper;
bool m_success;
};
......
/*
* Copyright (c) 2007 Henrique Pinto <henrique.pinto@kdemail.net>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ( INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef JOBS_P_H
#define JOBS_P_H
#include <ThreadWeaver/Job>
#include <ThreadWeaver/Weaver>
#include "archiveinterface.h"
#include <QList>
class ArchiveJobHelper: public QObject, public ArchiveObserver
{
Q_OBJECT
public:
ArchiveJobHelper( ReadOnlyArchiveInterface *archive, QObject *parent = 0 );
~ArchiveJobHelper();
bool getTheListing();
void onError( const QString & message, const QString & details );
void onEntry( const ArchiveEntry & archiveEntry );
void onProgress( double );
signals:
void entry( const ArchiveEntry & );
void progress( double );
private slots:
void entryslot( const ArchiveEntry & );
private:
ReadOnlyArchiveInterface *m_archive;
};
#endif // JOBS_P_H
......@@ -40,106 +40,6 @@
#include <QStringList>
#include <QDateTime>
class ExtractionJob: public ThreadWeaver::Job
{
public:
ExtractionJob( const QString & fileName, const QStringList & entries, const QString & baseDirectory, QObject *parent = 0 )
: ThreadWeaver::Job( parent ), m_fileName( fileName ), m_entries( entries ),
m_directory( baseDirectory ), m_success( false )
{
}
bool success() const { return m_success; }
protected:
void run()
{
kDebug( 1601 ) << "ExtractionJob::run() will try to extract " << m_entries << endl;
m_success = extractFiles();
}
private:
int flags()
{
int result = ARCHIVE_EXTRACT_TIME;
if ( ArkSettings::preservePerms() )
{
result &= ARCHIVE_EXTRACT_PERM;
}
if ( !ArkSettings::extractOverwrite() )
{
result &= ARCHIVE_EXTRACT_NO_OVERWRITE;
}
return result;
}
bool extractFiles()
{
QDir::setCurrent( m_directory );
const bool extractAll = m_entries.isEmpty();
struct archive *arch, *writer;
struct archive_entry *entry;
arch = archive_read_new();
if ( !arch )
{
return false;
}
writer = archive_write_disk_new();
archive_write_disk_set_options( writer, flags() );
archive_read_support_compression_all( arch );
archive_read_support_format_all( arch );
int res = archive_read_open_filename( arch, QFile::encodeName( m_fileName ), 10240 );
if ( res != ARCHIVE_OK )
{
kDebug( 1601 ) << "Couldn't open the file '" << m_fileName << "', libarchive can't handle it." << endl;
return false;
}
while ( archive_read_next_header( arch, &entry ) == ARCHIVE_OK )
{
QString entryName = QFile::decodeName( archive_entry_pathname( entry ) );
if ( m_entries.contains( entryName ) || extractAll )
{
if ( archive_write_header( writer, entry ) == ARCHIVE_OK )
copyData( arch, writer );
m_entries.removeAll( entryName );
}
else
{
kDebug( 1601 ) << entryName << " matches no requested file. " << endl;
archive_read_data_skip( arch );
}
}
if ( m_entries.size() > 0 ) return false;
return archive_read_finish( arch ) == ARCHIVE_OK;
}
void copyData( struct archive *source, struct archive *dest )
{
const void *buff = 0;
size_t size;
off_t offset;
while ( archive_read_data_block( source, &buff, &size, &offset ) == ARCHIVE_OK )
{
kDebug( 1601 ) << " copyData: copying " << size << " from offset " << offset << endl;
archive_write_data_block( dest, buff, size, offset );
}
}
QString m_fileName;
QStringList m_entries;
QString m_directory;
bool m_success;
};
LibArchiveHandler::LibArchiveHandler( const QString &filename )
: Arch( filename )
{
......@@ -185,7 +85,7 @@ void LibArchiveHandler::remove( const QStringList & )
void LibArchiveHandler::extractFiles( const QStringList & files, const QString& destinationDir )
{
ExtractionJob *job = new ExtractionJob( fileName(), files, destinationDir, this );
ExtractionJob *job = new ExtractionJob( new LibArchiveInterface( fileName(), this ), files, destinationDir, this );
connect( job, SIGNAL( done( ThreadWeaver::Job* ) ),
this, SLOT( extractionDone( ThreadWeaver::Job * ) ) );
ThreadWeaver::Weaver::instance()->enqueue( job );
......@@ -258,8 +158,81 @@ bool LibArchiveInterface::list()
bool LibArchiveInterface::copyFiles( const QStringList & files, const QString & destinationDirectory )
{
error( "Not implemented yet", QString() );
return false;
QDir::setCurrent( destinationDirectory );
const bool extractAll = files.isEmpty();
struct archive *arch, *writer;
struct archive_entry *entry;
QStringList entries = files;
arch = archive_read_new();
if ( !arch )
{
return false;
}
writer = archive_write_disk_new();
archive_write_disk_set_options( writer, extractionFlags() );
archive_read_support_compression_all( arch );
archive_read_support_format_all( arch );
int res = archive_read_open_filename( arch, QFile::encodeName( filename() ), 10240 );
if ( res != ARCHIVE_OK )
{
kDebug( 1601 ) << "Couldn't open the file '" << filename() << "', libarchive can't handle it." << endl;
return false;
}
while ( archive_read_next_header( arch, &entry ) == ARCHIVE_OK )
{
QString entryName = QFile::decodeName( archive_entry_pathname( entry ) );
if ( entries.contains( entryName ) || extractAll )
{
if ( archive_write_header( writer, entry ) == ARCHIVE_OK )
copyData( arch, writer );
entries.removeAll( entryName );
}
else
{
kDebug( 1601 ) << entryName << " matches no requested file. " << endl;
archive_read_data_skip( arch );
}
}
if ( entries.size() > 0 ) return false;
return archive_read_finish( arch ) == ARCHIVE_OK;
}
int LibArchiveInterface::extractionFlags() const
{
int result = ARCHIVE_EXTRACT_TIME;
if ( ArkSettings::preservePerms() )
{
result &= ARCHIVE_EXTRACT_PERM;
}
if ( !ArkSettings::extractOverwrite() )
{
result &= ARCHIVE_EXTRACT_NO_OVERWRITE;
}
return result;
}
void LibArchiveInterface::copyData( struct archive *source, struct archive *dest )
{
const void *buff = 0;
size_t size;
off_t offset;
while ( archive_read_data_block( source, &buff, &size, &offset ) == ARCHIVE_OK )
{
kDebug( 1601 ) << " copyData: copying " << size << " from offset " << offset << endl;
archive_write_data_block( dest, buff, size, offset );
}
}
#include "libarchivehandler.moc"
......@@ -43,6 +43,10 @@ class LibArchiveInterface: public ReadOnlyArchiveInterface
bool list();
bool copyFiles( const QStringList & files, const QString & destinationDirectory );
private:
int extractionFlags() const;
void copyData( struct archive *source, struct archive *dest );
};
class LibArchiveHandler: public Arch
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment