Skip to content

Commit

Permalink
Merge pull request #139 from etiennesky/zip_fixes
Browse files Browse the repository at this point in the history
Zip support fixes from Etienne
  • Loading branch information
timlinux committed May 8, 2012
2 parents 0dbf937 + f60d40a commit 50f6f4c
Show file tree
Hide file tree
Showing 36 changed files with 124 additions and 7,421 deletions.
14 changes: 0 additions & 14 deletions CMakeLists.txt
Expand Up @@ -258,20 +258,6 @@ FIND_PROGRAM(QT_LRELEASE_EXECUTABLE
NO_DEFAULT_PATH
)


#############################################################
# search for zlib optional, used by quazip
# this uses script provided by cmake
# if WIN32 should use zlib from QT
FIND_PACKAGE(ZLIB)
IF (ZLIB_FOUND)
MESSAGE(STATUS "Found zlib: ${ZLIB_LIBRARY}")
SET(HAVE_ZLIB TRUE)
ELSE (ZLIB_FOUND)
MESSAGE(STATUS "Could not find zlib (optional)")
ENDIF(ZLIB_FOUND)


#############################################################
# enable warnings

Expand Down
31 changes: 0 additions & 31 deletions PROVENANCE
Expand Up @@ -68,35 +68,4 @@ licensed under the GPL or LGPL, version 2.
== External Source Files ==
The following files are included in the QGIS source tree from external
sources. The source, license, and copyright are noted for each.
=== src/core/quazip ===
QuaZIP is the C++ wrapper for the Gilles Vollant's ZIP/UNZIP package
using Trolltech's Qt library.
Copyright (C) 2005-2011 Sergey A. Tachenov
Added to the QGIS source tree 17 April 2012 as part of a patch from
Etienne Tourigny <etourigny.dev@gmail.com>

* COPYING
* ioapi.h
* JlCompress.h
* quaadler32.cpp
* quachecksum32.h
* quacrc32.h
* quazipfile.cpp
* quazipfileinfo.h
* quazip.h
* quazipnewinfo.h
* unzip.c
* zip.c
* crypt.h
* JlCompress.cpp
* qioapi.cpp
* quaadler32.h
* quacrc32.cpp
* quazip.cpp
* quazipfile.h
* quazip_global.h
* quazipnewinfo.cpp
* README.txt
* unzip.h
* zip.h

2 changes: 0 additions & 2 deletions cmake_templates/qgsconfig.h.in
Expand Up @@ -31,8 +31,6 @@

#cmakedefine HAVE_SPATIALITE

#cmakedefine HAVE_ZLIB

#cmakedefine HAVE_MSSQL

#cmakedefine HAVE_PYTHON
Expand Down
10 changes: 1 addition & 9 deletions src/app/qgsoptions.cpp
Expand Up @@ -210,17 +210,9 @@ QgsOptions::QgsOptions( QWidget *parent, Qt::WFlags fl ) :
cmbScanZipInBrowser->clear();
cmbScanZipInBrowser->addItem( tr( "No" ) ); // 0
cmbScanZipInBrowser->addItem( tr( "Passthru" ) ); // 1
// only add these options if zlib is available
#ifdef HAVE_ZLIB
cmbScanZipInBrowser->addItem( tr( "Basic scan" ) ); // 2
cmbScanZipInBrowser->addItem( tr( "Full scan" ) ); // 3
cmbScanZipInBrowser->setCurrentIndex( settings.value( "/qgis/scanZipInBrowser", 1 ).toInt() );
#else
if ( settings.value( "/qgis/scanZipInBrowser", 1 ) == 0 )
cmbScanZipInBrowser->setCurrentIndex( 0 );
else
cmbScanZipInBrowser->setCurrentIndex( 1 );
#endif
cmbScanZipInBrowser->setCurrentIndex( settings.value( "/qgis/scanZipInBrowser", 2 ).toInt() );

// set the display update threshold
spinBoxUpdateThreshold->setValue( settings.value( "/Map/updateThreshold" ).toInt() );
Expand Down
29 changes: 0 additions & 29 deletions src/core/CMakeLists.txt
Expand Up @@ -177,23 +177,6 @@ SET(QGIS_CORE_SRCS
qgsspatialindex.cpp
)

IF(HAVE_ZLIB)
ADD_DEFINITIONS(-DQUAZIP_BUILD)

SET(QGIS_CORE_SRCS
${QGIS_CORE_SRCS}
quazip/unzip.c
quazip/zip.c
quazip/JlCompress.cpp
quazip/qioapi.cpp
quazip/quaadler32.cpp
quazip/quacrc32.cpp
quazip/quazip.cpp
quazip/quazipfile.cpp
quazip/quazipnewinfo.cpp
)
ENDIF(HAVE_ZLIB)

