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 = 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  if(!expand()) {
73  throw std::bad_alloc();
74  }
75  break;
76  default:
77  throw std::bad_alloc();
78  }
79  }
80  }
81 
82  char* data()
83  {
84  return m_data;
85  }
86 
87  const char* data() const
88  {
89  return m_data;
90  }
91 
92  size_t size() const
93  {
94  return reinterpret_cast<char*>(m_stream.next_out) - m_data;
95  }
96 
97  void reset()
98  {
99  if(deflateReset(&m_stream) != Z_OK) {
100  throw std::bad_alloc();
101  }
102  reset_buffer();
103  }
104 
106  {
107  m_stream.avail_out += reinterpret_cast<char*>(m_stream.next_out) - m_data;
108  m_stream.next_out = reinterpret_cast<Bytef*>(m_data);
109  }
110 
112  {
113  char* tmp = m_data;
114  m_data = MSGPACK_NULLPTR;
115  m_stream.next_out = MSGPACK_NULLPTR;
116  m_stream.avail_out = 0;
117  return tmp;
118  }
119 
120 private:
121  bool expand()
122  {
123  size_t used = reinterpret_cast<char*>(m_stream.next_out) - m_data;
124  size_t csize = used + m_stream.avail_out;
125  size_t nsize = (csize == 0) ? m_init_size : csize * 2;
126 
127  char* tmp = static_cast<char*>(::realloc(m_data, nsize));
128  if(tmp == MSGPACK_NULLPTR) {
129  return false;
130  }
131 
132  m_data = tmp;
133  m_stream.next_out = reinterpret_cast<Bytef*>(tmp + used);
134  m_stream.avail_out = nsize - used;
135 
136  return true;
137  }
138 #if defined(MSGPACK_USE_CPP03)
139 private:
140  zbuffer(const zbuffer&);
141  zbuffer& operator=(const zbuffer&);
142 #else // defined(MSGPACK_USE_CPP03)
143  zbuffer(const zbuffer&) = delete;
144  zbuffer& operator=(const zbuffer&) = delete;
145 #endif // defined(MSGPACK_USE_CPP03)
146 
147 private:
148  z_stream m_stream;
149  char* m_data;
150  size_t m_init_size;
151 };
152 
154 } // MSGPACK_API_VERSION_NAMESPACE(v1)
156 
157 } // namespace msgpack
158 
159 #endif // MSGPACK_V1_ZBUFFER_HPP
char * flush()
Definition: zbuffer.hpp:65
Definition: zbuffer.hpp:24
char * data()
Definition: zbuffer.hpp:82
Definition: adaptor_base.hpp:15
#define MSGPACK_ZBUFFER_RESERVE_SIZE
Definition: zbuffer_decl.hpp:16
#define MSGPACK_API_VERSION_NAMESPACE(ns)
Definition: versioning.hpp:58
size_t size() const
Definition: zbuffer.hpp:92
zbuffer(int level=Z_DEFAULT_COMPRESSION, size_t init_size=MSGPACK_ZBUFFER_INIT_SIZE)
Definition: zbuffer.hpp:26
~zbuffer()
Definition: zbuffer.hpp:40
#define MSGPACK_NULLPTR
Definition: cpp_config_decl.hpp:35
char * release_buffer()
Definition: zbuffer.hpp:111
void write(const char *buf, size_t len)
Definition: zbuffer.hpp:47
const char * data() const
Definition: zbuffer.hpp:87
#define MSGPACK_ZBUFFER_INIT_SIZE
Definition: zbuffer_decl.hpp:20
void reset()
Definition: zbuffer.hpp:97
void reset_buffer()
Definition: zbuffer.hpp:105