/*************************************************************************** splitter.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 "splitter.h" #include "../VFS/vfs.h" #include #include #include #include #include #include Splitter::Splitter( TQWidget* parent, KURL fileNameIn, KURL destinationDirIn ) : TQProgressDialog( parent, "Krusader::Splitter", true, 0 ), splitSize( 0 ) { fileName = fileNameIn; destinationDir = destinationDirIn; crcContext = new CRC32(); setTotalSteps( 100 ); setAutoClose( false ); /* don't close or reset the dialog automatically */ setAutoReset( false ); } Splitter::~Splitter() { splitAbortJobs(); delete crcContext; } void Splitter::split( TDEIO::filesize_t splitSizeIn ) { KFileItem file(KFileItem::Unknown, KFileItem::Unknown, fileName ); file.refresh(); permissions = file.permissions() | TQFileInfo::WriteUser; splitSize = splitSizeIn; setCaption( i18n("Krusader::Splitting...") ); setLabelText( i18n("Splitting the file %1...").arg( vfs::pathOrURL( fileName ) ) ); if( file.isDir() ) { KMessageBox::error(0, i18n("Can't split a directory!")); return; } fileSize = 0; fileNumber = 0; splitReadJob = TDEIO::get( fileName, false, false ); connect(splitReadJob, TQT_SIGNAL(data(TDEIO::Job *, const TQByteArray &)), this, TQT_SLOT(splitDataReceived(TDEIO::Job *, const TQByteArray &))); connect(splitReadJob, TQT_SIGNAL(result(TDEIO::Job*)), this, TQT_SLOT(splitReceiveFinished(TDEIO::Job *))); connect(splitReadJob, TQT_SIGNAL(percent (TDEIO::Job *, unsigned long)), this, TQT_SLOT(splitReceivePercent(TDEIO::Job *, unsigned long))); splitWriteJob = 0; noValidWriteJob = true; exec(); } void Splitter::splitDataReceived(TDEIO::Job *, const TQByteArray &byteArray) { if( byteArray.size() == 0 ) return; crcContext->update( (unsigned char *)byteArray.data(), byteArray.size() ); fileSize += byteArray.size(); if( noValidWriteJob ) splitCreateWriteJob(); transferArray = byteArray.copy(); if(splitWriteJob) { splitReadJob->suspend(); /* start writing */ splitWriteJob->resume(); } } void Splitter::splitReceiveFinished(TDEIO::Job *job) { splitReadJob = 0; /* KIO automatically deletes the object after Finished signal */ if( splitWriteJob ) /* write out the end of the file */ splitWriteJob->resume(); if( job->error() ) /* any error occurred? */ { splitAbortJobs(); KMessageBox::error(0, i18n("Error reading file %1!").arg( vfs::pathOrURL( fileName ) ) ); emit reject(); return; } TQString crcResult = TQString( "%1" ).arg( crcContext->result(), 0, 16 ).upper().stripWhiteSpace() .rightJustify(8, '0'); splitFile = TQString( "filename=%1\n" ).arg( fileName.fileName() )+ TQString( "size=%1\n" ) .arg( TDEIO::number( fileSize ) )+ TQString( "crc32=%1\n" ) .arg( crcResult ); } void Splitter::splitReceivePercent (TDEIO::Job *, unsigned long percent) { setProgress( percent ); } void Splitter::splitCreateWriteJob() { TQString index( "%1" ); /* making the splitted filename */ index = index.arg(++fileNumber).rightJustify( 3, '0' ); TQString outFileName = fileName.fileName() + "." + index; writeURL = destinationDir; writeURL.addPath( outFileName ); /* creating a write job */ splitWriteJob = TDEIO::put( writeURL, permissions, true, false, false ); outputFileSize = 0; connect(splitWriteJob, TQT_SIGNAL(dataReq(TDEIO::Job *, TQByteArray &)), this, TQT_SLOT(splitDataSend(TDEIO::Job *, TQByteArray &))); connect(splitWriteJob, TQT_SIGNAL(result(TDEIO::Job*)), this, TQT_SLOT(splitSendFinished(TDEIO::Job *))); noValidWriteJob = false; } void Splitter::splitDataSend(TDEIO::Job *, TQByteArray &byteArray) { int bufferLen = transferArray.size(); if( noValidWriteJob ) /* splitted file should be closed ? */ { byteArray = TQByteArray(); /* giving empty buffer which indicates closing */ } else if( outputFileSize + bufferLen > splitSize ) /* maximum length reached? */ { int shortLen = splitSize - outputFileSize; byteArray.duplicate( transferArray.data(), shortLen ); transferArray.duplicate( transferArray.data() + shortLen, bufferLen - shortLen ); noValidWriteJob = true; /* close the current segment */ } else { outputFileSize += bufferLen; /* write the whole buffer out to the split file */ byteArray = transferArray; transferArray = TQByteArray(); if(splitReadJob) { splitReadJob->resume(); /* start reading */ splitWriteJob->suspend(); } } } void Splitter::splitSendFinished(TDEIO::Job *job) { splitWriteJob = 0; /* KIO automatically deletes the object after Finished signal */ if( job->error() ) /* any error occurred? */ { splitAbortJobs(); KMessageBox::error(0, i18n("Error writing file %1!").arg( vfs::pathOrURL( writeURL ) ) ); emit reject(); return; } if( transferArray.size() ) /* any data remained in the transfer buffer? */ splitCreateWriteJob(); /* create a new write job */ else { /* writing the split information file out */ writeURL = destinationDir; writeURL.addPath( fileName.fileName() + ".crc" ); splitWriteJob = TDEIO::put( writeURL, permissions, true, false, false ); connect(splitWriteJob, TQT_SIGNAL(dataReq(TDEIO::Job *, TQByteArray &)), this, TQT_SLOT(splitFileSend(TDEIO::Job *, TQByteArray &))); connect(splitWriteJob, TQT_SIGNAL(result(TDEIO::Job*)), this, TQT_SLOT(splitFileFinished(TDEIO::Job *))); } } void Splitter::splitAbortJobs() { if( splitReadJob ) splitReadJob->kill(); if( splitWriteJob ) splitWriteJob->kill(); splitReadJob = splitWriteJob = 0; } void Splitter::splitFileSend(TDEIO::Job *, TQByteArray &byteArray) { const char *content = splitFile.ascii(); byteArray.duplicate( content, strlen ( content ) ); splitFile = ""; } void Splitter::splitFileFinished(TDEIO::Job *job) { splitWriteJob = 0; /* KIO automatically deletes the object after Finished signal */ if( job->error() ) /* any error occurred? */ { KMessageBox::error(0, i18n("Error at writing file %1!").arg( vfs::pathOrURL( writeURL ) ) ); emit reject(); return; } emit accept(); } #include "splitter.moc"