00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024
00025
00026
00027 #include <boost/bind.hpp>
00028 #include <senf/Utils/Exception.hh>
00029
00030 #define prefix_
00031
00032
00033 template <class Handle>
00034 prefix_ senf::WriteHelper<Handle>::WriteHelper(Handle handle, std::string const & data,
00035 Callback callback)
00036 : handle_(handle),
00037 fde_("WriteHelper", boost::bind(&WriteHelper::dispatchProcess, ptr(this), _1, _2),
00038 handle, scheduler::FdEvent::EV_WRITE),
00039 data_(data), callback_(callback), offset_(data_.begin()), errno_(0)
00040 {}
00041
00042 template <class Handle>
00043 prefix_ std::string const & senf::WriteHelper<Handle>::data()
00044 const
00045 {
00046 if (offset_ > data_.begin()) {
00047 data_.erase(data_.begin(),offset_);
00048 offset_ = data_.begin();
00049 }
00050 return data_;
00051 }
00052
00053 template <class Handle>
00054 prefix_ void senf::WriteHelper<Handle>::revoke()
00055 {
00056 ptr guard (this);
00057 fde_.disable();
00058 fde_.action(0);
00059 }
00060
00061 template <class Handle>
00062 prefix_ void senf::WriteHelper<Handle>::dispatchProcess(ptr helper, Handle handle,
00063 scheduler::FdEvent::Events event)
00064 {
00065
00066
00067 helper->process(handle, event);
00068 }
00069
00070 template <class Handle>
00071 prefix_ void senf::WriteHelper<Handle>::process(Handle handle,
00072 scheduler::FdEvent::Events event)
00073 {
00074 bool complete_ (false);
00075 try {
00076 if (event != scheduler::FdEvent::EV_WRITE)
00077 throw SystemException(EPIPE SENF_EXC_DEBUGINFO);
00078 offset_ = handle.write(std::make_pair(offset_,data_.end()));
00079 if (offset_ == data_.end()) {
00080 data_.erase();
00081 offset_ = data_.begin();
00082 complete_ = true;
00083 }
00084 }
00085 catch (senf::SystemException const & ex) {
00086 errno_ = ex.errorNumber();
00087 done();
00088 return;
00089 }
00090 if (complete_)
00091 done();
00092 }
00093
00094 template <class Handle>
00095 prefix_ void senf::WriteHelper<Handle>::done()
00096 {
00097 revoke();
00098 callback_(ptr(this));
00099 }
00100
00101
00102 #undef prefix_
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113