Added support for reading gzipped glabels files.
- Use zlib to uncompress input
This commit is contained in:
@@ -17,6 +17,7 @@ set (Unique_Package_Name ${Package_Name}-${API_Version})
|
|||||||
|
|
||||||
|
|
||||||
find_package(Qt4 4.8.4 REQUIRED QtCore QtGui QtXml)
|
find_package(Qt4 4.8.4 REQUIRED QtCore QtGui QtXml)
|
||||||
|
find_package(ZLIB REQUIRED)
|
||||||
|
|
||||||
|
|
||||||
add_definitions (-g)
|
add_definitions (-g)
|
||||||
|
|||||||
@@ -93,6 +93,7 @@ include (${QT_USE_FILE})
|
|||||||
|
|
||||||
|
|
||||||
include_directories (
|
include_directories (
|
||||||
|
${ZLIB_INCLUDE_DIRS}
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
${glabels_qt_SOURCE_DIR}
|
${glabels_qt_SOURCE_DIR}
|
||||||
@@ -107,6 +108,7 @@ add_executable (glabels-qt ${glabels_sources} ${glabels_moc_sources} ${glabels_q
|
|||||||
target_link_libraries (glabels-qt
|
target_link_libraries (glabels-qt
|
||||||
libglabels
|
libglabels
|
||||||
${QT_LIBRARIES}
|
${QT_LIBRARIES}
|
||||||
|
${ZLIB_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+69
-3
@@ -31,6 +31,8 @@
|
|||||||
#include "libglabels/XmlUtil.h"
|
#include "libglabels/XmlUtil.h"
|
||||||
|
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
|
#include <QByteArray>
|
||||||
|
#include <zlib.h>
|
||||||
#include <QtDebug>
|
#include <QtDebug>
|
||||||
|
|
||||||
|
|
||||||
@@ -38,26 +40,41 @@ glabels::LabelModel* glabels::XmlLabel::readFile( const QString& fileName )
|
|||||||
{
|
{
|
||||||
QFile file( fileName );
|
QFile file( fileName );
|
||||||
|
|
||||||
if ( !file.open( QFile::ReadOnly | QFile::Text) )
|
if ( !file.open( QFile::ReadOnly ) )
|
||||||
{
|
{
|
||||||
qWarning() << "Error: Cannot read file " << qPrintable(fileName)
|
qWarning() << "Error: Cannot read file " << qPrintable(fileName)
|
||||||
<< ": " << file.errorString();
|
<< ": " << file.errorString();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QDomDocument doc;
|
QDomDocument doc;
|
||||||
|
bool success;
|
||||||
QString errorString;
|
QString errorString;
|
||||||
int errorLine;
|
int errorLine;
|
||||||
int errorColumn;
|
int errorColumn;
|
||||||
|
|
||||||
if ( !doc.setContent( &file, false, &errorString, &errorLine, &errorColumn ) )
|
QByteArray rawData = file.readAll();
|
||||||
|
if ( ((rawData[0]&0xFF) == 0x1F) && ((rawData[1]&0xFF) == 0x8b) ) // gzip magic number 0x1F, 0x8B
|
||||||
|
{
|
||||||
|
// gzip compressed format
|
||||||
|
QByteArray unzippedData;
|
||||||
|
gunzip( rawData, unzippedData );
|
||||||
|
success = doc.setContent( unzippedData, false, &errorString, &errorLine, &errorColumn );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// plain text
|
||||||
|
success = doc.setContent( rawData, false, &errorString, &errorLine, &errorColumn );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !success )
|
||||||
{
|
{
|
||||||
qWarning() << "Error: Parse error at line " << errorLine
|
qWarning() << "Error: Parse error at line " << errorLine
|
||||||
<< "column " << errorColumn
|
<< "column " << errorColumn
|
||||||
<< ": " << errorString;
|
<< ": " << errorString;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QDomElement root = doc.documentElement();
|
QDomElement root = doc.documentElement();
|
||||||
if ( root.tagName() != "Glabels-document" )
|
if ( root.tagName() != "Glabels-document" )
|
||||||
@@ -124,6 +141,55 @@ void glabels::XmlLabel::writeBuffer( const LabelModel* label, QString& buffer )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void glabels::XmlLabel::gunzip( const QByteArray& data, QByteArray& result )
|
||||||
|
{
|
||||||
|
result.clear();
|
||||||
|
|
||||||
|
if (data.size() <= 4) {
|
||||||
|
qWarning("XmlLabel::gunzip: Input data is truncated");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup stream for inflate()
|
||||||
|
z_stream strm;
|
||||||
|
strm.zalloc = Z_NULL;
|
||||||
|
strm.zfree = Z_NULL;
|
||||||
|
strm.opaque = Z_NULL;
|
||||||
|
strm.avail_in = data.size();
|
||||||
|
strm.next_in = (Bytef*)(data.data());
|
||||||
|
|
||||||
|
int ret = inflateInit2(&strm, MAX_WBITS + 16); // gzip decoding
|
||||||
|
if (ret != Z_OK)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int CHUNK_SIZE = 1024;
|
||||||
|
char out[CHUNK_SIZE];
|
||||||
|
|
||||||
|
// run inflate(), one chunk at a time
|
||||||
|
do {
|
||||||
|
strm.avail_out = CHUNK_SIZE;
|
||||||
|
strm.next_out = (Bytef*)(out);
|
||||||
|
|
||||||
|
ret = inflate(&strm, Z_NO_FLUSH);
|
||||||
|
Q_ASSERT(ret != Z_STREAM_ERROR); // state not clobbered
|
||||||
|
|
||||||
|
if ( (ret == Z_NEED_DICT) || (ret == Z_DATA_ERROR) || (ret == Z_MEM_ERROR) )
|
||||||
|
{
|
||||||
|
// clean up
|
||||||
|
inflateEnd(&strm);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
result.append(out, CHUNK_SIZE - strm.avail_out);
|
||||||
|
} while (strm.avail_out == 0);
|
||||||
|
|
||||||
|
// clean up
|
||||||
|
inflateEnd(&strm);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
glabels::LabelModel* glabels::XmlLabel::parseRootNode( const QDomElement &node )
|
glabels::LabelModel* glabels::XmlLabel::parseRootNode( const QDomElement &node )
|
||||||
{
|
{
|
||||||
using namespace libglabels;
|
using namespace libglabels;
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ namespace glabels
|
|||||||
static void writeBuffer( const LabelModel* label, QString& buffer );
|
static void writeBuffer( const LabelModel* label, QString& buffer );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
static void gunzip( const QByteArray& gzippedData, QByteArray& data );
|
||||||
static LabelModel* parseRootNode( const QDomElement &node );
|
static LabelModel* parseRootNode( const QDomElement &node );
|
||||||
static void parseObjectsNode( const QDomElement &node, LabelModel* label );
|
static void parseObjectsNode( const QDomElement &node, LabelModel* label );
|
||||||
static void parseObjectBoxNode( const QDomElement &node, LabelModel* label );
|
static void parseObjectBoxNode( const QDomElement &node, LabelModel* label );
|
||||||
|
|||||||
Reference in New Issue
Block a user