gui2023: a new GUI with ZIP file support
[trut64.git] / gui / gui2023 / ziparchive.cpp
blob91d237a16c0d4cfe40b5bc15bbcd3321024ed4c2
1 /*
2 * Copyright (C) 2023 Anton Blad
3 * Copyright (C) 2023 Fredrik Kuivinen
4 * Copyright (C) 2023 Jakob Rosén
6 * This file is licensed under GPL v2.
7 */
9 // Simple C++ wrapper for minizip
10 // Uses std
12 #include "ziparchive.h"
13 #include <minizip/unzip.h>
15 ZipArchive::ZipArchive(std::string zipname)
17 filename=zipname;
20 bool ZipArchive::isZipFile() {
21 unzFile zipfile=unzOpen(filename.c_str());
22 if (!zipfile) {
23 return false;
25 return true;
28 bool ZipArchive::strEndsWith(const std::string &str, const std::string &suffix) {
29 if (str.length()<suffix.length()) {
30 return false;
32 return str.compare(str.length()-suffix.length(), suffix.length(), suffix) == 0;
35 /// return list of filenames in zip archive
36 std::vector<std::string> ZipArchive::getFilenames(const std::string suffix) {
37 std::vector<std::string> filenames;
38 unzFile zip=unzOpen(filename.c_str());
39 if (!zip) {
40 return filenames; // Return empty list
42 if (UNZ_OK == unzGoToFirstFile(zip)){
43 do {
44 char itemname[MAX_FILENAME_LENGTH];
45 if (UNZ_OK==unzGetCurrentFileInfo(zip, NULL, itemname, sizeof(itemname), NULL, 0, NULL, 0)) {
46 std::string itemstr=std::string(itemname);
47 if (strEndsWith(tolower(itemstr), tolower(suffix))) {
48 filenames.push_back(std::string(itemname));
51 } while (UNZ_OK == unzGoToNextFile(zip));
53 unzClose(zip);
54 return filenames;
57 bool ZipArchive::extractItem(const std::string itemName, struct zip_buffer* zipbuf) {
59 unz_file_info info;
60 int err;
62 unzFile zip = unzOpen(filename.c_str());
63 if (!zip) {
64 fprintf(stderr,"ZipArchive: Could not open zip file\n");
65 return false;
68 err = unzLocateFile(zip, itemName.c_str(), 0);
69 if (err != UNZ_OK) {
70 fprintf(stderr, "ZipArchive: Could not locate file in zip archive\n");
71 return false;
74 err = unzOpenCurrentFile(zip);
75 if (err != UNZ_OK) {
76 fprintf(stderr,"ZipArchive: Could not open located file in zip archive\n");
77 return false;
80 unzGetCurrentFileInfo(zip, &info, NULL, 0, NULL, 0, NULL, 0);
81 printf("ZipArchive: Length of extracted file: %lu\n", info.uncompressed_size);
82 zipbuf->length=info.uncompressed_size;
83 zipbuf->data=(uint8_t*)malloc(info.uncompressed_size);
84 if (zipbuf->data == NULL) {
85 printf("ZipArchive: Error, cannot allocate tap buffer\n");
86 return false;
89 bool return_value=true;
90 int bytes=unzReadCurrentFile(zip, zipbuf->data, info.uncompressed_size);
91 if (bytes<0) {
92 fprintf(stderr, "ZipArchive: Error reading from file in zip archive\n");
93 free(zipbuf->data);
94 return_value=false;
97 unzCloseCurrentFile(zip);
98 unzClose(zip);
100 return return_value;
103 std::string ZipArchive::tolower(std::string str) {
104 std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c){ return std::tolower(c); });
105 return str;