error_code.ipp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. //
  2. // impl/error_code.ipp
  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. #ifndef ASIO_IMPL_ERROR_CODE_IPP
  11. #define ASIO_IMPL_ERROR_CODE_IPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #if defined(ASIO_WINDOWS) || defined(__CYGWIN__)
  17. # include <winerror.h>
  18. #elif defined(ASIO_WINDOWS_RUNTIME)
  19. # include <windows.h>
  20. #else
  21. # include <cerrno>
  22. # include <cstring>
  23. # include <string>
  24. #endif
  25. #include "asio/detail/local_free_on_block_exit.hpp"
  26. #include "asio/detail/socket_types.hpp"
  27. #include "asio/error_code.hpp"
  28. #include "asio/detail/push_options.hpp"
  29. namespace asio {
  30. namespace detail {
  31. class system_category : public error_category
  32. {
  33. public:
  34. const char* name() const ASIO_ERROR_CATEGORY_NOEXCEPT
  35. {
  36. return "asio.system";
  37. }
  38. std::string message(int value) const
  39. {
  40. #if defined(ASIO_WINDOWS) || defined(__CYGWIN__)
  41. char* msg = 0;
  42. DWORD length = ::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
  43. | FORMAT_MESSAGE_FROM_SYSTEM
  44. | FORMAT_MESSAGE_IGNORE_INSERTS, 0, value,
  45. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0);
  46. detail::local_free_on_block_exit local_free_obj(msg);
  47. if (length && msg[length - 1] == '\n')
  48. msg[--length] = '\0';
  49. if (length && msg[length - 1] == '\r')
  50. msg[--length] = '\0';
  51. if (length)
  52. return msg;
  53. else
  54. return "asio.system error";
  55. #elif defined(ASIO_WINDOWS_RUNTIME)
  56. std::wstring wmsg(128, wchar_t());
  57. for (;;)
  58. {
  59. DWORD wlength = ::FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
  60. | FORMAT_MESSAGE_IGNORE_INSERTS, 0, value,
  61. MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), &wmsg[0], wmsg.size(), 0);
  62. if (wlength == 0 && ::GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  63. {
  64. wmsg.resize(wmsg.size() + wmsg.size() / 2);
  65. continue;
  66. }
  67. if (wlength && wmsg[wlength - 1] == '\n')
  68. --wlength;
  69. if (wlength && wmsg[wlength - 1] == '\r')
  70. --wlength;
  71. if (wlength)
  72. {
  73. std::string msg(wlength * 2, char());
  74. int length = ::WideCharToMultiByte(CP_ACP, 0,
  75. wmsg.c_str(), static_cast<int>(wlength),
  76. &msg[0], static_cast<int>(wlength * 2), 0, 0);
  77. if (length <= 0)
  78. return "asio.system error";
  79. msg.resize(static_cast<std::size_t>(length));
  80. return msg;
  81. }
  82. else
  83. return "asio.system error";
  84. }
  85. #else // defined(ASIO_WINDOWS)
  86. #if !defined(__sun)
  87. if (value == ECANCELED)
  88. return "Operation aborted.";
  89. #endif // !defined(__sun)
  90. #if defined(__sun) || defined(__QNX__) || defined(__SYMBIAN32__)
  91. using namespace std;
  92. return strerror(value);
  93. #elif defined(__MACH__) && defined(__APPLE__) \
  94. || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) \
  95. || defined(_AIX) || defined(__hpux) || defined(__osf__) \
  96. || defined(__ANDROID__)
  97. char buf[256] = "";
  98. using namespace std;
  99. strerror_r(value, buf, sizeof(buf));
  100. return buf;
  101. #else
  102. char buf[256] = "";
  103. return strerror_r(value, buf, sizeof(buf));
  104. #endif
  105. #endif // defined(ASIO_WINDOWS)
  106. }
  107. };
  108. } // namespace detail
  109. const error_category& system_category()
  110. {
  111. static detail::system_category instance;
  112. return instance;
  113. }
  114. } // namespace asio
  115. #include "asio/detail/pop_options.hpp"
  116. #endif // ASIO_IMPL_ERROR_CODE_IPP