CppCMS
buffer.h
1 //
2 // Copyright (C) 2009-2012 Artyom Beilis (Tonkikh)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See
5 // accompanying file LICENSE_1_0.txt or copy at
6 // http://www.boost.org/LICENSE_1_0.txt)
7 //
8 #ifndef BOOSTER_AIO_BUFFER_H
9 #define BOOSTER_AIO_BUFFER_H
10 
11 #include <vector>
12 #include <string>
13 
14 namespace booster {
15  namespace aio {
23  template<typename Pointer>
24  class buffer_impl {
25  public:
29  struct entry {
30  Pointer ptr;
31  size_t size;
32  };
33 
38  size_(0)
39  {
40  }
41 
43  typedef std::pair<entry const *,size_t> buffer_data_type;
44 
48  std::pair<entry const *,size_t> get() const
49  {
50  if(size_ == 0) {
52  bt.first=0;
53  bt.second=0;
54  return bt;
55  }
56  else if(size_ == 1)
57  return buffer_data_type(&entry_,1);
58  else
59  return buffer_data_type(&vec_.front(),vec_.size());
60  }
64  void add(Pointer p,size_t s)
65  {
66  if(s==0)
67  return;
68  if(size_ == 0) {
69  entry_.ptr = p;
70  entry_.size = s;
71  size_ = 1;
72  return;
73  }
74  else if(size_ == 1) {
75  vec_.push_back(entry_);
76  }
77  entry tmp = { p,s };
78  vec_.push_back(tmp);
79  size_ = vec_.size();
80  }
84  bool empty() const
85  {
86  return size_ == 0;
87  }
88  private:
89  int size_;
90  entry entry_;
91  std::vector<entry> vec_;
92  };
93 
97  class mutable_buffer : public buffer_impl<char *> {
98  public:
99  mutable_buffer() {}
100  };
101 
105  class const_buffer : public buffer_impl<const char *> {
106  public:
107  const_buffer() {}
112  {
113  mutable_buffer::buffer_data_type data = other.get();
114  for(unsigned i=0;i<data.second;i++)
115  add(data.first[i].ptr,data.first[i].size);
116  }
117  };
118 
122  inline const_buffer buffer(void const *p,size_t n)
123  {
124  const_buffer tmp;
125  tmp.add(reinterpret_cast<char const *>(p),n);
126  return tmp;
127  }
131  inline mutable_buffer buffer(void *p,size_t n)
132  {
133  mutable_buffer tmp;
134  tmp.add(reinterpret_cast<char *>(p),n);
135  return tmp;
136  }
140  inline const_buffer buffer(std::vector<char> const &d)
141  {
142  return buffer(&d.front(),d.size());
143  }
147  inline mutable_buffer buffer(std::vector<char> &d)
148  {
149  return buffer(&d.front(),d.size());
150  }
154  inline const_buffer buffer(std::string const &d)
155  {
156  return buffer(d.c_str(),d.size());
157  }
158 
160 
161  namespace details {
162  template<typename Buffer>
163  Buffer advance(Buffer const &buf,size_t n)
164  {
165  Buffer res;
166  typename Buffer::buffer_data_type data=buf.get();
167  while(data.second > 0 && n > 0) {
168  if(data.first->size <= n) {
169  n-= data.first->size;
170  data.second--;
171  data.first++;
172  }
173  else {
174  res.add(data.first->ptr + n,data.first->size - n);
175  n=0;
176  data.second--;
177  data.first++;
178  }
179  }
180  while(data.second > 0) {
181  res.add(data.first->ptr,data.first->size);
182  data.second--;
183  data.first++;
184  }
185  return res;
186  }
187  template<typename Buffer>
188  void add(Buffer &left,Buffer const &right)
189  {
190  typename Buffer::buffer_data_type data=right.get();
191  for(unsigned i=0;i<data.second;i++)
192  left.add(data.first[i].ptr,data.first[i].size);
193  }
194  } // details
195 
197 
203  inline const_buffer operator+(const_buffer const &buf,size_t n)
204  {
205  return details::advance(buf,n);
206  }
212  inline mutable_buffer operator+(mutable_buffer const &buf,size_t n)
213  {
214  return details::advance(buf,n);
215  }
219  inline const_buffer &operator+=(const_buffer &buf,size_t n)
220  {
221  buf = details::advance(buf,n);
222  return buf;
223  }
227  inline mutable_buffer &operator+=(mutable_buffer &buf,size_t n)
228  {
229  buf = details::advance(buf,n);
230  return buf;
231  }
235  inline const_buffer operator+(const_buffer const &b1,const_buffer const &b2)
236  {
237  const_buffer tmp=b1;
238  details::add(tmp,b2);
239  return tmp;
240  }
245  {
246  details::add(b1,b2);
247  return b1;
248  }
253  {
254  mutable_buffer tmp=b1;
255  details::add(tmp,b2);
256  return tmp;
257  }
262  {
263  details::add(b1,b2);
264  return b1;
265  }
266 
267  } // aio
268 } // booster
269 
270 
271 
272 
273 
274 #endif
A mutable buffer - a buffer for read operations.
Definition: buffer.h:97
bool empty() const
Definition: buffer.h:84
const_buffer & operator+=(const_buffer &buf, size_t n)
Definition: buffer.h:219
An immutable buffer - buffer for write operations.
Definition: buffer.h:105
This is a base class that represents a buffer - a set of contiguous chunks of memory that can be tran...
Definition: buffer.h:24
const_buffer operator+(const_buffer const &buf, size_t n)
Definition: buffer.h:203
const_buffer(mutable_buffer const &other)
Definition: buffer.h:111
buffer_impl()
Definition: buffer.h:37
std::pair< entry const *, size_t > get() const
Definition: buffer.h:48
Definition: buffer.h:29
const_buffer buffer(void const *p, size_t n)
Definition: buffer.h:122
std::pair< entry const *, size_t > buffer_data_type
A pair that defined the chunk.
Definition: buffer.h:43
void add(Pointer p, size_t s)
Definition: buffer.h:64