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 #include <boost/assert.hpp>
19 
20 namespace msgpack {
21 
25 
26 class zbuffer {
27 public:
28  zbuffer(int level = Z_DEFAULT_COMPRESSION,
29  size_t init_size = MSGPACK_ZBUFFER_INIT_SIZE)
30  : m_data(MSGPACK_NULLPTR), m_init_size(init_size)
31  {
32  m_stream.zalloc = Z_NULL;
33  m_stream.zfree = Z_NULL;
34  m_stream.opaque = Z_NULL;
35  m_stream.next_out = Z_NULL;
36  m_stream.avail_out = 0;
37  if(deflateInit(&m_stream, level) != Z_OK) {
38  throw std::bad_alloc();
39  }
40  }
41 
43  {
44  deflateEnd(&m_stream);
45  ::free(m_data);
46  }
47 
48 public:
49  void write(const char* buf, size_t len)
50  {
51  BOOST_ASSERT(buf || len == 0);
52  if (!buf) return;
53 
54  m_stream.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(buf));
55  m_stream.avail_in = static_cast<uInt>(len);
56 
57  while(m_stream.avail_in > 0) {
58  if(m_stream.avail_out < MSGPACK_ZBUFFER_RESERVE_SIZE) {
59  if(!expand()) {
60  throw std::bad_alloc();
61  }
62  }
63 
64  if(deflate(&m_stream, Z_NO_FLUSH) != Z_OK) {
65  throw std::bad_alloc();
66  }
67  }
68  }
69 
70  char* flush()
71  {
72  while(true) {
73  switch(deflate(&m_stream, Z_FINISH)) {
74  case Z_STREAM_END:
75  return m_data;
76  case Z_OK:
77  case Z_BUF_ERROR:
78  if(!expand()) {
79  throw std::bad_alloc();
80  }
81  break;
82  default:
83  throw std::bad_alloc();
84  }
85  }
86  }
87 
88  char* data()
89  {
90  return m_data;
91  }
92 
93  const char* data() const
94  {
95  return m_data;
96  }
97 
98  size_t size() const
99  {
100  return static_cast<size_t>(reinterpret_cast<char*>(m_stream.next_out) - m_data);
101  }
102 
103  void reset()
104  {
105  if(deflateReset(&m_stream) != Z_OK) {
106  throw std::bad_alloc();
107  }
108  reset_buffer();
109  }
110 
112  {
113  m_stream.avail_out += static_cast<uInt>(reinterpret_cast<char*>(m_stream.next_out) - m_data);
114  m_stream.next_out = reinterpret_cast<Bytef*>(m_data);
115  }
116 
118  {
119  char* tmp = m_data;
120  m_data = MSGPACK_NULLPTR;
121  m_stream.next_out = MSGPACK_NULLPTR;
122  m_stream.avail_out = 0;
123  return tmp;
124  }
125 
126 private:
127  bool expand()
128  {
129  size_t used = static_cast<size_t>(reinterpret_cast<char*>(m_stream.next_out) - m_data);
130  size_t csize = used + m_stream.avail_out;
131  size_t nsize = (csize == 0) ? m_init_size : csize * 2;
132 
133  char* tmp = static_cast<char*>(::realloc(m_data, nsize));
134  if(tmp == MSGPACK_NULLPTR) {
135  return false;
136  }
137 
138  m_data = tmp;
139  m_stream.next_out = reinterpret_cast<Bytef*>(tmp + used);
140  m_stream.avail_out = static_cast<uInt>(nsize - used);
141 
142  return true;
143  }
144 #if defined(MSGPACK_USE_CPP03)
145 private:
146  zbuffer(const zbuffer&);
147  zbuffer& operator=(const zbuffer&);
148 #else // defined(MSGPACK_USE_CPP03)
149  zbuffer(const zbuffer&) = delete;
150  zbuffer& operator=(const zbuffer&) = delete;
151 #endif // defined(MSGPACK_USE_CPP03)
152 
153 private:
154  z_stream m_stream;
155  char* m_data;
156  size_t m_init_size;
157 };
158 
160 } // MSGPACK_API_VERSION_NAMESPACE(v1)
162 
163 } // namespace msgpack
164 
165 #endif // MSGPACK_V1_ZBUFFER_HPP
Definition: zbuffer.hpp:26
size_t size() const
Definition: zbuffer.hpp:98
char * flush()
Definition: zbuffer.hpp:70
zbuffer(int level=Z_DEFAULT_COMPRESSION, size_t init_size=MSGPACK_ZBUFFER_INIT_SIZE)
Definition: zbuffer.hpp:28
char * data()
Definition: zbuffer.hpp:88
const char * data() const
Definition: zbuffer.hpp:93
~zbuffer()
Definition: zbuffer.hpp:42
void write(const char *buf, size_t len)
Definition: zbuffer.hpp:49
char * release_buffer()
Definition: zbuffer.hpp:117
void reset_buffer()
Definition: zbuffer.hpp:111
void reset()
Definition: zbuffer.hpp:103
Definition: adaptor_base.hpp:15
#define MSGPACK_NULLPTR
Definition: cpp_config_decl.hpp:85
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:66
#define MSGPACK_ZBUFFER_RESERVE_SIZE
Definition: zbuffer_decl.hpp:16
#define MSGPACK_ZBUFFER_INIT_SIZE
Definition: zbuffer_decl.hpp:20