3 // Copyright (C) 2006 Stefan Bund <g0dil@berlios.de>
5 // The contents of this file are subject to the Fraunhofer FOKUS Public License
6 // Version 1.0 (the "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 // http://senf.berlios.de/license.html
10 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
11 // but modifies the Mozilla Public License Version 1.1.
12 // See the full license text for the amendments.
14 // Software distributed under the License is distributed on an "AS IS" basis,
15 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
16 // for the specific language governing rights and limitations under the License.
18 // The Original Code is Fraunhofer FOKUS code.
20 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
21 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
22 // All Rights Reserved.
28 \brief ReadHelper public header */
30 #ifndef HH_SENF_Scheduler_ReadHelper_
31 #define HH_SENF_Scheduler_ReadHelper_ 1
35 #include <boost/function.hpp>
36 #include <boost/intrusive_ptr.hpp>
37 #include <boost/scoped_ptr.hpp>
39 #include <senf/Utils/intrusive_refcount.hh>
42 //#include "ReadHelper.mpp"
43 //-/////////////////////////////////////////////////////////////////////////////////////////////////
48 /** \brief Asynchronous reading helper
50 This class provides a simple asynchronous reading facility. This helper will register with
51 the Scheduler and read incoming data. It will collect the data until a specific number of
52 bytes has been read or some Predicate evaluated on the data read thus far signals end of
55 The ReadHelper accepts the same flexible file handle interfaces as the Scheduler.
57 The callback must take a ReadHelper::ptr argument. Using this ReadHelper instance, the
58 callback can access the data read or retrieve state information.
60 The ReadHelper separates the data into two parts: data() will return the matched data,
61 tail() will return any surplus data already read. If you don't specify a predicate, tail()
62 will always be empty (there may however some data be left in the socket input buffer after
63 the ReadHelper returns).
65 The predicate is any class instance with an <tt>operator(std::string const &)</tt>. This
66 operator is called, whenever some data has been read. If the data is not yet complete, the
67 predicate must return \c std::string::npos. If the ReadHelper should stop reading more
68 data, the predicate must return the number of bytes which are to be considered 'matched'.
70 \todo Move all not Handle dependent members to a ReadHandleBase class
71 \todo Add an optional <tt>std::string const & tail</tt> argument to the constructors which
72 takes the tail() of a previous ReadHelper instance.
74 template <class Handle>
76 : public senf::intrusive_refcount
79 //-////////////////////////////////////////////////////////////////////////
82 typedef boost::intrusive_ptr<ReadHelper> ptr; ///< Smart pointer type for this class
83 typedef boost::function<void (ptr)> Callback; ///< Callback type
85 //-////////////////////////////////////////////////////////////////////////
86 ///\name Structors and default members
89 static ptr dispatch(Handle handle, std::string::size_type maxSize,
90 Callback callback); ///< Register new ReadHandler instance
91 /**< The registered Callback will be called after \a maxSize
92 bytes have been read or EOF or some error is
94 \post The returned ReadHelper instance is registered
95 with the Scheduler to handle read events.
96 \param[in] handle file descriptor or handle providing
97 the Handle interface defined above.
98 \param[in] maxSize maximum number of bytes to read
99 \param[in] callback callback
100 \returns Smart pointer to new ReadHelper instance */
102 template <class Predicate>
103 static ptr dispatch(Handle handle, std::string::size_type maxSize, Predicate const & predicate,
104 Callback callback); ///< Register new ReadHelper instance
105 /**< The registered Callback will be called after the \a
106 predicate returns a Value other than \c
107 std::string::npos, \a maxSize bytes have been read, or
108 EOF or some error condition is encountered.
109 \post The returned ReadHelper instance is registered
110 with the Scheduler to handle read events
111 . \param[in] handle file descriptor or handle providing
112 the Handle interface defined above.
113 \param[in] maxSize maximum number of bytes to read
114 \param[in] predicate predicate to check
115 \param[in] callback callback
116 \returns smart pointer to new ReadHelper instance */
119 //-////////////////////////////////////////////////////////////////////////
121 Handle handle() const; ///< Access the handle object
122 std::string::size_type maxSize() const; ///< Return maximum number of bytes to be read
124 std::string const & data() const; ///< return data read
125 std::string const & tail() const; ///< return data read but not matched by the predicate
127 bool complete() const; ///< Check whether the read has completed successfully
128 bool error() const; ///< Check for error condition
129 void throw_error() const; ///< If an error occurred, throw it
131 void revoke(); ///< Remove the ReadHelper from the scheduler
136 struct InternalPredicate;
138 ReadHelper(Handle handle, std::string::size_type maxSize,
139 InternalPredicate * predicate, Callback cb);
141 static void dispatchProcess(ptr helper, Handle handle, int event);
142 void process(Handle handle, int event);
146 scheduler::FdEvent fde_;
147 std::string::size_type maxSize_;
148 boost::scoped_ptr<InternalPredicate> predicate_;
157 /** \brief ReadHelper predicate matching an arbitrary string
159 This predicate will terminate the read when the data read matches a given fixed string. All
160 data up to and including the string matched is considered to be part of the data() portion,
161 everything after the matched string is placed into the tail().
167 ReadUntil(std::string const & target);
168 std::string::size_type operator()(std::string const & data);
174 //-/////////////////////////////////////////////////////////////////////////////////////////////////
175 #include "ReadHelper.cci"
176 #include "ReadHelper.ct"
177 #include "ReadHelper.cti"
178 //#include "ReadHelper.mpp"
185 // c-file-style: "senf"
186 // indent-tabs-mode: nil
187 // ispell-local-dictionary: "american"
188 // compile-command: "scons -u test"
189 // comment-column: 40