$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: chris_at_[hidden]
Date: 2007-09-24 08:53:38
Author: chris_kohlhoff
Date: 2007-09-24 08:53:37 EDT (Mon, 24 Sep 2007)
New Revision: 39502
URL: http://svn.boost.org/trac/boost/changeset/39502
Log:
Use a switch rather than an array to translate system_category error codes to their corresponding default error conditions. Add translations for the Winsock error codes.
Text files modified: 
   trunk/libs/system/src/error_code.cpp       |   336 +++++++++++++++++++-------------------- 
   trunk/libs/system/test/error_code_test.cpp |    33 ++-                                     
   2 files changed, 187 insertions(+), 182 deletions(-)
Modified: trunk/libs/system/src/error_code.cpp
==============================================================================
--- trunk/libs/system/src/error_code.cpp	(original)
+++ trunk/libs/system/src/error_code.cpp	2007-09-24 08:53:37 EDT (Mon, 24 Sep 2007)
@@ -45,157 +45,6 @@
 
 namespace
 {
-
-  struct system_to_posix_t
-  { 
-    int system_value;
-    boost::system::posix::posix_errno posix_value;
-  };
-
-  const system_to_posix_t system_to_posix[] = 
-  {
-
-#ifdef BOOST_POSIX_API
-  //  POSIX-like O/S -> posix_errno decode table  ----------------------------//
-
-    // most common errors first to speed sequential search
-    { ENOENT, no_such_file_or_directory },
-    { EACCES, permission_denied },
-    { EINVAL, invalid_argument },
-
-    // rest are alphabetical for easy maintenance
-    { 0, success }, 
-    { E2BIG, argument_list_too_long },
-    { EADDRINUSE, address_in_use },
-    { EADDRNOTAVAIL, address_not_available },
-    { EAFNOSUPPORT, address_family_not_supported },
-    { EAGAIN, resource_unavailable_try_again },
-    { EALREADY, connection_already_in_progress },
-    { EBADF, bad_file_descriptor },
-    { EBADMSG, bad_message },
-    { EBUSY, device_or_resource_busy },
-    { ECANCELED, operation_canceled },
-    { ECHILD, no_child_process },
-    { ECONNABORTED, connection_aborted },
-    { ECONNREFUSED, connection_refused },
-    { ECONNRESET, connection_reset },
-    { EDEADLK, resource_deadlock_would_occur },
-    { EDESTADDRREQ, destination_address_required },
-    { EDOM, argument_out_of_domain },
-    { EEXIST, file_exists },
-    { EFAULT, bad_address },
-    { EFBIG, file_too_large },
-    { EHOSTUNREACH, host_unreachable },
-    { EIDRM, identifier_removed },
-    { EILSEQ, illegal_byte_sequence },
-    { EINPROGRESS, operation_in_progress },
-    { EINTR, interrupted },
-    { EIO, io_error },
-    { EISCONN, already_connected },
-    { EISDIR, is_a_directory },
-    { ELOOP, too_many_synbolic_link_levels },
-    { EMFILE, too_many_files_open },
-    { EMLINK, too_many_links },
-    { EMSGSIZE, message_size },
-    { ENAMETOOLONG, filename_too_long },
-    { ENETDOWN, network_down },
-    { ENETRESET, network_reset },
-    { ENETUNREACH, network_unreachable },
-    { ENFILE, too_many_files_open_in_system },
-    { ENOBUFS, no_buffer_space },
-    { ENODATA, no_message_available },
-    { ENODEV, no_such_device },
-    { ENOEXEC, executable_format_error },
-    { ENOLCK, no_lock_available },
-    { ENOLINK, no_link },
-    { ENOMEM, not_enough_memory },
-    { ENOMSG, no_message },
-    { ENOPROTOOPT, no_protocol_option },
-    { ENOSPC, no_space_on_device },
-    { ENOSR, no_stream_resources },
-    { ENOSTR, not_a_stream },
-    { ENOSYS, function_not_supported },
-    { ENOTCONN, not_connected },
-    { ENOTDIR, not_a_directory },
-    { ENOTEMPTY, directory_not_empty },
-    { ENOTRECOVERABLE, state_not_recoverable },
-    { ENOTSOCK, not_a_socket },
-    { ENOTSUP, not_supported },
-    { ENOTTY, inappropriate_io_control_operation },
-    { ENXIO, no_such_device_or_address },
-    { EOPNOTSUPP, operation_not_supported },
-    { EOVERFLOW, value_too_large },
-    { EOWNERDEAD, owner_dead },
-    { EPERM, operation_not_permitted },
-    { EPIPE, broken_pipe },
-    { EPROTO, protocol_error },
-    { EPROTONOSUPPORT, protocol_not_supported },
-    { EPROTOTYPE, wrong_protocol_type },
-    { ERANGE, result_out_of_range },
-    { EROFS, read_only_file_system },
-    { ESPIPE, invalid_seek },
-    { ESRCH, no_such_process },
-    { ETIME, stream_timeout },
-    { ETIMEDOUT, timed_out },
-    { ETXTBSY, text_file_busy },
-    { EWOULDBLOCK, operation_would_block },
-    { EXDEV, cross_device_link }
-
-#else
-
-  //  Windows system -> posix_errno decode table  ----------------------------//  
-
-    // see WinError.h comments for descriptions of errors
-    
-    // most common errors first to speed sequential search
-    { ERROR_FILE_NOT_FOUND, no_such_file_or_directory },
-    { ERROR_PATH_NOT_FOUND, no_such_file_or_directory },
-
-    // rest are alphabetical for easy maintenance
-    { 0, success }, 
-    { ERROR_ACCESS_DENIED, permission_denied },
-    { ERROR_ALREADY_EXISTS, file_exists },
-    { ERROR_BAD_UNIT, no_such_device },
-    { ERROR_BUFFER_OVERFLOW, filename_too_long },
-    { ERROR_BUSY, device_or_resource_busy },
-    { ERROR_BUSY_DRIVE, device_or_resource_busy },
-    { ERROR_CANNOT_MAKE, permission_denied },
-    { ERROR_CANTOPEN, io_error },
-    { ERROR_CANTREAD, io_error },
-    { ERROR_CANTWRITE, io_error },
-    { ERROR_CURRENT_DIRECTORY, permission_denied },
-    { ERROR_DEV_NOT_EXIST, no_such_device },
-    { ERROR_DEVICE_IN_USE, device_or_resource_busy },
-    { ERROR_DIR_NOT_EMPTY, directory_not_empty },
-    { ERROR_DIRECTORY, invalid_argument }, // WinError.h: "The directory name is invalid"
-    { ERROR_DISK_FULL, no_space_on_device },
-    { ERROR_FILE_EXISTS, file_exists },
-    { ERROR_HANDLE_DISK_FULL, no_space_on_device },
-    { ERROR_INVALID_ACCESS, permission_denied },
-    { ERROR_INVALID_DRIVE, no_such_device },
-    { ERROR_INVALID_FUNCTION, function_not_supported },
-    { ERROR_INVALID_HANDLE, invalid_argument },
-    { ERROR_INVALID_NAME, invalid_argument },
-    { ERROR_LOCK_VIOLATION, no_lock_available },
-    { ERROR_LOCKED, no_lock_available },
-    { ERROR_NEGATIVE_SEEK, invalid_argument },
-    { ERROR_NOACCESS, permission_denied },
-    { ERROR_NOT_ENOUGH_MEMORY, not_enough_memory },
-    { ERROR_NOT_READY, resource_unavailable_try_again },
-    { ERROR_NOT_SAME_DEVICE, cross_device_link },
-    { ERROR_OPEN_FAILED, io_error },
-    { ERROR_OPEN_FILES, device_or_resource_busy },
-    { ERROR_OUTOFMEMORY, not_enough_memory },
-    { ERROR_READ_FAULT, io_error },
-    { ERROR_SEEK, io_error },
-    { ERROR_SHARING_VIOLATION, permission_denied },
-    { ERROR_TOO_MANY_OPEN_FILES, too_many_files_open },
-    { ERROR_WRITE_FAULT, io_error },
-    { ERROR_WRITE_PROTECT, permission_denied }
-
-#endif
-  };
-
   //  standard error categories  -------------------------------------------//
 
   class posix_error_category : public error_category
@@ -209,7 +58,6 @@
   {
   public:
     const char *        name() const;
-    posix::posix_errno  posix( int ev ) const;
     std::string         message( int ev ) const;
     error_condition     default_error_condition( int ev ) const;
   };
@@ -298,25 +146,175 @@
     return "system";
   }
 
