Created
March 19, 2017 02:36
-
-
Save VictorZhang2014/4bc04a4546ada869b9973a8506ec5297 to your computer and use it in GitHub Desktop.
Decompress/compress std::string methods was written by C++
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <zlib.h> | |
#include <sstream> | |
/** Compress a STL string using zlib with given compression level and return | |
* the binary data. | |
https://panthema.net/2007/0328-ZLibString.html | |
*/ | |
std::string VLUtilitiesEncoding::compress(const std::string & str, int compressionlevel = Z_BEST_COMPRESSION) | |
{ | |
z_stream zs; // z_stream is zlib's control structure | |
memset(&zs, 0, sizeof(zs)); | |
if (deflateInit(&zs, compressionlevel) != Z_OK) | |
throw(std::runtime_error("deflateInit failed while compressing.")); | |
zs.next_in = (Bytef*)str.data(); | |
zs.avail_in = (uint)str.size(); // set the z_stream's input | |
int ret; | |
char outbuffer[32768]; | |
std::string outstring; | |
// retrieve the compressed bytes blockwise | |
do { | |
zs.next_out = reinterpret_cast<Bytef*>(outbuffer); | |
zs.avail_out = sizeof(outbuffer); | |
ret = deflate(&zs, Z_FINISH); | |
if (outstring.size() < zs.total_out) { | |
// append the block to the output string | |
outstring.append(outbuffer, | |
zs.total_out - outstring.size()); | |
} | |
} while (ret == Z_OK); | |
deflateEnd(&zs); | |
if (ret != Z_STREAM_END) { // an error occurred that was not EOF | |
std::ostringstream oss; | |
oss << "Exception during zlib compression: (" << ret << ") " << zs.msg; | |
throw(std::runtime_error(oss.str())); | |
} | |
return outstring; | |
} | |
/** Decompress an STL string using zlib and return the original data. */ | |
std::string VLUtilitiesEncoding::decompress(const std::string & str) | |
{ | |
z_stream zs; // z_stream is zlib's control structure | |
memset(&zs, 0, sizeof(zs)); | |
if (inflateInit(&zs) != Z_OK) | |
throw(std::runtime_error("inflateInit failed while decompressing.")); | |
zs.next_in = (Bytef*)str.data(); | |
zs.avail_in = (uint)str.size(); | |
int ret; | |
char outbuffer[32768]; | |
std::string outstring; | |
// get the decompressed bytes blockwise using repeated calls to inflate | |
do { | |
zs.next_out = reinterpret_cast<Bytef*>(outbuffer); | |
zs.avail_out = sizeof(outbuffer); | |
ret = inflate(&zs, 0); | |
if (outstring.size() < zs.total_out) { | |
outstring.append(outbuffer, | |
zs.total_out - outstring.size()); | |
} | |
} while (ret == Z_OK); | |
inflateEnd(&zs); | |
if (ret != Z_STREAM_END) { // an error occurred that was not EOF | |
std::ostringstream oss; | |
oss << "Exception during zlib decompression: (" << ret << ") " | |
<< zs.msg; | |
throw(std::runtime_error(oss.str())); | |
} | |
return outstring; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment