summaryrefslogtreecommitdiffstats
path: root/krusader/Splitter/combiner.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'krusader/Splitter/combiner.cpp')
-rw-r--r--krusader/Splitter/combiner.cpp328
1 files changed, 328 insertions, 0 deletions
diff --git a/krusader/Splitter/combiner.cpp b/krusader/Splitter/combiner.cpp
new file mode 100644
index 0000000..e32db05
--- /dev/null
+++ b/krusader/Splitter/combiner.cpp
@@ -0,0 +1,328 @@
+/***************************************************************************
+ combiner.cpp - description
+ -------------------
+ copyright : (C) 2003 by Csaba Karai
+ e-mail : krusader@users.sourceforge.net
+ web site : http://krusader.sourceforge.net
+ ---------------------------------------------------------------------------
+ Description
+ ***************************************************************************
+
+ A
+
+ db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b.
+ 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D
+ 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY'
+ 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b
+ 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88.
+ YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD
+
+ S o u r c e F i l e
+
+ ***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ ***************************************************************************/
+
+#include "combiner.h"
+#include "../VFS/vfs.h"
+#include <klocale.h>
+#include <kmessagebox.h>
+#include <kfileitem.h>
+#include <kio/job.h>
+#include <qfileinfo.h>
+
+Combiner::Combiner( QWidget* parent, KURL baseURLIn, KURL destinationURLIn, bool unixNamingIn ) :
+ QProgressDialog( parent, "Krusader::Combiner", true, 0 ), baseURL( baseURLIn ), destinationURL( destinationURLIn ),
+ hasValidSplitFile( false ), fileCounter ( 0 ), permissions( -1 ), receivedSize( 0 ),
+ combineReadJob( 0 ), combineWriteJob( 0 ), unixNaming( unixNamingIn )
+{
+ crcContext = new CRC32();
+
+ splitFile = "";
+
+ setTotalSteps( 100 );
+ setAutoClose( false ); /* don't close or reset the dialog automatically */
+ setAutoReset( false );
+}
+
+Combiner::~Combiner()
+{
+ combineAbortJobs();
+ delete crcContext;
+}
+
+void Combiner::combine()
+{
+ setCaption( i18n("Krusader::Combining...") );
+ setLabelText( i18n("Combining the file %1...").arg( vfs::pathOrURL( baseURL ) ));
+
+ /* check whether the .crc file exists */
+ splURL = baseURL;
+ splURL.setFileName( baseURL.fileName() + ".crc" );
+ KFileItem file(KFileItem::Unknown, KFileItem::Unknown, splURL );
+ file.refresh();
+
+ if( !file.isReadable() )
+ {
+ int ret = KMessageBox::questionYesNo(0, i18n("The CRC information file (%1) is missing!\n"
+ "Validity checking is impossible without it. Continue combining?")
+ .arg( vfs::pathOrURL( splURL ) ) );
+
+ if( ret == KMessageBox::No )
+ {
+ emit reject();
+ return;
+ }
+
+ openNextFile();
+ }
+ else
+ {
+ permissions = file.permissions() | QFileInfo::WriteUser;
+
+ combineReadJob = KIO::get( splURL, false, false );
+
+ connect(combineReadJob, SIGNAL(data(KIO::Job *, const QByteArray &)),
+ this, SLOT(combineSplitFileDataReceived(KIO::Job *, const QByteArray &)));
+ connect(combineReadJob, SIGNAL(result(KIO::Job*)),
+ this, SLOT(combineSplitFileFinished(KIO::Job *)));
+ }
+
+ exec();
+}
+
+void Combiner::combineSplitFileDataReceived(KIO::Job *, const QByteArray &byteArray)
+{
+ splitFile += QString( byteArray );
+}
+
+void Combiner::combineSplitFileFinished(KIO::Job *job)
+{
+ combineReadJob = 0;
+ QString error;
+
+ if( job->error() )
+ error = i18n("Error at reading the CRC file (%1)!").arg( vfs::pathOrURL( splURL ) );
+ else
+ {
+ splitFile.remove( '\r' ); // Windows compatibility
+ QStringList splitFileContent = QStringList::split( '\n', splitFile );
+
+ bool hasFileName = false, hasSize = false, hasCrc = false;
+
+ for(unsigned int i = 0; i != splitFileContent.count(); i++ )
+ {
+ int ndx = splitFileContent[i].find( '=' );
+ if( ndx == -1 )
+ continue;
+ QString token = splitFileContent[i].left( ndx ).stripWhiteSpace();
+ QString value = splitFileContent[i].mid( ndx + 1 );
+
+ if( token == "filename" )
+ {
+ expectedFileName = value;
+ hasFileName = true;
+ }
+ else if( token == "size" )
+ {
+ sscanf( value.stripWhiteSpace().ascii(), "%llu", &expectedSize );
+ hasSize = true;
+ }
+ if( token == "crc32" )
+ {
+ expectedCrcSum = value.stripWhiteSpace().rightJustify( 8, '0' );
+ hasCrc = true;
+ }
+ }
+
+ if( !hasFileName || !hasSize || !hasCrc )
+ error = i18n("Not a valid CRC file!");
+ else
+ hasValidSplitFile = true;
+ }
+
+ if( !error.isEmpty() )
+ {
+ int ret = KMessageBox::questionYesNo( 0, error+ "\n" +
+ i18n("Validity checking is impossible without a good CRC file. Continue combining?") );
+ if( ret == KMessageBox::No )
+ {
+ emit reject();
+ return;
+ }
+ }
+
+ openNextFile();
+}
+
+void Combiner::openNextFile()
+{
+ if( unixNaming )
+ {
+ if( readURL.isEmpty() )
+ readURL = baseURL;
+ else
+ {
+ QString name = readURL.fileName();
+ int pos = name.length()-1;
+ QChar ch;
+
+ do
+ {
+ ch = name.at( pos ).latin1() + 1;
+ if( ch == QChar( 'Z' + 1 ) )
+ ch = 'A';
+ if( ch == QChar( 'z' + 1 ) )
+ ch = 'a';
+ name[ pos ] = ch;
+ pos--;
+ } while( pos >=0 && ch.upper() == QChar( 'A' ) );
+
+ readURL.setFileName( name );
+ }
+ }
+ else
+ {
+ QString index( "%1" ); /* determining the filename */
+ index = index.arg(++fileCounter).rightJustify( 3, '0' );
+ readURL = baseURL;
+ readURL.setFileName( baseURL.fileName() + "." + index );
+ }
+
+ /* creating a write job */
+ combineReadJob = KIO::get( readURL, false, false );
+
+ connect(combineReadJob, SIGNAL(data(KIO::Job *, const QByteArray &)),
+ this, SLOT(combineDataReceived(KIO::Job *, const QByteArray &)));
+ connect(combineReadJob, SIGNAL(result(KIO::Job*)),
+ this, SLOT(combineReceiveFinished(KIO::Job *)));
+ if( hasValidSplitFile )
+ connect(combineReadJob, SIGNAL(percent (KIO::Job *, unsigned long)),
+ this, SLOT(combineWritePercent(KIO::Job *, unsigned long)));
+
+}
+
+void Combiner::combineDataReceived(KIO::Job *, const QByteArray &byteArray)
+{
+ if( byteArray.size() == 0 )
+ return;
+
+ crcContext->update( (unsigned char *)byteArray.data(), byteArray.size() );
+ transferArray = byteArray.copy();
+
+ receivedSize += byteArray.size();
+
+ if( combineWriteJob == 0 )
+ {
+ writeURL = destinationURL;
+ writeURL.addPath( baseURL.fileName() );
+ if( hasValidSplitFile )
+ writeURL.setFileName( expectedFileName );
+ else if( unixNaming )
+ writeURL.setFileName( baseURL.fileName() + ".out" );
+
+ combineWriteJob = KIO::put( writeURL, permissions, true, false, false );
+
+ connect(combineWriteJob, SIGNAL(dataReq(KIO::Job *, QByteArray &)),
+ this, SLOT(combineDataSend(KIO::Job *, QByteArray &)));
+ connect(combineWriteJob, SIGNAL(result(KIO::Job*)),
+ this, SLOT(combineSendFinished(KIO::Job *)));
+ }
+
+ if( combineWriteJob )
+ {
+ if( combineReadJob ) combineReadJob->suspend(); /* start writing */
+ combineWriteJob->resume();
+ }
+}
+
+void Combiner::combineReceiveFinished(KIO::Job *job)
+{
+ combineReadJob = 0; /* KIO automatically deletes the object after Finished signal */
+
+ if( job->error() )
+ {
+ if( combineWriteJob ) /* write out the remaining part of the file */
+ combineWriteJob->resume();
+
+ if( fileCounter == 1 )
+ {
+ combineAbortJobs();
+ KMessageBox::questionYesNo(0, i18n("Can't open the first split file of %1!")
+ .arg( vfs::pathOrURL( baseURL ) ) );
+ emit reject();
+ return;
+ }
+
+ if( hasValidSplitFile )
+ {
+ QString crcResult = QString( "%1" ).arg( crcContext->result(), 0, 16 ).upper().stripWhiteSpace()
+ .rightJustify(8, '0');
+
+ if( receivedSize != expectedSize )
+ error = i18n("Incorrect filesize! The file might have been corrupted!");
+ else if ( crcResult != expectedCrcSum.upper().stripWhiteSpace() )
+ error = i18n("Incorrect CRC checksum! The file might have been corrupted!");
+ }
+ return;
+ }
+ openNextFile();
+}
+
+void Combiner::combineDataSend(KIO::Job *, QByteArray &byteArray)
+{
+ byteArray = transferArray;
+ transferArray = QByteArray();
+
+ if( combineReadJob )
+ {
+ combineReadJob->resume(); /* start reading */
+ combineWriteJob->suspend();
+ }
+}
+
+void Combiner::combineSendFinished(KIO::Job *job)
+{
+ combineWriteJob = 0; /* KIO automatically deletes the object after Finished signal */
+
+ if( job->error() ) /* any error occurred? */
+ {
+ combineAbortJobs();
+ KMessageBox::error(0, i18n("Error writing file %1!").arg( vfs::pathOrURL( writeURL ) ) );
+ emit reject();
+ return;
+ }
+
+ if( !error.isEmpty() ) /* was any error message at reading ? */
+ {
+ combineAbortJobs(); /* we cannot write out it in combineReceiveFinished */
+ KMessageBox::error(0, error ); /* because emit accept closes it in this function */
+ emit reject();
+ return;
+ }
+
+ emit accept();
+}
+
+void Combiner::combineAbortJobs()
+{
+ if( combineReadJob )
+ combineReadJob->kill();
+ if( combineWriteJob )
+ combineWriteJob->kill();
+
+ combineReadJob = combineWriteJob = 0;
+}
+
+void Combiner::combineWritePercent(KIO::Job *, unsigned long)
+{
+ int percent = (int)((((double)receivedSize / expectedSize ) * 100. ) + 0.5 );
+ setProgress( percent );
+}
+
+#include "combiner.moc"