Crow  1.1
A C++ microframework for the web
 
Loading...
Searching...
No Matches
compression.h
1#ifdef CROW_ENABLE_COMPRESSION
2#pragma once
3
4#include <string>
5#include <zlib.h>
6
7// http://zlib.net/manual.html
8namespace crow // NOTE: Already documented in "crow/app.h"
9{
10 namespace compression
11 {
12 // Values used in the 'windowBits' parameter for deflateInit2.
13 enum algorithm
14 {
15 // 15 is the default value for deflate
16 DEFLATE = 15,
17 // windowBits can also be greater than 15 for optional gzip encoding.
18 // Add 16 to windowBits to write a simple gzip header and trailer around the compressed data instead of a zlib wrapper.
19 GZIP = 15 | 16,
20 };
21
22 inline std::string compress_string(std::string const& str, algorithm algo)
23 {
24 std::string compressed_str;
25 z_stream stream{};
26 // Initialize with the default values
27 if (::deflateInit2(&stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, algo, 8, Z_DEFAULT_STRATEGY) == Z_OK)
28 {
29 char buffer[8192];
30
31 stream.avail_in = str.size();
32 // zlib does not take a const pointer. The data is not altered.
33 stream.next_in = const_cast<Bytef*>(reinterpret_cast<const Bytef*>(str.c_str()));
34
35 int code = Z_OK;
36 do
37 {
38 stream.avail_out = sizeof(buffer);
39 stream.next_out = reinterpret_cast<Bytef*>(&buffer[0]);
40
41 code = ::deflate(&stream, Z_FINISH);
42 // Successful and non-fatal error code returned by deflate when used with Z_FINISH flush
43 if (code == Z_OK || code == Z_STREAM_END)
44 {
45 std::copy(&buffer[0], &buffer[sizeof(buffer) - stream.avail_out], std::back_inserter(compressed_str));
46 }
47
48 } while (code == Z_OK);
49
50 if (code != Z_STREAM_END)
51 compressed_str.clear();
52
53 ::deflateEnd(&stream);
54 }
55
56 return compressed_str;
57 }
58
59 inline std::string decompress_string(std::string const& deflated_string)
60 {
61 std::string inflated_string;
62 Bytef tmp[8192];
63
64 z_stream zstream{};
65 zstream.avail_in = deflated_string.size();
66 // Nasty const_cast but zlib won't alter its contents
67 zstream.next_in = const_cast<Bytef*>(reinterpret_cast<Bytef const*>(deflated_string.c_str()));
68 // Initialize with automatic header detection, for gzip support
69 if (::inflateInit2(&zstream, MAX_WBITS | 32) == Z_OK)
70 {
71 do
72 {
73 zstream.avail_out = sizeof(tmp);
74 zstream.next_out = &tmp[0];
75
76 auto ret = ::inflate(&zstream, Z_NO_FLUSH);
77 if (ret == Z_OK || ret == Z_STREAM_END)
78 {
79 std::copy(&tmp[0], &tmp[sizeof(tmp) - zstream.avail_out], std::back_inserter(inflated_string));
80 }
81 else
82 {
83 // Something went wrong with inflate; make sure we return an empty string
84 inflated_string.clear();
85 break;
86 }
87
88 } while (zstream.avail_out == 0);
89
90 // Free zlib's internal memory
91 ::inflateEnd(&zstream);
92 }
93
94 return inflated_string;
95 }
96 } // namespace compression
97} // namespace crow
98
99#endif
The main namespace of the library. In this namespace is defined the most important classes and functi...