From 92414c7e630fff77b53c3da64c548cbc26b74fbd Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 7 May 2004 02:12:16 +0000 Subject: [PATCH] Remove recv_decode and friends, in anticipation of a new improved way of writing message decoders. --- asio/TODO | 10 - asio/include/asio/recv.hpp | 401 ------------------------------------- 2 files changed, 411 deletions(-) diff --git a/asio/TODO b/asio/TODO index 77265d6c..030632ec 100644 --- a/asio/TODO +++ b/asio/TODO @@ -6,16 +6,6 @@ Add vectored send/recv functions Add the sendv and recvv functions to basic_stream_socket and presumably also to the buffered stream templates. -Add encode_send/async_encode_send functions -------------------------------------------- -Add new free functions encode_send/async_encode_send that mirror the -functionality of recv_decode/async_recv_decode. - -Develop a safe version of recv_until ------------------------------------- -The current implementation of recv_until (and async_recv_until) does not set -an upper limit on the size of the received data. This is not particularly safe. - Demuxer functions for event loop integration -------------------------------------------- Add functions demuxer::work_pending() and demuxer::perform_work() that can be diff --git a/asio/include/asio/recv.hpp b/asio/include/asio/recv.hpp index a17b49e1..51ca9e6f 100644 --- a/asio/include/asio/recv.hpp +++ b/asio/include/asio/recv.hpp @@ -17,11 +17,6 @@ #include "asio/detail/push_options.hpp" -#include "asio/detail/push_options.hpp" -#include -#include -#include "asio/detail/pop_options.hpp" - #include "asio/detail/bind_handler.hpp" namespace asio { @@ -479,402 +474,6 @@ inline void async_recv_at_least_n(Stream& s, void* data, size_t min_length, max_length, handler)); } -/// Read some data from a stream and decode it. -/** - * This function is used to receive data on a stream and decode it in a single - * operation. The function call will block until the decoder function object - * indicates that it has finished. - * - * @param s The stream on which the data is to be received. - * - * @param decoder The decoder function object to be called to decode the - * received data. The function object is assumed to be stateful. That is, it - * may not be given sufficient data in a single invocation to complete - * decoding, and is expected to maintain state so that it may resume decoding - * when the next piece of data is supplied. Copies will be made of the decoder - * function object as required, however with respect to maintaining state it - * can rely on the fact that only an up-to-date copy will be used. The - * equivalent function signature of the handler must be: - * @code std::pair decoder( - * const char* begin, // Pointer to the beginning of data to be decoded. - * const char* end // Pointer to one-past-the-end of data to be decoded. - * ); @endcode - * The first element of the return value is true if the decoder has finished. - * The second element is a pointer to the beginning of the unused portion of - * the data. - * - * @param total_bytes_recvd An optional output parameter that receives the - * total number of bytes actually received. - * - * @returns The number of bytes received on the last recv, or 0 if end-of-file - * was reached or the connection was closed cleanly. - * - * @note Throws an exception on failure. The type of the exception depends - * on the underlying stream's recv operation. - */ -template -size_t recv_decode(Buffered_Stream& s, Decoder decoder, - size_t* total_bytes_recvd = 0) -{ - size_t total_recvd = 0; - for (;;) - { - if (s.recv_buffer().empty() && s.fill() == 0) - { - if (total_bytes_recvd) - *total_bytes_recvd = total_recvd; - return 0; - } - - std::pair result = - decoder(s.recv_buffer().begin(), s.recv_buffer().end()); - - size_t bytes_read = result.second - s.recv_buffer().begin(); - s.recv_buffer().pop(bytes_read); - total_recvd += bytes_read; - - if (result.first) - { - if (total_bytes_recvd) - *total_bytes_recvd = total_recvd; - return bytes_read; - } - } -} - -/// Read some data from a stream and decode it. -/** - * This function is used to receive data on a stream and decode it in a single - * operation. The function call will block until the decoder function object - * indicates that it has finished. - * - * @param s The stream on which the data is to be received. - * - * @param decoder The decoder function object to be called to decode the - * received data. The function object is assumed to be stateful. That is, it - * may not be given sufficient data in a single invocation to complete - * decoding, and is expected to maintain state so that it may resume decoding - * when the next piece of data is supplied. Copies will be made of the decoder - * function object as required, however with respect to maintaining state it - * can rely on the fact that only an up-to-date copy will be used. The - * equivalent function signature of the handler must be: - * @code std::pair decoder( - * const char* begin, // Pointer to the beginning of data to be decoded. - * const char* end // Pointer to one-past-the-end of data to be decoded. - * ); @endcode - * The first element of the return value is true if the decoder has finished. - * The second element is a pointer to the beginning of the unused portion of - * the data. - * - * @param total_bytes_recvd An optional output parameter that receives the - * total number of bytes actually received. - * - * @param error_handler The handler to be called when an error occurs. Copies - * will be made of the handler as required. The equivalent function signature - * of the handler must be: - * @code template - * void error_handler( - * const Error& error // Result of operation (the actual type is dependent on - * // the underlying stream's recv operation) - * ); @endcode - * - * @returns The number of bytes received on the last recv, or 0 if end-of-file - * was reached or the connection was closed cleanly. - */ -template -size_t recv_decode(Buffered_Stream& s, Decoder decoder, - size_t* total_bytes_recvd, Error_Handler error_handler) -{ - size_t total_recvd = 0; - for (;;) - { - if (s.recv_buffer().empty() && s.fill(error_handler) == 0) - { - if (total_bytes_recvd) - *total_bytes_recvd = total_recvd; - return 0; - } - - std::pair result = - decoder(s.recv_buffer().begin(), s.recv_buffer().end()); - - size_t bytes_read = result.second - s.recv_buffer().begin(); - s.recv_buffer().pop(bytes_read); - total_recvd += bytes_read; - - if (result.first) - { - if (total_bytes_recvd) - *total_bytes_recvd = total_recvd; - return bytes_read; - } - } -} - -namespace detail -{ - template - class recv_decode_handler - { - public: - recv_decode_handler(Buffered_Stream& stream, Decoder decoder, - Handler handler) - : stream_(stream), - decoder_(decoder), - total_recvd_(0), - handler_(handler) - { - } - - template - void operator()(const Error& e, size_t bytes_recvd) - { - if (e || bytes_recvd == 0) - { - stream_.demuxer().dispatch( - detail::bind_handler(handler_, e, bytes_recvd, total_recvd_)); - } - else - { - while (!stream_.recv_buffer().empty()) - { - std::pair result = - decoder_(stream_.recv_buffer().begin(), - stream_.recv_buffer().end()); - - size_t bytes_read = result.second - stream_.recv_buffer().begin(); - stream_.recv_buffer().pop(bytes_read); - total_recvd_ += bytes_read; - - if (result.first) - { - stream_.demuxer().dispatch( - detail::bind_handler(handler_, 0, bytes_read, total_recvd_)); - return; - } - } - - stream_.async_fill(*this); - } - } - - private: - Buffered_Stream& stream_; - Decoder decoder_; - size_t total_recvd_; - Handler handler_; - }; -} // namespace detail - -/// Start an asynchronous receive that will not complete until some data has -/// been fully decoded. -/** - * This function is used to receive data on a stream and decode it in a single - * asynchronous operation. The function call always returns immediately. The - * asynchronous operation will complete only when the decoder indicates that it - * has finished. - * - * @param s The stream on which the data is to be received. - * - * @param decoder The decoder function object to be called to decode the - * received data. The function object is assumed to be stateful. That is, it - * may not be given sufficient data in a single invocation to complete - * decoding, and is expected to maintain state so that it may resume decoding - * when the next piece of data is supplied. Copies will be made of the decoder - * function object as required, however with respect to maintaining state it - * can rely on the fact that only an up-to-date copy will be used. The - * equivalent function signature of the handler must be: - * @code std::pair decoder( - * const char* begin, // Pointer to the beginning of data to be decoded. - * const char* end // Pointer to one-past-the-end of data to be decoded. - * ); @endcode - * The first element of the return value is true if the decoder has finished. - * The second element is a pointer to the beginning of the unused portion of - * the data. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The equivalent - * function signature of the handler must be: - * @code template - * void handler( - * const Error& error, // Result of operation (the actual type is - * // dependent on the underlying stream's recv - * // operation) - * size_t last_bytes_recvd, // Number of bytes received on last recv - * // operation - * size_t total_bytes_recvd // Total number of bytes successfully received - * ); @endcode - */ -template -void async_recv_decode(Buffered_Stream& s, Decoder decoder, Handler handler) -{ - while (!s.recv_buffer().empty()) - { - std::pair result = - decoder(s.recv_buffer().begin(), s.recv_buffer().end()); - - size_t bytes_read = result.second - s.recv_buffer().begin(); - s.recv_buffer().pop(bytes_read); - - if (result.first) - { - s.demuxer().post( - detail::bind_handler(handler, 0, bytes_read, bytes_read)); - return; - } - } - - s.async_fill(detail::recv_decode_handler( - s, decoder, handler)); -} - -namespace detail -{ - class recv_until_decoder - { - public: - recv_until_decoder(std::string& data, const std::string& delimiter) - : data_(data), - delimiter_(delimiter), - delimiter_length_(delimiter.length()), - delimiter_pos_(0) - { - data_ = ""; - } - - std::pair operator()(const char* begin, const char* end) - { - const char* p = begin; - while (p < end) - { - char next_char = *p++; - if (next_char == delimiter_[delimiter_pos_]) - { - if (++delimiter_pos_ == delimiter_length_) - { - data_.append(begin, p - begin); - return std::make_pair(true, p); - } - } - else - { - delimiter_pos_ = 0; - } - } - data_.append(begin, end - begin); - return std::make_pair(false, end); - } - - private: - std::string& data_; - std::string delimiter_; - size_t delimiter_length_; - size_t delimiter_pos_; - }; -} - -/// Read data from the stream until a delimiter is reached. -/** - * This function is used to receive data from the stream into a std::string - * object until a specified delimiter is reached. The function call will block - * until the delimiter is found or an error occurs. - * - * @param s The stream on which the data is to be received. - * - * @param data The std::string object into which the received data will be - * written. - * - * @param delimiter The pattern marking the end of the data to receive. - * - * @param total_bytes_recvd An optional output parameter that receives the - * total number of bytes actually received. - * - * @returns The number of bytes received on the last recv, or 0 if end-of-file - * was reached or the connection was closed cleanly. - * - * @note Throws an exception on failure. The type of the exception depends - * on the underlying stream's recv operation. - */ -template -inline size_t recv_until(Buffered_Stream& s, std::string& data, - const std::string& delimiter, size_t* total_bytes_recvd = 0) -{ - return recv_decode(s, detail::recv_until_decoder(data, delimiter), - total_bytes_recvd); -} - -/// Read data from the stream until a delimiter is reached. -/** - * This function is used to receive data from the stream into a std::string - * object until a specified delimiter is reached. The function call will block - * until the delimiter is found or an error occurs. - * - * @param s The stream on which the data is to be received. - * - * @param data The std::string object into which the received data will be - * written. - * - * @param delimiter The pattern marking the end of the data to receive. - * - * @param total_bytes_recvd An optional output parameter that receives the - * total number of bytes actually received. - * - * @param error_handler The handler to be called when an error occurs. Copies - * will be made of the handler as required. The equivalent function signature - * of the handler must be: - * @code template - * void error_handler( - * const Error& error // Result of operation (the actual type is dependent on - * // the underlying stream's recv operation) - * ); @endcode - * - * @returns The number of bytes received on the last recv, or 0 if end-of-file - * was reached or the connection was closed cleanly. - */ -template -inline size_t recv_until(Buffered_Stream& s, std::string& data, - const std::string& delimiter, size_t* total_bytes_recvd, - Error_Handler error_handler) -{ - return recv_decode(s, detail::recv_until_decoder(data, delimiter), - total_bytes_recvd, error_handler); -} - -/// Start an asynchronous receive that will not complete until the specified -/// delimiter is encountered. -/** - * This function is used to asynchronously receive data from a stream until a - * given delimiter is found. The function call always returns immediately. - * - * @param s The stream on which the data is to be received. - * - * @param data The std:::string object into which the received data will be - * written. Ownership of the object is retained by the caller, which must - * guarantee that it is valid until the handler is called. - * - * @param delimiter The pattern marking the end of the data to receive. Copies - * will be made of the string as required. - * - * @param handler The handler to be called when the receive operation - * completes. Copies will be made of the handler as required. The equivalent - * function signature of the handler must be: - * @code template - * void handler( - * const Error& error, // Result of operation (the actual type is - * // dependent on the underlying stream's recv - * // operation) - * size_t last_bytes_recvd, // Number of bytes received on last recv - * // operation - * size_t total_bytes_recvd // Total number of bytes successfully received - * ); @endcode - */ -template -inline void async_recv_until(Buffered_Stream& s, std::string& data, - const std::string& delimiter, Handler handler) -{ - async_recv_decode(s, detail::recv_until_decoder(data, delimiter), handler); -} - } // namespace asio #include "asio/detail/pop_options.hpp"