Krita Source Code Documentation
Loading...
Searching...
No Matches
KoQuaZipStore Class Reference

#include <KoQuaZipStore.h>

+ Inheritance diagram for KoQuaZipStore:

Classes

struct  Private
 

Public Member Functions

QStringList directoryList () const override
 
 KoQuaZipStore (const QString &_filename, Mode _mode, const QByteArray &appIdentification, bool writeMimetype=true)
 
 KoQuaZipStore (QIODevice *dev, Mode mode, const QByteArray &appIdentification, bool writeMimetype=true)
 
void setCompressionEnabled (bool enabled) override
 
qint64 write (const char *_data, qint64 _len) override
 
 ~KoQuaZipStore () override
 
- Public Member Functions inherited from KoStore
bool atEnd () const
 
bool bad () const
 
bool close ()
 
QString currentPath () const
 
QIODevice * device () const
 
virtual bool enterDirectory (const QString &directory)
 
bool extractFile (const QString &sourceName, QByteArray &data)
 
bool finalize ()
 
bool hasDirectory (const QString &directoryName)
 
bool hasFile (const QString &fileName) const
 
bool isOpen () const
 
bool leaveDirectory ()
 
Mode mode () const
 
bool open (const QString &name)
 
void popDirectory ()
 
qint64 pos () const
 
void pushDirectory ()
 
qint64 read (char *buffer, qint64 length)
 
QByteArray read (qint64 max)
 
bool seek (qint64 pos)
 See QIODevice.
 
void setSubstitution (const QString &name, const QString &substitution)
 When reading, in the paths in the store where name occurs, substitution is used.
 
qint64 size () const
 
qint64 write (const QByteArray &data)
 
virtual ~KoStore ()
 

Protected Member Functions

bool closeRead () override
 
bool closeWrite () override
 
bool doFinalize () override
 
bool enterAbsoluteDirectory (const QString &path) override
 
bool enterRelativeDirectory (const QString &dirName) override
 
bool fileExists (const QString &absPath) const override
 
void init (const QByteArray &appIdentification)
 
bool openRead (const QString &name) override
 
bool openWrite (const QString &name) override
 
- Protected Member Functions inherited from KoStore
 KoStore (Mode mode, bool writeMimetype=true)
 

Private Attributes

const QScopedPointer< Privatedd
 

Additional Inherited Members

- Public Types inherited from KoStore
enum  Backend { Auto , Zip , Directory }
 
enum  Mode { Read , Write }
 
- Static Public Member Functions inherited from KoStore
static KoStorecreateStore (const QString &fileName, Mode mode, const QByteArray &appIdentification=QByteArray(), Backend backend=Auto, bool writeMimetype=true)
 
static KoStorecreateStore (QIODevice *device, Mode mode, const QByteArray &appIdentification=QByteArray(), Backend backend=Auto, bool writeMimetype=true)
 
- Protected Attributes inherited from KoStore
KoStorePrivated_ptr
 

Detailed Description

Definition at line 15 of file KoQuaZipStore.h.

Constructor & Destructor Documentation

◆ KoQuaZipStore() [1/2]

KoQuaZipStore::KoQuaZipStore ( const QString & _filename,
KoStore::Mode _mode,
const QByteArray & appIdentification,
bool writeMimetype = true )

Definition at line 43 of file KoQuaZipStore.cpp.

44 : KoStore(_mode, writeMimetype)
45 , dd(new Private())
46{
47 Q_D(KoStore);
48 d->localFileName = _filename;
49 dd->archive = new QuaZip(_filename);
50 init(appIdentification);
51
52}
void init(const QByteArray &appIdentification)
const QScopedPointer< Private > dd
KoStore(Mode mode, bool writeMimetype=true)
Definition KoStore.cpp:98

References dd, and init().

◆ KoQuaZipStore() [2/2]

KoQuaZipStore::KoQuaZipStore ( QIODevice * dev,
KoStore::Mode _mode,
const QByteArray & appIdentification,
bool writeMimetype = true )

Definition at line 54 of file KoQuaZipStore.cpp.

