Add support for PKZIP-based stpZ files

FreeCAD uses gzip-based stpZ files but many programs will compress using
the archive format of PKZIP (e.g. WinZIP).  This handles the archive
format, taking the first file from the archive, which by the standard
should be the STEP file

Fixes https://gitlab.com/kicad/code/kicad/issues/5376
This commit is contained in:
Seth Hillbrand 2021-02-27 16:41:14 -08:00
parent 061218e567
commit 1d3159c1cb
2 changed files with 44 additions and 12 deletions

View File

@ -33,6 +33,7 @@
#include <wx/stdpaths.h> #include <wx/stdpaths.h>
#include <wx/string.h> #include <wx/string.h>
#include <wx/wfstream.h> #include <wx/wfstream.h>
#include <wx/zipstrm.h>
#include <decompress.hpp> #include <decompress.hpp>
@ -473,6 +474,7 @@ bool readSTEPZ( Handle(TDocStd_Document)& m_doc, const char* aFileName )
return false; return false;
{ {
bool success = false;
wxFFileOutputStream ofile( outFile.GetFullPath() ); wxFFileOutputStream ofile( outFile.GetFullPath() );
if( !ofile.IsOk() ) if( !ofile.IsOk() )
@ -486,17 +488,33 @@ bool readSTEPZ( Handle(TDocStd_Document)& m_doc, const char* aFileName )
try try
{ {
expanded = gzip::decompress( buffer, size ); expanded = gzip::decompress( buffer, size );
success = true;
} }
catch(...) catch(...)
{}
if( expanded.empty() )
{ {
delete[] buffer; ifile.Reset();
return false; ifile.SeekI( 0 );
wxZipInputStream izipfile( ifile );
std::unique_ptr<wxZipEntry> zip_file( izipfile.GetNextEntry() );
if( zip_file && !zip_file->IsDir() && izipfile.CanRead() )
{
izipfile.Read( ofile );
success = true;
}
}
else
{
ofile.Write( expanded.data(), expanded.size() );
} }
delete[] buffer; delete[] buffer;
ofile.Write( expanded.data(), expanded.size() );
ofile.Close(); ofile.Close();
return success;
} }
bool retval = readSTEP( m_doc, outFile.GetFullPath().mb_str() ); bool retval = readSTEP( m_doc, outFile.GetFullPath().mb_str() );

View File

@ -31,6 +31,7 @@
#include <wx/filefn.h> #include <wx/filefn.h>
#include <wx/stdpaths.h> #include <wx/stdpaths.h>
#include <wx/wfstream.h> #include <wx/wfstream.h>
#include <wx/zipstrm.h>
#include <decompress.hpp> #include <decompress.hpp>
@ -1020,14 +1021,11 @@ bool PCBMODEL::getModelLabel( const std::string& aFileName, TRIPLET aScale, TDF_
} }
{ {
bool success = false;
wxFFileOutputStream ofile( outFile.GetFullPath() ); wxFFileOutputStream ofile( outFile.GetFullPath() );
if( !ofile.IsOk() ) if( !ofile.IsOk() )
{
ReportMessage( wxString::Format( "readSTEP() failed on filename %s\n",
outFile.GetFullPath() ) );
return false; return false;
}
char *buffer = new char[size]; char *buffer = new char[size];
@ -1037,17 +1035,33 @@ bool PCBMODEL::getModelLabel( const std::string& aFileName, TRIPLET aScale, TDF_
try try
{ {
expanded = gzip::decompress( buffer, size ); expanded = gzip::decompress( buffer, size );
success = true;
} }
catch(...) catch(...)
{}
if( expanded.empty() )
{ {
delete[] buffer; ifile.Reset();
return false; ifile.SeekI( 0 );
wxZipInputStream izipfile( ifile );
std::unique_ptr<wxZipEntry> zip_file( izipfile.GetNextEntry() );
if( zip_file && !zip_file->IsDir() && izipfile.CanRead() )
{
izipfile.Read( ofile );
success = true;
}
}
else
{
ofile.Write( expanded.data(), expanded.size() );
} }
delete[] buffer; delete[] buffer;
ofile.Write( expanded.data(), expanded.size() );
ofile.Close(); ofile.Close();
return success;
} }
return getModelLabel( outFile.GetFullPath().ToStdString(), aScale, aLabel ); return getModelLabel( outFile.GetFullPath().ToStdString(), aScale, aLabel );