IF(WIN32)
SET(QGIS_CORE_SRCS
${QGIS_CORE_SRCS}
Expand Down Expand Up @@ -298,13 +281,6 @@ SET(QGIS_CORE_MOC_HDRS
gps/qextserialport/qextserialenumerator.h
)

IF (HAVE_ZLIB)
SET(QGIS_CORE_MOC_HDRS
${QGIS_CORE_MOC_HDRS}
quazip/quazipfile.h
)
ENDIF(HAVE_ZLIB)


IF (QT_MOBILITY_LOCATION_FOUND)
SET(QGIS_CORE_MOC_HDRS
Expand Down Expand Up @@ -541,11 +517,6 @@ ELSE (WITH_INTERNAL_SPATIALITE)
TARGET_LINK_LIBRARIES(qgis_core ${SQLITE3_LIBRARY})
ENDIF (WITH_INTERNAL_SPATIALITE)

IF (HAVE_ZLIB)
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(qgis_core ${ZLIB_LIBRARY})
ENDIF (HAVE_ZLIB)

IF (APPLE)
SET_TARGET_PROPERTIES(qgis_core PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
ENDIF (APPLE)
Expand Down
105 changes: 71 additions & 34 deletions src/core/qgsdataitem.cpp
Expand Up @@ -36,11 +36,9 @@
#include "qgsproviderregistry.h"
#include "qgsconfig.h"

// use internal quazip for /vsizip support
#ifdef HAVE_ZLIB
#define QUAZIP_STATIC
#include <quazip/quazip.h>
#endif
// use GDAL VSI mechanism
#include "cpl_vsi.h"
#include "cpl_string.h"

// shared icons
const QIcon &QgsLayerItem::iconPoint()
Expand Down Expand Up @@ -449,7 +447,7 @@ QVector<QgsDataItem*> QgsDirectoryItem::createChildren( )
QVector<QgsDataItem*> children;
QDir dir( mPath );
QSettings settings;
bool scanZip = ( settings.value( "/qgis/scanZipInBrowser", 1 ).toInt() != 0 );
bool scanZip = ( settings.value( "/qgis/scanZipInBrowser", 2 ).toInt() != 0 );

QStringList entries = dir.entryList( QDir::AllDirs | QDir::NoDotAndDotDot, QDir::Name | QDir::IgnoreCase );
foreach( QString subdir, entries )
Expand Down Expand Up @@ -775,14 +773,70 @@ QgsZipItem::~QgsZipItem()
{
}

// internal function to scan a vsidir (zip or tar file) recursively
// hopefully this will make it to GDAL
char **VSIReadDirRecursive1( const char *pszPath )
{
char **papszFiles = NULL;
char **papszFiles1 = NULL;
char **papszFiles2 = NULL;
VSIStatBufL psStatBuf;
char szTemp1[1096];
char szTemp2[1096];

// get listing
papszFiles1 = VSIReadDir( pszPath );
if ( ! papszFiles1 )
return NULL;

// get files and directories inside listing
for ( int i = 0; i < CSLCount( papszFiles1 ); i++ )
{
// build complete file name for stat
strcpy( szTemp1, pszPath );
strcat( szTemp1, ( char* )"/" ); // this might not be ok on windows
strcat( szTemp1, papszFiles1[i] );
// if is file, add it
if ( VSIStatL( szTemp1, &psStatBuf ) == 0 &&
VSI_ISREG( psStatBuf.st_mode ) )
{
papszFiles = CSLAddString( papszFiles, papszFiles1[i] );
}
else if ( VSIStatL( szTemp1, &psStatBuf ) == 0 &&
VSI_ISDIR( psStatBuf.st_mode ) )
{
// add directory entry
strcpy( szTemp2, papszFiles1[i] );
strcat( szTemp2, ( char* )"/" ); // this might not be ok on windows
papszFiles = CSLAddString( papszFiles, szTemp2 );
// recursively add files inside directory
papszFiles2 = VSIReadDirRecursive1( szTemp1 );
if ( papszFiles2 )
{
for ( int j = 0; j < CSLCount( papszFiles2 ); j++ )
{
strcpy( szTemp2, papszFiles1[i] );
strcat( szTemp2, ( char* )"/" ); // this might not be ok on windows
strcat( szTemp2, papszFiles2[j] );
papszFiles = CSLAddString( papszFiles, szTemp2 );
}
CSLDestroy( papszFiles2 );
}
}
}
CSLDestroy( papszFiles1 );

return papszFiles;
}

QVector<QgsDataItem*> QgsZipItem::createChildren( )
{
QVector<QgsDataItem*> children;
QString tmpPath;
QString childPath;

QSettings settings;
int scanZipSetting = settings.value( "/qgis/scanZipInBrowser", 1 ).toInt();
int scanZipSetting = settings.value( "/qgis/scanZipInBrowser", 2 ).toInt();

mZipFileList.clear();

Expand All @@ -794,15 +848,6 @@ QVector<QgsDataItem*> QgsZipItem::createChildren( )
return children;
}

#ifndef HAVE_ZLIB
// if zlib not available, only support Passthru
if ( scanZipSetting == 2 || scanZipSetting == 3 )
{
scanZipSetting = 1;
settings.setValue( "/qgis/scanZipInBrowser", 1 );
}
#endif

// if scanZipBrowser == 1 (Passthru): do not scan zip and allow to open directly with /vsizip/
if ( scanZipSetting == 1 )
{
Expand All @@ -811,32 +856,25 @@ QVector<QgsDataItem*> QgsZipItem::createChildren( )
return children;
}

#ifdef HAVE_ZLIB
QgsDebugMsg( QString( "Open file %1 with quazip" ).arg( path() ) );
// get list of files inside zip file
QuaZip zip( path() );
if ( ! zip.open( QuaZip::mdUnzip ) || ! zip.isOpen() )
{
QgsDebugMsg( QString( "Zip error: %1" ).arg( zip.getZipError() ) );
}
else
QgsDebugMsg( QString( "Open file %1 with gdal vsi" ).arg( path() ) );
char **papszSiblingFiles = VSIReadDirRecursive1( QString( "/vsizip/" + path() ).toLocal8Bit().constData() );
if ( papszSiblingFiles )
{
for ( bool more = zip.goToFirstFile(); more; more = zip.goToNextFile() )
for ( int i = 0; i < CSLCount( papszSiblingFiles ); i++ )
{
tmpPath = zip.getCurrentFileName();
tmpPath = papszSiblingFiles[i];
QgsDebugMsg( QString( "Read file %1" ).arg( tmpPath ) );
// skip directories (files ending with /)
if ( tmpPath.right( 1 ) != "/" )
mZipFileList << tmpPath;
}
zip.close();
CSLDestroy( papszSiblingFiles );
}
if ( zip.getZipError() != UNZ_OK )
else
{
QgsDebugMsg( QString( "Zip error: %1" ).arg( zip.getZipError() ) );
QgsDebugMsg( QString( "Error reading %1" ).arg( path() ) );
}
#else
QgsDebugMsg( QString( "Cannot open file %1 with quazip - zlib not configured" ).arg( path() ) );
#endif

// loop over files inside zip
foreach( QString fileName, mZipFileList )
Expand Down Expand Up @@ -897,9 +935,8 @@ QVector<QgsDataItem*> QgsZipItem::createChildren( )

QgsDataItem* QgsZipItem::itemFromPath( QgsDataItem* parent, QString path, QString name )
{

QSettings settings;
int scanZipSetting = settings.value( "/qgis/scanZipInBrowser", 1 ).toInt();
int scanZipSetting = settings.value( "/qgis/scanZipInBrowser", 2 ).toInt();
QString vsizipPath = path;
int zipFileCount = 0;
QFileInfo fileInfo( path );
Expand Down
15 changes: 8 additions & 7 deletions src/core/qgsmaplayer.cpp
Expand Up @@ -553,15 +553,16 @@ QString QgsMapLayer::styleURI( )
{
QString myURI = publicSource();

// if file is using the /vsizip/ or /vsigzip/ mechanism, cleanup the name
if ( myURI.left( 9 ) == "/vsigzip/" )
// if file is using the VSIFILE mechanism, remove the prefix
if ( myURI.startsWith( "/vsigzip/", Qt::CaseInsensitive ) )
{
myURI.remove( 1, 9 );
myURI.remove( 0, 9 );
}
else if ( myURI.left( 8 ) == "/vsizip/" && myURI.right( 4 ) == ".zip" )
else if ( myURI.startsWith( "/vsizip/", Qt::CaseInsensitive ) &&
myURI.endsWith( ".zip", Qt::CaseInsensitive ) )
{
// ideally we should look for .qml file inside zip file
myURI.remove( 1, 8 );
myURI.remove( 0, 8 );
}

QFileInfo myFileInfo( myURI );
Expand All @@ -570,12 +571,12 @@ QString QgsMapLayer::styleURI( )
if ( myFileInfo.exists() )
{
// if file is using the /vsizip/ or /vsigzip/ mechanism, cleanup the name
if ( myURI.right( 3 ) == ".gz" )
if ( myURI.endsWith( ".gz", Qt::CaseInsensitive ) )
{
myURI.chop( 3 );
myFileInfo.setFile( myURI );
}
else if ( myURI.right( 4 ) == ".zip" )
else if ( myURI.endsWith( ".zip", Qt::CaseInsensitive ) )
{
myURI.chop( 4 );
myFileInfo.setFile( myURI );
Expand Down

0 comments on commit 50f6f4c

Please sign in to comment.