-  posix_errno system_error_category::posix( int ev ) const
-  {
-    const system_to_posix_t * cur = system_to_posix;
-    do
-    {
-      if ( ev == cur->system_value )
-        return cur->posix_value;
-      ++cur;
-    } while ( cur != system_to_posix
-      + sizeof(system_to_posix)/sizeof(system_to_posix_t) );
-    return static_cast<posix::posix_errno>(-1);
-  }
-
   error_condition system_error_category::default_error_condition( int ev ) const
   {
-    int tmp = posix(ev);
-    return tmp >= 0
-      ? error_condition( tmp, posix_category )
-      : error_condition( ev, system_category );
+    switch ( ev )
+    {
+    case 0: return make_error_condition( success );
+  # if defined(BOOST_POSIX_API)
+    // POSIX-like O/S -> posix_errno decode table  ---------------------------//
+    case E2BIG: return make_error_condition( argument_list_too_long );
+    case EACCES: return make_error_condition( permission_denied );
+    case EADDRINUSE: return make_error_condition( address_in_use );
+    case EADDRNOTAVAIL: return make_error_condition( address_not_available );
+    case EAFNOSUPPORT: return make_error_condition( address_family_not_supported );
+    case EAGAIN: return make_error_condition( resource_unavailable_try_again );
+    case EALREADY: return make_error_condition( connection_already_in_progress );
+    case EBADF: return make_error_condition( bad_file_descriptor );
+    case EBADMSG: return make_error_condition( bad_message );
+    case EBUSY: return make_error_condition( device_or_resource_busy );
+    case ECANCELED: return make_error_condition( operation_canceled );
+    case ECHILD: return make_error_condition( no_child_process );
+    case ECONNABORTED: return make_error_condition( connection_aborted );
+    case ECONNREFUSED: return make_error_condition( connection_refused );
+    case ECONNRESET: return make_error_condition( connection_reset );
+    case EDEADLK: return make_error_condition( resource_deadlock_would_occur );
+    case EDESTADDRREQ: return make_error_condition( destination_address_required );
+    case EDOM: return make_error_condition( argument_out_of_domain );
+    case EEXIST: return make_error_condition( file_exists );
+    case EFAULT: return make_error_condition( bad_address );
+    case EFBIG: return make_error_condition( file_too_large );
+    case EHOSTUNREACH: return make_error_condition( host_unreachable );
+    case EIDRM: return make_error_condition( identifier_removed );
+    case EILSEQ: return make_error_condition( illegal_byte_sequence );
+    case EINPROGRESS: return make_error_condition( operation_in_progress );
+    case EINTR: return make_error_condition( interrupted );
+    case EINVAL: return make_error_condition( invalid_argument );
+    case EIO: return make_error_condition( io_error );
+    case EISCONN: return make_error_condition( already_connected );
+    case EISDIR: return make_error_condition( is_a_directory );
+    case ELOOP: return make_error_condition( too_many_synbolic_link_levels );
+    case EMFILE: return make_error_condition( too_many_files_open );
+    case EMLINK: return make_error_condition( too_many_links );
+    case EMSGSIZE: return make_error_condition( message_size );
+    case ENAMETOOLONG: return make_error_condition( filename_too_long );
+    case ENETDOWN: return make_error_condition( network_down );
+    case ENETRESET: return make_error_condition( network_reset );
+    case ENETUNREACH: return make_error_condition( network_unreachable );
+    case ENFILE: return make_error_condition( too_many_files_open_in_system );
+    case ENOBUFS: return make_error_condition( no_buffer_space );
+    case ENODATA: return make_error_condition( no_message_available );
+    case ENODEV: return make_error_condition( no_such_device );
+    case ENOENT: return make_error_condition( no_such_file_or_directory );
+    case ENOEXEC: return make_error_condition( executable_format_error );
+    case ENOLCK: return make_error_condition( no_lock_available );
+    case ENOLINK: return make_error_condition( no_link );
+    case ENOMEM: return make_error_condition( not_enough_memory );
+    case ENOMSG: return make_error_condition( no_message );
+    case ENOPROTOOPT: return make_error_condition( no_protocol_option );
+    case ENOSPC: return make_error_condition( no_space_on_device );
+    case ENOSR: return make_error_condition( no_stream_resources );
+    case ENOSTR: return make_error_condition( not_a_stream );
+    case ENOSYS: return make_error_condition( function_not_supported );
+    case ENOTCONN: return make_error_condition( not_connected );
+    case ENOTDIR: return make_error_condition( not_a_directory );
+    case ENOTEMPTY: return make_error_condition( directory_not_empty );
+    case ENOTRECOVERABLE: return make_error_condition( state_not_recoverable );
+    case ENOTSOCK: return make_error_condition( not_a_socket );
+    case ENOTSUP: return make_error_condition( not_supported );
+    case ENOTTY: return make_error_condition( inappropriate_io_control_operation );
+    case ENXIO: return make_error_condition( no_such_device_or_address );
+  # if EOPNOTSUPP != ENOTSUP
+    case EOPNOTSUPP: return make_error_condition( operation_not_supported );
+  # endif // EOPNOTSUPP != ENOTSUP
+    case EOVERFLOW: return make_error_condition( value_too_large );
+    case EOWNERDEAD: return make_error_condition( owner_dead );
+    case EPERM: return make_error_condition( operation_not_permitted );
+    case EPIPE: return make_error_condition( broken_pipe );
+    case EPROTO: return make_error_condition( protocol_error );
+    case EPROTONOSUPPORT: return make_error_condition( protocol_not_supported );
+    case EPROTOTYPE: return make_error_condition( wrong_protocol_type );
+    case ERANGE: return make_error_condition( result_out_of_range );
+    case EROFS: return make_error_condition( read_only_file_system );
+    case ESPIPE: return make_error_condition( invalid_seek );
+    case ESRCH: return make_error_condition( no_such_process );
+    case ETIME: return make_error_condition( stream_timeout );
+    case ETIMEDOUT: return make_error_condition( timed_out );
+    case ETXTBSY: return make_error_condition( text_file_busy );
+  # if EAGAIN != EWOULDBLOCK
+    case EWOULDBLOCK: return make_error_condition( operation_would_block );
+  # endif // EAGAIN != EWOULDBLOCK
+    case EXDEV: return make_error_condition( cross_device_link );
+  #else
+    // Windows system -> posix_errno decode table  ---------------------------//
+    // see WinError.h comments for descriptions of errors
+    case ERROR_ACCESS_DENIED: return make_error_condition( permission_denied );
+    case ERROR_ALREADY_EXISTS: return make_error_condition( file_exists );
+    case ERROR_BAD_UNIT: return make_error_condition( no_such_device );
+    case ERROR_BUFFER_OVERFLOW: return make_error_condition( filename_too_long );
+    case ERROR_BUSY: return make_error_condition( device_or_resource_busy );
+    case ERROR_BUSY_DRIVE: return make_error_condition( device_or_resource_busy );
+    case ERROR_CANNOT_MAKE: return make_error_condition( permission_denied );
+    case ERROR_CANTOPEN: return make_error_condition( io_error );
+    case ERROR_CANTREAD: return make_error_condition( io_error );
+    case ERROR_CANTWRITE: return make_error_condition( io_error );
+    case ERROR_CURRENT_DIRECTORY: return make_error_condition( permission_denied );
+    case ERROR_DEV_NOT_EXIST: return make_error_condition( no_such_device );
+    case ERROR_DEVICE_IN_USE: return make_error_condition( device_or_resource_busy );
+    case ERROR_DIR_NOT_EMPTY: return make_error_condition( directory_not_empty );
+    case ERROR_DIRECTORY: return make_error_condition( invalid_argument ); // WinError.h: "The directory name is invalid"
+    case ERROR_DISK_FULL: return make_error_condition( no_space_on_device );
+    case ERROR_FILE_EXISTS: return make_error_condition( file_exists );
+    case ERROR_FILE_NOT_FOUND: return make_error_condition( no_such_file_or_directory );
+    case ERROR_HANDLE_DISK_FULL: return make_error_condition( no_space_on_device );
+    case ERROR_INVALID_ACCESS: return make_error_condition( permission_denied );
+    case ERROR_INVALID_DRIVE: return make_error_condition( no_such_device );
+    case ERROR_INVALID_FUNCTION: return make_error_condition( function_not_supported );
+    case ERROR_INVALID_HANDLE: return make_error_condition( invalid_argument );
+    case ERROR_INVALID_NAME: return make_error_condition( invalid_argument );
+    case ERROR_LOCK_VIOLATION: return make_error_condition( no_lock_available );
+    case ERROR_LOCKED: return make_error_condition( no_lock_available );
+    case ERROR_NEGATIVE_SEEK: return make_error_condition( invalid_argument );
+    case ERROR_NOACCESS: return make_error_condition( permission_denied );
+    case ERROR_NOT_ENOUGH_MEMORY: return make_error_condition( not_enough_memory );
+    case ERROR_NOT_READY: return make_error_condition( resource_unavailable_try_again );
+    case ERROR_NOT_SAME_DEVICE: return make_error_condition( cross_device_link );
+    case ERROR_OPEN_FAILED: return make_error_condition( io_error );
+    case ERROR_OPEN_FILES: return make_error_condition( device_or_resource_busy );
+    case ERROR_OPERATION_ABORTED: return make_error_condition( operation_canceled );
+    case ERROR_OUTOFMEMORY: return make_error_condition( not_enough_memory );
+    case ERROR_PATH_NOT_FOUND: return make_error_condition( no_such_file_or_directory );
+    case ERROR_READ_FAULT: return make_error_condition( io_error );
+    case ERROR_RETRY: return make_error_condition( resource_unavailable_try_again );
+    case ERROR_SEEK: return make_error_condition( io_error );
+    case ERROR_SHARING_VIOLATION: return make_error_condition( permission_denied );
+    case ERROR_TOO_MANY_OPEN_FILES: return make_error_condition( too_many_files_open );
+    case ERROR_WRITE_FAULT: return make_error_condition( io_error );
+    case ERROR_WRITE_PROTECT: return make_error_condition( permission_denied );
+    case WSAEACCES: return make_error_condition( permission_denied );
+    case WSAEADDRINUSE: return make_error_condition( address_in_use );
+    case WSAEADDRNOTAVAIL: return make_error_condition( address_not_available );
+    case WSAEAFNOSUPPORT: return make_error_condition( address_family_not_supported );
+    case WSAEALREADY: return make_error_condition( connection_already_in_progress );
+    case WSAEBADF: return make_error_condition( bad_file_descriptor );
+    case WSAECONNABORTED: return make_error_condition( connection_aborted );
+    case WSAECONNREFUSED: return make_error_condition( connection_refused );
+    case WSAECONNRESET: return make_error_condition( connection_reset );
+    case WSAEDESTADDRREQ: return make_error_condition( destination_address_required );
+    case WSAEFAULT: return make_error_condition( bad_address );
+    case WSAEHOSTUNREACH: return make_error_condition( host_unreachable );
+    case WSAEINPROGRESS: return make_error_condition( operation_in_progress );
+    case WSAEINTR: return make_error_condition( interrupted );
+    case WSAEINVAL: return make_error_condition( invalid_argument );
+    case WSAEISCONN: return make_error_condition( already_connected );
+    case WSAEMFILE: return make_error_condition( too_many_files_open );
+    case WSAEMSGSIZE: return make_error_condition( message_size );
+    case WSAENAMETOOLONG: return make_error_condition( filename_too_long );
+    case WSAENETDOWN: return make_error_condition( network_down );
+    case WSAENETRESET: return make_error_condition( network_reset );
+    case WSAENETUNREACH: return make_error_condition( network_unreachable );
+    case WSAENOBUFS: return make_error_condition( no_buffer_space );
+    case WSAENOPROTOOPT: return make_error_condition( no_protocol_option );
+    case WSAENOTCONN: return make_error_condition( not_connected );
+    case WSAENOTSOCK: return make_error_condition( not_a_socket );
+    case WSAEOPNOTSUPP: return make_error_condition( operation_not_supported );
+    case WSAEPROTONOSUPPORT: return make_error_condition( protocol_not_supported );
+    case WSAEPROTOTYPE: return make_error_condition( wrong_protocol_type );
+    case WSAETIMEDOUT: return make_error_condition( timed_out );
+    case WSAEWOULDBLOCK: return make_error_condition( operation_would_block );
+  #endif
+    default: return error_condition( ev, system_category );
+    }
   }
 
 # if !defined( BOOST_WINDOWS_API )
