当前位置:网站首页>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
边栏推荐
- ctfshow-web361(SSTI)
- [mathematical modeling] - analytic hierarchy process (AHP)
- Simplified path (force buckle 71)
- WebView opens H5 video and displays gray background or black triangle button. Problem solved
- The corresponding permissions required to automatically open the app in the setting interface through accessibility service
- Sentinel规则持久化进Nacos
- After opening the original normal project, the dependency package displays red and does not exist.
- QT error: no matching member function for call to ‘connect‘
- Keil RVMDK compiled data type
- WebView saves the last browsing location
猜你喜欢
ESP32 LVGL8. 1 - input devices (input devices 18)
C: generic reflection
使用 bitnami/postgresql-repmgr 镜像快速设置 PostgreSQL HA
Solutions such as unknown or garbled code or certificate problem prompt in Charles's mobile phone packet capture, actual measurement.
Query the logistics update quantity according to the express order number
The first leg of the national tour of shengteng AI developer creation and enjoyment day was successfully held in Xi'an
Esp32 (UART receiving and sending) - receiving and sending communication of serial port (4)
ESP32 LVGL8. 1. Detailed migration tutorial of m5stack + lvgl + IDF (27)
简化路径(力扣71)
ctfshow-web361(SSTI)
随机推荐
视频边框背景如何虚化,简单操作几步实现
机器学习理论之(8):模型集成 Ensemble Learning
特征选择feature_selection--SelectKBest
Go 语言 GUI 框架 fyne 中文乱码或者不显示的问题
K210 serial communication
Nacos as service registry
使用晨曦记账本,分析某个时间段每个账户收支结余
ESP32 LVGL8. 1 - calendar (calendar 25)
Download xshell 6 and xftp6 official websites
Nacos作为服务配置中心实战
Tangle
Nacos集群搭建和mysql持久化配置
Get a list of recent apps
Database computer experiment 4 (data integrity and stored procedure)
Use bitnami / PostgreSQL repmgr image to quickly set up PostgreSQL ha
Golang 语言实现TCP UDP通信
WebView opens H5 video and displays gray background or black triangle button. Problem solved
Iptables - L executes slowly
Ucosiii transplantation and use, reference punctual atom
Simple use of navigation in jetpack