当前位置:网站首页>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
边栏推荐
- 使用 bitnami/postgresql-repmgr 镜像快速设置 PostgreSQL HA
- CANopen usage method and main parameters of object dictionary
- Druid SQL和Security在美团点评的实践
- Use Chenxi bookkeeping book to analyze the balance of revenue and expenditure of each account in a certain period of time
- Click the input box to pop up the keyboard layout and move up
- Esp32 drive encoder -- siq-02fvs3 (vscade + IDF)
- 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
- ESP32 LVGL8. 1 - bar progress bar (bar 21)
- Nacos as service registry
- : app: transformclasseswithrobustfordevrease meituan hot repair compilation error record
猜你喜欢
ESP32 LVGL8. 1 - msgbox message box (msgbox 28)
Introduction to micro build low code zero Foundation (lesson 3)
Esp32 (UART ecoh) - serial port echo worm learning (2)
Machine learning theory (8): model integration ensemble learning
ESP32 LVGL8. 1 - img picture (IMG 20)
Druid SQL和Security在美团点评的实践
[mathematical modeling] - analytic hierarchy process (AHP)
One of the reasons why the WebView web page cannot be opened (and some WebView problem records encountered by myself)
Practice of Druid SQL and security in meituan review
mysql_linux版本的下载及安装详解
随机推荐
PyGame tank battle
Ucosiii transplantation and use, reference punctual atom
玻璃体中的硫酸软骨素
Ionic instruction set order from creation to packaging
配置iptables
From technical system to business insight, the closing chapter of the practice of small and medium-sized R & D team structure
Esp32 (UART event) - serial port event learning (1)
Use of kotlin collaboration in the project
Introduction to micro build low code zero Foundation (lesson 3)
QT error: no matching member function for call to ‘connect‘
[popular science] CRC verification (I) what is CRC verification?
Sentinel服务熔断实战(sentinel整合ribbon+openFeign+fallback)
Halo open source project learning (VII): caching mechanism
After opening the original normal project, the dependency package displays red and does not exist.
ESP32 LVGL8. 1 - bar progress bar (bar 21)
昇腾 AI 开发者创享日全国巡回首站在西安成功举行
ESP32 LVGL8. 1 - arc (arc 19)
七、DOM(下) - 章节课后练习题及答案
教你用简单几个步骤快速重命名文件夹名
ESP32 LVGL8. 1 - BTN button (BTN 15)