From 8cf274c35a83bf829a54cf22f0c82fdbfb333c03 Mon Sep 17 00:00:00 2001 From: Alexander Golubev Date: Sat, 7 May 2016 13:20:21 +1000 Subject: Removed crappy FileListView::updateItem() method and replace it with addOrUpdateItem() Enhanced in several ways parsing of rar-5+ output (fixes a crash and several potential issues) Spacing fixes Minor modification: replace assert with if() Signed-off-by: Michele Calgaro --- ark/rar.cpp | 169 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 87 insertions(+), 82 deletions(-) (limited to 'ark/rar.cpp') diff --git a/ark/rar.cpp b/ark/rar.cpp index 103f4ce..02600d5 100644 --- a/ark/rar.cpp +++ b/ark/rar.cpp @@ -30,6 +30,8 @@ #include // QT includes +#include +#include #include #include #include @@ -39,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -83,94 +86,96 @@ RarArch::RarArch( ArkWidget *_gui, const TQString & _fileName ) verifyUncompressUtilityIsAvailable( m_unarchiver_program ); setReadOnly( true ); } - - m_headerString = ""; } bool RarArch::processLine( const TQCString &line ) { - TQString unicode_line; - - TQTextCodec *codec = TQTextCodec::codecForLocale(); - unicode_line = codec->toUnicode( line ); - - // Look for rar/unrar version first - if (!m_version) - { - if (line.left(3) == "RAR") - { - bool ok_flag = false; - short version = line.mid(4, 1).toShort(&ok_flag); - if (ok_flag) - { - m_version = version; - if (m_version < VERSION_5) - { - m_headerString = "-------------------------------------------------------------------------------"; - m_isFirstLine = true; - } - else - { - m_headerString = "----------- --------- -------- ----- ---------- ----- -------- ----"; - } - setHeaders(); - return true; - } - } - return false; - } - - if (m_version < VERSION_5 && m_isFirstLine) + TQString uline = TQTextCodec::codecForLocale()->toUnicode(line); + + // Look for rar/unrar version first + if (!m_version) { - m_entryFilename = TQString::fromLocal8Bit( line ); - m_entryFilename.remove( 0, 1 ); - m_isFirstLine = false; - return true; + TQRegExp versionRegExp (TQString::fromLatin1 ("RAR\\s(\\d+)\\.(\\S+)\\s.*")); + + if (versionRegExp.exactMatch (uline)) + { + m_version = versionRegExp.capturedTexts()[1].toShort (); + + if (m_version < VERSION_5) { + m_headerString = "-------------------------------------------------------------------------------"; + m_isFirstLine = true; + } else { + m_headerString = "----------- --------- -------- ----- ---------- ----- -------- ----"; + } + setHeaders(); //< Note: header order for version 5 is different, but keep the old one for consistency + return true; + } + return false; } - TQStringList list; - TQStringList l2 = TQStringList::split( ' ', line ); + TQStringList entry; + TQStringList parsedData = TQStringList::split(QChar(' '), uline); - if (m_version < VERSION_5) + if (m_version < VERSION_5) { + if (m_isFirstLine) + { + m_entryFilename = uline.remove( 0, 1 ); + m_isFirstLine = false; + return true; + } + + if (parsedData.size() < 9) { + kdError ( 1601 ) << "Failed to parse rar<5 output string: \"" << uline << "\"" << endl; + } + + entry << m_entryFilename; // filename + entry << parsedData[ 0 ]; // size + entry << parsedData[ 1 ]; // packed + entry << parsedData[ 2 ]; // ratio + + TQStringList date = TQStringList::split( '-', parsedData[ 3 ] ); + entry << ArkUtils::fixYear( date[ 2 ].latin1() ) + '-' + date[ 1 ] + '-' + date [ 0 ] + ' ' + parsedData[4]; // date + entry << parsedData[ 5 ]; // attributes + entry << parsedData[ 6 ]; // crc + entry << parsedData[ 7 ]; // method + entry << parsedData[ 8 ]; // Version + + m_isFirstLine = true; + } + else { - list << m_entryFilename; // filename - list << l2[ 0 ]; // size - list << l2[ 1 ]; // packed - list << l2[ 2 ]; // ratio - - TQStringList date = TQStringList::split( '-', l2[ 3 ] ); - list << ArkUtils::fixYear( date[ 2 ].latin1() ) + '-' + date[ 1 ] + '-' + date [ 0 ] + ' ' + l2[4]; // date - list << l2[ 5 ]; // attributes - list << l2[ 6 ]; // crc - list << l2[ 7 ]; // method - list << l2[ 8 ]; // Version - - m_isFirstLine = true; - } - else - { - m_entryFilename = line.mid(line.find(l2[7])); - list << m_entryFilename; // filename - list << l2[ 1 ]; // size - list << l2[ 2 ]; // packed - list << l2[ 3 ]; // ratio - - TQStringList date = TQStringList::split('-', l2[4]); - list << l2[ 4 ] + " " + l2[ 5 ]; // date and time - list << l2[ 0 ]; // attributes - list << l2[ 6 ]; // crc - } - // send to GUI - if ( l2[6] == "00000000" ) - { - // folders have CRC equal to 00000000 - // RAR utilities show the folders at the end of the listing so the folders - // have been already added to the listview at this point without specifying - // all the columns but the name. Update the item with the missing info - m_gui->fileList()->updateItem( list ); - } - else - m_gui->fileList()->addItem( list ); + // Note: don't use parsedData for names due to they may contain trailing spaces + TQRegExp nameRegExp (TQString::fromLatin1 ("\\s*(\\S+\\s+){6}\\S+ (.*)")); + + if (parsedData.size() >= 8 && nameRegExp.exactMatch (uline)) { + m_entryFilename = nameRegExp.capturedTexts()[2]; + + entry << m_entryFilename; // filename + entry << parsedData[ 1 ]; // size + entry << parsedData[ 2 ]; // packed + entry << parsedData[ 3 ]; // ratio + + entry << parsedData[ 4 ] + " " + parsedData[ 5 ]; // date and time + entry << parsedData[ 0 ]; // attributes + entry << parsedData[ 6 ]; // crc + } else { + kdError ( 1601 ) << "Failed to parse rar-5+ output string: \"" << uline << "\"" << endl; + return false; + } + } + + // send to GUI + // Use addOrUpdateItem() rather than addItem() due to recent RAR version + // place directories in archive after their content. + FileLVI *item = m_gui->fileList()->addOrUpdateItem( entry ); + + // But archives packaged with older versions of ark may have directories + // entries first, so make sure they will get an appropriate icon + if (item && entry[5].find('d', 0, false) != -1) { + // check attr's for d (case insensitive to handle windows archives) + item->setPixmap( 0, KMimeType::mimeType( "inode/directory" )->pixmap( TDEIcon::Small ) ); + } + return true; } @@ -216,9 +221,9 @@ void RarArch::setHeaders() list.append( CRC_COLUMN ); if (m_version < VERSION_5) { - list.append( METHOD_COLUMN ); - list.append( VERSION_COLUMN ); - } + list.append( METHOD_COLUMN ); + list.append( VERSION_COLUMN ); + } emit headers( list ); } -- cgit v1.2.1