Modified: trunk/libs/system/test/error_code_test.cpp
==============================================================================
--- trunk/libs/system/test/error_code_test.cpp	(original)
+++ trunk/libs/system/test/error_code_test.cpp	2007-09-24 08:53:37 EDT (Mon, 24 Sep 2007)
@@ -148,33 +148,40 @@
   std::cout << "Windows tests...\n";
   // these tests probe the Windows posix decoder
   //   test the first entry in the decoder table:
-  ec = error_code( ERROR_FILE_NOT_FOUND, system_category );
-  BOOST_CHECK( ec.value() == ERROR_FILE_NOT_FOUND );
-  BOOST_CHECK( ec == posix::no_such_file_or_directory );
-  BOOST_CHECK( ec.default_error_condition().value() == posix::no_such_file_or_directory );
+  ec = error_code( ERROR_ACCESS_DENIED, system_category );
+  BOOST_CHECK( ec.value() == ERROR_ACCESS_DENIED );
+  BOOST_CHECK( ec == posix::permission_denied );
+  BOOST_CHECK( ec.default_error_condition().value() == posix::permission_denied );
   BOOST_CHECK( ec.default_error_condition().category() == posix_category );
 
   //   test the second entry in the decoder table:
-  ec = error_code( ERROR_PATH_NOT_FOUND, system_category );
-  BOOST_CHECK( ec.value() == ERROR_PATH_NOT_FOUND );
-  BOOST_CHECK( ec == posix::no_such_file_or_directory );
-  BOOST_CHECK( ec.default_error_condition().value() == posix::no_such_file_or_directory );
+  ec = error_code( ERROR_ALREADY_EXISTS, system_category );
+  BOOST_CHECK( ec.value() == ERROR_ALREADY_EXISTS );
+  BOOST_CHECK( ec == posix::file_exists );
+  BOOST_CHECK( ec.default_error_condition().value() == posix::file_exists );
   BOOST_CHECK( ec.default_error_condition().category() == posix_category );
 
   //   test the third entry in the decoder table:
