Warning, file /office/calligra/libs/store/KoZipStore.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 Copyright (C) 2000-2002 David Faure <faure@kde.org> 0003 Copyright (C) 2010 C. Boemann <cbo@boemann.dk> 0004 0005 This library is free software; you can redistribute it and/or 0006 modify it under the terms of the GNU Library General Public 0007 License as published by the Free Software Foundation; either 0008 version 2 of the License, or (at your option) any later version. 0009 0010 This library is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 Library General Public License for more details. 0014 0015 You should have received a copy of the GNU Library General Public License 0016 along with this library; see the file COPYING.LIB. If not, write to 0017 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include "KoZipStore.h" 0022 #include "KoStore_p.h" 0023 0024 #include <QBuffer> 0025 #include <QByteArray> 0026 0027 #include <kzip.h> 0028 #include <StoreDebug.h> 0029 0030 #include <QUrl> 0031 #include <KoNetAccess.h> 0032 0033 KoZipStore::KoZipStore(const QString & _filename, Mode mode, const QByteArray & appIdentification, 0034 bool writeMimetype) 0035 : KoStore(mode, writeMimetype) 0036 { 0037 debugStore << "KoZipStore Constructor filename =" << _filename 0038 << " mode = " << int(mode) 0039 << " mimetype = " << appIdentification << endl; 0040 Q_D(KoStore); 0041 0042 d->localFileName = _filename; 0043 0044 m_pZip = new KZip(_filename); 0045 0046 init(appIdentification); // open the zip file and init some vars 0047 } 0048 0049 KoZipStore::KoZipStore(QIODevice *dev, Mode mode, const QByteArray & appIdentification, 0050 bool writeMimetype) 0051 : KoStore(mode, writeMimetype) 0052 { 0053 m_pZip = new KZip(dev); 0054 init(appIdentification); 0055 } 0056 0057 KoZipStore::KoZipStore(QWidget* window, const QUrl &_url, const QString & _filename, Mode mode, 0058 const QByteArray & appIdentification, bool writeMimetype) 0059 : KoStore(mode, writeMimetype) 0060 { 0061 debugStore << "KoZipStore Constructor url" << _url.url(QUrl::PreferLocalFile) 0062 << " filename = " << _filename 0063 << " mode = " << int(mode) 0064 << " mimetype = " << appIdentification << endl; 0065 Q_D(KoStore); 0066 0067 d->url = _url; 0068 d->window = window; 0069 0070 if (mode == KoStore::Read) { 0071 d->fileMode = KoStorePrivate::RemoteRead; 0072 d->localFileName = _filename; 0073 0074 } else { 0075 d->fileMode = KoStorePrivate::RemoteWrite; 0076 d->localFileName = QLatin1String("/tmp/kozip"); // ### FIXME with KTempFile 0077 } 0078 0079 m_pZip = new KZip(d->localFileName); 0080 init(appIdentification); // open the zip file and init some vars 0081 } 0082 0083 KoZipStore::~KoZipStore() 0084 { 0085 Q_D(KoStore); 0086 debugStore << "KoZipStore::~KoZipStore"; 0087 if (!d->finalized) 0088 finalize(); // ### no error checking when the app forgot to call finalize itself 0089 delete m_pZip; 0090 0091 // Now we have still some job to do for remote files. 0092 if (d->fileMode == KoStorePrivate::RemoteRead) { 0093 KIO::NetAccess::removeTempFile(d->localFileName); 0094 } else if (d->fileMode == KoStorePrivate::RemoteWrite) { 0095 KIO::NetAccess::upload(d->localFileName, d->url, d->window); 0096 // ### FIXME: delete temp file 0097 } 0098 } 0099 0100 void KoZipStore::init(const QByteArray& appIdentification) 0101 { 0102 Q_D(KoStore); 0103 0104 m_currentDir = 0; 0105 d->good = m_pZip->open(d->mode == Write ? QIODevice::WriteOnly : QIODevice::ReadOnly); 0106 0107 if (!d->good) 0108 return; 0109 0110 if (d->mode == Write) { 0111 //debugStore <<"KoZipStore::init writing mimetype" << appIdentification; 0112 0113 m_pZip->setCompression(KZip::NoCompression); 0114 m_pZip->setExtraField(KZip::NoExtraField); 0115 0116 // Write identification 0117 if (d->writeMimetype) { 0118 (void)m_pZip->writeFile(QLatin1String("mimetype"), appIdentification); 0119 } 0120 0121 m_pZip->setCompression(KZip::DeflateCompression); 0122 // We don't need the extra field in Calligra - so we leave it as "no extra field". 0123 } else { 0124 d->good = m_pZip->directory() != 0; 0125 } 0126 } 0127 0128 void KoZipStore::setCompressionEnabled(bool e) 0129 { 0130 if (e) { 0131 m_pZip->setCompression(KZip::DeflateCompression); 0132 } else { 0133 m_pZip->setCompression(KZip::NoCompression); 0134 } 0135 } 0136 0137 bool KoZipStore::doFinalize() 0138 { 0139 return m_pZip->close(); 0140 } 0141 0142 bool KoZipStore::openWrite(const QString& name) 0143 { 0144 Q_D(KoStore); 0145 d->stream = 0; // Don't use! 0146 return m_pZip->prepareWriting(name, "", "" /*m_pZip->rootDir()->user(), m_pZip->rootDir()->group()*/, 0); 0147 } 0148 0149 bool KoZipStore::openRead(const QString& name) 0150 { 0151 Q_D(KoStore); 0152 const KArchiveEntry * entry = m_pZip->directory()->entry(name); 0153 if (entry == 0) { 0154 return false; 0155 } 0156 if (entry->isDirectory()) { 0157 warnStore << name << " is a directory !"; 0158 return false; 0159 } 0160 // Must cast to KZipFileEntry, not only KArchiveFile, because device() isn't virtual! 0161 const KZipFileEntry * f = static_cast<const KZipFileEntry *>(entry); 0162 delete d->stream; 0163 d->stream = f->createDevice(); 0164 d->size = f->size(); 0165 return true; 0166 } 0167 0168 qint64 KoZipStore::write(const char* _data, qint64 _len) 0169 { 0170 Q_D(KoStore); 0171 if (_len == 0) return 0; 0172 //debugStore <<"KoZipStore::write" << _len; 0173 0174 if (!d->isOpen) { 0175 errorStore << "KoStore: You must open before writing" << endl; 0176 return 0; 0177 } 0178 if (d->mode != Write) { 0179 errorStore << "KoStore: Can not write to store that is opened for reading" << endl; 0180 return 0; 0181 } 0182 0183 d->size += _len; 0184 if (m_pZip->writeData(_data, _len)) // writeData returns a bool! 0185 return _len; 0186 return 0; 0187 } 0188 0189 QStringList KoZipStore::directoryList() const 0190 { 0191 QStringList retval; 0192 const KArchiveDirectory *directory = m_pZip->directory(); 0193 foreach(const QString &name, directory->entries()) { 0194 const KArchiveEntry* fileArchiveEntry = m_pZip->directory()->entry(name); 0195 if (fileArchiveEntry->isDirectory()) { 0196 retval << name; 0197 } 0198 } 0199 return retval; 0200 } 0201 0202 bool KoZipStore::closeWrite() 0203 { 0204 Q_D(KoStore); 0205 debugStore << "Wrote file" << d->fileName << " into ZIP archive. size" << d->size; 0206 return m_pZip->finishWriting(d->size); 0207 } 0208 0209 bool KoZipStore::enterRelativeDirectory(const QString& dirName) 0210 { 0211 Q_D(KoStore); 0212 if (d->mode == Read) { 0213 if (!m_currentDir) { 0214 m_currentDir = m_pZip->directory(); // initialize 0215 Q_ASSERT(d->currentPath.isEmpty()); 0216 } 0217 const KArchiveEntry *entry = m_currentDir->entry(dirName); 0218 if (entry && entry->isDirectory()) { 0219 m_currentDir = dynamic_cast<const KArchiveDirectory*>(entry); 0220 return m_currentDir != 0; 0221 } 0222 return false; 0223 } else // Write, no checking here 0224 return true; 0225 } 0226 0227 bool KoZipStore::enterAbsoluteDirectory(const QString& path) 0228 { 0229 if (path.isEmpty()) { 0230 m_currentDir = 0; 0231 return true; 0232 } 0233 m_currentDir = dynamic_cast<const KArchiveDirectory*>(m_pZip->directory()->entry(path)); 0234 Q_ASSERT(m_currentDir); 0235 return m_currentDir != 0; 0236 } 0237 0238 bool KoZipStore::fileExists(const QString& absPath) const 0239 { 0240 const KArchiveEntry *entry = m_pZip->directory()->entry(absPath); 0241 return entry && entry->isFile(); 0242 }