Warning, file /office/calligra/libs/store/KoTarStore.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 "KoTarStore.h"
0022 #include "KoStore_p.h"
0023 
0024 #include <QBuffer>
0025 
0026 #include <QByteArray>
0027 
0028 #include <ktar.h>
0029 #include <StoreDebug.h>
0030 #include <QUrl>
0031 
0032 #include <KoNetAccess.h>
0033 
0034 KoTarStore::KoTarStore(const QString & _filename, Mode mode, const QByteArray & appIdentification,
0035                        bool writeMimetype)
0036  : KoStore(mode, writeMimetype)
0037 {
0038     debugStore << "KoTarStore Constructor filename =" << _filename
0039     << " mode = " << int(mode) << endl;
0040     Q_D(KoStore);
0041 
0042     d->localFileName = _filename;
0043 
0044     m_pTar = new KTar(_filename, "application/x-gzip");
0045 
0046     init(appIdentification);   // open the targz file and init some vars
0047 }
0048 
0049 KoTarStore::KoTarStore(QIODevice *dev, Mode mode, const QByteArray & appIdentification,
0050                        bool writeMimetype)
0051  : KoStore(mode, writeMimetype)
0052 {
0053     m_pTar = new KTar(dev);
0054 
0055     init(appIdentification);
0056 }
0057 
0058 KoTarStore::KoTarStore(QWidget* window, const QUrl &_url, const QString & _filename, Mode mode,
0059                        const QByteArray & appIdentification, bool writeMimetype)
0060  : KoStore(mode, writeMimetype)
0061 {
0062     debugStore << "KoTarStore Constructor url=" << _url.url(QUrl::PreferLocalFile)
0063                   << " filename = " << _filename
0064                   << " mode = " << int(mode) << 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 = "/tmp/kozip"; // ### FIXME with KTempFile
0077     }
0078 
0079     m_pTar = new KTar(d->localFileName, "application/x-gzip");
0080 
0081     init(appIdentification);   // open the targz file and init some vars
0082 }
0083 
0084 KoTarStore::~KoTarStore()
0085 {
0086     Q_D(KoStore);
0087     if (!d->finalized)
0088         finalize(); // ### no error checking when the app forgot to call finalize itself
0089     delete m_pTar;
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 QStringList KoTarStore::directoryList() const
0101 {
0102     QStringList retval;
0103     const KArchiveDirectory *directory = m_pTar->directory();
0104     foreach(const QString &name, directory->entries()) {
0105         const KArchiveEntry* fileArchiveEntry = m_pTar->directory()->entry(name);
0106         if (fileArchiveEntry->isDirectory()) {
0107             retval << name;
0108         }
0109     }
0110     return retval;
0111 }
0112 
0113 QByteArray KoTarStore::completeMagic(const QByteArray& appMimetype)
0114 {
0115     debugStore << "QCString KoTarStore::completeMagic( const QCString& appMimetype )********************";
0116     QByteArray res("Calligra ");
0117     res += appMimetype;
0118     res += '\004'; // Two magic bytes to make the identification
0119     res += '\006'; // more reliable (DF)
0120     debugStore << "sssssssssssssssssssssxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
0121     debugStore << " return :!!!!!!!!!!!!!!! :" << res;
0122     return res;
0123 }
0124 
0125 void KoTarStore::init(const QByteArray &appIdentification)
0126 {
0127     Q_D(KoStore);
0128     m_currentDir = 0;
0129     d->good = m_pTar->open(d->mode == Write ? QIODevice::WriteOnly : QIODevice::ReadOnly);
0130 
0131     if (!d->good)
0132         return;
0133 
0134     if (d->mode == Write) {
0135         debugStore << "appIdentification :" << appIdentification;
0136         m_pTar->setOrigFileName(completeMagic(appIdentification));
0137     } else {
0138         d->good = m_pTar->directory() != 0;
0139     }
0140 }
0141 
0142 bool KoTarStore::doFinalize()
0143 {
0144     return m_pTar->close();
0145 }
0146 
0147 // When reading, d->stream comes directly from KArchiveFile::device()
0148 // When writing, d->stream buffers the data into m_byteArray
0149 
0150 bool KoTarStore::openWrite(const QString& /*name*/)
0151 {
0152     Q_D(KoStore);
0153     // Prepare memory buffer for writing
0154     m_byteArray.resize(0);
0155     d->stream = new QBuffer(&m_byteArray);
0156     d->stream->open(QIODevice::WriteOnly);
0157     return true;
0158 }
0159 
0160 bool KoTarStore::openRead(const QString& name)
0161 {
0162     Q_D(KoStore);
0163     const KArchiveEntry * entry = m_pTar->directory()->entry(name);
0164     if (entry == 0) {
0165         return false;
0166     }
0167     if (entry->isDirectory()) {
0168         warnStore << name << " is a directory !";
0169         return false;
0170     }
0171     KArchiveFile * f = (KArchiveFile *) entry;
0172     m_byteArray.resize(0);
0173     delete d->stream;
0174     d->stream = f->createDevice();
0175     d->size = f->size();
0176     return true;
0177 }
0178 
0179 bool KoTarStore::closeWrite()
0180 {
0181     Q_D(KoStore);
0182     // write the whole bytearray at once into the tar file
0183 
0184     debugStore << "Writing file" << d->fileName << " into TAR archive. size" << d->size;
0185     m_byteArray.resize(d->size); // TODO: check if really needed
0186     if (!m_pTar->writeFile(d->fileName, m_byteArray, 0100644, QLatin1String("user"), QLatin1String("group")))
0187         warnStore << "Failed to write " << d->fileName;
0188     m_byteArray.resize(0);   // save memory
0189     return true;
0190 }
0191 
0192 bool KoTarStore::enterRelativeDirectory(const QString& dirName)
0193 {
0194     Q_D(KoStore);
0195     if (d->mode == Read) {
0196         if (!m_currentDir) {
0197             m_currentDir = m_pTar->directory(); // initialize
0198             Q_ASSERT(d->currentPath.isEmpty());
0199         }
0200         const KArchiveEntry *entry = m_currentDir->entry(dirName);
0201         if (entry && entry->isDirectory()) {
0202             m_currentDir = dynamic_cast<const KArchiveDirectory*>(entry);
0203             return m_currentDir != 0;
0204         }
0205         return false;
0206     } else // Write, no checking here
0207         return true;
0208 }
0209 
0210 bool KoTarStore::enterAbsoluteDirectory(const QString& path)
0211 {
0212     Q_D(KoStore);
0213     if (path.isEmpty()) {
0214         m_currentDir = 0;
0215         return true;
0216     }
0217     if (d->mode == Read) {
0218         m_currentDir = dynamic_cast<const KArchiveDirectory*>(m_pTar->directory()->entry(path));
0219         Q_ASSERT(m_currentDir);
0220         return m_currentDir != 0;
0221     } else
0222         return true;
0223 }
0224 
0225 bool KoTarStore::fileExists(const QString& absPath) const
0226 {
0227     return m_pTar->directory()->entry(absPath) != 0;
0228 }