Skip to content

Instantly share code, notes, and snippets.

@halloweeks
Last active January 12, 2024 08:20
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save halloweeks/8bb0a745229b4674aaacffc7a23e5956 to your computer and use it in GitHub Desktop.
Save halloweeks/8bb0a745229b4674aaacffc7a23e5956 to your computer and use it in GitHub Desktop.
c++ zlib compress decompress string
# compile
g++ zlib.cpp -o zz -lz
# run
root@localhost:~# ./zz
Orignal string size: 43
Original string: halloweeks halloweeks halloweeks halloweeks
--------------------
Compressed string size: 22
Compressed string: x��H���/OM�.V� �w�
--------------------
Decompressed string size: 43
Decompressed string: halloweeks halloweeks halloweeks halloweeks
root@localhost:~#
#include <iostream>
#include <string.h>
#include <stdexcept>
#include <iomanip>
#include <sstream>
#include <zlib.h>
class myzlib {
public:
std::string compress(const std::string&, int);
std::string decompress(const std::string&);
};
/** Compress a STL string using zlib with given compression level and return* the binary data. */
std::string myzlib::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 = str.size(); // set the z_stream's input
int ret;
char outbuffer[10240];
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 myzlib::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 = str.size();
int ret;
char outbuffer[10240];
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;
}
myzlib zlib;
int main() {
std::string data = "halloweeks halloweeks halloweeks halloweeks";
std::cout << "Orignal string size: " << data.size() << "\n";
std::cout << "Original string: " << data << "\n";
std::cout << "--------------------\n";
// zlib compress data. last parameter is 6 for best compression
std::string com = zlib.compress(data, 6);
std::cout << "Compressed string size: " << com.size() << "\n";
std::cout << "Compressed string: " << com << "\n";
std::cout << "--------------------\n";
// zlib decompress data
std::string decom = zlib.decompress(com);
std::cout << "Decompressed string size: " << decom.size() << "\n";
std::cout << "Decompressed string: " << decom << "\n";
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment