zlib 简单封装
下列代码用于压缩和解压字符串,使用标准库string。实现了对zlib的简单封装。
#pragma once
#include <boost/noncopyable.hpp>
#include <zlib.h>
#include <string>
#include <cassert>
#include <strings.h> // for bzero
class ZlibDecompressor : boost::noncopyable {
public:
ZlibDecompressor(const std::string &input)
: zerror_(Z_OK),
z_init_error_(Z_OK),
input_(input),
output_()
{
::bzero(&zstream_, sizeof(zstream_));
z_init_error_ = inflateInit(&zstream_);
if (z_init_error_ == Z_OK)
zerror_ = decompress();
}
const char *zlibErrorMessage() const { return zstream_.msg; }
int zlibErrorCode() const { return zerror_; }
~ZlibDecompressor()
{
if (z_init_error_ == Z_OK)
inflateEnd(&zstream_);
}
std::string output() const
{
if(valid())
return output_;
return output_;
}
bool valid() const { return zerror_ == Z_OK; }
private:
const static int CHUNK = 8192;
int decompress() {
int ret;
size_t begin = 0;
size_t size = input_.size();
unsigned char out[CHUNK];
do {
int chunk = ((size - begin) < CHUNK ? size - begin : CHUNK);
if (chunk == 0)
break;
zstream_.avail_in = static_cast<uint>(chunk);
zstream_.next_in = (Bytef *) &input_[begin];
do
{
zstream_.avail_out = CHUNK;
zstream_.next_out = (Bytef*)out;
ret = inflate(&zstream_, Z_NO_FLUSH);
assert(ret != Z_STREAM_ERROR);
switch (ret)
{
case Z_NEED_DICT:
ret = Z_DATA_ERROR;
case Z_DATA_ERROR:
case Z_MEM_ERROR:
return ret;
}
int have = CHUNK - static_cast<int>(zstream_.avail_out);
output_.append(out, out + have);
} while (zstream_.avail_out == 0);
begin += chunk;
} while (ret != Z_STREAM_END);
return ret;
}
z_stream zstream_;
int zerror_;
int z_init_error_;
std::string input_;
std::string output_;
};
class ZlibCompressor : boost::noncopyable {
public:
explicit ZlibCompressor(const std::string &input)
: zerror_(Z_OK),
z_init_error_(Z_OK),
input_(input),
output_()
{
::bzero(&zstream_, sizeof(zstream_));
z_init_error_ = deflateInit(&zstream_, -1);
if(z_init_error_ == Z_OK)
zerror_ = compress();
}
explicit ZlibCompressor(const std::string& input, int level)
: zerror_(Z_OK),
z_init_error_(Z_OK),
input_(input),
output_()
{
assert(level >= -1 && level <= 9);
::bzero(&zstream_, sizeof(zstream_));
z_init_error_ = deflateInit(&zstream_, level);
if(z_init_error_ == Z_OK)
zerror_ = compress();
}
~ZlibCompressor() {
if(z_init_error_ == Z_OK)
deflateEnd(&zstream_);
}
const char *zlibErrorMessage() const { return zstream_.msg; }
int zlibErrorCode() const { return zerror_; }
std::string output() const
{
if(valid())
return output_;
return "";
}
bool valid() const { return zerror_ == Z_OK; }
private:
const static int CHUNK = 8192;
int compress() {
unsigned char out[CHUNK];
size_t size = input_.size();
size_t begin = 0;
int ret;
int flush;
do
{
int chunk;
if(size - begin <= CHUNK)
{
chunk = size - begin;
flush = Z_FINISH;
}
else
{
chunk = CHUNK;
flush = Z_NO_FLUSH;
}
zstream_.avail_in = chunk;
zstream_.next_in = (Bytef *)&input_[begin];
do
{
zstream_.avail_out = CHUNK;
zstream_.next_out = out;
ret = deflate(&zstream_, flush);
assert(ret != Z_STREAM_ERROR);
int have = CHUNK - static_cast<int>(zstream_.avail_out);
output_.append(out, out + have);
}while(zstream_.avail_out == 0);
assert(zstream_.avail_in == 0);
begin += chunk;
}while(flush != Z_FINISH);
assert(ret == Z_STREAM_END);
return Z_OK;
}
z_stream zstream_;
int zerror_;
int z_init_error_;
std::string input_;
std::string output_;
};
zlib 简单封装的更多相关文章
- Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池
前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...
- FMDB简单封装和使用
工具:火狐浏览器+SQLite Manager插件 ; Xcode; FMDB库; 效果: 项目地址: https://github.com/sven713/PackFMDB 主要参考这两篇博客: 1 ...
- Android--Retrofit+RxJava的简单封装(三)
1,继续接着上一篇的讲讲,话说如果像上一篇这样的话,那么我们每一次请求一个结构都要创建一堆的Retrofit对象,而且代码都是相同的,我们可以试试封装一下 先创建一个HttpMethods类,将Ret ...
- okhttp3 get post 简单封装
最近打算在新项目中使用 okhttp3, 简单封装了一下异步 get post 因为 CallBack 也是在子线程中执行,所以用到了 Handler public class MyOkHttpCli ...
- python网页请求urllib2模块简单封装代码
这篇文章主要分享一个python网页请求模块urllib2模块的简单封装代码. 原文转自:http://www.jbxue.com/article/16585.html 对python网页请求模块ur ...
- 对pymysql的简单封装
#coding=utf-8 #!/usr/bin/python import pymysql class MYSQL: """ 对pymysql的简单封装 "& ...
- iOS开发——UI篇OC篇&UITableView简单封装
UITableView简单封装 UITableView时iOS开发中使用最多也是最重的一个UI空间,其实在App Store里面的%80以上的应用都用到了这个控件,所以就给大家介绍一下,前面的文章中也 ...
- iOS sqlite 增删改查 简单封装(基于 FMDB)
/** * 对 sqlite 的使用进行简单封装,仅涉及简单的单表 增删改查 * * 基于 FMDB * * 操作基于 model ,数据库表字段与 model 属性一一对应,对 model 整 ...
- ADO简单封装(MFC)
简单封装了一下,不是很严谨. /************************************************************************/ /* INSTRUC ...
随机推荐
- npm和node的版本过低时的解决办法
npm版本过低时的解决办法npm全名Node Package Manager 1.配置源的三种方法:1).npmrc文件的作用,就是配置npm源:使用淘宝源的方法就是在文件.npmrc中加入下面的语句 ...
- jenkins编译jar包 报connection连接错误
原因是因为编译启动连接了注册中心 eureka.client.service-url.defaultZone=http://localhost:8093/eureka/ eureka.client.r ...
- jmeter(十八)关联之XPath Extractor
之前的博客,有介绍jmeter如何对请求进行关联的一种常见用法,即:后置处理器中的正则表达式提取器,下面介绍另一种关联方法,XPath Extractor! 所谓关联,从业务角度讲,即:某些操作步骤与 ...
- Omi框架学习之旅 - 插件机制之omi-transform及原理说明
给omi-transform插件做个笔记,使用起来也很爽. transform.js这个库,一直想写一篇帖子的,可是,数学不好,三维矩阵和二位矩阵理解的不好,所以迟迟没写了, 这也是一个神库,反正我很 ...
- C语言中getch()、getche()和getchar()
本文章为转载文章,文档贡献者wdzhangxiang 个人网址:www.baidu.com/p/wdzhangxiang 首先不要忘了,要用getch()必须引入头文件conio.h,以前学C语言的时 ...
- Python内存优化:Profile,slots,compact dict
实际项目中,pythoner更加关注的是Python的性能问题,之前也写过一篇文章<Python性能优化>介绍Python性能优化的一些方法.而本文,关注的是Python的内存优化,一般说 ...
- python 对时间操作
from datetime import datetime,timedelta 'date_test':fields.function(_datetime_all,type='datetime', ...
- C# 程序默认使用管理员权限(转载)
1.从A程序启动B程序,当B程序需要管理员权限的时候代码如下 A程序里面启动B程序的代码如下 ProcessStartInfo startInfo = new ProcessStartInfo(); ...
- Luogu P4053 [JSOI2007]建筑抢修
一道贪心题,看数据范围就知道要套一个数据结构上去. 别走啊不是什么很高级的数据结构 考虑最朴素的想法,按建筑的抢修时间排序并先拿小的 然后随便想想都可以找到一堆反例 所以我们就直接考虑模拟这个过程,按 ...
- 【php增删改查实例】第十九节 - session的使用: 让服务器知道你是谁?
因为HTTP请求是一种无状态的请求,所谓无状态,就是服务器不会记录下你本次请求的信息.http它是基于请求 - 相应模式的一种数据传输协议.就是说,你发送一个请求,我服务器给你一个响应,这件事情就算完 ...