55 : KoStore(_mode, writeMimetype)
56 , dd(new Private())
57{
58 dd->archive = new QuaZip(dev);
59 init(appIdentification);
60}

References dd, and init().

◆ ~KoQuaZipStore()

KoQuaZipStore::~KoQuaZipStore ( )
override

Definition at line 62 of file KoQuaZipStore.cpp.

63{
64 Q_D(KoStore);
65
66 if (d->good && dd->currentFile && dd->currentFile->isOpen()) {
67 dd->currentFile->close();
68 }
69
70 if (!d->finalized) {
71 finalize();
72 }
73
74
75 // NOTE:
76 // If the dd->currentFile is corrupt (and ->getZipError() returns an error code)
77 // QuaZip cannot really close it properly (and I don't see an accessible function to reset the error code).
78 // Therefore the destructor thinks the file is open and tries to close it.
79 // And closing the file means checking if the zip archive associated with the file is open or not.
80 // Therefore the archive must exist when the file is being closed, therefore also when it's being deleted.
81 // In comparison, the archive can be deleted whenever and it doesn't check the current file.
82 // Therefore we gotta delete the file first, then the zip archive.
83
84 // From QuaZip code comments for `QuaZipFile(QuaZip *zip, QObject *parent =nullptr);`:
85 // "* Summary: do not close \c zip object or change its current file as
86 // * long as QuaZipFile is open."
87
88 if (dd->currentFile) {
89 delete dd->currentFile;
90 }
91 delete dd->archive;
92
93}
bool finalize()
Definition KoStore.cpp:395

References dd, and KoStore::finalize().

Member Function Documentation

◆ closeRead()

bool KoQuaZipStore::closeRead ( )
overrideprotectedvirtual
Returns
true on success

Implements KoStore.

Definition at line 270 of file KoQuaZipStore.cpp.

271{
272 Q_D(KoStore);
273 d->stream = 0;
274 return true;
275}

◆ closeWrite()

bool KoQuaZipStore::closeWrite ( )
overrideprotectedvirtual
Returns
true on success

Implements KoStore.

Definition at line 253 of file KoQuaZipStore.cpp.

254{
255 Q_D(KoStore);
256
257 bool r = true;
258 if (dd->currentFile->write(dd->cache) != dd->cache.size()) {
259 // write() returns number of bytes written, or -1 in case of error
260 // let's allow write 0 bytes in the cache, when needed
261 qWarning() << "Could not write buffer to the file";
262 r = false;
263 }
264 dd->buffer.close();
265 dd->currentFile->close();
266 d->stream = 0;
267 return (r && dd->currentFile->getZipError() == ZIP_OK);
268}

References dd.

◆ directoryList()

QStringList KoQuaZipStore::directoryList ( ) const
overridevirtual

If an store is opened for reading, then the directories of the store can be accessed via this function.

Returns
a stringlist with all directories found

Reimplemented from KoStore.

Definition at line 126 of file KoQuaZipStore.cpp.

127{
128 // If in Read mode, we can assume the directory listing won't change between invocations.
129 if(mode() == Read) {
130 if(!dd->directoryListCached) {
131 dd->directoryListCache = dd->archive->getFileNameList();
132 dd->directoryListCached = true;
133 }
134 return dd->directoryListCache;
135 }
136 else {
137 return dd->archive->getFileNameList();
138 }
139}
@ Read
Definition KoStore.h:29
Mode mode() const
Definition KoStore.cpp:420

References dd, KoStore::mode(), and KoStore::Read.

◆ doFinalize()

bool KoQuaZipStore::doFinalize ( )
overrideprotectedvirtual

Finalize store - called by finalize.

Returns
true on success

Reimplemented from KoStore.

Definition at line 181 of file KoQuaZipStore.cpp.

182{
183 Q_D(KoStore);
184
185 d->stream = 0;
186 if (d->good && !dd->usingSaveFile) {
187 dd->archive->close();
188 }
189 return dd->archive->getZipError() == ZIP_OK;
190
191}

References dd.

◆ enterAbsoluteDirectory()

