Added GzipDevice
This commit is contained in:
@ -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
80
gzipdevice.cpp
Normal 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
30
gzipdevice.h
Normal 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;
|
||||
};
|
Reference in New Issue
Block a user