37bool QgsZipUtils::unzip( 
const QString &zipFilename, 
const QString &dir, QStringList &files, 
bool checkConsistency )
 
   41  if ( !QFileInfo::exists( zipFilename ) )
 
   46  else if ( zipFilename.isEmpty() )
 
   51  else if ( !QDir( dir ).exists( dir ) )
 
   56  else if ( !QFileInfo( dir ).isDir() )
 
   61  else if ( !QFileInfo( dir ).isWritable() )
 
   68  const QByteArray fileNamePtr = zipFilename.toUtf8();
 
   69  struct zip *z = zip_open( fileNamePtr.constData(), checkConsistency ? ZIP_CHECKCONS : 0, &rc );
 
   71  if ( rc == ZIP_ER_OK && z )
 
   73    const int count = zip_get_num_entries( z, ZIP_FL_UNCHANGED );
 
   78      for ( 
int i = 0; i < count; i++ )
 
   80        zip_stat_index( z, i, 0, &stat );
 
   81        const size_t len = stat.size;
 
   83        struct zip_file *file = zip_fopen_index( z, i, 0 );
 
   84        const std::unique_ptr< char[] > buf( 
new char[len] );
 
   85        if ( zip_fread( file, buf.get(), len ) != -1 )
 
   87          const QString fileName( stat.name );
 
   88          if ( fileName.endsWith( 
"/" ) )
 
   93          const QFileInfo newFile( QDir( dir ), fileName );
 
   95          if ( !QString( QDir::cleanPath( newFile.absolutePath() ) + QStringLiteral( 
"/" ) ).startsWith( QDir( dir ).absolutePath() + QStringLiteral( 
"/" ) ) )
 
   98                                         newFile.absoluteFilePath(),
 
   99                                         QDir( dir ).absolutePath()
 
  105          if ( !newFile.absoluteDir().exists() )
 
  107            if ( !QDir( dir ).mkpath( newFile.absolutePath() ) )
 
  111          QFile outFile( newFile.absoluteFilePath() );
 
  112          if ( !outFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
 
  118            outFile.write( buf.get(), len );
 
  121          files.append( newFile.absoluteFilePath() );
 
  142    QgsMessageLog::logMessage( QObject::tr( 
"Error opening zip archive: '%1' (Error code: %2)" ).arg( z ? zip_strerror( z ) : zipFilename ).arg( rc ) );
 
 
  149bool QgsZipUtils::zip( 
const QString &zipFilename, 
const QStringList &files, 
bool overwrite )
 
  151  if ( zipFilename.isEmpty() )
 
  158  const QByteArray zipFileNamePtr = zipFilename.toUtf8();
 
  159  struct zip *z = zip_open( zipFileNamePtr.constData(), overwrite ? ( ZIP_CREATE | ZIP_TRUNCATE ) : ZIP_CREATE, &rc );
 
  161  if ( rc == ZIP_ER_OK && z )
 
  163    for ( 
const auto &file : 
files )
 
  165      const QFileInfo fileInfo( file );
 
  166      if ( !fileInfo.exists() )
 
  173      const QByteArray fileNamePtr = file.toUtf8();
 
  174      zip_source *src = zip_source_file( z, fileNamePtr.constData(), 0, 0 );
 
  177        const QByteArray fileInfoPtr = fileInfo.fileName().toUtf8();
 
  178#if LIBZIP_VERSION_MAJOR < 1 
  179        rc = ( int ) zip_add( z, fileInfoPtr.constData(), src );
 
  181        rc = ( int ) zip_file_add( z, fileInfoPtr.constData(), src, 0 );
 
  202    QgsMessageLog::logMessage( QObject::tr( 
"Error creating zip archive '%1': %2" ).arg( zipFilename, z ? zip_strerror( z ) : zipFilename ) );
 
 
  216  unsigned char *bytesInPtr = 
reinterpret_cast<unsigned char *
>( 
const_cast<char *
>( bytesIn ) );
 
  217  uint bytesInLeft = 
static_cast<uint
>( size );
 
  219  const uint CHUNK = 16384;
 
  220  unsigned char out[CHUNK];
 
  221  const int DEC_MAGIC_NUM_FOR_GZIP = 16;
 
  225  strm.zalloc = Z_NULL;
 
  227  strm.opaque = Z_NULL;
 
  229  strm.next_in = Z_NULL;
 
  231  int ret = inflateInit2( &strm, MAX_WBITS + DEC_MAGIC_NUM_FOR_GZIP );
 
  238  while ( ret != Z_STREAM_END ) 
 
  241    const uint bytesToProcess = std::min( CHUNK, bytesInLeft );
 
  242    strm.next_in = bytesInPtr;
 
  243    strm.avail_in = bytesToProcess;
 
  244    bytesInPtr += bytesToProcess;
 
  245    bytesInLeft -= bytesToProcess;
 
  247    if ( bytesToProcess == 0 )
 
  253      strm.avail_out = CHUNK;
 
  255      ret = inflate( &strm, Z_NO_FLUSH );
 
  256      Q_ASSERT( ret != Z_STREAM_ERROR ); 
 
  257      if ( ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR )
 
  262      const unsigned have = CHUNK - strm.avail_out;
 
  263      bytesOut.append( QByteArray::fromRawData( 
reinterpret_cast<const char *
>( out ), 
static_cast<int>( have ) ) );
 
  265    while ( strm.avail_out == 0 );
 
  269  return ret == Z_STREAM_END;
 
 
  274  unsigned char *bytesInPtr = 
reinterpret_cast<unsigned char *
>( 
const_cast<char *
>( bytesIn.constData() ) );
 
  275  const uint bytesInLeft = 
static_cast<uint
>( bytesIn.count() );
 
  277  const uint CHUNK = 16384;
 
  278  unsigned char out[CHUNK];
 
  279  const int DEC_MAGIC_NUM_FOR_GZIP = 16;
 
  283  strm.zalloc = Z_NULL;
 
  285  strm.opaque = Z_NULL;
 
  287  int ret = deflateInit2( &strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + DEC_MAGIC_NUM_FOR_GZIP, 8, Z_DEFAULT_STRATEGY );
 
  291  strm.avail_in = bytesInLeft;
 
  292  strm.next_in = bytesInPtr;
 
  298    strm.avail_out = CHUNK;
 
  300    ret = deflate( &strm, Z_FINISH );  
 
  301    Q_ASSERT( ret != Z_STREAM_ERROR ); 
 
  303    const unsigned have = CHUNK - strm.avail_out;
 
  304    bytesOut.append( QByteArray::fromRawData( 
reinterpret_cast<const char *
>( out ), 
static_cast<int>( have ) ) );
 
  306  while ( strm.avail_out == 0 );
 
  307  Q_ASSERT( ret == Z_STREAM_END );      
 
 
  316  if ( 
zip.isEmpty() && !QFileInfo::exists( 
zip ) )
 
  318    return QStringList();
 
  323  const QByteArray fileNamePtr = 
zip.toUtf8();
 
  324  struct zip *z = zip_open( fileNamePtr.constData(), 0, &rc );
 
  326  if ( rc == ZIP_ER_OK && z )
 
  328    const int count = zip_get_num_entries( z, ZIP_FL_UNCHANGED );
 
  331      struct zip_stat stat;
 
  333      for ( 
int i = 0; i < count; i++ )
 
  335        zip_stat_index( z, i, 0, &stat );
 
  336        files << QString( stat.name );
 
 
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
Adds a message to the log instance (and creates it if necessary).
 
static bool unzip(const QString &zip, const QString &dir, QStringList &files, bool checkConsistency=true)
Unzip a zip file in an output directory.