Search:

SENF Extensible Network Framework

  • Home
  • Download
  • Wiki
  • BerliOS
  • ChangeLog
  • Browse SVN
  • Bug Tracker
  • Overview
  • Examples
  • HowTos
  • Glossary
  • PPI
  • Packets
  • Scheduler
  • Socket
  • Utils
  • Console
  • Daemon
  • Logger
  • Termlib
  • Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

ReadHelper.ct

Go to the documentation of this file.
00001 // $Id: ReadHelper.ct 1781 2011-04-11 12:10:19Z tho $
00002 //
00003 // Copyright (C) 2006 Stefan Bund <g0dil@berlios.de>
00004 //
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 2 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program; if not, write to the
00017 // Free Software Foundation, Inc.,
00018 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019 // Copyright (C) 2006
00020 
00024 #include "ReadHelper.ih"
00025 
00026 // Custom includes
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     // Here we add a *static* member taking a *smart* pointer as first
00042     // argument instead of a simple bound-member as callback to the
00043     // scheduler. This ensures, that the refcount is at least 1 as
00044     // long as the helper is registered with the scheduler.
00045 }
00046 
00047 template <class Handle>
00048 prefix_ void senf::ReadHelper<Handle>::revoke()
00049 {
00050     ptr guard (this); // To ensure, 'this' is deleted only after this method terminates ...
00051     fde_.disable();
00052     fde_.action(0); // Remove smart pointer reference to this
00053 }
00054 
00055 template <class Handle>
00056 prefix_ void
00057 senf::ReadHelper<Handle>::dispatchProcess(ptr helper, Handle handle, int event)
00058 {
00059     // since we have a 'ptr' argument, the instance cannot be deleted
00060     // before this method returns
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 // Local Variables:
00112 // mode: c++
00113 // fill-column: 100
00114 // c-file-style: "senf"
00115 // indent-tabs-mode: nil
00116 // ispell-local-dictionary: "american"
00117 // compile-command: "scons -u test"
00118 // comment-column: 40
00119 // End:

Contact: senf-dev@lists.berlios.de | © 2006-2010 Fraunhofer Institute for Open Communication Systems, Network Research