bool KoQuaZipStore::enterAbsoluteDirectory ( const QString & path)
overrideprotectedvirtual

Enter a directory where we've been before. It is guaranteed to always exist.

Implements KoStore.

Definition at line 282 of file KoQuaZipStore.cpp.

283{
284 QString fixedPath = path;
285 fixedPath.replace("//", "/");
286
287 if (fixedPath.isEmpty()) {
288 fixedPath = "/";
289 }
290
291 QuaZipDir currentDir (dd->archive, fixedPath);
292
293 return currentDir.exists();
294}

References dd.

◆ enterRelativeDirectory()

bool KoQuaZipStore::enterRelativeDirectory ( const QString & dirName)
overrideprotectedvirtual

Enter a subdirectory of the current directory. The directory might not exist yet in Write mode.

Implements KoStore.

Definition at line 277 of file KoQuaZipStore.cpp.

278{
279 return true;
280}

◆ fileExists()

bool KoQuaZipStore::fileExists ( const QString & absPath) const
overrideprotectedvirtual

Check if a file exists inside the store.

Parameters
absPaththe absolute path inside the store, i.e. not relative to the current directory

Implements KoStore.

Definition at line 296 of file KoQuaZipStore.cpp.

297{
298 Q_D(const KoStore);
299
300 QString fixedPath = absPath;
301 fixedPath.replace("//", "/");
302
303 if (!d->substituteThis.isEmpty()) {
304 fixedPath = fixedPath.replace(d->substituteThis, d->substituteWith);
305 }
306
307 return directoryList().contains(fixedPath);
308}
QStringList directoryList() const override

References directoryList().

◆ init()

void KoQuaZipStore::init ( const QByteArray & appIdentification)
protected

Definition at line 141 of file KoQuaZipStore.cpp.

142{
143 Q_D(KoStore);
144
145 bool enableZip64 = false;
146 if (appIdentification == "application/x-krita") {
147 enableZip64 = KSharedConfig::openConfig()->group("").readEntry<bool>("UseZip64", false);
148 }
149
150 dd->archive->setDataDescriptorWritingEnabled(false);
151 dd->archive->setZip64Enabled(enableZip64);
152 dd->archive->setFileNameCodec("UTF-8");
153 dd->usingSaveFile = dd->archive->getIoDevice() && dd->archive->getIoDevice()->inherits("QSaveFile");
154 dd->archive->setAutoClose(!dd->usingSaveFile);
155
156 d->good = dd->archive->open(d->mode == Write ? QuaZip::mdCreate : QuaZip::mdUnzip);
157
158 if (!d->good) {
159 return;
160 }
161
162 if (d->mode == Write) {
163 if (d->writeMimetype) {
164 QuaZipFile f(dd->archive);
165 QuaZipNewInfo newInfo("mimetype");
166 newInfo.setPermissions(QFileDevice::ReadOwner | QFileDevice::ReadGroup | QFileDevice::ReadOther);
167 if (!f.open(QIODevice::WriteOnly, newInfo, 0, 0, 0, Z_NO_COMPRESSION)) {
168 d->good = false;
169 return;
170 }
171 f.write(appIdentification);
172 f.close();
173 }
174 }
175 else {
176 debugStore << dd->archive->getEntriesCount() << directoryList();
177 d->good = dd->archive->getEntriesCount();
178 }
179}
#define debugStore
Definition StoreDebug.h:15
@ Write
Definition KoStore.h:29

References dd, debugStore, directoryList(), and KoStore::Write.

◆ openRead()

bool KoQuaZipStore::openRead ( const QString & name)
overrideprotectedvirtual

Open the file name in the store, for reading. On success, this method must set m_stream to a stream from which we can read, as well as setting m_iSize to the size of the file.

Parameters
name"absolute path" (in the archive) to the file to open
Returns
true on success

Implements KoStore.

Definition at line 218 of file KoQuaZipStore.cpp.

