00001
00002
00003
00004
00005
00006
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 }
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 }
00268 }
00269
00270
00271
00272
00273
00274 #endif