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          const QFileInfo newFile( QDir( dir ), fileName );
 
   91          if ( !newFile.absoluteDir().exists() )
 
   93            if ( !QDir( dir ).mkpath( newFile.absolutePath() ) )
 
   97          QFile outFile( newFile.absoluteFilePath() );
 
   98          if ( !outFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
 
  104            outFile.write( buf.get(), len );
 
  107          files.append( newFile.absoluteFilePath() );
 
  128    QgsMessageLog::logMessage( QObject::tr( 
"Error opening zip archive: '%1' (Error code: %2)" ).arg( z ? zip_strerror( z ) : zipFilename ).arg( rc ) );
 
 
  137  if ( zipFilename.isEmpty() )
 
  144  const QByteArray zipFileNamePtr = zipFilename.toUtf8();
 
  145  struct zip *z = zip_open( zipFileNamePtr.constData(), ZIP_CREATE, &rc );
 
  147  if ( rc == ZIP_ER_OK && z )
 
  149    for ( 
const auto &file : 
files )
 
  151      const QFileInfo fileInfo( file );
 
  152      if ( !fileInfo.exists() )
 
  159      const QByteArray fileNamePtr = file.toUtf8();
 
  160      zip_source *src = zip_source_file( z, fileNamePtr.constData(), 0, 0 );
 
  163        const QByteArray fileInfoPtr = fileInfo.fileName().toUtf8();
 
  164#if LIBZIP_VERSION_MAJOR < 1 
  165        rc = ( int ) zip_add( z, fileInfoPtr.constData(), src );
 
  167        rc = ( int ) zip_file_add( z, fileInfoPtr.constData(), src, 0 );
 
 
  202  unsigned char *bytesInPtr = 
reinterpret_cast<unsigned char *
>( 
const_cast<char *
>( bytesIn ) );
 
  203  uint bytesInLeft = 
static_cast<uint
>( size );
 
  205  const uint CHUNK = 16384;
 
  206  unsigned char out[CHUNK];
 
  207  const int DEC_MAGIC_NUM_FOR_GZIP = 16;
 
  211  strm.zalloc = Z_NULL;
 
  213  strm.opaque = Z_NULL;
 
  215  strm.next_in = Z_NULL;
 
  217  int ret = inflateInit2( &strm, MAX_WBITS + DEC_MAGIC_NUM_FOR_GZIP );
 
  221  while ( ret != Z_STREAM_END ) 
 
  224    const uint bytesToProcess = std::min( CHUNK, bytesInLeft );
 
  225    strm.next_in = bytesInPtr;
 
  226    strm.avail_in = bytesToProcess;
 
  227    bytesInPtr += bytesToProcess;
 
  228    bytesInLeft -= bytesToProcess;
 
  230    if ( bytesToProcess == 0 )
 
  236      strm.avail_out = CHUNK;
 
  238      ret = inflate( &strm, Z_NO_FLUSH );
 
  239      Q_ASSERT( ret != Z_STREAM_ERROR ); 
 
  240      if ( ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR )
 
  245      const unsigned have = CHUNK - strm.avail_out;
 
  246      bytesOut.append( QByteArray::fromRawData( 
reinterpret_cast<const char *
>( out ), 
static_cast<int>( have ) ) );
 
  248    while ( strm.avail_out == 0 );
 
  252  return ret == Z_STREAM_END;
 
 
  257  unsigned char *bytesInPtr = 
reinterpret_cast<unsigned char *
>( 
const_cast<char *
>( bytesIn.constData() ) );
 
  258  const uint bytesInLeft = 
static_cast<uint
>( bytesIn.count() );
 
  260  const uint CHUNK = 16384;
 
  261  unsigned char out[CHUNK];
 
  262  const int DEC_MAGIC_NUM_FOR_GZIP = 16;
 
  266  strm.zalloc = Z_NULL;
 
  268  strm.opaque = Z_NULL;
 
  270  int ret = deflateInit2( &strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + DEC_MAGIC_NUM_FOR_GZIP, 8, Z_DEFAULT_STRATEGY );
 
  274  strm.avail_in = bytesInLeft;
 
  275  strm.next_in = bytesInPtr;
 
  281    strm.avail_out = CHUNK;
 
  283    ret = deflate( &strm, Z_FINISH );  
 
  284    Q_ASSERT( ret != Z_STREAM_ERROR ); 
 
  286    const unsigned have = CHUNK - strm.avail_out;
 
  287    bytesOut.append( QByteArray::fromRawData( 
reinterpret_cast<const char *
>( out ), 
static_cast<int>( have ) ) );
 
  289  while ( strm.avail_out == 0 );
 
  290  Q_ASSERT( ret == Z_STREAM_END );      
 
 
  299  if ( 
zip.isEmpty() && !QFileInfo::exists( 
zip ) )
 
  301    return QStringList();
 
  306  const QByteArray fileNamePtr = 
zip.toUtf8();
 
  307  struct zip *z = zip_open( fileNamePtr.constData(), 0, &rc );
 
  309  if ( rc == ZIP_ER_OK && z )
 
  311    const int count = zip_get_num_entries( z, ZIP_FL_UNCHANGED );
 
  314      struct zip_stat stat;
 
  316      for ( 
int i = 0; i < count; i++ )
 
  318        zip_stat_index( z, i, 0, &stat );
 
  319        files << QString( stat.name );
 
 
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
 
CORE_EXPORT bool unzip(const QString &zip, const QString &dir, QStringList &files, bool checkConsistency=true)
Unzip a zip file in an output directory.