MessagePack for C++
zbuffer.hpp
Go to the documentation of this file.
1 //
2 // MessagePack for C++ deflate buffer implementation
3 //
4 // Copyright (C) 2010-2016 FURUHASHI Sadayuki and KONDO Takatoshi
5 //
6 // Distributed under the Boost Software License, Version 1.0.
7 // (See accompanying file LICENSE_1_0.txt or copy at
8 // http://www.boost.org/LICENSE_1_0.txt)
9 //
10 #ifndef MSGPACK_V1_ZBUFFER_HPP
11 #define MSGPACK_V1_ZBUFFER_HPP
12 
14 
15 #include <stdexcept>
16 #include <zlib.h>
17 
18 namespace msgpack {
19 
23 
24 class zbuffer {
25 public:
26  zbuffer(int level = Z_DEFAULT_COMPRESSION,
27  size_t init_size = MSGPACK_ZBUFFER_INIT_SIZE)
28  : m_data(MSGPACK_NULLPTR), m_init_size(init_size)
29  {
30  m_stream.zalloc = Z_NULL;
31  m_stream.zfree = Z_NULL;
32  m_stream.opaque = Z_NULL;
33  m_stream.next_out = Z_NULL;
34  m_stream.avail_out = 0;
35  if(deflateInit(&m_stream, level) != Z_OK) {
36  throw std::bad_alloc();
37  }
38  }
39 
41  {
42  deflateEnd(&m_stream);
43  ::free(m_data);
44  }
45 
46 public:
47  void write(const char* buf, size_t len)
48  {
49  m_stream.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(buf));
50  m_stream.avail_in = static_cast<uInt>(len);
51 
52  while(m_stream.avail_in > 0) {
53  if(m_stream.avail_out < MSGPACK_ZBUFFER_RESERVE_SIZE) {
54  if(!expand()) {
55  throw std::bad_alloc();
56  }
57  }
58 
59  if(deflate(&m_stream, Z_NO_FLUSH) != Z_OK) {
60  throw std::bad_alloc();
61  }
62  }
63  }
64 
65  char* flush()
66  {
67  while(true) {
68  switch(deflate(&m_stream, Z_FINISH)) {
69  case Z_STREAM_END:
70  return m_data;
71  case Z_OK:
72  case Z_BUF_ERROR:
73  if(!expand()) {
74  throw std::bad_alloc();
75  }
76  break;
77  default:
78  throw std::bad_alloc();
79  }
80  }
81  }
82 
83  char* data()
84  {
85  return m_data;
86  }
87 
88  const char* data() const
89  {
90  return m_data;
91  }
92 
93  size_t size() const
94  {
95  return static_cast<size_t>(reinterpret_cast<char*>(m_stream.next_out) - m_data);
96  }
97 
98  void reset()
99  {
100  if(deflateReset(&m_stream) != Z_OK) {
101  throw std::bad_alloc();
102  }
103  reset_buffer();
104  }
105 
107  {
108  m_stream.avail_out += static_cast<uInt>(reinterpret_cast<char*>(m_stream.next_out) - m_data);
109  m_stream.next_out = reinterpret_cast<Bytef*>(m_data);
110  }
111 
113  {
114  char* tmp = m_data;
115  m_data = MSGPACK_NULLPTR;
116  m_stream.next_out = MSGPACK_NULLPTR;
117  m_stream.avail_out = 0;
118  return tmp;
119  }
120 
121 private:
122  bool expand()
123  {
124  size_t used = static_cast<size_t>(reinterpret_cast<char*>(m_stream.next_out) - m_data);
125  size_t csize = used + m_stream.avail_out;
126  size_t nsize = (csize == 0) ? m_init_size : csize * 2;
127 
128  char* tmp = static_cast<char*>(::realloc(m_data, nsize));
129  if(tmp == MSGPACK_NULLPTR) {
130  return false;
131  }
132 
133  m_data = tmp;
134  m_stream.next_out = reinterpret_cast<Bytef*>(tmp + used);
135  m_stream.avail_out = static_cast<uInt>(nsize - used);
136 
137  return true;
138  }
139 #if defined(MSGPACK_USE_CPP03)
140 private:
141  zbuffer(const zbuffer&);
142  zbuffer& operator=(const zbuffer&);
143 #else // defined(MSGPACK_USE_CPP03)
144  zbuffer(const zbuffer&) = delete;
145  zbuffer& operator=(const zbuffer&) = delete;
146 #endif // defined(MSGPACK_USE_CPP03)
147 
148 private:
149  z_stream m_stream;
150  char* m_data;
151  size_t m_init_size;
152 };
153 
155 } // MSGPACK_API_VERSION_NAMESPACE(v1)
157 
158 } // namespace msgpack
159 
160 #endif // MSGPACK_V1_ZBUFFER_HPP
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
Definition: adaptor_base.hpp:15
msgpack::zbuffer::reset
void reset()
Definition: zbuffer.hpp:98
msgpack::zbuffer::release_buffer
char * release_buffer()
Definition: zbuffer.hpp:112
MSGPACK_API_VERSION_NAMESPACE
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:58
zbuffer_decl.hpp
MSGPACK_NULLPTR
#define MSGPACK_NULLPTR
Definition: cpp_config_decl.hpp:35
msgpack::zbuffer::reset_buffer
void reset_buffer()
Definition: zbuffer.hpp:106
msgpack::zbuffer
Definition: zbuffer.hpp:24
msgpack::zbuffer::data
char * data()
Definition: zbuffer.hpp:83
MSGPACK_ZBUFFER_RESERVE_SIZE
#define MSGPACK_ZBUFFER_RESERVE_SIZE
Definition: zbuffer_decl.hpp:16
msgpack::zbuffer::size
size_t size() const
Definition: zbuffer.hpp:93
msgpack::zbuffer::flush
char * flush()
Definition: zbuffer.hpp:65
MSGPACK_ZBUFFER_INIT_SIZE
#define MSGPACK_ZBUFFER_INIT_SIZE
Definition: zbuffer_decl.hpp:20
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:88