Home | History | Annotate | Download | only in asio
      1 //
      2 // completion_condition.hpp
      3 // ~~~~~~~~~~~~~~~~~~~~~~~~
      4 //
      5 // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com)
      6 //
      7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
      8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
      9 //
     10 
     11 #ifndef ASIO_COMPLETION_CONDITION_HPP
     12 #define ASIO_COMPLETION_CONDITION_HPP
     13 
     14 
     15 #include "asio/detail/config.hpp"
     16 #include <cstddef>
     17 
     18 #include "asio/detail/push_options.hpp"
     19 
     20 namespace asio {
     21 
     22 namespace detail {
     23 
     24 // The default maximum number of bytes to transfer in a single operation.
     25 enum default_max_transfer_size_t { default_max_transfer_size = 65536 };
     26 
     27 // Adapt result of old-style completion conditions (which had a bool result
     28 // where true indicated that the operation was complete).
     29 inline std::size_t adapt_completion_condition_result(bool result)
     30 {
     31   return result ? 0 : default_max_transfer_size;
     32 }
     33 
     34 // Adapt result of current completion conditions (which have a size_t result
     35 // where 0 means the operation is complete, and otherwise the result is the
     36 // maximum number of bytes to transfer on the next underlying operation).
     37 inline std::size_t adapt_completion_condition_result(std::size_t result)
     38 {
     39   return result;
     40 }
     41 
     42 class transfer_all_t
     43 {
     44 public:
     45   typedef std::size_t result_type;
     46 
     47   template <typename Error>
     48   std::size_t operator()(const Error& err, std::size_t)
     49   {
     50     return !!err ? 0 : default_max_transfer_size;
     51   }
     52 };
     53 
     54 class transfer_at_least_t
     55 {
     56 public:
     57   typedef std::size_t result_type;
     58 
     59   explicit transfer_at_least_t(std::size_t minimum)
     60     : minimum_(minimum)
     61   {
     62   }
     63 
     64   template <typename Error>
     65   std::size_t operator()(const Error& err, std::size_t bytes_transferred)
     66   {
     67     return (!!err || bytes_transferred >= minimum_)
     68       ? 0 : default_max_transfer_size;
     69   }
     70 
     71 private:
     72   std::size_t minimum_;
     73 };
     74 
     75 class transfer_exactly_t
     76 {
     77 public:
     78   typedef std::size_t result_type;
     79 
     80   explicit transfer_exactly_t(std::size_t size)
     81     : size_(size)
     82   {
     83   }
     84 
     85   template <typename Error>
     86   std::size_t operator()(const Error& err, std::size_t bytes_transferred)
     87   {
     88     return (!!err || bytes_transferred >= size_) ? 0 :
     89       (size_ - bytes_transferred < default_max_transfer_size
     90         ? size_ - bytes_transferred : std::size_t(default_max_transfer_size));
     91   }
     92 
     93 private:
     94   std::size_t size_;
     95 };
     96 
     97 } // namespace detail
     98 
     99 /**
    100  * @defgroup completion_condition Completion Condition Function Objects
    101  *
    102  * Function objects used for determining when a read or write operation should
    103  * complete.
    104  */
    105 /*@{*/
    106 
    107 /// Return a completion condition function object that indicates that a read or
    108 /// write operation should continue until all of the data has been transferred,
    109 /// or until an error occurs.
    110 /**
    111  * This function is used to create an object, of unspecified type, that meets
    112  * CompletionCondition requirements.
    113  *
    114  * @par Example
    115  * Reading until a buffer is full:
    116  * @code
    117  * boost::array<char, 128> buf;
    118  * asio::error_code ec;
    119  * std::size_t n = asio::read(
    120  *     sock, asio::buffer(buf),
    121  *     asio::transfer_all(), ec);
    122  * if (ec)
    123  * {
    124  *   // An error occurred.
    125  * }
    126  * else
    127  * {
    128  *   // n == 128
    129  * }
    130  * @endcode
    131  */
    132 inline detail::transfer_all_t transfer_all()
    133 {
    134   return detail::transfer_all_t();
    135 }
    136 
    137 /// Return a completion condition function object that indicates that a read or
    138 /// write operation should continue until a minimum number of bytes has been
    139 /// transferred, or until an error occurs.
    140 /**
    141  * This function is used to create an object, of unspecified type, that meets
    142  * CompletionCondition requirements.
    143  *
    144  * @par Example
    145  * Reading until a buffer is full or contains at least 64 bytes:
    146  * @code
    147  * boost::array<char, 128> buf;
    148  * asio::error_code ec;
    149  * std::size_t n = asio::read(
    150  *     sock, asio::buffer(buf),
    151  *     asio::transfer_at_least(64), ec);
    152  * if (ec)
    153  * {
    154  *   // An error occurred.
    155  * }
    156  * else
    157  * {
    158  *   // n >= 64 && n <= 128
    159  * }
    160  * @endcode
    161  */
    162 inline detail::transfer_at_least_t transfer_at_least(std::size_t minimum)
    163 {
    164   return detail::transfer_at_least_t(minimum);
    165 }
    166 
    167 /// Return a completion condition function object that indicates that a read or
    168 /// write operation should continue until an exact number of bytes has been
    169 /// transferred, or until an error occurs.
    170 /**
    171  * This function is used to create an object, of unspecified type, that meets
    172  * CompletionCondition requirements.
    173  *
    174  * @par Example
    175  * Reading until a buffer is full or contains exactly 64 bytes:
    176  * @code
    177  * boost::array<char, 128> buf;
    178  * asio::error_code ec;
    179  * std::size_t n = asio::read(
    180  *     sock, asio::buffer(buf),
    181  *     asio::transfer_exactly(64), ec);
    182  * if (ec)
    183  * {
    184  *   // An error occurred.
    185  * }
    186  * else
    187  * {
    188  *   // n == 64
    189  * }
    190  * @endcode
    191  */
    192 inline detail::transfer_exactly_t transfer_exactly(std::size_t size)
    193 {
    194   return detail::transfer_exactly_t(size);
    195 }
    196 
    197 /*@}*/
    198 
    199 } // namespace asio
    200 
    201 #include "asio/detail/pop_options.hpp"
    202 
    203 #endif // ASIO_COMPLETION_CONDITION_HPP
    204