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