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