CppCMS
|
00001 // 00002 // Copyright (C) 2009-2012 Artyom Beilis (Tonkikh) 00003 // 00004 // Distributed under the Boost Software License, Version 1.0. (See 00005 // accompanying file LICENSE_1_0.txt or copy at 00006 // http://www.boost.org/LICENSE_1_0.txt) 00007 // 00008 #ifndef BOOSTER_AIO_BUFFER_H 00009 #define BOOSTER_AIO_BUFFER_H 00010 00011 #include <vector> 00012 #include <string> 00013 00014 namespace booster { 00015 namespace aio { 00023 template<typename Pointer> 00024 class buffer_impl { 00025 public: 00029 struct entry { 00030 Pointer ptr; 00031 size_t size; 00032 }; 00033 00037 buffer_impl() : 00038 size_(0) 00039 { 00040 } 00041 00043 typedef std::pair<entry const *,size_t> buffer_data_type; 00044 00048 std::pair<entry const *,size_t> get() const 00049 { 00050 if(size_ == 0) { 00051 buffer_data_type bt; 00052 bt.first=0; 00053 bt.second=0; 00054 return bt; 00055 } 00056 else if(size_ == 1) 00057 return buffer_data_type(&entry_,1); 00058 else 00059 return buffer_data_type(&vec_.front(),vec_.size()); 00060 } 00064 void add(Pointer p,size_t s) 00065 { 00066 if(s==0) 00067 return; 00068 if(size_ == 0) { 00069 entry_.ptr = p; 00070 entry_.size = s; 00071 size_ = 1; 00072 return; 00073 } 00074 else if(size_ == 1) { 00075 vec_.push_back(entry_); 00076 } 00077 entry tmp = { p,s }; 00078 vec_.push_back(tmp); 00079 size_ = vec_.size(); 00080 } 00084 bool empty() const 00085 { 00086 return size_ == 0; 00087 } 00088 private: 00089 int size_; 00090 entry entry_; 00091 std::vector<entry> vec_; 00092 }; 00093 00097 class mutable_buffer : public buffer_impl<char *> { 00098 public: 00099 mutable_buffer() {} 00100 }; 00101 00105 class const_buffer : public buffer_impl<const char *> { 00106 public: 00107 const_buffer() {} 00111 const_buffer(mutable_buffer const &other) 00112 { 00113 mutable_buffer::buffer_data_type data = other.get(); 00114 for(unsigned i=0;i<data.second;i++) 00115 add(data.first[i].ptr,data.first[i].size); 00116 } 00117 }; 00118 00122 inline const_buffer buffer(void const *p,size_t n) 00123 { 00124 const_buffer tmp; 00125 tmp.add(reinterpret_cast<char const *>(p),n); 00126 return tmp; 00127 } 00131 inline mutable_buffer buffer(void *p,size_t n) 00132 { 00133 mutable_buffer tmp; 00134 tmp.add(reinterpret_cast<char *>(p),n); 00135 return tmp; 00136 } 00140 inline const_buffer buffer(std::vector<char> const &d) 00141 { 00142 return buffer(&d.front(),d.size()); 00143 } 00147 inline mutable_buffer buffer(std::vector<char> &d) 00148 { 00149 return buffer(&d.front(),d.size()); 00150 } 00154 inline const_buffer buffer(std::string const &d) 00155 { 00156 return buffer(d.c_str(),d.size()); 00157 } 00158 00160 00161 namespace details { 00162 template<typename Buffer> 00163 Buffer advance(Buffer const &buf,size_t n) 00164 { 00165 Buffer res; 00166 typename Buffer::buffer_data_type data=buf.get(); 00167 while(data.second > 0 && n > 0) { 00168 if(data.first->size <= n) { 00169 n-= data.first->size; 00170 data.second--; 00171 data.first++; 00172 } 00173 else { 00174 res.add(data.first->ptr + n,data.first->size - n); 00175 n=0; 00176 data.second--; 00177 data.first++; 00178 } 00179 } 00180 while(data.second > 0) { 00181 res.add(data.first->ptr,data.first->size); 00182 data.second--; 00183 data.first++; 00184 } 00185 return res; 00186 } 00187 template<typename Buffer> 00188 void add(Buffer &left,Buffer const &right) 00189 { 00190 typename Buffer::buffer_data_type data=right.get(); 00191 for(unsigned i=0;i<data.second;i++) 00192 left.add(data.first[i].ptr,data.first[i].size); 00193 } 00194 } // details 00195 00197 00203 inline const_buffer operator+(const_buffer const &buf,size_t n) 00204 { 00205 return details::advance(buf,n); 00206 } 00212 inline mutable_buffer operator+(mutable_buffer const &buf,size_t n) 00213 { 00214 return details::advance(buf,n); 00215 } 00219 inline const_buffer &operator+=(const_buffer &buf,size_t n) 00220 { 00221 buf = details::advance(buf,n); 00222 return buf; 00223 } 00227 inline mutable_buffer &operator+=(mutable_buffer &buf,size_t n) 00228 { 00229 buf = details::advance(buf,n); 00230 return buf; 00231 } 00235 inline const_buffer operator+(const_buffer const &b1,const_buffer const &b2) 00236 { 00237 const_buffer tmp=b1; 00238 details::add(tmp,b2); 00239 return tmp; 00240 } 00244 inline const_buffer &operator+=(const_buffer &b1,const_buffer const &b2) 00245 { 00246 details::add(b1,b2); 00247 return b1; 00248 } 00252 inline mutable_buffer operator+(mutable_buffer const &b1,mutable_buffer const &b2) 00253 { 00254 mutable_buffer tmp=b1; 00255 details::add(tmp,b2); 00256 return tmp; 00257 } 00261 inline mutable_buffer &operator+=(mutable_buffer &b1,mutable_buffer const &b2) 00262 { 00263 details::add(b1,b2); 00264 return b1; 00265 } 00266 00267 } // aio 00268 } // booster 00269 00270 00271 00272 00273 00274 #endif