bool ZipCreator::SaveAs(const WCHAR *zipFilePath) { if (d->pathsAndZipNames.Count() == 0) return false; zlib_filefunc64_def ffunc; fill_win32_filefunc64(&ffunc); zipFile zf = zipOpen2_64(zipFilePath, 0, NULL, &ffunc); if (!zf) return false; bool result = true; for (size_t i = 0; i < d->pathsAndZipNames.Count(); i += 2) { const WCHAR *fileName = d->pathsAndZipNames.At(i); const WCHAR *nameInZip = d->pathsAndZipNames.At(i + 1); size_t fileSize; ScopedMem<char> fileData(file::ReadAll(fileName, &fileSize)); if (!fileData) { result = false; break; } result = AppendFileToZip(zf, nameInZip, fileData, fileSize); if (!result) break; } int err = zipClose(zf, NULL); if (err != ZIP_OK) result = false; return result; }
// TODO: using this for XPS files results in documents that Microsoft XPS Viewer can't read IStream *OpenDirAsZipStream(const WCHAR *dirPath, bool recursive) { if (!dir::Exists(dirPath)) return NULL; ScopedComPtr<IStream> stream; if (FAILED(CreateStreamOnHGlobal(NULL, TRUE, &stream))) return NULL; zlib_filefunc64_def ffunc; fill_win32s_filefunc64(&ffunc); zipFile zf = zipOpen2_64(stream, 0, NULL, &ffunc); if (!zf) return NULL; size_t dirLen = str::Len(dirPath); if (!path::IsSep(dirPath[dirLen - 1])) dirLen++; bool ok = true; DirIter di(dirPath, recursive); for (const WCHAR *filePath = di.First(); filePath && ok; filePath = di.Next()) { CrashIf(!str::StartsWith(filePath, dirPath)); const WCHAR *nameInZip = filePath + dirLen; size_t fileSize; ScopedMem<char> fileData(file::ReadAll(filePath, &fileSize)); ok = fileData && AppendFileToZip(zf, nameInZip, fileData, fileSize); } int err = zipClose(zf, NULL); if (!ok || err != ZIP_OK) return NULL; stream->AddRef(); return stream; }