当前位置:网站首页>Zlib realizes streaming decompression
Zlib realizes streaming decompression
2022-04-23 18:52:00 【Brick Porter】
#define CHUNK_SIZE 4096
class CZipFileStream {
// zlib Support .
z_stream m_stream;
int m_last_inflate_;
// Decompression buffer .
char m_zlib_buffer[CHUNK_SIZE];
// Number of bytes entered .
std::size_t m_zlib_buffer_size;
std::ifstream& m_fs;
bool m_auto_close_fs;
public:
/// <summary>
/// Construct a decompression class
/// </summary>
/// <param name="fs"> Input file stream </param>
/// <param name="autoClosefs"> Do you want to close the file automatically , It is not automatically closed by default </param>
CZipFileStream(std::ifstream& fs,bool autoClosefs=false) :m_fs(fs), m_auto_close_fs(autoClosefs), m_last_inflate_(Z_OK)
{
memset(&m_stream, 0, sizeof(z_stream));
//inflateInit(&m_stream);
}
~CZipFileStream()
{
if (m_stream.zalloc)
inflateEnd(&m_stream);
if (m_auto_close_fs && m_fs.is_open())
m_fs.close();
}
int Read(BYTE* buf, std::size_t bufsize)
{
if (!m_fs.is_open())
{
m_last_inflate_ = Z_DATA_ERROR;
return 0;
}
if (IsBadReadPtr(buf, bufsize) || buf == 0)
{
m_last_inflate_ = Z_BUF_ERROR;
return 0;
}
if (!m_stream.zalloc)
{
m_last_inflate_ = inflateInit(&m_stream);
if (m_last_inflate_ != Z_OK)
{
return m_last_inflate_;
}
}
m_stream.next_out = (Bytef*)buf;
m_stream.avail_out = bufsize;
while (!m_fs.eof()|| m_stream.avail_in)
{
if (m_stream.avail_in == 0)
{
m_fs.read(m_zlib_buffer, CHUNK_SIZE);
m_zlib_buffer_size = m_fs.gcount();
m_stream.avail_in = (uInt)m_zlib_buffer_size;
m_stream.next_in = (z_const Bytef*) & m_zlib_buffer[0];
}
// No data to read .
if (m_zlib_buffer_size == 0)
{
if (m_stream.zalloc)
{
inflateEnd(&m_stream);
m_last_inflate_ = Z_STREAM_END;
}
break;
}
m_last_inflate_ = inflate(&m_stream, Z_SYNC_FLUSH);
// After decompression, whether the output is full or not
if (m_last_inflate_ == Z_STREAM_END)
{
if (m_auto_close_fs)
m_fs.close();
if (m_stream.zalloc)
inflateEnd(&m_stream);
return bufsize-m_stream.avail_out;
}
// If the decompression is successful and the output is not filled, continue to read the data
else if (m_last_inflate_ == Z_OK)
{
if (m_stream.avail_out)
continue;
else
return bufsize-m_stream.avail_out;
}
else
{// That means something went wrong
if (m_stream.zalloc)
{
if (m_auto_close_fs)
m_fs.close();
inflateEnd(&m_stream);
}
break;
}
}
return 0;
}
// Judge whether the file has been decompressed
bool Eof()
{
return (m_last_inflate_ == Z_STREAM_END || m_last_inflate_!=Z_OK);
}
// Normally, when the decompression is completed, it should be Z_STREAM_END , This function can judge whether the decompressed data is successful in the end
bool IsOk()
{
return (m_last_inflate_ == Z_STREAM_END );
}
// Directly decompress all the data , You need to know the buffer size in advance .
static bool UnCompress(const BYTE* pcCompBuf, uLong ulCompLen, BYTE* pcUnCompBuf, uLong& uncomprLen)
{
if (pcCompBuf == NULL)
{
return false;
}
int err = uncompress(pcUnCompBuf, &uncomprLen, (const Bytef*)pcCompBuf, ulCompLen);
if (err != Z_OK)
{
return false;
}
return true;
}
};
The call is roughly as follows . The preliminary test of the code passed . Static functions UnCompress Is to decompress all the data at once . You can use it to verify the extracted data , But its buffer needs to be large enough .
std::ifstream infile(inputPath.c_str(), std::ios_base::binary | std::ios_base::in);
CZipFileStream zipstreame(infile,true);
std::vector<BYTE> outbuf;
while (!zipstreame.Eof())
{
BYTE buf[1024];
int readcount = zipstreame.Read(buf, sizeof(buf));
outbuf.insert(outbuf.end(), buf, buf + readcount);
}
版权声明
本文为[Brick Porter]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204210603257433.html
边栏推荐
- K210 serial communication
- 【历史上的今天】4 月 23 日:YouTube 上传第一个视频;网易云音乐正式上线;数字音频播放器的发明者出生
- Esp32 (UART event) - serial port event learning (1)
- iptables -L执行缓慢
- Simplified path (force buckle 71)
- Ucosiii transplantation and use, reference punctual atom
- Click the input box to pop up the keyboard layout and move up
- Introduction to ROS learning notes (II)
- 机器学习理论基础篇--关于机器学习的一些术语
- Dynamically add and delete layouts
猜你喜欢

Iptables - L executes slowly

Setting up keil environment of GD single chip microcomputer

Use bitnami / PostgreSQL repmgr image to quickly set up PostgreSQL ha

One of the reasons why the WebView web page cannot be opened (and some WebView problem records encountered by myself)

Introduction to ROS learning notes (I)

Esp32 (UART ecoh) - serial port echo worm learning (2)

ctfshow-web361(SSTI)

MVVM模型

Use Chenxi bookkeeping book to analyze the balance of revenue and expenditure of each account in a certain period of time

STM32: LCD显示
随机推荐
ESP32 LVGL8. 1 - slider slider (slider 22)
QT curve / oscilloscope customplot control
ESP32 LVGL8. 1 - BTN button (BTN 15)
使用晨曦记账本,分析某个时间段每个账户收支结余
Methods of nested recycleview to solve sliding conflict and incomplete item display
玻璃体中的硫酸软骨素
Ctfshow - web362 (ssti)
Esp32 (UART 485 communication) - 485 communication of serial port (3)
迁移学习进阶
Sentinel rule persistence into Nacos
Ionic instruction set order from creation to packaging
Database computer experiment 4 (data integrity and stored procedure)
MySQL学习第五弹——事务及其操作特性详解
Résolution: cnpm: impossible de charger le fichier... Cnpm. PS1 parce que l'exécution de scripts est désactivée sur ce système
Recyclerview control list item layout match_ Fundamental principle of parent attribute invalidation
#yyds干货盘点#stringprep --- 因特网字符串预备
Seata handles distributed transactions
Sentinel规则持久化进Nacos
Introduction to micro build low code zero Foundation (lesson 3)
After opening the original normal project, the dependency package displays red and does not exist.