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) {
51  buffer_data_type bt;
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  }
92  size_t size() const
93  {
94  return size_;
95  }
100  size_t bytes_count() const
101  {
102  if(size_ == 0)
103  return 0;
104  if(size_ == 1)
105  return entry_.size;
106  size_t n = 0;
107  for(size_t i=0;i<vec_.size();i++)
108  n+=vec_[i].size;
109  return n;
110  }
111  private:
112  int size_;
113  entry entry_;
114  std::vector<entry> vec_;
115  };
116 
120  class mutable_buffer : public buffer_impl<char *> {
121  public:
122  mutable_buffer() {}
123  };
124 
128  class const_buffer : public buffer_impl<const char *> {
129  public:
130  const_buffer() {}
135  {
136  mutable_buffer::buffer_data_type data = other.get();
137  for(unsigned i=0;i<data.second;i++)
138  add(data.first[i].ptr,data.first[i].size);
139  }
140  };
141 
145  inline const_buffer buffer(void const *p,size_t n)
146  {
147  const_buffer tmp;
148  tmp.add(reinterpret_cast<char const *>(p),n);
149  return tmp;
150  }
154  inline mutable_buffer buffer(void *p,size_t n)
155  {
156  mutable_buffer tmp;
157  tmp.add(reinterpret_cast<char *>(p),n);
158  return tmp;
159  }
163  inline const_buffer buffer(std::vector<char> const &d)
164  {
165  return buffer(&d.front(),d.size());
166  }
170  inline mutable_buffer buffer(std::vector<char> &d)
171  {
172  return buffer(&d.front(),d.size());
173  }
177  inline const_buffer buffer(std::string const &d)
178  {
179  return buffer(d.c_str(),d.size());
180  }
181 
183 
184  namespace details {
185  template<typename Buffer>
186  Buffer advance(Buffer const &buf,size_t n)
187  {
188  Buffer res;
189  typename Buffer::buffer_data_type data=buf.get();
190  while(data.second > 0 && n > 0) {
191  if(data.first->size <= n) {
192  n-= data.first->size;
193  data.second--;
194  data.first++;
195  }
196  else {
197  res.add(data.first->ptr + n,data.first->size - n);
198  n=0;
199  data.second--;
200  data.first++;
201  }
202  }
203  while(data.second > 0) {
204  res.add(data.first->ptr,data.first->size);
205  data.second--;
206  data.first++;
207  }
208  return res;
209  }
210  template<typename Buffer>
211  void add(Buffer &left,Buffer const &right)
212  {
213  typename Buffer::buffer_data_type data=right.get();
214  for(unsigned i=0;i<data.second;i++)
215  left.add(data.first[i].ptr,data.first[i].size);
216  }
217  } // details
218 
220 
226  inline const_buffer operator+(const_buffer const &buf,size_t n)
227  {
228  return details::advance(buf,n);
229  }
235  inline mutable_buffer operator+(mutable_buffer const &buf,size_t n)
236  {
237  return details::advance(buf,n);
238  }
242  inline const_buffer &operator+=(const_buffer &buf,size_t n)
243  {
244  buf = details::advance(buf,n);
245  return buf;
246  }
250  inline mutable_buffer &operator+=(mutable_buffer &buf,size_t n)
251  {
252  buf = details::advance(buf,n);
253  return buf;
254  }
258  inline const_buffer operator+(const_buffer const &b1,const_buffer const &b2)
259  {
260  const_buffer tmp=b1;
261  details::add(tmp,b2);
262  return tmp;
263  }
268  {
269  details::add(b1,b2);
270  return b1;
271  }
276  {
277  mutable_buffer tmp=b1;
278  details::add(tmp,b2);
279  return tmp;
280  }
285  {
286  details::add(b1,b2);
287  return b1;
288  }
289 
290  } // aio
291 } // booster
292 
293 
294 
295 
296 
297 #endif
A mutable buffer - a buffer for read operations.
Definition: buffer.h:120
bool empty() const
Definition: buffer.h:84
const_buffer & operator+=(const_buffer &buf, size_t n)
Definition: buffer.h:242
An immutable buffer - buffer for write operations.
Definition: buffer.h:128
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:226
const_buffer(mutable_buffer const &other)
Definition: buffer.h:134
buffer_impl()
Definition: buffer.h:37
std::pair< entry const *, size_t > get() const
Definition: buffer.h:48
size_t bytes_count() const
Definition: buffer.h:100
Definition: buffer.h:29
size_t size() const
Definition: buffer.h:92
Booster library namespace. The library that implements Boost Like API in ABI backward compatible way...
Definition: application.h:23
const_buffer buffer(void const *p, size_t n)
Definition: buffer.h:145
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