下列代码用于压缩和解压字符串,使用标准库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 简单封装的更多相关文章

  1. Android AsyncTask 深度理解、简单封装、任务队列分析、自定义线程池

    前言:由于最近在做SDK的功能,需要设计线程池.看了很多资料不知道从何开始着手,突然发现了AsyncTask有对线程池的封装,so,就拿它开刀,本文将从AsyncTask的基本用法,到简单的封装,再到 ...

  2. FMDB简单封装和使用

    工具:火狐浏览器+SQLite Manager插件 ; Xcode; FMDB库; 效果: 项目地址: https://github.com/sven713/PackFMDB 主要参考这两篇博客: 1 ...

  3. Android--Retrofit+RxJava的简单封装(三)

    1,继续接着上一篇的讲讲,话说如果像上一篇这样的话,那么我们每一次请求一个结构都要创建一堆的Retrofit对象,而且代码都是相同的,我们可以试试封装一下 先创建一个HttpMethods类,将Ret ...

  4. okhttp3 get post 简单封装

    最近打算在新项目中使用 okhttp3, 简单封装了一下异步 get post 因为 CallBack 也是在子线程中执行,所以用到了 Handler public class MyOkHttpCli ...

  5. python网页请求urllib2模块简单封装代码

    这篇文章主要分享一个python网页请求模块urllib2模块的简单封装代码. 原文转自:http://www.jbxue.com/article/16585.html 对python网页请求模块ur ...

  6. 对pymysql的简单封装

    #coding=utf-8 #!/usr/bin/python import pymysql class MYSQL: """ 对pymysql的简单封装 "& ...

  7. iOS开发——UI篇OC篇&UITableView简单封装

    UITableView简单封装 UITableView时iOS开发中使用最多也是最重的一个UI空间,其实在App Store里面的%80以上的应用都用到了这个控件,所以就给大家介绍一下,前面的文章中也 ...

  8. iOS sqlite 增删改查 简单封装(基于 FMDB)

    /** *  对 sqlite 的使用进行简单封装,仅涉及简单的单表 增删改查 * *  基于 FMDB * *  操作基于 model ,数据库表字段与 model 属性一一对应,对 model 整 ...

  9. ADO简单封装(MFC)

    简单封装了一下,不是很严谨. /************************************************************************/ /* INSTRUC ...

随机推荐

  1. JS进阶之---作用域,作用域链,闭包

    一.作用域: 在JavaScript中,我们可以将作用域定义为一套规则,这套规则用来管理引擎如何在当前作用域以及嵌套的子作用域中根据标识符名称进行变量查找.这里的标识符,指的是变量名或者函数名. Ja ...

  2. ucml选项卡

    当业务视图组件VC并排摆放时就会形成选项卡,本章介绍选项卡有关的操作函数和事件. 页面中有三个对象:TabStrip,Panel和Tab,TabStrip含Panel对象和Tab对象.业务单元BPO没 ...

  3. day02---编程语言、python解释器以及变量

    计算机编程语言分类: 机器语言 直接用计算机能理解的二进制指令编写程序,来直接控制硬件.(用机器语言编写的程序称为目标程序) 优点:执行效率高,属于计算机最底层语言 缺点:开发效率低.跨平台性差 汇编 ...

  4. 使用cmd导出mysql数据到excel

    windows环境 (有时候复制的不好使,最好可以手动输入一次试试) 1.windows + R 输入cmd弹出命令框 2.cd  C:\Program Files\MySQL\MySQL Serve ...

  5. JavaScript模块化思想

    1. 首先,我们需要明白为什么要用模块化? 功能都是为了解决需求的.模块化可以带来的优点有以下几点: (1)可维护性.举个例子,如果我们把未使用模块化的代码比作油和水混合在了一起,模块化之后的代码就好 ...

  6. 修改windows7本地策略--不能挂载磁盘和复制 -- 黏贴板-驱动器映射

    1.gpedit.msc -- > 计算机配置-- > 管理模板 -- > windows 组件 -- > 远程桌面服务 -- > 远程桌面服务主机 -- > 设备 ...

  7. Skyline中的GDAL

    安装Skyline的TerraExplorer Pro软件后,我们很容易在其安装目录中找到这样一些文件: gdal.dll.gdal_csharp.dll.ogr_csharp.dll.osr_csh ...

  8. SQLServer 窗口函数(转载)

    一.窗口函数的作用 窗口函数是对一组值进行操作,不需要使用GROUP BY 子句对数据进行分组,还能够在同一行中同时返回基础行的列和聚合列.窗口函数,基础列和聚合列的查询都非常简单. 二.语法格式 窗 ...

  9. Python基础语法复习

    1.数据类型 List 列表 函数 append(): 在列表末尾追加. count(): 计算对象在列表中出现的次数. extend():将列表内容添加到列表中. index(): 计算对象在列表中 ...

  10. CF915G Coprime Arrays 莫比乌斯反演、差分、前缀和

    传送门 差分是真心人类智慧--完全不会 这么经典的式子肯定考虑莫比乌斯反演,不难得到\(b_k = \sum\limits_{i=1}^k \mu(i) \lfloor\frac{k}{i} \rfl ...