22#include <wx/filedlg.h>
25#include <wx/wfstream.h>
26#include <wx/zipstrm.h>
41#define ZipFileExtension wxT( "zip" )
47 wxZipOutputStream& aZipFileOutput,
48 REPORTER& aReporter,
bool aVerbose ) :
57 virtual wxDirTraverseResult
OnFile(
const wxString& aFilename )
override
66 wxFileName package( aFilename );
68 package.SetExt( wxS(
"pkg" ) );
71 if( package.Exists() )
76 return wxDIR_CONTINUE;
79 virtual wxDirTraverseResult
OnDir(
const wxString& aDirname )
override
81 return wxDIR_CONTINUE;
100 wxFileName curr_fn( aFilename );
101 wxFileName curr_prjdir;
109 curr_fn.MakeRelativeTo( curr_prjdir.GetFullPath() );
111 wxString currFilename = curr_fn.GetFullPath();
114 wxFSFile* infile = fsfile.OpenFile( currFilename );
118 m_zipFile.PutNextEntry( currFilename, infile->GetModificationTime() );
126 msg.Printf(
_(
"Archived file '%s'." ), currFilename );
136 msg.Printf(
_(
"Failed to archive file '%s'." ), currFilename );
165 const wxString& aZipFileB,
REPORTER& aReporter )
167 wxFFileInputStream streamA( aZipFileA );
168 wxFFileInputStream streamB( aZipFileB );
170 if( !streamA.IsOk() || !streamB.IsOk() )
176 wxZipInputStream zipStreamA = wxZipInputStream( streamA );
177 wxZipInputStream zipStreamB = wxZipInputStream( streamB );
179 std::set<wxUint32> crcsA;
180 std::set<wxUint32> crcsB;
183 for( wxZipEntry* entry = zipStreamA.GetNextEntry(); entry; entry = zipStreamA.GetNextEntry() )
185 crcsA.insert( entry->GetCrc() );
188 for( wxZipEntry* entry = zipStreamB.GetNextEntry(); entry; entry = zipStreamB.GetNextEntry() )
190 crcsB.insert( entry->GetCrc() );
193 return crcsA == crcsB;
201 wxFFileInputStream stream( aSrcFile );
209 const wxArchiveClassFactory* archiveClassFactory =
210 wxArchiveClassFactory::Find( aSrcFile, wxSTREAM_FILEEXT );
212 if( !archiveClassFactory )
218 std::unique_ptr<wxArchiveInputStream> archiveStream( archiveClassFactory->NewStream( stream ) );
222 for( wxArchiveEntry* entry = archiveStream->GetNextEntry(); entry;
223 entry = archiveStream->GetNextEntry() )
225 fileStatus.Printf(
_(
"Extracting file '%s'." ), entry->GetName() );
228 wxString fullname = aDestDir + entry->GetName();
231 wxString t_path = wxPathOnly( fullname );
233 if( !wxDirExists( t_path ) )
235 wxFileName::Mkdir( t_path, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
243 wxTempFileOutputStream outputFileStream( fullname );
245 if(
CopyStreamData( *archiveStream, outputFileStream, entry->GetSize() ) )
246 outputFileStream.Commit();
251 wxFileName outputFileName( fullname );
252 wxDateTime fileTime = entry->GetDateTime();
256 outputFileName.SetTimes( &fileTime, &fileTime, &fileTime );
265 REPORTER& aReporter,
bool aVerbose,
bool aIncludeExtraFiles )
268#define EXT( ext ) "\\." + ext + "|"
269#define NAME( name ) name + "|"
270#define EXT_NO_PIPE( ext ) "\\." + ext
271#define NAME_NO_PIPE( name ) name
274 std::string fileExtensionRegex =
"("
291 if( aIncludeExtraFiles )
293 fileExtensionRegex +=
"|"
322 fileExtensionRegex +=
")";
331 wxString oldCwd = wxGetCwd();
333 wxFileName sourceDir( aSrcDir );
335 wxSetWorkingDirectory( sourceDir.GetFullPath() );
337 wxFFileOutputStream ostream( aDestFile );
339 if( !ostream.IsOk() )
341 msg.Printf(
_(
"Failed to create file '%s'." ), aDestFile );
346 wxZipOutputStream zipstream( ostream, -1, wxConvUTF8 );
348 wxDir projectDir( aSrcDir );
349 wxString currFilename;
352 if( !projectDir.IsOpened() )
356 msg.Printf(
_(
"Error opening directory: '%s'." ), aSrcDir );
360 wxSetWorkingDirectory( oldCwd );
367 aReporter, aVerbose );
369 projectDir.Traverse( traverser );
374 [](
unsigned long aSize ) -> wxString
376 constexpr float KB = 1024.0;
377 constexpr float MB = KB * 1024.0;
380 return wxString::Format( wxT(
"%0.2f MB" ), aSize / MB );
381 else if( aSize >= KB )
382 return wxString::Format( wxT(
"%0.2f KB" ), aSize / KB );
384 return wxString::Format( wxT(
"%lu bytes" ), aSize );
387 size_t zipBytesCnt = ostream.GetSize();
390 if( zipstream.Close() )
392 msg.Printf(
_(
"Zip archive '%s' created (%s uncompressed, %s compressed)." ),
394 reportSize( uncompressedBytes ),
395 reportSize( zipBytesCnt ) );
400 msg.Printf( wxT(
"Failed to create file '%s'." ), aDestFile );
405 catch(
const std::regex_error& e )
408 wxASSERT_MSG(
false, e.what() );
412 msg.Printf(
_(
"Error: '%s'." ), e.what() );
419 wxSetWorkingDirectory( oldCwd );
wxZipOutputStream & m_zipFile
virtual wxDirTraverseResult OnDir(const wxString &aDirname) override
PROJECT_ARCHIVER_DIR_ZIP_TRAVERSER(const std::string &aExtRegex, const wxString &aPrjDir, wxZipOutputStream &aZipFileOutput, REPORTER &aReporter, bool aVerbose)
virtual wxDirTraverseResult OnFile(const wxString &aFilename) override
unsigned long m_uncompressedBytes
void addFileToZip(const wxString &aFilename)
std::regex m_fileExtRegex
unsigned long GetUncompressedBytes() const
bool GetErrorOccurred() const
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)=0
Report a string with a given severity.
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 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.
#define NAME_NO_PIPE(name)
Definition of file extensions used in Kicad.
static bool CopyStreamData(wxInputStream &inputStream, wxOutputStream &outputStream, wxFileOffset size)