ZIPProvider::ZIPHandle * ZIPProvider::getZIPHandle( const std::string & archiveFileName, bool createFile) { ZIPHandle * handle = nullptr; // Check if archive is already opened. auto it = openHandles.find(archiveFileName); if (it != openHandles.end()) { return it->second; } int flags = ZIP_CHECKCONS; // Check if archive exists. if (!FileUtils::isFile(FileName(archiveFileName))) { if (!createFile) { return nullptr; } else { flags |= ZIP_CREATE; } } // Open archive. int error; zip * zipHandle = zip_open(archiveFileName.c_str(), flags, &error); if (zipHandle == nullptr) { char errorString[256]; zip_error_to_str(errorString, 256, error, errno); WARN(errorString+std::string(" File: ")+archiveFileName); return nullptr; } FileName archiveRoot; archiveRoot.setFSName("zip"); archiveRoot.setDir( archiveFileName+'$' ); handle = new ZIPHandle(archiveRoot,zipHandle); openHandles[archiveFileName] = handle; return handle; }
AbstractFSProvider::status_t ZIPProvider::ZIPHandle::dir( const std::string & localDirectory, std::list<FileName> & result, const uint8_t flags) { int num = zip_get_num_files(handle); if (num == -1) { WARN(zip_strerror(handle)); return FAILURE; } struct zip_stat sb; zip_stat_init(&sb); // Iterate over indices. for (int i = 0; i < num; ++i) { if (zip_stat_index(handle, i, 0, &sb) == -1) { WARN(zip_strerror(handle)); return FAILURE; } FileName entryFileName(sb.name); // Determine if the entry is a file or a directory. if (entryFileName.getFile().empty()) { if(!(flags & FileUtils::DIR_DIRECTORIES)) { continue; } if (!(flags & FileUtils::DIR_RECURSIVE)) { std::string entryDirectory = entryFileName.getDir(); if(entryDirectory == localDirectory) { continue; } if(entryDirectory.back() == '/') { entryDirectory.resize(entryDirectory.size() - 1); } const auto slashPos = entryDirectory.find_last_of('/'); if(slashPos != std::string::npos) { entryDirectory = entryDirectory.substr(0, slashPos + 1); } else { entryDirectory.clear(); } // Compare the parent directory of the directory with the requested localDirectory. if(entryDirectory != localDirectory) { continue; } } } else { if(!(flags & FileUtils::DIR_FILES)) { continue; } // Compare the directory of the file with the requested localDirectory. if (!(flags & FileUtils::DIR_RECURSIVE) && entryFileName.getDir() != localDirectory) { continue; } } // Check for hidden files beginning with '.' (files only). if (entryFileName.getFile().front() == '.' && !(flags & FileUtils::DIR_HIDDEN_FILES)) { continue; } FileName f; f.setFSName(archiveRoot.getFSName()); f.setDir(archiveRoot.getDir() + entryFileName.getDir()); f.setFile(entryFileName.getFile()); result.push_back(f); } return OK; }