File: kziptest.cpp

package info (click to toggle)
karchive 5.116.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,436 kB
  • sloc: cpp: 10,083; python: 37; sh: 14; makefile: 5
file content (340 lines) | stat: -rw-r--r-- 11,994 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
/*
 *  SPDX-FileCopyrightText: 2002-2013 David Faure <faure@kde.org>
 *
 *  SPDX-License-Identifier: LGPL-2.0-or-later
 */

#include "kzip.h"
#include "kcompressiondevice.h"

#include <QCoreApplication>
#include <QDebug>
#include <QFile>

#include <stdio.h>

void recursive_print(const KArchiveDirectory *dir, const QString &path)
{
    const QStringList lst = dir->entries();
    for (const QString &it : lst) {
        const KArchiveEntry *entry = dir->entry(it);
        printf("mode=%07o %s %s \"%s%s\" size: %lld pos: %lld isdir=%d%s",
               entry->permissions(),
               entry->user().toLatin1().constData(),
               entry->group().toLatin1().constData(),
               path.toLatin1().constData(),
               it.toLatin1().constData(),
               entry->isDirectory() ? 0 : (static_cast<const KArchiveFile *>(entry))->size(),
               entry->isDirectory() ? 0 : (static_cast<const KArchiveFile *>(entry))->position(),
               entry->isDirectory(),
               entry->symLinkTarget().isEmpty() ? "" : QStringLiteral(" symlink: %1").arg(entry->symLinkTarget()).toLatin1().constData());

        //    if (!entry->isDirectory()) printf("%d", (static_cast<const KArchiveFile *>(entry))->size());
        printf("\n");
        if (entry->isDirectory()) {
            recursive_print(static_cast<const KArchiveDirectory *>(entry), path + it + '/');
        }
    }
}

void recursive_transfer(const KArchiveDirectory *dir, const QString &path, KZip *zip)
{
    const QStringList lst = dir->entries();
    for (const QString &it : lst) {
        const KArchiveEntry *e = dir->entry(it);
        qDebug() << "actual file: " << e->name();
        if (e->isFile()) {
            Q_ASSERT(e && e->isFile());
            const KArchiveFile *f = static_cast<const KArchiveFile *>(e);
            printf("FILE=%s\n", qPrintable(e->name()));

            QByteArray arr(f->data());
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
            printf("SIZE=%lli\n", arr.size());
#else
            printf("SIZE=%i\n", arr.size());
#endif
            QString str(arr);
            printf("DATA=%s\n", qPrintable(str));

            if (e->symLinkTarget().isEmpty()) {
                zip->writeFile(path + e->name(), arr);
            } else {
                zip->writeSymLink(path + e->name(), e->symLinkTarget());
            }
        } else if (e->isDirectory()) {
            recursive_transfer(static_cast<const KArchiveDirectory *>(e), path + e->name() + '/', zip);
        }
    }
}

static int doList(const QString &fileName)
{
    KZip zip(fileName);
    if (!zip.open(QIODevice::ReadOnly)) {
        qWarning() << "Could not open" << fileName << "for reading. ZIP file doesn't exist or is invalid:" << zip.errorString();
        return 1;
    }
    const KArchiveDirectory *dir = zip.directory();
    recursive_print(dir, QString());
    zip.close();
    return 0;
}

static int doPrintAll(const QString &fileName)
{
    KZip zip(fileName);
    qDebug() << "Opening zip file";
    if (!zip.open(QIODevice::ReadOnly)) {
        qWarning() << "Could not open" << fileName << "for reading. ZIP file doesn't exist or is invalid:" << zip.errorString();
        return 1;
    }
    const KArchiveDirectory *dir = zip.directory();
    qDebug() << "Listing toplevel of zip file";
    const QStringList lst = dir->entries();
    for (const QString &it : lst) {
        const KArchiveEntry *e = dir->entry(it);
        qDebug() << "Printing" << it;
        if (e->isFile()) {
            Q_ASSERT(e && e->isFile());
            const KArchiveFile *f = static_cast<const KArchiveFile *>(e);
            const QByteArray data(f->data());
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
            printf("SIZE=%lli\n", data.size());
#else
            printf("SIZE=%i\n", data.size());
#endif
            QString str = QString::fromUtf8(data);
            printf("DATA=%s\n", qPrintable(str));
        }
    }
    zip.close();
    return 0;
}

