// 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; }
ZipFile::ZipFile(IStream *stream, ZipMethod method, Allocator *allocator) : filenames(0, allocator), fileinfo(0, allocator), filepos(0, allocator), allocator(allocator), commentLen(0) { zlib_filefunc64_def ffunc; fill_win32s_filefunc64(&ffunc); uf = unzOpen2_64(stream, &ffunc); if (uf) ExtractFilenames(method); }