-  ec = error_code( ERROR_ACCESS_DENIED, system_category );
-  BOOST_CHECK( ec.value() == ERROR_ACCESS_DENIED );
-  BOOST_CHECK( ec == posix::permission_denied );
-  BOOST_CHECK( ec.default_error_condition().value() == posix::permission_denied );
+  ec = error_code( ERROR_BAD_UNIT, system_category );
+  BOOST_CHECK( ec.value() == ERROR_BAD_UNIT );
+  BOOST_CHECK( ec == posix::no_such_device );
+  BOOST_CHECK( ec.default_error_condition().value() == posix::no_such_device );
   BOOST_CHECK( ec.default_error_condition().category() == posix_category );
 
-  //   test the last regular entry in the decoder table:
+  //   test the last non-Winsock entry in the decoder table:
   ec = error_code( ERROR_WRITE_PROTECT, system_category );
   BOOST_CHECK( ec.value() == ERROR_WRITE_PROTECT );
   BOOST_CHECK( ec == posix::permission_denied );
   BOOST_CHECK( ec.default_error_condition().value() == posix::permission_denied );
   BOOST_CHECK( ec.default_error_condition().category() == posix_category );
 
+  //   test the last Winsock entry in the decoder table:
+  ec = error_code( WSAEWOULDBLOCK, system_category );
+  BOOST_CHECK( ec.value() == WSAEWOULDBLOCK );
+  BOOST_CHECK( ec == posix::operation_would_block );
+  BOOST_CHECK( ec.default_error_condition().value() == posix::operation_would_block );
+  BOOST_CHECK( ec.default_error_condition().category() == posix_category );
+
   //   test not-in-table condition:
   ec = error_code( 1234567890, system_category );
   BOOST_CHECK( ec.value() == 1234567890 );