File indexing completed on 2024-05-19 04:52:44
0001 /* This file is part of the KDE project 0002 SPDX-FileCopyrightText: 2000-2002 David Faure <faure@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "KoZipStore.h" 0008 0009 #include "kostore_log.h" 0010 0011 #include <KZip> 0012 #include <KIO/StoredTransferJob> 0013 #include <KJobWidgets> 0014 #include <QBuffer> 0015 #include <QByteArray> 0016 #include <QUrl> 0017 0018 KoZipStore::KoZipStore( const QString & _filename, Mode _mode, const QByteArray & appIdentification ) 0019 { 0020 qCDebug(K3B_KOSTORE_LOG) <<"KoZipStore Constructor filename =" << _filename 0021 << " mode = " << int(_mode) 0022 << " mimetype = " << appIdentification << Qt::endl; 0023 0024 m_pZip = new KZip( _filename ); 0025 0026 m_bGood = initZipStore( _mode, appIdentification ); // open the zip file and init some vars 0027 } 0028 0029 KoZipStore::KoZipStore( QIODevice *dev, Mode mode, const QByteArray & appIdentification ) 0030 { 0031 m_pZip = new KZip( dev ); 0032 m_bGood = initZipStore( mode, appIdentification ); 0033 } 0034 0035 KoZipStore::KoZipStore( QWidget* window, const QUrl & _url, const QString & _filename, Mode _mode, const QByteArray & appIdentification ) 0036 { 0037 qCDebug(K3B_KOSTORE_LOG) <<"KoZipStore Constructor url" << _url.toDisplayString( QUrl::PreferLocalFile ) 0038 << " filename = " << _filename 0039 << " mode = " << int(_mode) 0040 << " mimetype = " << appIdentification << Qt::endl; 0041 0042 m_url = _url; 0043 m_window = window; 0044 0045 if ( _mode == KoStore::Read ) 0046 { 0047 m_fileMode = KoStoreBase::RemoteRead; 0048 m_localFileName = _filename; 0049 0050 } 0051 else 0052 { 0053 m_fileMode = KoStoreBase::RemoteWrite; 0054 m_localFileName = "/var/tmp/kozip"; // ### FIXME with KTempFile 0055 } 0056 0057 m_pZip = new KZip( m_localFileName ); 0058 m_bGood = initZipStore( _mode, appIdentification ); // open the zip file and init some vars 0059 } 0060 0061 KoZipStore::~KoZipStore() 0062 { 0063 qCDebug(K3B_KOSTORE_LOG) <<"KoZipStore::~KoZipStore"; 0064 if ( !m_bFinalized ) 0065 finalize(); // ### no error checking when the app forgot to call finalize itself 0066 delete m_pZip; 0067 0068 // Now we have still some job to do for remote files. 0069 if ( m_fileMode == KoStoreBase::RemoteRead ) 0070 { 0071 QFile::remove( m_localFileName ); 0072 } 0073 else if ( m_fileMode == KoStoreBase::RemoteWrite ) 0074 { 0075 QFile file( m_localFileName ); 0076 if( file.open( QFile::ReadOnly ) ) 0077 { 0078 KIO::StoredTransferJob* transferJob = KIO::storedPut( file.readAll(), m_url, -1 ); 0079 KJobWidgets::setWindow( transferJob, m_window ); 0080 transferJob->exec(); 0081 } 0082 // ### FIXME: delete temp file 0083 } 0084 } 0085 0086 bool KoZipStore::initZipStore( Mode _mode, const QByteArray& appIdentification ) 0087 { 0088 KoStore::init( _mode ); 0089 m_currentDir = 0; 0090 bool good = m_pZip->open( _mode == Write ? QIODevice::WriteOnly : QIODevice::ReadOnly ); 0091 0092 if ( good && _mode == Read ) 0093 good = m_pZip->directory() != 0; 0094 else if ( good && _mode == Write ) 0095 { 0096 //qCDebug(K3B_KOSTORE_LOG) <<"KoZipStore::init writing mimetype" << appIdentification; 0097 0098 m_pZip->setCompression( KZip::NoCompression ); 0099 m_pZip->setExtraField( KZip::NoExtraField ); 0100 // Write identification 0101 m_pZip->writeFile( "mimetype", appIdentification ); 0102 m_pZip->setCompression( KZip::DeflateCompression ); 0103 // We don't need the extra field in KOffice - so we leave it as "no extra field". 0104 } 0105 return good; 0106 } 0107 0108 bool KoZipStore::doFinalize() 0109 { 0110 return m_pZip->close(); 0111 } 0112 0113 bool KoZipStore::openWrite( const QString& name ) 0114 { 0115 #if 0 0116 // Prepare memory buffer for writing 0117 m_byteArray.resize( 0 ); 0118 m_stream = new QBuffer( m_byteArray ); 0119 m_stream->open( QIODevice::WriteOnly ); 0120 return true; 0121 #endif 0122 m_stream = 0L; // Don't use! 0123 return m_pZip->prepareWriting( name, "", "" /*m_pZip->rootDir()->user(), m_pZip->rootDir()->group()*/, 0 ); 0124 } 0125 0126 bool KoZipStore::openRead( const QString& name ) 0127 { 0128 const KArchiveEntry * entry = m_pZip->directory()->entry( name ); 0129 if ( entry == 0L ) 0130 { 0131 //qCWarning(K3B_KOSTORE_LOG) << "Unknown filename " << name; 0132 //return KIO::ERR_DOES_NOT_EXIST; 0133 return false; 0134 } 0135 if ( entry->isDirectory() ) 0136 { 0137 qCWarning(K3B_KOSTORE_LOG) << name << " is a directory !"; 0138 //return KIO::ERR_IS_DIRECTORY; 0139 return false; 0140 } 0141 // Must cast to KZipFileEntry, not only KArchiveFile, because device() isn't virtual! 0142 const KZipFileEntry * f = static_cast<const KZipFileEntry *>(entry); 0143 delete m_stream; 0144 m_stream = f->createDevice(); 0145 m_iSize = f->size(); 0146 return true; 0147 } 0148 0149 qint64 KoZipStore::write( const char* _data, qint64 _len ) 0150 { 0151 if ( _len == 0L ) return 0; 0152 //qCDebug(K3B_KOSTORE_LOG) <<"KoZipStore::write" << _len; 0153 0154 if ( !m_bIsOpen ) 0155 { 0156 qCCritical(K3B_KOSTORE_LOG) << "KoStore: You must open before writing" << Qt::endl; 0157 return 0L; 0158 } 0159 if ( m_mode != Write ) 0160 { 0161 qCCritical(K3B_KOSTORE_LOG) << "KoStore: Can not write to store that is opened for reading" << Qt::endl; 0162 return 0L; 0163 } 0164 0165 m_iSize += _len; 0166 if ( m_pZip->writeData( _data, _len ) ) // writeData returns a bool! 0167 return _len; 0168 return 0L; 0169 } 0170 0171 bool KoZipStore::closeWrite() 0172 { 0173 qCDebug(K3B_KOSTORE_LOG) <<"Wrote file" << m_sName <<" into ZIP archive. size" 0174 << m_iSize << Qt::endl; 0175 return m_pZip->finishWriting( m_iSize ); 0176 #if 0 0177 if ( !m_pZip->writeFile( m_sName , "user", "group", m_iSize, m_byteArray.data() ) ) 0178 qCWarning( KOSTORE ) << "Failed to write " << m_sName; 0179 m_byteArray.resize( 0 ); // save memory 0180 return true; 0181 #endif 0182 } 0183 0184 bool KoZipStore::enterRelativeDirectory( const QString& dirName ) 0185 { 0186 if ( m_mode == Read ) { 0187 if ( !m_currentDir ) { 0188 m_currentDir = m_pZip->directory(); // initialize 0189 Q_ASSERT( m_currentPath.isEmpty() ); 0190 } 0191 const KArchiveEntry *entry = m_currentDir->entry( dirName ); 0192 if ( entry && entry->isDirectory() ) { 0193 m_currentDir = dynamic_cast<const KArchiveDirectory*>( entry ); 0194 return m_currentDir != 0; 0195 } 0196 return false; 0197 } 0198 else // Write, no checking here 0199 return true; 0200 } 0201 0202 bool KoZipStore::enterAbsoluteDirectory( const QString& path ) 0203 { 0204 if ( path.isEmpty() ) 0205 { 0206 m_currentDir = 0; 0207 return true; 0208 } 0209 m_currentDir = dynamic_cast<const KArchiveDirectory*>( m_pZip->directory()->entry( path ) ); 0210 Q_ASSERT( m_currentDir ); 0211 return m_currentDir != 0; 0212 } 0213 0214 bool KoZipStore::fileExists( const QString& absPath ) const 0215 { 0216 const KArchiveEntry *entry = m_pZip->directory()->entry( absPath ); 0217 return entry && entry->isFile(); 0218 }