22#include <wx/filedlg.h>
26#include <wx/wfstream.h>
27#include <wx/zipstrm.h>
43#define ZipFileExtension wxT( "zip" )
52 virtual wxDirTraverseResult
OnFile(
const wxString& aFilename )
override
54 m_files.emplace_back( aFilename );
56 return wxDIR_CONTINUE;
59 virtual wxDirTraverseResult
OnDir(
const wxString& aDirname )
override
61 return wxDIR_CONTINUE;
81 const wxString& aZipFileB,
REPORTER& aReporter )
83 wxFFileInputStream streamA( aZipFileA );
84 wxFFileInputStream streamB( aZipFileB );
86 if( !streamA.IsOk() || !streamB.IsOk() )
92 wxZipInputStream zipStreamA = wxZipInputStream( streamA );
93 wxZipInputStream zipStreamB = wxZipInputStream( streamB );
95 std::set<wxUint32> crcsA;
96 std::set<wxUint32> crcsB;
99 for( wxZipEntry* entry = zipStreamA.GetNextEntry(); entry; entry = zipStreamA.GetNextEntry() )
101 crcsA.insert( entry->GetCrc() );
104 for( wxZipEntry* entry = zipStreamB.GetNextEntry(); entry; entry = zipStreamB.GetNextEntry() )
106 crcsB.insert( entry->GetCrc() );
109 return crcsA == crcsB;
117 wxFFileInputStream stream( aSrcFile );
125 const wxArchiveClassFactory* archiveClassFactory =
126 wxArchiveClassFactory::Find( aSrcFile, wxSTREAM_FILEEXT );
128 if( !archiveClassFactory )
134 std::unique_ptr<wxArchiveInputStream> archiveStream( archiveClassFactory->NewStream( stream ) );
138 for( wxArchiveEntry* entry = archiveStream->GetNextEntry(); entry;
139 entry = archiveStream->GetNextEntry() )
141 fileStatus.Printf(
_(
"Extracting file '%s'." ), entry->GetName() );
149 aReporter.
Report( wxString::Format(
_(
"Refusing to extract file '%s': the archive "
150 "entry points outside of the destination "
157 wxString fullname = target.GetFullPath();
158 const bool isDir = entry->IsDir();
161 wxString t_path = isDir ? fullname : wxPathOnly( fullname );
163 if( !wxDirExists( t_path ) )
165 wxFileName::Mkdir( t_path, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
172 wxTempFileOutputStream outputFileStream( fullname );
174 if(
CopyStreamData( *archiveStream, outputFileStream, entry->GetSize() ) )
175 outputFileStream.Commit();
180 wxFileName outputFileName( fullname );
181 wxDateTime fileTime = entry->GetDateTime();
185 outputFileName.SetTimes( &fileTime, &fileTime, &fileTime );
194 REPORTER& aReporter,
bool aVerbose,
bool aIncludeExtraFiles )
197 std::set<wxString> extensions;
198 std::set<wxString> files;
217 if( aIncludeExtraFiles )
232 extensions.emplace(
"nc" );
233 extensions.emplace(
"xnc" );
244 extensions.emplace(
"pkg" );
250 wxASSERT( gerberFiles.IsValid() );
254 wxString oldCwd = wxGetCwd();
256 wxFileName sourceDir( aSrcDir, wxEmptyString, wxEmptyString );
258 wxSetWorkingDirectory( aSrcDir );
260 wxFFileOutputStream ostream( aDestFile );
262 if( !ostream.IsOk() )
264 msg.Printf(
_(
"Failed to create file '%s'." ), aDestFile );
270 if( FILE* fp = ostream.GetFile()->fp() )
273 wxZipOutputStream zipstream( ostream, -1, wxConvUTF8 );
275 wxDir projectDir( aSrcDir );
277 if( !projectDir.IsOpened() )
279 msg.Printf(
_(
"Error opening directory: '%s'." ), aSrcDir );
282 wxSetWorkingDirectory( oldCwd );
286 size_t uncompressedBytes = 0;
291 projectDir.Traverse( traverser, wxEmptyString, wxDIR_FILES | wxDIR_DIRS );
295 wxFileName fn( fileName );
296 wxString extLower = fn.GetExt().Lower();
297 wxString fileNameLower = fn.GetName().Lower();
298 bool archive =
false;
300 if( !extLower.IsEmpty() )
302 if( ( extensions.find( extLower ) != extensions.end() )
303 || ( aIncludeExtraFiles && gerberFiles.Matches( extLower ) ) )
306 else if( !fileNameLower.IsEmpty() && ( files.find( fileNameLower ) != files.end() ) )
315 fn.MakeRelativeTo( aSrcDir );
317 wxString relativeFn = fn.GetFullPath();
320 wxFSFile* infile =
nullptr;
325 wxLogNull suppressSysErrorPopups;
326 infile = fsFile.OpenFile( relativeFn );
330 if(
unsigned long code = wxSysErrorCode() )
331 sysError = wxSysErrorMsgStr( code );
337 zipstream.PutNextEntry( relativeFn, infile->GetModificationTime() );
338 infile->GetStream()->Read( zipstream );
339 zipstream.CloseEntry();
341 uncompressedBytes += infile->GetStream()->GetSize();
345 msg.Printf(
_(
"Archived file '%s'." ), relativeFn );
353 if( sysError.IsEmpty() )
354 msg.Printf(
_(
"Failed to archive file '%s'." ), relativeFn );
356 msg.Printf(
_(
"Failed to archive file '%s': %s" ), relativeFn, sysError );
363 [](
size_t aSize ) -> wxString
365 constexpr float KB = 1024.0;
366 constexpr float MB = KB * 1024.0;
369 return wxString::Format( wxT(
"%0.2f MB" ), aSize /
MB );
370 else if( aSize >= KB )
371 return wxString::Format( wxT(
"%0.2f KB" ), aSize / KB );
373 return wxString::Format( wxT(
"%zu bytes" ), aSize );
376 if( zipstream.Close() )
380 size_t zipBytesCnt = ostream.GetSize();
384 msg.Printf(
_(
"Zip archive '%s' created (%s uncompressed, %s compressed)." ), aDestFile,
385 reportSize( uncompressedBytes ), reportSize( zipBytesCnt ) );
391 msg.Printf(
_(
"Failed to create file '%s'." ), aDestFile );
396 wxSetWorkingDirectory( oldCwd );
const std::vector< wxString > & GetFilesToArchive() const
virtual wxDirTraverseResult OnDir(const wxString &aDirname) override
virtual wxDirTraverseResult OnFile(const wxString &aFilename) override
std::vector< wxString > m_files
PROJECT_ARCHIVER_DIR_ZIP_TRAVERSER(const wxString &aPrjDir)
static bool Archive(const wxString &aSrcDir, const wxString &aDestFile, REPORTER &aReporter, bool aVerbose=true, bool aIncludeExtraFiles=false)
Create an archive of the project.
static bool Unarchive(const wxString &aSrcFile, const wxString &aDestDir, REPORTER &aReporter)
Extract an archive of the current project over existing files.
static bool AreZipArchivesIdentical(const wxString &aZipFileA, const wxString &aZipFileB, REPORTER &aReporter)
Compare the CRCs of all the files in zip archive to determine whether the archives are identical.
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
static bool ResolveArchiveEntryPath(const wxString &aDestDir, const wxString &aEntryName, wxFileName &aResult)
Resolve an untrusted archive entry name against the directory it is extracted into.
static const std::string LegacySchematicFileExtension
static const wxString GerberFileExtensionsRegex
static const std::string NetlistFileExtension
static const std::string SymbolLibraryTableFileName
static const std::string GerberJobFileExtension
static const std::string StepFileAbrvExtension
static const std::string WorkbookFileExtension
static const std::string ReportFileExtension
static const std::string ProjectFileExtension
static const std::string FootprintPlaceFileExtension
static const std::string JsonFileExtension
static const std::string LegacyPcbFileExtension
static const std::string LegacyProjectFileExtension
static const std::string ProjectLocalSettingsFileExtension
static const std::string KiCadSchematicFileExtension
static const std::string LegacySymbolLibFileExtension
static const std::string DesignBlockLibraryTableFileName
static const std::string KiCadSymbolLibFileExtension
static const std::string SpiceFileExtension
static const std::string PdfFileExtension
static const std::string TextFileExtension
static const std::string FootprintLibraryTableFileName
static const std::string GencadFileExtension
static const std::string DrawingSheetFileExtension
static const std::string IbisFileExtension
static const std::string IpcD356FileExtension
static const std::string KiCadJobSetFileExtension
static const std::string LegacyFootprintLibPathExtension
static const std::string PythonFileExtension
static const std::string StepFileExtension
static const std::string LegacySymbolDocumentFileExtension
static const std::string FootprintAssignmentFileExtension
static const std::string DrillFileExtension
static const std::string SpiceSubcircuitFileExtension
static const std::string SpiceModelFileExtension
static const std::string DesignRulesFileExtension
static const std::string VrmlFileExtension
static const std::string KiCadFootprintFileExtension
static const std::string KiCadPcbFileExtension
This file contains miscellaneous commonly used macros and functions.
static const size_t MB
Tests for the predictive GPU buffer resize strategy guard that keeps a large-board defragmentResize()...
Definition of file extensions used in Kicad.
static bool CopyStreamData(wxInputStream &inputStream, wxOutputStream &outputStream, wxFileOffset size)