1 #include "zlibstream.hpp"
9 void throw_zlib_error(int x
)
12 case Z_NEED_DICT
: throw std::runtime_error("Dictionary needed");
13 case Z_ERRNO
: throw std::runtime_error(std::string("OS error: ") + strerror(errno
));
14 case Z_STREAM_ERROR
: throw std::runtime_error("Stream error");
15 case Z_DATA_ERROR
: throw std::runtime_error("Data error");
16 case Z_MEM_ERROR
: throw std::bad_alloc();
17 case Z_BUF_ERROR
: throw std::runtime_error("Buffer error");
18 case Z_VERSION_ERROR
: throw std::runtime_error("Version error");
22 default: throw std::runtime_error("Unknown error");
27 zlibstream::zlibstream(unsigned compression
)
30 memset(&z
, 0, sizeof(z
));
31 throw_zlib_error(deflateInit(&z
, compression
));
34 zlibstream::~zlibstream()
39 void zlibstream::reset(uint8_t* data
, size_t datalen
)
41 _reset(data
, datalen
, true);
44 void zlibstream::_reset(uint8_t* data
, size_t datalen
, bool doactually
)
46 std::list
<struct page
> tmp
;
47 size_t odatalen
= datalen
;
49 tmp
.push_back(page());
50 size_t copylen
= min(datalen
, static_cast<size_t>(ZLIB_PAGE_STORAGE
));
51 memcpy(&tmp
.back().data
[0], data
, copylen
);
52 tmp
.back().used
= copylen
;
58 streamsize
= odatalen
;
63 void zlibstream::write(uint8_t* data
, size_t datalen
)
65 flushpage(data
, datalen
, 0);
68 void zlibstream::read(std::vector
<char>& out
)
73 void zlibstream::_read(std::vector
<char>& out
, int mode
)
75 flushpage(NULL
, 0, mode
);
76 out
.resize(streamsize
);
78 for(auto& i
: storage
) {
79 memcpy(&out
[itr
], i
.data
, i
.used
);
84 void zlibstream::flushpage(uint8_t* data
, size_t datalen
, int mode
)
88 while(z
.avail_in
|| mode
) {
89 if(storage
.empty() || storage
.back().used
== ZLIB_PAGE_STORAGE
) {
90 storage
.push_back(page());
91 storage
.back().used
= 0;
93 z
.next_out
= storage
.back().data
+ storage
.back().used
;
94 z
.avail_out
= ZLIB_PAGE_STORAGE
- storage
.back().used
;
95 size_t itmp
= z
.avail_out
;
96 int x
= deflate(&z
, mode
);
97 storage
.back().used
+= (itmp
- z
.avail_out
);
98 streamsize
+= (itmp
- z
.avail_out
);
100 if(mode
&& !z
.avail_in
&& z
.avail_out
)
105 void zlibstream::readsync(std::vector
<char>& out
)
107 _read(out
, Z_SYNC_FLUSH
);
110 void zlibstream::adddata(uint8_t* data
, size_t datalen
)
112 _reset(data
, datalen
, false);
115 void zlibstream::set_flag(bool f
)
120 bool zlibstream::get_flag()