123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- //
- // MessagePack for C++ deflate buffer implementation
- //
- // Copyright (C) 2010-2016 FURUHASHI Sadayuki and KONDO Takatoshi
- //
- // Distributed under the Boost Software License, Version 1.0.
- // (See accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- //
- #ifndef MSGPACK_V1_ZBUFFER_HPP
- #define MSGPACK_V1_ZBUFFER_HPP
- #include "msgpack/v1/zbuffer_decl.hpp"
- #include <stdexcept>
- #include <zlib.h>
- namespace msgpack {
- /// @cond
- MSGPACK_API_VERSION_NAMESPACE(v1) {
- /// @endcond
- class zbuffer {
- public:
- zbuffer(int level = Z_DEFAULT_COMPRESSION,
- size_t init_size = MSGPACK_ZBUFFER_INIT_SIZE)
- : m_data(MSGPACK_NULLPTR), m_init_size(init_size)
- {
- m_stream.zalloc = Z_NULL;
- m_stream.zfree = Z_NULL;
- m_stream.opaque = Z_NULL;
- m_stream.next_out = Z_NULL;
- m_stream.avail_out = 0;
- if(deflateInit(&m_stream, level) != Z_OK) {
- throw std::bad_alloc();
- }
- }
- ~zbuffer()
- {
- deflateEnd(&m_stream);
- ::free(m_data);
- }
- public:
- void write(const char* buf, size_t len)
- {
- m_stream.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(buf));
- m_stream.avail_in = len;
- while(m_stream.avail_in > 0) {
- if(m_stream.avail_out < MSGPACK_ZBUFFER_RESERVE_SIZE) {
- if(!expand()) {
- throw std::bad_alloc();
- }
- }
- if(deflate(&m_stream, Z_NO_FLUSH) != Z_OK) {
- throw std::bad_alloc();
- }
- }
- }
- char* flush()
- {
- while(true) {
- switch(deflate(&m_stream, Z_FINISH)) {
- case Z_STREAM_END:
- return m_data;
- case Z_OK:
- if(!expand()) {
- throw std::bad_alloc();
- }
- break;
- default:
- throw std::bad_alloc();
- }
- }
- }
- char* data()
- {
- return m_data;
- }
- const char* data() const
- {
- return m_data;
- }
- size_t size() const
- {
- return reinterpret_cast<char*>(m_stream.next_out) - m_data;
- }
- void reset()
- {
- if(deflateReset(&m_stream) != Z_OK) {
- throw std::bad_alloc();
- }
- reset_buffer();
- }
- void reset_buffer()
- {
- m_stream.avail_out += reinterpret_cast<char*>(m_stream.next_out) - m_data;
- m_stream.next_out = reinterpret_cast<Bytef*>(m_data);
- }
- char* release_buffer()
- {
- char* tmp = m_data;
- m_data = MSGPACK_NULLPTR;
- m_stream.next_out = MSGPACK_NULLPTR;
- m_stream.avail_out = 0;
- return tmp;
- }
- private:
- bool expand()
- {
- size_t used = reinterpret_cast<char*>(m_stream.next_out) - m_data;
- size_t csize = used + m_stream.avail_out;
- size_t nsize = (csize == 0) ? m_init_size : csize * 2;
- char* tmp = static_cast<char*>(::realloc(m_data, nsize));
- if(tmp == MSGPACK_NULLPTR) {
- return false;
- }
- m_data = tmp;
- m_stream.next_out = reinterpret_cast<Bytef*>(tmp + used);
- m_stream.avail_out = nsize - used;
- return true;
- }
- #if defined(MSGPACK_USE_CPP03)
- private:
- zbuffer(const zbuffer&);
- zbuffer& operator=(const zbuffer&);
- #else // defined(MSGPACK_USE_CPP03)
- zbuffer(const zbuffer&) = delete;
- zbuffer& operator=(const zbuffer&) = delete;
- #endif // defined(MSGPACK_USE_CPP03)
- private:
- z_stream m_stream;
- char* m_data;
- size_t m_init_size;
- };
- /// @cond
- } // MSGPACK_API_VERSION_NAMESPACE(v1)
- /// @endcond
- } // namespace msgpack
- #endif // MSGPACK_V1_ZBUFFER_HPP
|