219{
220 Q_D(KoStore);
221
222 QString fixedPath = name;
223 fixedPath.replace("//", "/");
224
225 delete d->stream;
226 d->stream = 0;
227 delete dd->currentFile;
228 dd->currentFile = 0;
229
230 if (!currentPath().isEmpty() && !fixedPath.startsWith(currentPath())) {
231 fixedPath = currentPath() + '/' + fixedPath;
232 }
233
234 if (!d->substituteThis.isEmpty()) {
235 fixedPath = fixedPath.replace(d->substituteThis, d->substituteWith);
236 }
237
238 if (!dd->archive->setCurrentFile(fixedPath)) {
239 qWarning() << "\t\tCould not set current file" << dd->archive->getZipError() << fixedPath;
240 return false;
241 }
242
243 dd->currentFile = new QuaZipFile(dd->archive);
244 if (!dd->currentFile->open(QIODevice::ReadOnly)) {
245 qWarning() << "\t\t\tBut could not open!!!" << dd->archive->getZipError();
246 return false;
247 }
248 d->stream = dd->currentFile;
249 d->size = dd->currentFile->size();
250 return true;
251}
QString currentPath() const
Definition KoStore.cpp:281
const char * name(StandardAction id)

References KoStore::currentPath(), and dd.

◆ openWrite()

bool KoQuaZipStore::openWrite ( const QString & name)
overrideprotectedvirtual

Open the file name in the store, for writing On success, this method must set m_stream to a stream in which we can write.

Parameters
name"absolute path" (in the archive) to the file to open
Returns
true on success

Implements KoStore.

Definition at line 193 of file KoQuaZipStore.cpp.

194{
195 Q_D(KoStore);
196 QString fixedPath = name;
197 fixedPath.replace("//", "/");
198
199 delete d->stream;
200 d->stream = 0; // Not used when writing
201
202 delete dd->currentFile;
203 dd->currentFile = new QuaZipFile(dd->archive);
204 QuaZipNewInfo newInfo(fixedPath);
205 newInfo.setPermissions(QFileDevice::ReadOwner | QFileDevice::ReadGroup | QFileDevice::ReadOther);
206 bool r = dd->currentFile->open(QIODevice::WriteOnly, newInfo, 0, 0, Z_DEFLATED, dd->compressionLevel);
207 if (!r) {
208 qWarning() << "Could not open" << name << dd->currentFile->getZipError();
209 }
210
211 dd->cache = QByteArray();
212 dd->buffer.setBuffer(&dd->cache);
213 dd->buffer.open(QBuffer::WriteOnly);
214
215 return r;
216}

References dd.

◆ setCompressionEnabled()

void KoQuaZipStore::setCompressionEnabled ( bool e)
overridevirtual

Allow to enable or disable compression of the files. Only supported by the ZIP backend.

Reimplemented from KoStore.

Definition at line 95 of file KoQuaZipStore.cpp.

96{
97
98 if (enabled) {
99 dd->compressionLevel = Z_DEFAULT_COMPRESSION;
100 }
101 else {
102 dd->compressionLevel = Z_NO_COMPRESSION;
103 }
104}

References dd.

◆ write()

qint64 KoQuaZipStore::write ( const char * data,
qint64 length )
overridevirtual

Write data into the currently opened file. You can also use the streams for this.

Reimplemented from KoStore.

Definition at line 106 of file KoQuaZipStore.cpp.

107{
108 Q_D(KoStore);
109 if (_len == 0) return 0;
110
111 if (!d->isOpen) {
112 errorStore << "KoStore: You must open before writing" << Qt::endl;
113 return 0;
114 }
115
116 if (d->mode != Write) {
117 errorStore << "KoStore: Can not write to store that is opened for reading" << Qt::endl;
118 return 0;
119 }
120
121 qint64 nwritten = dd->buffer.write(_data, _len);
122 d->size += nwritten;
123 return nwritten;
124}
#define errorStore
Definition StoreDebug.h:17

References dd, errorStore, and KoStore::Write.

Member Data Documentation

◆ dd

const QScopedPointer<Private> KoQuaZipStore::dd
private

Definition at line 44 of file KoQuaZipStore.h.


The documentation for this class was generated from the following files: