| 197 | } |
| 198 | |
| 199 | int zipDir(const char* srcDir, const char* outZipPath) |
| 200 | { |
| 201 | std::vector<TransferProto::SendFile> files; |
| 202 | std::vector<std::string> dirs; |
| 203 | if (!collect(srcDir, "", files, dirs)) { |
| 204 | return -1; |
| 205 | } |
| 206 | const std::optional<uint64_t> totalBytes = TransferProto::zipStreamSize(files, dirs); |
| 207 | if (!totalBytes) { |
| 208 | return -1; // exceeds the 4 GB store-only ceiling (no save comes close) |
| 209 | } |
| 210 | |
| 211 | FILE* f = fopen(outZipPath, "wb"); |
| 212 | if (f == nullptr) { |
| 213 | return -1; |
| 214 | } |
| 215 | FileSink sink(f); |
| 216 | StdFileReader reader; |
| 217 | bool wasCancelled = false; |
| 218 | // Drives the reserved innermost bar so a script gets a byte-level bar |
| 219 | // under whatever item-level bar it drives itself, without writing any |
| 220 | // progress code around the call. |
| 221 | ScriptConsole::get().beginIo("zip", (long long)*totalBytes); |
| 222 | const bool ok = TransferProto::sendZipStream( |
| 223 | sink, files, dirs, reader, scriptCancelled, [](size_t n) { ScriptConsole::get().addIo((long long)n); }, wasCancelled); |
| 224 | ScriptConsole::get().endIo(); |
| 225 | fclose(f); |
| 226 | if (!ok) { |
| 227 | remove(outZipPath); |
| 228 | return wasCancelled ? -2 : -1; |
| 229 | } |
| 230 | return 0; |
| 231 | } |
| 232 | |
| 233 | int unzipTo(const char* zipPath, const char* outDir) |
| 234 | { |
no test coverage detected