MCPcopy Create free account
hub / github.com/VCVRack/Rack / archiveDirectory

Function archiveDirectory

src/system.cpp:384–485  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

382
383
384static void archiveDirectory(const std::string& archivePath, std::vector<uint8_t>* archiveData, const std::string& dirPath, int compressionLevel) {
385 // Based on minitar.c create() in libarchive examples
386 int r;
387
388 // Open archive for writing
389 struct archive* a = archive_write_new();
390 DEFER({archive_write_free(a);});
391 // For some reason libarchive adds 10k of padding to archive_write_open() (but not archive_write_open_filename()) unless this is set to 0.
392 archive_write_set_bytes_per_block(a, 0);
393 archive_write_set_format_pax_restricted(a);
394 archive_write_add_filter_zstd(a);
395 if (!(0 <= compressionLevel && compressionLevel <= 19))
396 throw Exception("Invalid Zstandard compression level");
397 r = archive_write_set_filter_option(a, NULL, "compression-level", std::to_string(compressionLevel).c_str());
398 if (r < ARCHIVE_OK)
399 throw Exception("Archiver could not set filter option: %s", archive_error_string(a));
400
401 if (archiveData) {
402 // Open vector
403 archive_write_open(a, (void*) archiveData, NULL, archiveWriteVectorCallback, NULL);
404 }
405 else {
406 // Open file
407#if defined ARCH_WIN
408 r = archive_write_open_filename_w(a, string::UTF8toUTF16(archivePath).c_str());
409#else
410 r = archive_write_open_filename(a, archivePath.c_str());
411#endif
412 if (r < ARCHIVE_OK)
413 throw Exception("Archiver could not open archive %s for writing: %s", archivePath.c_str(), archive_error_string(a));
414 }
415 DEFER({archive_write_close(a);});
416
417 // Open dir for reading
418 struct archive* disk = archive_read_disk_new();
419 DEFER({archive_read_free(disk);});
420#if defined ARCH_WIN
421 r = archive_read_disk_open_w(disk, string::UTF8toUTF16(dirPath).c_str());
422#else
423 r = archive_read_disk_open(disk, dirPath.c_str());
424#endif
425 if (r < ARCHIVE_OK)
426 throw Exception("Archiver could not open dir %s for reading: %s", dirPath.c_str(), archive_error_string(a));
427 DEFER({archive_read_close(a);});
428
429 // Iterate dir
430 for (;;) {
431 struct archive_entry* entry = archive_entry_new();
432 DEFER({archive_entry_free(entry);});
433
434 r = archive_read_next_header2(disk, entry);
435 if (r == ARCHIVE_EOF)
436 break;
437 if (r < ARCHIVE_OK)
438 throw Exception("Archiver could not get next entry from archive: %s", archive_error_string(disk));
439
440 // Recurse dirs
441 archive_read_disk_descend(disk);

Callers 1

saveMethod · 0.85

Calls 4

ExceptionClass · 0.85
UTF8toUTF16Function · 0.85
UTF16toUTF8Function · 0.85
getRelativePathFunction · 0.85

Tested by

no test coverage detected