static int doSave(const QString &fileName)
{
    KZip zip(fileName);
    if (!zip.open(QIODevice::WriteOnly)) {
        qWarning() << "Could not open" << fileName << "for writing:" << zip.errorString();
        return 1;
    }

    const QByteArray data = "This is the data for the main file";
    bool writeOk = zip.writeFile(QStringLiteral("maindoc.txt"), data);
    if (!writeOk) {
        qWarning() << "Write error (main file)";
        return 1;
    }
    const QByteArray data2 = "This is the data for the other file";
    writeOk = zip.writeFile(QStringLiteral("subdir/other.txt"), data2);
    if (!writeOk) {
        qWarning() << "Write error (other file)";
        return 1;
    }
    // writeOk = zip.addLocalFile("David.jpg", "picture.jpg");
    // if (!writeOk) {
    //    qWarning() << "Write error (picture)";
    //    return 1;
    //}
    return 0;
}

static int doLoad(const QString &fileName)
{
    KZip zip(fileName);
    if (!zip.open(QIODevice::ReadOnly)) {
        qWarning() << "Could not open" << fileName << "for reading. ZIP file doesn't exist or is invalid:" << zip.errorString();
        return 1;
    }
    const KArchiveDirectory *dir = zip.directory();
    const KArchiveEntry *mainEntry = dir->entry(QStringLiteral("maindoc.txt"));
    Q_ASSERT(mainEntry && mainEntry->isFile());
    const KArchiveFile *mainFile = static_cast<const KArchiveFile *>(mainEntry);
    qDebug() << "maindoc.txt:" << mainFile->data();
    return 0;
}

static int doPrint(const QString &fileName, const QString &entryName)
{
    KZip zip(fileName);
    if (!zip.open(QIODevice::ReadOnly)) {
        qWarning() << "Could not open" << fileName << "for reading. ZIP file doesn't exist or is invalid:" << zip.errorString();
        return 1;
    }
    const KArchiveDirectory *dir = zip.directory();
    const KArchiveEntry *e = dir->entry(entryName);
    Q_ASSERT(e && e->isFile());
    const KArchiveFile *f = static_cast<const KArchiveFile *>(e);

    const QByteArray arr(f->data());
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
    printf("SIZE=%lli\n", arr.size());
#else
    printf("SIZE=%i\n", arr.size());
#endif

    QString str = QString::fromUtf8(arr);
    printf("%s", qPrintable(str));
    return zip.close() ? 0 : 1 /*error*/;
}

static int doCreate(const QString &archiveName, const QStringList &fileNames)
{
    KZip zip(archiveName);
    if (!zip.open(QIODevice::WriteOnly)) {
        qWarning() << "Could not open" << archiveName << "for writing:" << zip.errorString();
        return 1;
    }
    for (const QString &fileName : fileNames) {
        QFile f(fileName);
        if (!f.open(QIODevice::ReadOnly)) {
            qWarning() << "Could not open" << fileName << "for reading:" << zip.errorString();
            return 1;
        }
        zip.writeFile(fileName, f.readAll());
    }
    return zip.close() ? 0 : 1 /*error*/;
}

static int doUpdate(const QString &archiveName, const QString &fileName)
{
    KZip zip(archiveName);
    if (!zip.open(QIODevice::ReadWrite)) {
        qWarning() << "Could not open" << archiveName << "for read/write:" << zip.errorString();
        return 1;
    }

    QFile f(fileName);
    if (!f.open(QIODevice::ReadOnly)) {
        qWarning() << "Could not open" << fileName << "for reading:" << zip.errorString();
        return 1;
    }

    zip.writeFile(fileName, f.readAll());
    return zip.close() ? 0 : 1 /*error*/;
}

