Added GzipDevice

This commit is contained in:
2019-04-19 21:04:17 +02:00
parent 8cea4ccce4
commit 529f7b15f9
3 changed files with 115 additions and 2 deletions

View File

@ -3,6 +3,7 @@ project(DbCoreLib)
find_package(Qt5Core CONFIG REQUIRED)
find_package(Qt5Test CONFIG REQUIRED)
find_package(Qt5LinguistTools CONFIG REQUIRED)
find_package(ZLIB REQUIRED)
enable_testing()
@ -11,6 +12,7 @@ set(HEADERS
dbcorelib_global.h
fifostream.h
fixedsizematrix.h
gzipdevice.h
randomdevice.h
waverecorder.h
utils/datastreamutils.h
@ -21,6 +23,7 @@ set(HEADERS
set(SOURCES
fifostream.cpp
gzipdevice.cpp
randomdevice.cpp
waverecorder.cpp
utils/fileutils.cpp
@ -41,7 +44,7 @@ add_library(dbcorelib SHARED ${HEADERS} ${SOURCES} ${TRANSLATIONS_C})
target_compile_definitions(dbcorelib PRIVATE DBCORELIB_LIBRARY)
target_link_libraries(dbcorelib Qt5::Core)
target_link_libraries(dbcorelib Qt5::Core z)
target_include_directories(dbcorelib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
@ -50,4 +53,4 @@ add_dependencies(libs dbcorelib)
add_executable(tst_fixedsizematrix tst_fixedsizematrix.cpp)
add_test(tst_fixedsizematrix tst_fixedsizematrix)
target_link_libraries(tst_fixedsizematrix Qt5::Core Qt5::Test dbcorelib)
target_link_libraries(tst_fixedsizematrix stdc++ Qt5::Core Qt5::Test dbcorelib)

80
gzipdevice.cpp Normal file
View File

@ -0,0 +1,80 @@
#include "gzipdevice.h"
#include <QFile>
#include <stdexcept>
#include <zlib.h>
GzipDevice::GzipDevice(QFile &file, QObject *parent) :
QIODevice(parent),
m_file(file),
m_strm(std::make_unique<z_stream>())
{
if (!m_file.isOpen())
throw std::runtime_error("file is not open");
setOpenMode(QIODevice::ReadOnly);
// Prepare inflater status
m_strm->zalloc = Z_NULL;
m_strm->zfree = Z_NULL;
m_strm->opaque = Z_NULL;
m_strm->avail_in = 0;
m_strm->next_in = Z_NULL;
// Initialize inflater
m_result = inflateInit2(m_strm.get(), 15 + 16);
if (m_result != Z_OK)
throw std::runtime_error("could not init z_stream");
}
GzipDevice::~GzipDevice()
{
inflateEnd(m_strm.get());
}
bool GzipDevice::isSequential() const
{
return true;
}
bool GzipDevice::atEnd() const
{
return m_result == Z_STREAM_END;
}
qint64 GzipDevice::readData(char *data, qint64 maxlen)
{
if (m_strm->avail_in == 0)
{
m_strm->next_in = reinterpret_cast<unsigned char *>(m_readBuffer);
m_strm->avail_in = m_file.read(m_readBuffer, m_readBufferSize);
}
m_strm->next_out = reinterpret_cast<unsigned char*>(data);
m_strm->avail_out = maxlen;
m_result = inflate(m_strm.get(), Z_NO_FLUSH);
switch (m_result) {
case Z_NEED_DICT:
throw std::runtime_error("decompression failed: Z_NEED_DICT");
case Z_DATA_ERROR:
throw std::runtime_error("decompression failed: Z_DATA_ERROR");
case Z_MEM_ERROR:
throw std::runtime_error("decompression failed: Z_MEM_ERROR");
case Z_STREAM_ERROR:
throw std::runtime_error("decompression failed: Z_STREAM_ERROR");
}
return maxlen-m_strm->avail_out;
}
qint64 GzipDevice::writeData(const char *data, qint64 len)
{
Q_UNUSED(data)
Q_UNUSED(len)
throw std::runtime_error("writing not allowed!");
return -1;
}

30
gzipdevice.h Normal file
View File

@ -0,0 +1,30 @@
#pragma once
#include <QIODevice>
#include <memory>
class QFile;
typedef struct z_stream_s z_stream;
class GzipDevice : public QIODevice
{
public:
GzipDevice(QFile &file, QObject *parent = nullptr);
~GzipDevice() override;
bool isSequential() const override;
bool atEnd() const override;
protected:
qint64 readData(char *data, qint64 maxlen) override;
qint64 writeData(const char *data, qint64 len) override;
private:
QFile &m_file;
static constexpr std::size_t m_readBufferSize { 32 * 1024 };
char m_readBuffer[m_readBufferSize];
const std::unique_ptr<z_stream> m_strm;
int m_result;
};