Add support for using std::error_code when it's available.

This commit is contained in:
Christopher Kohlhoff 2011-02-08 15:09:22 +11:00
parent c95c7e0e97
commit 46e00e0479
8 changed files with 363 additions and 406 deletions

View File

@ -71,231 +71,6 @@ sub source_contains_asio_include
return 0; return 0;
} }
sub source_contains_boostify_error_categories
{
my ($from) = @_;
# Open the input file.
open(my $input, "<$from") or die("Can't open $from for reading");
# Check file for boostify error category directive.
while (my $line = <$input>)
{
chomp($line);
if ($line =~ /boostify: error category/)
{
close($input);
return 1;
}
}
close($input);
return 0;
}
my $error_cat_defns = <<"EOF";
inline const boost::system::error_category& get_system_category()
{
return boost::system::system_category();
}
#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
extern BOOST_ASIO_DECL
const boost::system::error_category& get_netdb_category();
extern BOOST_ASIO_DECL
const boost::system::error_category& get_addrinfo_category();
#else // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
inline const boost::system::error_category& get_netdb_category()
{
return get_system_category();
}
inline const boost::system::error_category& get_addrinfo_category()
{
return get_system_category();
}
#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
extern BOOST_ASIO_DECL
const boost::system::error_category& get_misc_category();
extern BOOST_ASIO_DECL
const boost::system::error_category& get_ssl_category();
static const boost::system::error_category& system_category
= boost::asio::error::get_system_category();
static const boost::system::error_category& netdb_category
= boost::asio::error::get_netdb_category();
static const boost::system::error_category& addrinfo_category
= boost::asio::error::get_addrinfo_category();
static const boost::system::error_category& misc_category
= boost::asio::error::get_misc_category();
static const boost::system::error_category& ssl_category
= boost::asio::error::get_ssl_category();
} // namespace error
} // namespace asio
namespace system {
template<> struct is_error_code_enum<boost::asio::error::basic_errors>
{
static const bool value = true;
};
template<> struct is_error_code_enum<boost::asio::error::netdb_errors>
{
static const bool value = true;
};
template<> struct is_error_code_enum<boost::asio::error::addrinfo_errors>
{
static const bool value = true;
};
template<> struct is_error_code_enum<boost::asio::error::misc_errors>
{
static const bool value = true;
};
template<> struct is_error_code_enum<boost::asio::error::ssl_errors>
{
static const bool value = true;
};
} // namespace system
namespace asio {
namespace error {
EOF
my $error_cat_func_defns = <<"EOF";
#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
namespace detail {
class netdb_category : public boost::system::error_category
{
public:
const char* name() const
{
return "asio.netdb";
}
std::string message(int value) const
{
if (value == error::host_not_found)
return "Host not found (authoritative)";
if (value == error::host_not_found_try_again)
return "Host not found (non-authoritative), try again later";
if (value == error::no_data)
return "The query is valid, but it does not have associated data";
if (value == error::no_recovery)
return "A non-recoverable error occurred during database lookup";
return "asio.netdb error";
}
};
} // namespace detail
const boost::system::error_category& get_netdb_category()
{
static detail::netdb_category instance;
return instance;
}
namespace detail {
class addrinfo_category : public boost::system::error_category
{
public:
const char* name() const
{
return "asio.addrinfo";
}
std::string message(int value) const
{
if (value == error::service_not_found)
return "Service not found";
if (value == error::socket_type_not_supported)
return "Socket type not supported";
return "asio.addrinfo error";
}
};
} // namespace detail
const boost::system::error_category& get_addrinfo_category()
{
static detail::addrinfo_category instance;
return instance;
}
#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
namespace detail {
class misc_category : public boost::system::error_category
{
public:
const char* name() const
{
return "asio.misc";
}
std::string message(int value) const
{
if (value == error::already_open)
return "Already open";
if (value == error::eof)
return "End of file";
if (value == error::not_found)
return "Element not found";
if (value == error::fd_set_failure)
return "The descriptor does not fit into the select call's fd_set";
return "asio.misc error";
}
};
} // namespace detail
const boost::system::error_category& get_misc_category()
{
static detail::misc_category instance;
return instance;
}
namespace detail {
class ssl_category : public boost::system::error_category
{
public:
const char* name() const
{
return "asio.ssl";
}
std::string message(int) const
{
return "asio.ssl error";
}
};
} // namespace detail
const boost::system::error_category& get_ssl_category()
{
static detail::ssl_category instance;
return instance;
}
EOF
sub copy_source_file sub copy_source_file
{ {
my ($from, $to) = @_; my ($from, $to) = @_;
@ -307,10 +82,11 @@ sub copy_source_file
# First determine whether the file makes any use of asio::thread. # First determine whether the file makes any use of asio::thread.
my $uses_asio_thread = source_contains_asio_thread_usage($from); my $uses_asio_thread = source_contains_asio_thread_usage($from);
my $includes_asio = source_contains_asio_include($from); my $includes_asio = source_contains_asio_include($from);
# Check whether the file includes error handling header files. my $is_error_hpp = 0;
my $includes_boostify_ecats = source_contains_boostify_error_categories($from); $is_error_hpp = 1 if ($from =~ /asio\/error\.hpp/);
# Open the files. # Open the files.
open(my $input, "<$from") or die("Can't open $from for reading"); open(my $input, "<$from") or die("Can't open $from for reading");
@ -367,33 +143,13 @@ sub copy_source_file
} }
print_line($output, $line, $from, $lineno); print_line($output, $line, $from, $lineno);
} }
elsif ($line =~ /^(# *include )[<"](asio\/detail\/config\.hpp)[>"]$/)
{
print_line($output, $1 . "<boost/" . $2 . ">", $from, $lineno);
if ($includes_boostify_ecats)
{
$includes_boostify_ecats = 0;
print_line($output, $1 . "<boost/cerrno.hpp>", $from, $lineno);
print_line($output, $1 . "<boost/system/error_code.hpp>", $from, $lineno);
}
}
elsif ($line =~ /# *include <cerrno>/)
{
if ($includes_boostify_ecats)
{
# Line is removed.
}
else
{
print_line($output, $line, $from, $lineno);
}
}
elsif ($line =~ /# *include [<"]asio\/thread\.hpp[>"]/) elsif ($line =~ /# *include [<"]asio\/thread\.hpp[>"]/)
{ {
# Line is removed. # Line is removed.
} }
elsif ($line =~ /(# *include )[<"]asio\/error_code\.hpp[>"]/) elsif ($line =~ /(# *include )[<"]asio\/error_code\.hpp[>"]/)
{ {
print_line($output, $1 . "<boost/cerrno.hpp>", $from, $lineno) if ($is_error_hpp);
print_line($output, $1 . "<boost/system/error_code.hpp>", $from, $lineno); print_line($output, $1 . "<boost/system/error_code.hpp>", $from, $lineno);
} }
elsif ($line =~ /# *include [<"]asio\/impl\/error_code\.[hi]pp[>"]/) elsif ($line =~ /# *include [<"]asio\/impl\/error_code\.[hi]pp[>"]/)
@ -408,28 +164,9 @@ sub copy_source_file
{ {
print_line($output, $1 . "<boost/" . $2 . ">" . $3, $from, $lineno); print_line($output, $1 . "<boost/" . $2 . ">" . $3, $from, $lineno);
} }
elsif ($line =~ /( *)op->Internal = asio::error::get_system_category\(\);/) elsif ($line =~ /#.*defined\(.*ASIO_HAS_STD_SYSTEM_ERROR\)$/)
{ {
my $indent = $1; # Line is removed.
$line =~ s/asio.*$/reinterpret_cast<ulong_ptr_t>(/g;
print_line($output, $line, $from, $lineno);
$line = $indent . " &boost::asio::error::get_system_category());";
print_line($output, $line, $from, $lineno);
}
elsif ($line =~ /op->Internal = ec\.category\(\);/)
{
$line =~ s/ec.*$/reinterpret_cast<ulong_ptr_t>(&ec.category());/g;
print_line($output, $line, $from, $lineno);
}
elsif ($line =~ /static_cast<asio::error_category>\(op->Internal\)\);/)
{
$line =~ s/static_cast<asio::error_category>/*reinterpret_cast<boost::system::error_category*>/g;
print_line($output, $line, $from, $lineno);
}
elsif ($line =~ /op->Internal = result_ec\.category\(\);/)
{
$line =~ s/res.*$/reinterpret_cast<ulong_ptr_t>(&result_ec.category());/g;
print_line($output, $line, $from, $lineno);
} }
elsif ($line =~ /asio::thread/) elsif ($line =~ /asio::thread/)
{ {
@ -448,21 +185,21 @@ sub copy_source_file
} }
print_line($output, $1 . "boost::thread" . $2, $from, $lineno); print_line($output, $1 . "boost::thread" . $2, $from, $lineno);
} }
elsif ($line =~ /boostify: error category definitions start here/) elsif ($line =~ /namespace std {/)
{ {
print($output $error_cat_defns); print_line($output, "namespace boost {", $from, $lineno);
while ($line = <$input>) print_line($output, "namespace system {", $from, $lineno);
{
last if $line =~ /boostify: error category definitions end here/;
}
} }
elsif ($line =~ /boostify: error category function definitions go here/) elsif ($line =~ /} \/\/ namespace std/)
{ {
print($output $error_cat_func_defns); print_line($output, "} // namespace system", $from, $lineno);
print_line($output, "} // namespace boost", $from, $lineno);
} }
elsif ($line =~ /asio::/ && !($line =~ /boost::asio::/)) elsif ($line =~ /asio::/ && !($line =~ /boost::asio::/))
{ {
$line =~ s/asio::error_code/boost::system::error_code/g; $line =~ s/asio::error_code/boost::system::error_code/g;
$line =~ s/asio::error_category/boost::system::error_category/g;
$line =~ s/asio::system_category/boost::system::system_category/g;
$line =~ s/asio::system_error/boost::system::system_error/g; $line =~ s/asio::system_error/boost::system::system_error/g;
$line =~ s/asio::/boost::asio::/g; $line =~ s/asio::/boost::asio::/g;
print_line($output, $line, $from, $lineno); print_line($output, $line, $from, $lineno);

View File

@ -46,6 +46,22 @@
# define ASIO_DECL # define ASIO_DECL
#endif // !defined(ASIO_DECL) #endif // !defined(ASIO_DECL)
// Standard library support for system errors.
#if !defined(ASIO_DISABLE_STD_SYSTEM_ERROR)
# if defined(__GNUC__)
# if ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
# if defined(__GXX_EXPERIMENTAL_CXX0X__)
# define ASIO_HAS_STD_SYSTEM_ERROR
# endif // defined(__GXX_EXPERIMENTAL_CXX0X__)
# endif // ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)) || (__GNUC__ > 4)
# endif // defined(__GNUC__)
# if defined(BOOST_MSVC)
# if (_MSC_VER >= 1600)
# define ASIO_HAS_STD_SYSTEM_ERROR
# endif // (_MSC_VER >= 1600)
# endif // defined(BOOST_MSVC)
#endif // !defined(ASIO_DISABLE_STD_SYSTEM_ERROR)
// Windows: target OS version. // Windows: target OS version.
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
# if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS) # if !defined(_WIN32_WINNT) && !defined(_WIN32_WINDOWS)

View File

@ -284,7 +284,8 @@ void win_iocp_io_service::on_completion(win_iocp_operation* op,
op->ready_ = 1; op->ready_ = 1;
// Store results in the OVERLAPPED structure. // Store results in the OVERLAPPED structure.
op->Internal = asio::error::get_system_category(); op->Internal = reinterpret_cast<ulong_ptr_t>(
&asio::error::get_system_category());
op->Offset = last_error; op->Offset = last_error;
op->OffsetHigh = bytes_transferred; op->OffsetHigh = bytes_transferred;
@ -306,7 +307,7 @@ void win_iocp_io_service::on_completion(win_iocp_operation* op,
op->ready_ = 1; op->ready_ = 1;
// Store results in the OVERLAPPED structure. // Store results in the OVERLAPPED structure.
op->Internal = ec.category(); op->Internal = reinterpret_cast<ulong_ptr_t>(&ec.category());
op->Offset = ec.value(); op->Offset = ec.value();
op->OffsetHigh = bytes_transferred; op->OffsetHigh = bytes_transferred;
@ -358,7 +359,7 @@ size_t win_iocp_io_service::do_one(bool block, asio::error_code& ec)
if (completion_key == overlapped_contains_result) if (completion_key == overlapped_contains_result)
{ {
result_ec = asio::error_code(static_cast<int>(op->Offset), result_ec = asio::error_code(static_cast<int>(op->Offset),
static_cast<asio::error_category>(op->Internal)); *reinterpret_cast<asio::error_category*>(op->Internal));
bytes_transferred = op->OffsetHigh; bytes_transferred = op->OffsetHigh;
} }
@ -366,7 +367,7 @@ size_t win_iocp_io_service::do_one(bool block, asio::error_code& ec)
// structure. // structure.
else else
{ {
op->Internal = result_ec.category(); op->Internal = reinterpret_cast<ulong_ptr_t>(&result_ec.category());
op->Offset = result_ec.value(); op->Offset = result_ec.value();
op->OffsetHigh = bytes_transferred; op->OffsetHigh = bytes_transferred;
} }

View File

@ -16,6 +16,7 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp" #include "asio/detail/config.hpp"
#include "asio/error_code.hpp"
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
# include <winerror.h> # include <winerror.h>
#else #else
@ -212,22 +213,87 @@ enum ssl_errors
{ {
}; };
// boostify: error category definitions start here. inline const asio::error_category& get_system_category()
{
return asio::system_category();
}
#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
extern ASIO_DECL
const asio::error_category& get_netdb_category();
extern ASIO_DECL
const asio::error_category& get_addrinfo_category();
#else // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
inline const asio::error_category& get_netdb_category()
{
return get_system_category();
}
inline const asio::error_category& get_addrinfo_category()
{
return get_system_category();
}
#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
extern ASIO_DECL
const asio::error_category& get_misc_category();
extern ASIO_DECL
const asio::error_category& get_ssl_category();
static const asio::error_category& system_category
= asio::error::get_system_category();
static const asio::error_category& netdb_category
= asio::error::get_netdb_category();
static const asio::error_category& addrinfo_category
= asio::error::get_addrinfo_category();
static const asio::error_category& misc_category
= asio::error::get_misc_category();
static const asio::error_category& ssl_category
= asio::error::get_ssl_category();
} // namespace error } // namespace error
} // namespace asio } // namespace asio
#include "asio/detail/pop_options.hpp" #if defined(ASIO_HAS_STD_SYSTEM_ERROR)
namespace std {
#include "asio/error_code.hpp" template<> struct is_error_code_enum<asio::error::basic_errors>
{
static const bool value = true;
};
#include "asio/detail/push_options.hpp" template<> struct is_error_code_enum<asio::error::netdb_errors>
{
static const bool value = true;
};
template<> struct is_error_code_enum<asio::error::addrinfo_errors>
{
static const bool value = true;
};
template<> struct is_error_code_enum<asio::error::misc_errors>
{
static const bool value = true;
};
template<> struct is_error_code_enum<asio::error::ssl_errors>
{
static const bool value = true;
};
} // namespace std
#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)
namespace asio { namespace asio {
namespace error { namespace error {
// boostify: error category definitions end here.
inline asio::error_code make_error_code(basic_errors e) inline asio::error_code make_error_code(basic_errors e)
{ {
return asio::error_code( return asio::error_code(

View File

@ -16,71 +16,81 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp" #include "asio/detail/config.hpp"
#include <string>
#if defined(GENERATING_DOCUMENTATION) #if defined(ASIO_HAS_STD_SYSTEM_ERROR)
# define ASIO_WIN_OR_POSIX(e_win, e_posix) implementation_defined # include <system_error>
#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__) #else // defined(ASIO_HAS_STD_SYSTEM_ERROR)
# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_win # include <string>
#else # include "asio/detail/noncopyable.hpp"
# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_posix # if !defined(BOOST_NO_IOSTREAM)
#endif # include <iosfwd>
# endif // !defined(BOOST_NO_IOSTREAM)
#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)
#include "asio/detail/push_options.hpp" #include "asio/detail/push_options.hpp"
namespace asio { namespace asio {
namespace error #if defined(ASIO_HAS_STD_SYSTEM_ERROR)
typedef std::error_category error_category;
#else // defined(ASIO_HAS_STD_SYSTEM_ERROR)
/// Base class for all error categories.
class error_category : private noncopyable
{ {
/// Available error code categories. public:
enum error_category /// Destructor.
virtual ~error_category()
{ {
/// System error codes. }
system_category = ASIO_WIN_OR_POSIX(0, 0),
/// Error codes from NetDB functions. /// Returns a string naming the error gategory.
netdb_category = ASIO_WIN_OR_POSIX(system_category, 1), virtual const char* name() const = 0;
/// Error codes from getaddrinfo. /// Returns a string describing the error denoted by @c value.
addrinfo_category = ASIO_WIN_OR_POSIX(system_category, 2), virtual std::string message(int value) const = 0;
/// Miscellaneous error codes. /// Equality operator to compare two error categories.
misc_category = ASIO_WIN_OR_POSIX(3, 3), bool operator==(const error_category& rhs) const
{
return this == &rhs;
}
/// SSL error codes. /// Inequality operator to compare two error categories.
ssl_category = ASIO_WIN_OR_POSIX(4, 4) bool operator!=(const error_category& rhs) const
}; {
return !(*this == rhs);
}
};
// Category getters. #endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)
inline error_category get_system_category() { return system_category; }
inline error_category get_netdb_category() { return netdb_category; }
inline error_category get_addrinfo_category() { return addrinfo_category; }
inline error_category get_misc_category() { return misc_category; }
inline error_category get_ssl_category() { return ssl_category; }
} // namespace error /// Returns the error category used for the system errors produced by asio.
extern ASIO_DECL const error_category& system_category();
/// Bring error category type into the asio namespace. #if defined(ASIO_HAS_STD_SYSTEM_ERROR)
typedef asio::error::error_category error_category;
typedef std::error_code error_code;
#else // defined(ASIO_HAS_STD_SYSTEM_ERROR)
/// Class to represent an error code value. /// Class to represent an error code value.
class error_code class error_code
{ {
public: public:
/// The underlying representation of an error code.
typedef int value_type;
/// Default constructor. /// Default constructor.
error_code() error_code()
: value_(0), : value_(0),
category_(error::system_category) category_(&system_category())
{ {
} }
/// Construct with specific error code and category. /// Construct with specific error code and category.
error_code(value_type v, error_category c) error_code(int v, const error_category& c)
: value_(v), : value_(v),
category_(c) category_(&c)
{ {
} }
@ -92,19 +102,22 @@ public:
} }
/// Get the error value. /// Get the error value.
value_type value() const int value() const
{ {
return value_; return value_;
} }
/// Get the error category. /// Get the error category.
error_category category() const const error_category& category() const
{ {
return category_; return *category_;
} }
/// Get the message associated with the error. /// Get the message associated with the error.
ASIO_DECL std::string message() const; std::string message() const
{
return category_->message(value_);
}
struct unspecified_bool_type_t struct unspecified_bool_type_t
{ {
@ -143,18 +156,31 @@ public:
private: private:
// The value associated with the error code. // The value associated with the error code.
value_type value_; int value_;
// The category associated with the error code. // The category associated with the error code.
error_category category_; const error_category* category_;
}; };
# if !defined(BOOST_NO_IOSTREAM)
/// Output an error code.
template <typename Elem, typename Traits>
std::basic_ostream<Elem, Traits>& operator<<(
std::basic_ostream<Elem, Traits>& os, const error_code& ec)
{
os << ec.category().name() << ':' << ec.value();
return os;
}
# endif // !defined(BOOST_NO_IOSTREAM)
#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)
} // namespace asio } // namespace asio
#include "asio/detail/pop_options.hpp" #include "asio/detail/pop_options.hpp"
#undef ASIO_WIN_OR_POSIX
#if defined(ASIO_HEADER_ONLY) #if defined(ASIO_HEADER_ONLY)
# include "asio/impl/error_code.ipp" # include "asio/impl/error_code.ipp"
#endif // defined(ASIO_HEADER_ONLY) #endif // defined(ASIO_HEADER_ONLY)

View File

@ -23,7 +23,125 @@
namespace asio { namespace asio {
namespace error { namespace error {
// boostify: error category function definitions go here. #if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
namespace detail {
class netdb_category : public asio::error_category
{
public:
const char* name() const
{
return "asio.netdb";
}
std::string message(int value) const
{
if (value == error::host_not_found)
return "Host not found (authoritative)";
if (value == error::host_not_found_try_again)
return "Host not found (non-authoritative), try again later";
if (value == error::no_data)
return "The query is valid, but it does not have associated data";
if (value == error::no_recovery)
return "A non-recoverable error occurred during database lookup";
return "asio.netdb error";
}
};
} // namespace detail
const asio::error_category& get_netdb_category()
{
static detail::netdb_category instance;
return instance;
}
namespace detail {
class addrinfo_category : public asio::error_category
{
public:
const char* name() const
{
return "asio.addrinfo";
}
std::string message(int value) const
{
if (value == error::service_not_found)
return "Service not found";
if (value == error::socket_type_not_supported)
return "Socket type not supported";
return "asio.addrinfo error";
}
};
} // namespace detail
const asio::error_category& get_addrinfo_category()
{
static detail::addrinfo_category instance;
return instance;
}
#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
namespace detail {
class misc_category : public asio::error_category
{
public:
const char* name() const
{
return "asio.misc";
}
std::string message(int value) const
{
if (value == error::already_open)
return "Already open";
if (value == error::eof)
return "End of file";
if (value == error::not_found)
return "Element not found";
if (value == error::fd_set_failure)
return "The descriptor does not fit into the select call's fd_set";
return "asio.misc error";
}
};
} // namespace detail
const asio::error_category& get_misc_category()
{
static detail::misc_category instance;
return instance;
}
namespace detail {
class ssl_category : public asio::error_category
{
public:
const char* name() const
{
return "asio.ssl";
}
std::string message(int) const
{
return "asio.ssl error";
}
};
} // namespace detail
const asio::error_category& get_ssl_category()
{
static detail::ssl_category instance;
return instance;
}
} // namespace error } // namespace error
} // namespace asio } // namespace asio

View File

@ -16,93 +16,73 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp" #include "asio/detail/config.hpp"
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
# include <winerror.h>
#else
# include <cerrno>
#endif
#include "asio/detail/local_free_on_block_exit.hpp" #include "asio/detail/local_free_on_block_exit.hpp"
#include "asio/detail/socket_types.hpp" #include "asio/detail/socket_types.hpp"
#include "asio/error.hpp"
#include "asio/error_code.hpp" #include "asio/error_code.hpp"
#include "asio/detail/push_options.hpp" #include "asio/detail/push_options.hpp"
namespace asio { namespace asio {
namespace detail {
std::string error_code::message() const class system_category : public error_category
{ {
if (category_ == error::get_misc_category()) public:
const char* name() const
{ {
if (value_ == error::already_open) return "asio.system";
return "Already open.";
if (value_ == error::not_found)
return "Not found.";
if (value_ == error::fd_set_failure)
return "The descriptor does not fit into the select call's fd_set.";
if (value_ == error::not_found)
return "Element not found.";
#if !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
if (value_ == error::eof)
return "End of file.";
#endif // !defined(BOOST_WINDOWS) && !defined(__CYGWIN__)
} }
if (category_ == error::get_ssl_category())
return "SSL error."; std::string message(int value) const
{
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__) #if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
value_type value = value_; char* msg = 0;
if (category_ == error::get_misc_category() && value_ == error::eof) DWORD length = ::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
value = ERROR_HANDLE_EOF; | FORMAT_MESSAGE_FROM_SYSTEM
else if (category_ != error::get_system_category()) | FORMAT_MESSAGE_IGNORE_INSERTS, 0, value,
return "asio error"; MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0);
char* msg = 0; detail::local_free_on_block_exit local_free_obj(msg);
DWORD length = ::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER if (length && msg[length - 1] == '\n')
| FORMAT_MESSAGE_FROM_SYSTEM msg[--length] = '\0';
| FORMAT_MESSAGE_IGNORE_INSERTS, 0, value, if (length && msg[length - 1] == '\r')
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0); msg[--length] = '\0';
detail::local_free_on_block_exit local_free_obj(msg); if (length)
if (length && msg[length - 1] == '\n') return msg;
msg[--length] = '\0'; else
if (length && msg[length - 1] == '\r') return "asio.system error";
msg[--length] = '\0';
if (length)
return msg;
else
return "asio error";
#else // defined(BOOST_WINDOWS) #else // defined(BOOST_WINDOWS)
if (category_ == error::get_netdb_category())
{
if (value_ == error::host_not_found)
return "Host not found (authoritative).";
if (value_ == error::host_not_found_try_again)
return "Host not found (non-authoritative), try again later.";
if (value_ == error::no_recovery)
return "A non-recoverable error occurred during database lookup.";
if (value_ == error::no_data)
return "The query is valid, but it does not have associated data.";
}
if (category_ == error::get_addrinfo_category())
{
if (value_ == error::service_not_found)
return "Service not found.";
if (value_ == error::socket_type_not_supported)
return "Socket type not supported.";
}
if (category_ != error::get_system_category())
return "asio error";
#if !defined(__sun) #if !defined(__sun)
if (value_ == error::operation_aborted) if (value == ECANCELED)
return "Operation aborted."; return "Operation aborted.";
#endif // !defined(__sun) #endif // !defined(__sun)
#if defined(__sun) || defined(__QNX__) || defined(__SYMBIAN32__) #if defined(__sun) || defined(__QNX__) || defined(__SYMBIAN32__)
using namespace std; using namespace std;
return strerror(value_); return strerror(value);
#elif defined(__MACH__) && defined(__APPLE__) \ #elif defined(__MACH__) && defined(__APPLE__) \
|| defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) \ || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) \
|| defined(_AIX) || defined(__hpux) || defined(__osf__) || defined(_AIX) || defined(__hpux) || defined(__osf__)
char buf[256] = ""; char buf[256] = "";
strerror_r(value_, buf, sizeof(buf)); strerror_r(value, buf, sizeof(buf));
return buf; return buf;
#else #else
char buf[256] = ""; char buf[256] = "";
return strerror_r(value_, buf, sizeof(buf)); return strerror_r(value, buf, sizeof(buf));
#endif #endif
#endif // defined(BOOST_WINDOWS) #endif // defined(BOOST_WINDOWS)
}
};
} // namespace detail
const error_category& system_category()
{
static detail::system_category instance;
return instance;
} }
} // namespace asio } // namespace asio

View File

@ -2,7 +2,7 @@
// system_error.hpp // system_error.hpp
// ~~~~~~~~~~~~~~~~ // ~~~~~~~~~~~~~~~~
// //
// Copyright (c) 2003-2011 Christopher M. Kohlhoff (chris at kohlhoff dot com) // Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com)
// //
// Distributed under the Boost Software License, Version 1.0. (See accompanying // Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@ -16,16 +16,27 @@
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
#include "asio/detail/config.hpp" #include "asio/detail/config.hpp"
#include <boost/scoped_ptr.hpp>
#include <cerrno> #if defined(ASIO_HAS_STD_SYSTEM_ERROR)
#include <exception> # include <system_error>
#include <string> #else // defined(ASIO_HAS_STD_SYSTEM_ERROR)
#include "asio/error_code.hpp" # include <boost/scoped_ptr.hpp>
# include <cerrno>
# include <exception>
# include <string>
# include "asio/error_code.hpp"
#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)
#include "asio/detail/push_options.hpp" #include "asio/detail/push_options.hpp"
namespace asio { namespace asio {
#if defined(ASIO_HAS_STD_SYSTEM_ERROR)
typedef std::system_error system_error;
#else // defined(ASIO_HAS_STD_SYSTEM_ERROR)
/// The system_error class is used to represent system conditions that /// The system_error class is used to represent system conditions that
/// prevent the library from operating correctly. /// prevent the library from operating correctly.
class system_error class system_error
@ -111,6 +122,8 @@ private:
mutable boost::scoped_ptr<std::string> what_; mutable boost::scoped_ptr<std::string> what_;
}; };
#endif // defined(ASIO_HAS_STD_SYSTEM_ERROR)
} // namespace asio } // namespace asio
#include "asio/detail/pop_options.hpp" #include "asio/detail/pop_options.hpp"