22#include <wx/filedlg.h>
25#include <wx/wfstream.h>
26#include <wx/zipstrm.h>
39#define ZipFileExtension wxT( "zip" )
46 const wxString& aZipFileB,
REPORTER& aReporter )
48 wxFFileInputStream streamA( aZipFileA );
49 wxFFileInputStream streamB( aZipFileB );
51 if( !streamA.IsOk() || !streamB.IsOk() )
57 wxZipInputStream zipStreamA = wxZipInputStream( streamA );
58 wxZipInputStream zipStreamB = wxZipInputStream( streamB );
60 std::set<wxUint32> crcsA;
61 std::set<wxUint32> crcsB;
64 for( wxZipEntry* entry = zipStreamA.GetNextEntry(); entry; entry = zipStreamA.GetNextEntry() )
66 crcsA.insert( entry->GetCrc() );
69 for( wxZipEntry* entry = zipStreamB.GetNextEntry(); entry; entry = zipStreamB.GetNextEntry() )
71 crcsB.insert( entry->GetCrc() );
74 return crcsA == crcsB;
82 wxFFileInputStream stream( aSrcFile );
90 const wxArchiveClassFactory* archiveClassFactory =
91 wxArchiveClassFactory::Find( aSrcFile, wxSTREAM_FILEEXT );
93 if( !archiveClassFactory )
99 std::unique_ptr<wxArchiveInputStream> archiveStream( archiveClassFactory->NewStream( stream ) );
103 for( wxArchiveEntry* entry = archiveStream->GetNextEntry(); entry;
104 entry = archiveStream->GetNextEntry() )
106 fileStatus.Printf(
_(
"Extracting file '%s'." ), entry->GetName() );
109 wxString fullname = aDestDir + entry->GetName();
112 wxString t_path = wxPathOnly( fullname );
114 if( !wxDirExists( t_path ) )
116 wxFileName::Mkdir( t_path, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
124 wxTempFileOutputStream outputFileStream( fullname );
126 if(
CopyStreamData( *archiveStream, outputFileStream, entry->GetSize() ) )
127 outputFileStream.Commit();
132 wxFileName outputFileName( fullname );
133 wxDateTime fileTime = entry->GetDateTime();
136 outputFileName.SetTimes( &fileTime, &fileTime, &fileTime );
145 REPORTER& aReporter,
bool aVerbose,
bool aIncludeExtraFiles )
149 wxT(
"*.kicad_pro" ),
150 wxT(
"*.kicad_prl" ),
151 wxT(
"*.kicad_sch" ),
152 wxT(
"*.kicad_sym" ),
153 wxT(
"*.kicad_pcb" ),
154 wxT(
"*.kicad_mod" ),
155 wxT(
"*.kicad_dru" ),
156 wxT(
"*.kicad_wks" ),
157 wxT(
"*.kicad_jobset" ),
159 wxT(
"fp-lib-table" ),
160 wxT(
"sym-lib-table" )
164 static const wxChar* extraExtensionList[] = {
167 wxT(
"*.lib" ), wxT(
"*.dcm" ),
171 wxT(
"*.stp" ), wxT(
"*.step" ),
173 wxT(
"*.g?" ), wxT(
"*.g??" ),
177 wxT(
"*.drl" ), wxT(
"*.nc" ), wxT(
"*.xnc" ),
184 wxT(
"*.cir" ), wxT(
"*.sub" ), wxT(
"*.model" ),
190 wxString oldCwd = wxGetCwd();
192 wxSetWorkingDirectory( aSrcDir );
194 wxFFileOutputStream ostream( aDestFile );
196 if( !ostream.IsOk() )
198 msg.Printf(
_(
"Failed to create file '%s'." ), aDestFile );
203 wxZipOutputStream zipstream( ostream, -1, wxConvUTF8 );
206 wxString currFilename;
213 if( aIncludeExtraFiles )
215 for(
unsigned ii = 0; ii <
arrayDim( extraExtensionList ); ii++ )
216 wxDir::GetAllFiles( aSrcDir, &files, extraExtensionList[ii] );
219 for(
unsigned ii = 0; ii < files.GetCount(); ++ii )
221 if( files[ii].EndsWith( wxS(
".ibs" ) ) )
223 wxFileName package( files[ ii ] );
224 package.MakeRelativeTo( aSrcDir );
225 package.SetExt( wxS(
"pkg" ) );
227 if( package.Exists() )
228 files.push_back( package.GetFullName() );
234 unsigned long uncompressedBytes = 0;
239 wxString lastStoredFile;
241 for(
unsigned ii = 0; ii < files.GetCount(); ii++ )
243 if( lastStoredFile == files[ii] )
246 lastStoredFile = files[ii];
250 wxFileName curr_fn( files[ii] );
251 curr_fn.MakeRelativeTo( aSrcDir );
252 currFilename = curr_fn.GetFullPath();
255 wxFSFile* infile = fsfile.OpenFile( wxFileSystem::FileNameToURL( curr_fn ) );
259 zipstream.PutNextEntry( currFilename, infile->GetModificationTime() );
260 infile->GetStream()->Read( zipstream );
261 zipstream.CloseEntry();
263 uncompressedBytes += infile->GetStream()->GetSize();
267 msg.Printf(
_(
"Archived file '%s'." ), currFilename );
277 msg.Printf(
_(
"Failed to archive file '%s'." ), currFilename );
286 [](
unsigned long aSize ) -> wxString
288 constexpr float KB = 1024.0;
289 constexpr float MB = KB * 1024.0;
292 return wxString::Format( wxT(
"%0.2f MB" ), aSize / MB );
293 else if( aSize >= KB )
294 return wxString::Format( wxT(
"%0.2f KB" ), aSize / KB );
296 return wxString::Format( wxT(
"%lu bytes" ), aSize );
299 size_t zipBytesCnt = ostream.GetSize();
301 if( zipstream.Close() )
303 msg.Printf(
_(
"Zip archive '%s' created (%s uncompressed, %s compressed)." ),
305 reportSize( uncompressedBytes ),
306 reportSize( zipBytesCnt ) );
311 msg.Printf( wxT(
"Failed to create file '%s'." ), aDestFile );
316 wxSetWorkingDirectory( oldCwd );
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
static bool Archive(const wxString &aSrcDir, const wxString &aDestFile, REPORTER &aReporter, bool aVerbose=true, bool aIncludeExtraFiles=false)
Creates an archive of the project.
static bool Unarchive(const wxString &aSrcFile, const wxString &aDestDir, REPORTER &aReporter)
Extracts an archive of the current project over existing files Warning: this will overwrite files in ...
static bool AreZipArchivesIdentical(const wxString &aZipFileA, const wxString &aZipFileB, REPORTER &aReporter)
Compares 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.
This file contains miscellaneous commonly used macros and functions.
static const std::vector< std::string > extensionList
Definition of file extensions used in Kicad.
static bool CopyStreamData(wxInputStream &inputStream, wxOutputStream &outputStream, wxFileOffset size)