199 lines
4.8 KiB
C++
199 lines
4.8 KiB
C++
|
//
|
||
|
// error.hpp
|
||
|
// ~~~~~~~~~
|
||
|
//
|
||
|
// Copyright (c) 2003-2006 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||
|
//
|
||
|
// 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)
|
||
|
//
|
||
|
|
||
|
#ifndef ASIO_SYSTEM_EXCEPTION_HPP
|
||
|
#define ASIO_SYSTEM_EXCEPTION_HPP
|
||
|
|
||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||
|
# pragma once
|
||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||
|
|
||
|
#include "asio/detail/push_options.hpp"
|
||
|
|
||
|
#include "asio/detail/push_options.hpp"
|
||
|
#include <boost/config.hpp>
|
||
|
#include <boost/scoped_ptr.hpp>
|
||
|
#include <cerrno>
|
||
|
#include <cstring>
|
||
|
#include <exception>
|
||
|
#include <string>
|
||
|
#include <boost/detail/workaround.hpp>
|
||
|
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||
|
# include <iostream>
|
||
|
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||
|
#include "asio/detail/pop_options.hpp"
|
||
|
|
||
|
#include "asio/detail/win_local_free_on_block_exit.hpp"
|
||
|
|
||
|
namespace asio {
|
||
|
|
||
|
/// The system_exception class is used to represent system conditions that
|
||
|
/// prevent the library from operating correctly.
|
||
|
class system_exception
|
||
|
: public std::exception
|
||
|
{
|
||
|
public:
|
||
|
/// Construct with a specific context and error code.
|
||
|
system_exception(const std::string& context, int code)
|
||
|
: context_(context),
|
||
|
code_(code)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
/// Copy constructor.
|
||
|
system_exception(const system_exception& e)
|
||
|
: std::exception(e),
|
||
|
context_(e.context_),
|
||
|
code_(e.code_)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
/// Destructor.
|
||
|
virtual ~system_exception() throw ()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
/// Assignment operator.
|
||
|
system_exception& operator=(const system_exception& e)
|
||
|
{
|
||
|
context_ = e.context_;
|
||
|
code_ = e.code_;
|
||
|
what_.reset();
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
/// Get a string representation of the exception.
|
||
|
virtual const char* what() const throw ()
|
||
|
{
|
||
|
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||
|
try
|
||
|
{
|
||
|
if (!what_)
|
||
|
{
|
||
|
char* msg = 0;
|
||
|
DWORD length = ::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER
|
||
|
| FORMAT_MESSAGE_FROM_SYSTEM
|
||
|
| FORMAT_MESSAGE_IGNORE_INSERTS, 0, code_,
|
||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (char*)&msg, 0, 0);
|
||
|
detail::win_local_free_on_block_exit local_free_obj(msg);
|
||
|
if (length && msg[length - 1] == '\n')
|
||
|
msg[--length] = '\0';
|
||
|
if (length && msg[length - 1] == '\r')
|
||
|
msg[--length] = '\0';
|
||
|
if (length)
|
||
|
{
|
||
|
std::string tmp(context_);
|
||
|
tmp += ": ";
|
||
|
tmp += msg;
|
||
|
what_.reset(new std::string(tmp));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return "asio system_exception";
|
||
|
}
|
||
|
}
|
||
|
return what_->c_str();
|
||
|
}
|
||
|
catch (std::exception&)
|
||
|
{
|
||
|
return "asio system_exception";
|
||
|
}
|
||
|
#elif defined(__sun) || defined(__QNX__)
|
||
|
return strerror(code_);
|
||
|
#elif defined(__MACH__) && defined(__APPLE__) \
|
||
|
|| defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||
|
try
|
||
|
{
|
||
|
char buf[256] = "";
|
||
|
strerror_r(code_, buf, sizeof(buf));
|
||
|
std::string tmp(context_);
|
||
|
tmp += ": ";
|
||
|
tmp += buf;
|
||
|
what_.reset(new std::string(tmp));
|
||
|
return what_->c_str();
|
||
|
}
|
||
|
catch (std::exception&)
|
||
|
{
|
||
|
return "asio system_exception";
|
||
|
}
|
||
|
#else
|
||
|
try
|
||
|
{
|
||
|
char buf[256] = "";
|
||
|
std::string tmp(context_);
|
||
|
tmp += ": ";
|
||
|
tmp += strerror_r(code_, buf, sizeof(buf));
|
||
|
what_.reset(new std::string(tmp));
|
||
|
return what_->c_str();
|
||
|
}
|
||
|
catch (std::exception&)
|
||
|
{
|
||
|
return "asio system_exception";
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
/// Get the implementation-defined context associated with the exception.
|
||
|
const std::string& context() const
|
||
|
{
|
||
|
return context_;
|
||
|
}
|
||
|
|
||
|
/// Get the implementation-defined code associated with the exception.
|
||
|
int code() const
|
||
|
{
|
||
|
return code_;
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
// The context associated with the error.
|
||
|
std::string context_;
|
||
|
|
||
|
// The code associated with the error.
|
||
|
int code_;
|
||
|
|
||
|
// The string representation of the error.
|
||
|
mutable boost::scoped_ptr<std::string> what_;
|
||
|
};
|
||
|
|
||
|
/// Output the string associated with a system exception.
|
||
|
/**
|
||
|
* Used to output a human-readable string that is associated with a system
|
||
|
* exception.
|
||
|
*
|
||
|
* @param os The output stream to which the string will be written.
|
||
|
*
|
||
|
* @param e The exception to be written.
|
||
|
*
|
||
|
* @return The output stream.
|
||
|
*
|
||
|
* @relates asio::system_exception
|
||
|
*/
|
||
|
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||
|
std::ostream& operator<<(std::ostream& os, const system_exception& e)
|
||
|
{
|
||
|
os << e.what();
|
||
|
return os;
|
||
|
}
|
||
|
#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||
|
template <typename Ostream>
|
||
|
Ostream& operator<<(Ostream& os, const system_exception& e)
|
||
|
{
|
||
|
os << e.what();
|
||
|
return os;
|
||
|
}
|
||
|
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||
|
|
||
|
} // namespace asio
|
||
|
|
||
|
#include "asio/detail/pop_options.hpp"
|
||
|
|
||
|
#endif // ASIO_SYSTEM_EXCEPTION_HPP
|