Added support for reading gzipped glabels files.

- Use zlib to uncompress input
This commit is contained in:
Jim Evins
2015-08-25 02:09:18 -04:00
parent 592aa32b90
commit 5dc773579b
4 changed files with 73 additions and 3 deletions
+2
View File
@@ -93,6 +93,7 @@ include (${QT_USE_FILE})
include_directories (
${ZLIB_INCLUDE_DIRS}
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_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
libglabels
${QT_LIBRARIES}
${ZLIB_LIBRARIES}
)
+69 -3
View File
@@ -31,6 +31,8 @@
#include "libglabels/XmlUtil.h"
#include <QFile>
#include <QByteArray>
#include <zlib.h>
#include <QtDebug>
@@ -38,26 +40,41 @@ glabels::LabelModel* glabels::XmlLabel::readFile( const QString& fileName )
{
QFile file( fileName );
if ( !file.open( QFile::ReadOnly | QFile::Text) )
if ( !file.open( QFile::ReadOnly ) )
{
qWarning() << "Error: Cannot read file " << qPrintable(fileName)
<< ": " << file.errorString();
return 0;
}
QDomDocument doc;
bool success;
QString errorString;
int errorLine;
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
<< "column " << errorColumn
<< ": " << errorString;
return 0;
}
QDomElement root = doc.documentElement();
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 )
{
using namespace libglabels;
+1
View File
@@ -52,6 +52,7 @@ namespace glabels
static void writeBuffer( const LabelModel* label, QString& buffer );
private:
static void gunzip( const QByteArray& gzippedData, QByteArray& data );
static LabelModel* parseRootNode( const QDomElement &node );
static void parseObjectsNode( const QDomElement &node, LabelModel* label );
static void parseObjectBoxNode( const QDomElement &node, LabelModel* label );