ReadHelper.ct
Go to the documentation of this file.
1 //
2 // Copyright (c) 2020 Fraunhofer Institute for Applied Information Technology (FIT)
3 // Network Research Group (NET)
4 // Schloss Birlinghoven, 53754 Sankt Augustin, GERMANY
5 // Contact: support@wiback.org
6 //
7 // This file is part of the SENF code tree.
8 // It is licensed under the 3-clause BSD License (aka New BSD License).
9 // See LICENSE.txt in the top level directory for details or visit
10 // https://opensource.org/licenses/BSD-3-Clause
11 //
12 
13 
14 /** \file
15  \brief ReadHelper non-inline template implementation */
16 
17 #include "ReadHelper.ih"
18 
19 // Custom includes
20 #include <boost/bind.hpp>
21 #include <senf/Utils/Exception.hh>
22 
23 #define prefix_
24 //-/////////////////////////////////////////////////////////////////////////////////////////////////
25 
26 template <class Handle>
27 prefix_ senf::ReadHelper<Handle>::ReadHelper(Handle handle, std::string::size_type maxSize,
28  InternalPredicate * predicate, Callback cb)
29  : handle_(handle),
30  fde_("senf::ReadHelper", boost::bind(&ReadHelper::dispatchProcess,ptr(this), handle, _1),
31  handle, scheduler::FdEvent::EV_READ),
32  maxSize_(maxSize), predicate_(predicate), callback_(cb), errno_(0), complete_(false)
33 {
34  // Here we add a *static* member taking a *smart* pointer as first
35  // argument instead of a simple bound-member as callback to the
36  // scheduler. This ensures, that the refcount is at least 1 as
37  // long as the helper is registered with the scheduler.
38 }
39 
40 template <class Handle>
41 prefix_ void senf::ReadHelper<Handle>::revoke()
42 {
43  ptr guard (this); // To ensure, 'this' is deleted only after this method terminates ...
44  fde_.disable();
45  fde_.action(0); // Remove smart pointer reference to this
46 }
47 
48 template <class Handle>
49 prefix_ void
50 senf::ReadHelper<Handle>::dispatchProcess(ptr helper, Handle handle, int event)
51 {
52  // since we have a 'ptr' argument, the instance cannot be deleted
53  // before this method returns
54  helper->process(handle,event);
55 }
56 
57 template <class Handle>
58 prefix_ void senf::ReadHelper<Handle>::process(Handle handle,int event)
59 {
60  try {
61  if (event != scheduler::FdEvent::EV_READ)
62  throw SystemException(EPIPE SENF_EXC_DEBUGINFO);
63  std::string rcv;
64  handle.read(rcv, maxSize_ - data_.size());
65  data_.append(rcv);
66  std::string::size_type n = predicate_ ? (*predicate_)(data_) : std::string::npos;
67  if (n != std::string::npos || data_.size() >= maxSize_ || rcv.size() == 0) {
68  complete_ = true;
69  if (n < data_.size()) {
70  tail_.assign(data_,n,std::string::npos);
71  data_.erase(n);
72  }
73  }
74  }
75  catch (senf::SystemException const & ex) {
76  errno_ = ex.errorNumber();
77  done();
78  return;
79  }
80  if (complete_)
81  done();
82 }
83 
84 template <class Handle>
85 prefix_ void senf::ReadHelper<Handle>::done()
86 {
87  revoke();
88  callback_(ptr(this));
89 }
90 
91 template <class Handle>
92 template <class Predicate>
93 prefix_ std::string::size_type
94 senf::ReadHelper<Handle>::InternalPredicate::Dispatcher<Predicate>::
95 operator()(std::string const & data)
96 {
97  return predicate(data);
98 }
99 
100 //-/////////////////////////////////////////////////////////////////////////////////////////////////
101 #undef prefix_
102 
103 
104 // Local Variables:
105 // mode: c++
106 // fill-column: 100
107 // c-file-style: "senf"
108 // indent-tabs-mode: nil
109 // ispell-local-dictionary: "american"
110 // compile-command: "scons -u test"
111 // comment-column: 40
112 // End: