11 #ifndef ASIO_IMPL_READ_UNTIL_HPP 12 #define ASIO_IMPL_READ_UNTIL_HPP 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 36 template <
typename SyncReadStream,
typename Allocator>
41 std::size_t bytes_transferred =
read_until(s, b, delim, ec);
43 return bytes_transferred;
46 template <
typename SyncReadStream,
typename Allocator>
51 std::size_t search_position = 0;
56 Allocator>::const_buffers_type const_buffers_type;
60 iterator start_pos = begin + search_position;
64 iterator iter = std::find(start_pos, end, delim);
69 return iter - begin + 1;
74 search_position = end -
begin;
92 template <
typename SyncReadStream,
typename Allocator>
97 std::size_t bytes_transferred =
read_until(s, b, delim, ec);
99 return bytes_transferred;
110 template <
typename Iterator1,
typename Iterator2>
112 Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
114 for (Iterator1 iter1 = first1; iter1 != last1; ++iter1)
116 Iterator1 test_iter1 = iter1;
117 Iterator2 test_iter2 = first2;
118 for (;; ++test_iter1, ++test_iter2)
120 if (test_iter2 == last2)
121 return std::make_pair(iter1,
true);
122 if (test_iter1 == last1)
124 if (test_iter2 != first2)
125 return std::make_pair(iter1,
false);
129 if (*test_iter1 != *test_iter2)
133 return std::make_pair(last1,
false);
137 template <
typename SyncReadStream,
typename Allocator>
142 std::size_t search_position = 0;
147 Allocator>::const_buffers_type const_buffers_type;
151 iterator start_pos = begin + search_position;
156 start_pos, end, delim.begin(), delim.end());
157 if (result.first != end)
163 return result.first - begin + delim.length();
168 search_position = result.first -
begin;
174 search_position = end -
begin;
192 #if defined(ASIO_HAS_BOOST_REGEX) 194 template <
typename SyncReadStream,
typename Allocator>
199 std::size_t bytes_transferred =
read_until(s, b, expr, ec);
201 return bytes_transferred;
204 template <
typename SyncReadStream,
typename Allocator>
209 std::size_t search_position = 0;
214 Allocator>::const_buffers_type const_buffers_type;
218 iterator start_pos = begin + search_position;
222 boost::match_results<iterator,
223 typename std::vector<boost::sub_match<iterator> >::allocator_type>
225 if (regex_search(start_pos, end, match_results, expr,
226 boost::match_default | boost::match_partial))
228 if (match_results[0].matched)
232 return match_results[0].second -
begin;
237 search_position = match_results[0].first -
begin;
243 search_position = end -
begin;
261 #endif // defined(ASIO_HAS_BOOST_REGEX) 263 template <
typename SyncReadStream,
typename Allocator,
typename MatchCondition>
269 std::size_t search_position = 0;
274 Allocator>::const_buffers_type const_buffers_type;
278 iterator start_pos = begin + search_position;
287 return result.first -
begin;
289 else if (result.first != end)
292 search_position = result.first -
begin;
297 search_position = end -
begin;
315 template <
typename SyncReadStream,
typename Allocator,
typename MatchCondition>
321 std::size_t bytes_transferred =
read_until(s, b, match_condition, ec);
323 return bytes_transferred;
328 template <
typename AsyncReadStream,
typename Allocator,
typename ReadHandler>
334 char delim, ReadHandler& handler)
336 streambuf_(streambuf),
344 #if defined(ASIO_HAS_MOVE) 364 #endif // defined(ASIO_HAS_MOVE) 367 std::size_t bytes_transferred,
int start = 0)
369 const std::size_t
not_found = (std::numeric_limits<std::size_t>::max)();
370 std::size_t bytes_to_read;
371 switch (start_ = start)
379 Allocator>::const_buffers_type const_buffers_type;
381 const_buffers_type
buffers = streambuf_.data();
383 iterator start_pos = begin + search_position_;
387 iterator iter = std::find(start_pos, end, delim_);
391 search_position_ = iter - begin + 1;
396 else if (streambuf_.size() == streambuf_.max_size())
406 search_position_ = end -
begin;
412 if (!start && bytes_to_read == 0)
416 stream_.async_read_some(streambuf_.prepare(bytes_to_read),
419 streambuf_.commit(bytes_transferred);
420 if (ec || bytes_transferred == 0)
428 const std::size_t result_n =
430 ? 0 : search_position_;
432 handler_(result_ec, result_n);
445 template <
typename AsyncReadStream,
typename Allocator,
typename ReadHandler>
448 Allocator, ReadHandler>* this_handler)
451 size, this_handler->handler_);
454 template <
typename AsyncReadStream,
typename Allocator,
typename ReadHandler>
457 Allocator, ReadHandler>* this_handler)
460 pointer, size, this_handler->handler_);
463 template <
typename AsyncReadStream,
typename Allocator,
typename ReadHandler>
466 Allocator, ReadHandler>* this_handler)
468 return this_handler->start_ == 0 ?
true 470 this_handler->handler_);
473 template <
typename Function,
typename AsyncReadStream,
typename Allocator,
474 typename ReadHandler>
477 Allocator, ReadHandler>* this_handler)
480 function, this_handler->handler_);
483 template <
typename Function,
typename AsyncReadStream,
typename Allocator,
484 typename ReadHandler>
487 Allocator, ReadHandler>* this_handler)
490 function, this_handler->handler_);
494 template <
typename AsyncReadStream,
typename Allocator,
typename ReadHandler>
497 async_read_until(AsyncReadStream& s,
520 template <
typename AsyncReadStream,
typename Allocator,
typename ReadHandler>
526 const std::string& delim, ReadHandler& handler)
528 streambuf_(streambuf),
536 #if defined(ASIO_HAS_MOVE) 556 #endif // defined(ASIO_HAS_MOVE) 559 std::size_t bytes_transferred,
int start = 0)
561 const std::size_t
not_found = (std::numeric_limits<std::size_t>::max)();
562 std::size_t bytes_to_read;
563 switch (start_ = start)
571 Allocator>::const_buffers_type const_buffers_type;
573 const_buffers_type
buffers = streambuf_.data();
575 iterator start_pos = begin + search_position_;
580 start_pos, end, delim_.begin(), delim_.end());
581 if (result.first != end && result.second)
584 search_position_ = result.first - begin + delim_.length();
589 else if (streambuf_.size() == streambuf_.max_size())
598 if (result.first != end)
602 search_position_ = result.first -
begin;
607 search_position_ = end -
begin;
615 if (!start && bytes_to_read == 0)
619 stream_.async_read_some(streambuf_.prepare(bytes_to_read),
622 streambuf_.commit(bytes_transferred);
623 if (ec || bytes_transferred == 0)
631 const std::size_t result_n =
633 ? 0 : search_position_;
635 handler_(result_ec, result_n);
648 template <
typename AsyncReadStream,
typename Allocator,
typename ReadHandler>
651 Allocator, ReadHandler>* this_handler)
654 size, this_handler->handler_);
657 template <
typename AsyncReadStream,
typename Allocator,
typename ReadHandler>
660 Allocator, ReadHandler>* this_handler)
663 pointer, size, this_handler->handler_);
666 template <
typename AsyncReadStream,
typename Allocator,
typename ReadHandler>
669 Allocator, ReadHandler>* this_handler)
671 return this_handler->start_ == 0 ?
true 673 this_handler->handler_);
676 template <
typename Function,
typename AsyncReadStream,
677 typename Allocator,
typename ReadHandler>
680 Allocator, ReadHandler>* this_handler)
683 function, this_handler->handler_);
686 template <
typename Function,
typename AsyncReadStream,
687 typename Allocator,
typename ReadHandler>
690 Allocator, ReadHandler>* this_handler)
693 function, this_handler->handler_);
697 template <
typename AsyncReadStream,
typename Allocator,
typename ReadHandler>
700 async_read_until(AsyncReadStream& s,
721 #if defined(ASIO_HAS_BOOST_REGEX) 725 template <
typename AsyncReadStream,
typename Allocator,
726 typename RegEx,
typename ReadHandler>
727 class read_until_expr_op
730 read_until_expr_op(AsyncReadStream& stream,
732 const boost::regex& expr, ReadHandler& handler)
734 streambuf_(streambuf),
742 #if defined(ASIO_HAS_MOVE) 743 read_until_expr_op(
const read_until_expr_op& other)
744 : stream_(other.stream_),
745 streambuf_(other.streambuf_),
747 start_(other.start_),
748 search_position_(other.search_position_),
749 handler_(other.handler_)
753 read_until_expr_op(read_until_expr_op&& other)
754 : stream_(other.stream_),
755 streambuf_(other.streambuf_),
757 start_(other.start_),
758 search_position_(other.search_position_),
762 #endif // defined(ASIO_HAS_MOVE) 765 std::size_t bytes_transferred,
int start = 0)
767 const std::size_t
not_found = (std::numeric_limits<std::size_t>::max)();
768 std::size_t bytes_to_read;
769 switch (start_ = start)
777 Allocator>::const_buffers_type const_buffers_type;
779 const_buffers_type
buffers = streambuf_.data();
781 iterator start_pos = begin + search_position_;
785 boost::match_results<iterator,
786 typename std::vector<boost::sub_match<iterator> >::allocator_type>
788 bool match = regex_search(start_pos, end, match_results, expr_,
789 boost::match_default | boost::match_partial);
790 if (match && match_results[0].matched)
793 search_position_ = match_results[0].second -
begin;
798 else if (streambuf_.size() == streambuf_.max_size())
811 search_position_ = match_results[0].first -
begin;
816 search_position_ = end -
begin;
824 if (!start && bytes_to_read == 0)
828 stream_.async_read_some(streambuf_.prepare(bytes_to_read),
831 streambuf_.commit(bytes_transferred);
832 if (ec || bytes_transferred == 0)
840 const std::size_t result_n =
842 ? 0 : search_position_;
844 handler_(result_ec, result_n);
849 AsyncReadStream& stream_;
853 std::size_t search_position_;
854 ReadHandler handler_;
857 template <
typename AsyncReadStream,
typename Allocator,
858 typename RegEx,
typename ReadHandler>
860 read_until_expr_op<AsyncReadStream,
861 Allocator, RegEx, ReadHandler>* this_handler)
864 size, this_handler->handler_);
867 template <
typename AsyncReadStream,
typename Allocator,
868 typename RegEx,
typename ReadHandler>
870 read_until_expr_op<AsyncReadStream,
871 Allocator, RegEx, ReadHandler>* this_handler)
874 pointer, size, this_handler->handler_);
877 template <
typename AsyncReadStream,
typename Allocator,
878 typename RegEx,
typename ReadHandler>
880 read_until_expr_op<AsyncReadStream,
881 Allocator, RegEx, ReadHandler>* this_handler)
883 return this_handler->start_ == 0 ?
true 885 this_handler->handler_);
888 template <
typename Function,
typename AsyncReadStream,
typename Allocator,
889 typename RegEx,
typename ReadHandler>
891 read_until_expr_op<AsyncReadStream,
892 Allocator, RegEx, ReadHandler>* this_handler)
895 function, this_handler->handler_);
898 template <
typename Function,
typename AsyncReadStream,
typename Allocator,
899 typename RegEx,
typename ReadHandler>
901 read_until_expr_op<AsyncReadStream,
902 Allocator, RegEx, ReadHandler>* this_handler)
905 function, this_handler->handler_);
909 template <
typename AsyncReadStream,
typename Allocator,
typename ReadHandler>
912 async_read_until(AsyncReadStream& s,
924 detail::read_until_expr_op<AsyncReadStream, Allocator,
933 #endif // defined(ASIO_HAS_BOOST_REGEX) 937 template <
typename AsyncReadStream,
typename Allocator,
938 typename MatchCondition,
typename ReadHandler>
946 streambuf_(streambuf),
947 match_condition_(match_condition),
954 #if defined(ASIO_HAS_MOVE) 974 #endif // defined(ASIO_HAS_MOVE) 977 std::size_t bytes_transferred,
int start = 0)
979 const std::size_t
not_found = (std::numeric_limits<std::size_t>::max)();
980 std::size_t bytes_to_read;
981 switch (start_ = start)
989 Allocator>::const_buffers_type const_buffers_type;
991 const_buffers_type
buffers = streambuf_.data();
993 iterator start_pos = begin + search_position_;
997 std::pair<iterator, bool> result = match_condition_(start_pos, end);
1001 search_position_ = result.first -
begin;
1006 else if (streambuf_.size() == streambuf_.max_size())
1015 if (result.first != end)
1019 search_position_ = result.first -
begin;
1024 search_position_ = end -
begin;
1032 if (!start && bytes_to_read == 0)
1036 stream_.async_read_some(streambuf_.prepare(bytes_to_read),
1039 streambuf_.commit(bytes_transferred);
1040 if (ec || bytes_transferred == 0)
1048 const std::size_t result_n =
1050 ? 0 : search_position_;
1052 handler_(result_ec, result_n);
1065 template <
typename AsyncReadStream,
typename Allocator,
1066 typename MatchCondition,
typename ReadHandler>
1069 Allocator, MatchCondition, ReadHandler>* this_handler)
1072 size, this_handler->handler_);
1075 template <
typename AsyncReadStream,
typename Allocator,
1076 typename MatchCondition,
typename ReadHandler>
1079 Allocator, MatchCondition, ReadHandler>* this_handler)
1082 pointer, size, this_handler->handler_);
1085 template <
typename AsyncReadStream,
typename Allocator,
1086 typename MatchCondition,
typename ReadHandler>
1089 Allocator, MatchCondition, ReadHandler>* this_handler)
1091 return this_handler->start_ == 0 ?
true 1093 this_handler->handler_);
1096 template <
typename Function,
typename AsyncReadStream,
typename Allocator,
1097 typename MatchCondition,
typename ReadHandler>
1100 Allocator, MatchCondition, ReadHandler>* this_handler)
1103 function, this_handler->handler_);
1106 template <
typename Function,
typename AsyncReadStream,
typename Allocator,
1107 typename MatchCondition,
typename ReadHandler>
1110 Allocator, MatchCondition, ReadHandler>* this_handler)
1113 function, this_handler->handler_);
1117 template <
typename AsyncReadStream,
typename Allocator,
1118 typename MatchCondition,
typename ReadHandler>
1121 async_read_until(AsyncReadStream& s,
1140 return init.
result.get();
1147 #endif // ASIO_IMPL_READ_UNTIL_HPP
void asio_handler_deallocate(void *pointer, std::size_t size, binder1< Handler, Arg1 > *this_handler)
asio::basic_streambuf< Allocator > & streambuf_
void throw_error(const asio::error_code &err)
std::size_t search_position_
AsyncReadStream & stream_
SocketService Iterator begin
void * asio_handler_allocate(std::size_t size, binder1< Handler, Arg1 > *this_handler)
std::size_t max_size() const
Get the maximum size of the basic_streambuf.
read_until_match_op(AsyncReadStream &stream, asio::basic_streambuf< Allocator > &streambuf, MatchCondition match_condition, ReadHandler &handler)
asio::basic_streambuf< Allocator > MatchCondition enable_if< is_match_condition< MatchCondition >::value >::type *detail::async_result_init< ReadHandler, void(asio::error_code, std::size_t)> init(ASIO_MOVE_CAST(ReadHandler)(handler))
void operator()(const asio::error_code &ec, std::size_t bytes_transferred, int start=0)
#define ASIO_HANDLER_TYPE(h, sig)
mutable_buffers_type prepare(std::size_t n)
A random access iterator over the bytes in a buffer sequence.
asio::basic_streambuf< Allocator > & b
ASIO_INITFN_RESULT_TYPE(ComposedConnectHandler, void(asio::error_code, Iterator)) async_connect(basic_socket< Protocol
MatchCondition match_condition_
void invoke(Function &function, Context &context)
asio::basic_streambuf< Allocator > & streambuf_
void operator()(const asio::error_code &ec, std::size_t bytes_transferred, int start=0)
const MutableBufferSequence & buffers
void commit(std::size_t n)
Move characters from the output sequence to the input sequence.
std::size_t read_until(SyncReadStream &s, asio::basic_streambuf< Allocator > &b, char delim)
Read data into a streambuf until it contains a specified delimiter.
#define ASIO_READ_HANDLER_CHECK(handler_type, handler)
void operator()(const asio::error_code &ec, std::size_t bytes_transferred, int start=0)
std::size_t size() const
Get the size of the input sequence.
AsyncReadStream & stream_
void asio_handler_invoke(Function &function, binder1< Handler, Arg1 > *this_handler)
asio::basic_streambuf< Allocator > CompletionCondition ASIO_MOVE_ARG(ReadHandler) handler)
bool is_continuation(Context &context)
read_until_delim_op(AsyncReadStream &stream, asio::basic_streambuf< Allocator > &streambuf, char delim, ReadHandler &handler)
Class to represent an error code value.
asio::basic_streambuf< Allocator > & streambuf_
AsyncReadStream & stream_
void deallocate(void *p, std::size_t s, Handler &h)
asio::basic_streambuf< Allocator > MatchCondition match_condition
std::size_t read_size_helper(basic_streambuf< Allocator > &sb, std::size_t max_size)
read_until_delim_string_op(AsyncReadStream &stream, asio::basic_streambuf< Allocator > &streambuf, const std::string &delim, ReadHandler &handler)
std::pair< Iterator1, bool > partial_search(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2)
Automatically resizable buffer class based on std::streambuf.
void * allocate(std::size_t s, Handler &h)
std::size_t search_position_
handler_type< Handler, Signature >::type handler
SocketService Iterator Iterator end
#define ASIO_MOVE_CAST(type)
async_result< typename handler_type< Handler, Signature >::type > result
asio::basic_streambuf< Allocator > char delim
const_buffers_type data() const
Get a list of buffers that represents the input sequence.
std::size_t search_position_
bool asio_handler_is_continuation(binder1< Handler, Arg1 > *this_handler)