MCPcopy Create free account
hub / github.com/MeshInspector/MeshLib / compressZip

Function compressZip

source/MRMesh/MRZip.cpp:366–475  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

364} // anonymous namespace
365
366Expected<void> compressZip( const std::filesystem::path& zipFile, const std::filesystem::path& sourceFolder, const CompressZipSettings& settings )
367{
368 MR_TIMER;
369
370 if ( !reportProgress( settings.cb, 0.0f ) )
371 return unexpectedOperationCanceled();
372
373 std::error_code ec;
374 if ( !std::filesystem::is_directory( sourceFolder, ec ) )
375 return unexpected( "Directory '" + utf8string( sourceFolder ) + "' does not exist" );
376
377 int err;
378 AutoCloseZip zip( utf8string( zipFile ).c_str(), ZIP_CREATE | ZIP_TRUNCATE, &err, subprogress( settings.cb, 0.8f, 1.0f ) );
379 if ( !zip )
380 return unexpected( "Cannot create zip, error code: " + std::to_string( err ) );
381
382 auto goodFile = [&]( const std::filesystem::path & path )
383 {
384 if ( !is_regular_file( path, ec ) )
385 return false;
386 auto excluded = std::find_if( settings.excludeFiles.begin(), settings.excludeFiles.end(), [&] ( const auto& a )
387 {
388 return std::filesystem::equivalent( a, path, ec );
389 } );
390 return excluded == settings.excludeFiles.end();
391 };
392
393 // pass #1: add directories in the archive and collect the files to compress
394 std::vector<std::pair<std::filesystem::path, std::string>> files;
395 for ( auto entry : DirectoryRecursive{ sourceFolder, ec } )
396 {
397 const auto path = entry.path();
398 if ( entry.is_directory( ec ) && path != sourceFolder )
399 {
400 auto archiveDirPath = utf8string( std::filesystem::relative( path, sourceFolder, ec ) );
401 // convert folder separators in Linux style for the latest 7-zip to open archive correctly
402 std::replace( archiveDirPath.begin(), archiveDirPath.end(), '\\', '/' );
403 if ( zip_dir_add( zip, archiveDirPath.c_str(), ZIP_FL_ENC_UTF_8 ) == -1 )
404 return unexpected( "Cannot add directory " + archiveDirPath + " to archive" );
405 continue;
406 }
407
408 if ( goodFile( path ) )
409 {
410 auto archiveFilePath = utf8string( std::filesystem::relative( path, sourceFolder, ec ) );
411 // convert folder separators in Linux style for the latest 7-zip to open archive correctly
412 std::replace( archiveFilePath.begin(), archiveFilePath.end(), '\\', '/' );
413 files.emplace_back( path, std::move( archiveFilePath ) );
414 }
415 }
416
417 // pass #2: deflate each file in parallel, then hand libzip pre-deflated bytes via a source
418 // callback — libzip's trust-source fast path copies them into the archive without recompressing.
419 // level 0 (the settings-level "use default") normalizes to 6 — zlib's internal default is 6,
420 // and APPNOTE has no sentinel for "default", so 6 is what the archive entry records
421 const int level = settings.compressionLevel == 0 ? 6 : std::clamp( settings.compressionLevel, 1, 9 );
422
423 // Phase A — parallel: read each file and deflate it into entries[i]. The first worker

Callers 4

TESTFunction · 0.85
serializeObjectTreeFunction · 0.85
to3mfFunction · 0.85
exportNesting3mfFunction · 0.85

Calls 15

reportProgressFunction · 0.85
utf8stringFunction · 0.85
subprogressFunction · 0.85
replaceFunction · 0.85
clampFunction · 0.85
ParallelForFunction · 0.85
zlibCompressStreamFunction · 0.85
errorMethod · 0.80
addPreDeflatedEntriesMethod · 0.80
unexpectedFunction · 0.70
beginMethod · 0.45

Tested by 1

TESTFunction · 0.68