00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00024 #include "ReadHelper.ih"
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::ReadHelper<Handle>::ReadHelper(Handle handle, std::string::size_type maxSize,
00035 InternalPredicate * predicate, Callback cb)
00036 : handle_(handle),
00037 fde_("senf::ReadHelper", boost::bind(&ReadHelper::dispatchProcess,ptr(this), handle, _1),
00038 handle, scheduler::FdEvent::EV_READ),
00039 maxSize_(maxSize), predicate_(predicate), callback_(cb), errno_(0), complete_(false)
00040 {
00041
00042
00043
00044
00045 }
00046
00047 template <class Handle>
00048 prefix_ void senf::ReadHelper<Handle>::revoke()
00049 {
00050 ptr guard (this);
00051 fde_.disable();
00052 fde_.action(0);
00053 }
00054
00055 template <class Handle>
00056 prefix_ void
00057 senf::ReadHelper<Handle>::dispatchProcess(ptr helper, Handle handle, int event)
00058 {
00059
00060
00061 helper->process(handle,event);
00062 }
00063
00064 template <class Handle>
00065 prefix_ void senf::ReadHelper<Handle>::process(Handle handle,int event)
00066 {
00067 try {
00068 if (event != scheduler::FdEvent::EV_READ)
00069 throw SystemException(EPIPE SENF_EXC_DEBUGINFO);
00070 std::string rcv;
00071 handle.read(rcv, maxSize_ - data_.size());
00072 data_.append(rcv);
00073 std::string::size_type n = predicate_ ? (*predicate_)(data_) : std::string::npos;
00074 if (n != std::string::npos || data_.size() >= maxSize_ || rcv.size() == 0) {
00075 complete_ = true;
00076 if (n < data_.size()) {
00077 tail_.assign(data_,n,std::string::npos);
00078 data_.erase(n);
00079 }
00080 }
00081 }
00082 catch (senf::SystemException const & ex) {
00083 errno_ = ex.errorNumber();
00084 done();
00085 return;
00086 }
00087 if (complete_)
00088 done();
00089 }
00090
00091 template <class Handle>
00092 prefix_ void senf::ReadHelper<Handle>::done()
00093 {
00094 revoke();
00095 callback_(ptr(this));
00096 }
00097
00098 template <class Handle>
00099 template <class Predicate>
00100 prefix_ std::string::size_type
00101 senf::ReadHelper<Handle>::InternalPredicate::Dispatcher<Predicate>::
00102 operator()(std::string const & data)
00103 {
00104 return predicate(data);
00105 }
00106
00107
00108 #undef prefix_
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119