zbuffer.hpp
Go to the documentation of this file.
//
// 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 {
MSGPACK_API_VERSION_NAMESPACE(v1) {
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;
};
} // MSGPACK_API_VERSION_NAMESPACE(v1)
} // namespace msgpack
#endif // MSGPACK_V1_ZBUFFER_HPP
msgpack::zbuffer::flush
char * flush()
Definition: zbuffer.hpp:65
zbuffer_decl.hpp
msgpack::zbuffer
Definition: zbuffer.hpp:24
msgpack::zbuffer::data
char * data()
Definition: zbuffer.hpp:82
msgpack
Definition: adaptor_base.hpp:15
MSGPACK_ZBUFFER_RESERVE_SIZE
#define MSGPACK_ZBUFFER_RESERVE_SIZE
Definition: zbuffer_decl.hpp:16
MSGPACK_API_VERSION_NAMESPACE
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:58
msgpack::zbuffer::size
size_t size() const
Definition: zbuffer.hpp:92
msgpack::zbuffer::zbuffer
zbuffer(int level=Z_DEFAULT_COMPRESSION, size_t init_size=MSGPACK_ZBUFFER_INIT_SIZE)
Definition: zbuffer.hpp:26
msgpack::zbuffer::~zbuffer
~zbuffer()
Definition: zbuffer.hpp:40
MSGPACK_NULLPTR
#define MSGPACK_NULLPTR
Definition: cpp_config_decl.hpp:35
msgpack::zbuffer::release_buffer
char * release_buffer()
Definition: zbuffer.hpp:111
msgpack::zbuffer::write
void write(const char *buf, size_t len)
Definition: zbuffer.hpp:47
msgpack::zbuffer::data
const char * data() const
Definition: zbuffer.hpp:87
MSGPACK_ZBUFFER_INIT_SIZE
#define MSGPACK_ZBUFFER_INIT_SIZE
Definition: zbuffer_decl.hpp:20
msgpack::zbuffer::reset
void reset()
Definition: zbuffer.hpp:97
msgpack::zbuffer::reset_buffer
void reset_buffer()
Definition: zbuffer.hpp:105