static int doTransfer(const QString &sourceFile, const QString &destFile)
{
    KZip zip1(sourceFile);
    KZip zip2(destFile);
    if (!zip1.open(QIODevice::ReadOnly)) {
        qWarning() << "Could not open" << sourceFile << "for reading. ZIP file doesn't exist or is invalid:" << zip1.errorString();
        return 1;
    }
    if (!zip2.open(QIODevice::WriteOnly)) {
        qWarning() << "Could not open" << destFile << "for writing:" << zip2.errorString();
        return 1;
    }
    const KArchiveDirectory *dir1 = zip1.directory();

    recursive_transfer(dir1, QLatin1String(""), &zip2);

    zip1.close();
    zip2.close();
    return 0;
}

static bool save(QIODevice *device)
{
    const QByteArray data = "This is some text that will be compressed.\n";
    const int written = device->write(data);
    if (written != data.size()) {
        qWarning() << "Error writing data";
        return 1;
    }
    // success
    return 0;
}

static int doCompress(const QString &fileName)
{
    KCompressionDevice device(fileName, KCompressionDevice::BZip2);
    if (!device.open(QIODevice::WriteOnly)) {
        qWarning() << "Could not open" << fileName << "for writing:" << device.errorString();
        return 1;
    }

    return save(&device);
}

static bool load(QIODevice *device)
{
    const QByteArray data = device->readAll();
    printf("%s", data.constData());
    return true;
}

static int doUncompress(const QString &fileName)
{
    KCompressionDevice device(fileName, KCompressionDevice::BZip2);
    if (!device.open(QIODevice::ReadOnly)) {
        qWarning() << "Could not open" << fileName << "for reading:" << device.errorString();
        return 1;
    }
    return load(&device);
}

int main(int argc, char **argv)
{
    if (argc < 3) {
        // ###### Note: please consider adding new tests to karchivetest (so that they can be automated)
        // rather than here (interactive)
        printf(
            "\n"
            " Usage :\n"
            " ./kziptest list /path/to/existing_file.zip       tests listing an existing zip\n"
            " ./kziptest print-all file.zip                    prints contents of all files.\n"
            " ./kziptest print file.zip filename               prints contents of one file.\n"
            " ./kziptest create file.zip filenames             create a new zip file with these files.\n"
            " ./kziptest update file.zip filename              update filename in file.zip.\n"
            " ./kziptest save file.zip                         save file.\n"
            " ./kziptest load file.zip                         load file.\n"
            " ./kziptest write file.bz2                        write compressed file.\n"
            " ./kziptest read file.bz2                         read uncompressed file.\n");
        return 1;
    }
    QCoreApplication app(argc, argv);
    QString command = argv[1];
    if (command == QLatin1String("list")) {
        return doList(QFile::decodeName(argv[2]));
    } else if (command == QLatin1String("print-all")) {
        return doPrintAll(QFile::decodeName(argv[2]));
    } else if (command == QLatin1String("print")) {
        if (argc != 4) {
            printf("usage: kziptest print archivename filename");
            return 1;
        }
        return doPrint(QFile::decodeName(argv[2]), argv[3]);
    } else if (command == QLatin1String("save")) {
        return doSave(QFile::decodeName(argv[2]));
    } else if (command == QLatin1String("load")) {
        return doLoad(QFile::decodeName(argv[2]));
    } else if (command == QLatin1String("write")) {
        return doCompress(QFile::decodeName(argv[2]));
    } else if (command == QLatin1String("read")) {
        return doUncompress(QFile::decodeName(argv[2]));
    } else if (command == QLatin1String("create")) {
        if (argc < 4) {
            printf("usage: kziptest create archivename filenames");
            return 1;
        }
        const QStringList fileNames = app.arguments().mid(3);
        return doCreate(QFile::decodeName(argv[2]), fileNames);
    } else if (command == QLatin1String("update")) {
        if (argc != 4) {
            printf("usage: kziptest update archivename filename");
            return 1;
        }
        return doUpdate(QFile::decodeName(argv[2]), QFile::decodeName(argv[3]));
    } else if (command == QLatin1String("transfer")) {
        if (argc != 4) {
            printf("usage: kziptest transfer sourcefile destfile");
            return 1;
        }
        return doTransfer(QFile::decodeName(argv[2]), QFile::decodeName(argv[3]));
    } else {
        printf("Unknown command\n");
    }
}