34  return QFileInfo( filename ).suffix().compare( QLatin1String( 
"qgz" ), Qt::CaseInsensitive ) == 0;
 
   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(), ZIP_CHECKCONS, &rc );
 
   71  if ( rc == ZIP_ER_OK && z )
 
   73    const int count = zip_get_num_files( z );
 
   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 );
 
  197  return decodeGzip( bytesIn.constData(), bytesIn.count(), bytesOut );
 
  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 );      
 
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 isZipFile(const QString &filename)
Returns true if the file name is a zipped file ( i.e with a '.qgz' extension, false otherwise.
 
CORE_EXPORT bool unzip(const QString &zip, const QString &dir, QStringList &files)
Unzip a zip file in an output directory.
 
CORE_EXPORT bool zip(const QString &zip, const QStringList &files)
Zip the list of files in the zip file.
 
CORE_EXPORT bool decodeGzip(const QByteArray &bytesIn, QByteArray &bytesOut)
Decodes gzip byte stream, returns true on success.
 
CORE_EXPORT bool encodeGzip(const QByteArray &bytesIn, QByteArray &bytesOut)
Encodes gzip byte stream, returns true on success.