//
// 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
quality 92%
¤ Dauer der Verarbeitung: 0.4 Sekunden
¤
*© Formatika GbR, Deutschland