コード例 #1
0
static void do_open(Fstream& s,
                    const Path& path,
                    const std::ios_base::openmode mode,
                    typename boost::enable_if<fs::is_basic_path<Path> >::type* = 0)
{
	try
	{
		if (!allow_read(path))
			throw system_error(error_code(EACCES, get_system_category()));

		stream_do_open(s, path, mode);

		if (!s.is_open())
			throw system_error(error_code(errno, get_system_category()));
	}
	catch (const system_error& e)
	{
		string what(e.std::runtime_error::what());
		if (!what.empty())
			what = ": " + what;
		what = rwu_error_message(s) + what;

		throw fs::filesystem_error(what, path, e.code());
	}
}
コード例 #2
0
ファイル: tcpClient.cpp プロジェクト: bizstation/transactd
inline bool connections::doHandShake(connection* c, handshake f, void* data)
{
    bool ret = true;
    try
    {
        // 1.0 - 2.1 namepd pipe is not HandShakable.
        if (c->isHandShakable())
        {
            if (!f)
                c->read();
            else
                ret = f(c, data);
            if (c->error())
                m_e = asio::error::connection_refused;
            else if (!ret)
                m_e = asio::error::no_permission;
            if (!ret)
                delete c;
        }
        return ret;
    }
    catch (bzs::netsvc::client::exception& e)
    {
        delete c;
        m_e = boost::system::error_code(e.error(), get_system_category());
        return false;
    }
    catch (boost::system::system_error& e)
    {
        m_e = e.code();
        delete c;
        return false;
    }
}
コード例 #3
0
static bool allow_readwrite(const boost::filesystem::path& path, const unsigned int recursion)
{
	if (recursion > SYMLOOP_MAX)
		throw system_error(error_code(ELOOP, get_system_category()));

	const bool symlink = fs::is_symlink(path);

	for (vector<fs::path>::const_iterator
	     dir  = allowed_readwrite_paths.begin();
	     dir != allowed_readwrite_paths.end();
	     ++dir)
		if (dir_contains_path(*dir, path))
			return symlink ?
				allow_readwrite(readlink(path), recursion + 1) :
				true;

	for (vector<fs::path>::const_iterator
	     dir  = allowed_read_paths.begin();
	     dir != allowed_read_paths.end();
	     ++dir)
		if (dir_contains_path(*dir, path))
			return symlink ?
				allow_readwrite(readlink(path), recursion + 1) :
				true;

	return false;
}
コード例 #4
0
ファイル: tcpClient.cpp プロジェクト: bizstation/transactd
inline connection* connections::doConnect(connection* c)
{
    try
    {
        c->connect();
        if (c->isConnected())
            return c;
        m_e = c->error();
        delete c;
        return NULL;
    }
    catch (bzs::netsvc::client::exception& e)
    {
        m_e = boost::system::error_code(e.error(), get_system_category());
        delete c;
        return NULL;
    }
    catch (boost::system::system_error& e)
    {
        m_e = e.code();
        delete c;
        return NULL;
    }
    catch (std::exception& /*e*/)
    {
        m_e = boost::system::error_code(1, get_system_category());
        delete c;
        return NULL;
    }
    catch (...)
    {
        m_e = boost::system::error_code(1, get_system_category());
        delete c;
        return NULL;
    }
}
コード例 #5
0
size_type file::get_size(error_code& ec) const
{
#ifdef TORRENT_WINDOWS
    LARGE_INTEGER file_size;
    if (!GetFileSizeEx(m_file_handle, &file_size))
    {
        ec = error_code(GetLastError(), get_system_category());
        return -1;
    }
    return file_size.QuadPart;
#else
    struct stat fs;
    if (fstat(m_fd, &fs) != 0)
    {
        ec = error_code(errno, get_posix_category());
        return -1;
    }
    return fs.st_size;
#endif
}
コード例 #6
0
ファイル: error.hpp プロジェクト: c-zheng/autowiring
inline const autoboost::system::error_category& get_netdb_category()
{
  return get_system_category();
}
コード例 #7
0
bool file::set_size(size_type s, error_code& ec)
{
    TORRENT_ASSERT(is_open());
    TORRENT_ASSERT(s >= 0);

#ifdef TORRENT_WINDOWS
    LARGE_INTEGER offs;
    LARGE_INTEGER cur_size;
    if (GetFileSizeEx(m_file_handle, &cur_size) == FALSE)
    {
        ec = error_code(GetLastError(), get_system_category());
        return false;
    }
    offs.QuadPart = s;
    // only set the file size if it's not already at
    // the right size. We don't want to update the
    // modification time if we don't have to
    if (cur_size.QuadPart != s)
    {
        if (SetFilePointerEx(m_file_handle, offs, &offs, FILE_BEGIN) == FALSE)
        {
            ec.assign(GetLastError(), get_system_category());
            return false;
        }
        if (::SetEndOfFile(m_file_handle) == FALSE)
        {
            ec.assign(GetLastError(), get_system_category());
            return false;
        }
    }
#if _WIN32_WINNT >= 0x501
    if ((m_open_mode & sparse) == 0)
    {
        // only allocate the space if the file
        // is not fully allocated
        DWORD high_dword = 0;
        offs.LowPart = GetCompressedFileSize(m_path.c_str(), &high_dword);
        offs.HighPart = high_dword;
        ec.assign(GetLastError(), get_system_category());
        if (ec) return false;
        if (offs.QuadPart != s)
        {
            // if the user has permissions, avoid filling
            // the file with zeroes, but just fill it with
            // garbage instead
            SetFileValidData(m_file_handle, offs.QuadPart);
        }
    }
#endif // _WIN32_WINNT >= 0x501
#else // NON-WINDOWS
    struct stat st;
    if (fstat(m_fd, &st) != 0)
    {
        ec.assign(errno, get_posix_category());
        return false;
    }

    // only truncate the file if it doesn't already
    // have the right size. We don't want to update
    if (st.st_size != s && ftruncate(m_fd, s) < 0)
    {
        ec.assign(errno, get_posix_category());
        return false;
    }

    // if we're not in sparse mode, allocate the storage
    // but only if the number of allocated blocks for the file
    // is less than the file size. Otherwise we would just
    // update the modification time of the file for no good
    // reason.
    if ((m_open_mode & sparse) == 0
            && st.st_blocks < (s + st.st_blksize - 1) / st.st_blksize)
    {
        // How do we know that the file is already allocated?
        // if we always try to allocate the space, we'll update
        // the modification time without actually changing the file
        // but if we don't do anything if the file size is
#ifdef F_PREALLOCATE
        fstore_t f = {F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, s, 0};
        if (fcntl(m_fd, F_PREALLOCATE, &f) < 0)
        {
            ec = error_code(errno, get_posix_category());
            return false;
        }
#endif // F_PREALLOCATE

#if defined TORRENT_LINUX || TORRENT_HAS_FALLOCATE
        int ret;
#endif

#if defined TORRENT_LINUX
        ret = my_fallocate(m_fd, 0, 0, s);
        // if we return 0, everything went fine
        // the fallocate call succeeded
        if (ret == 0) return true;
        // otherwise, something went wrong. If the error
        // is ENOSYS, just keep going and do it the old-fashioned
        // way. If fallocate failed with some other error, it
        // probably means the user should know about it, error out
        // and report it.
        if (errno != ENOSYS && errno != EOPNOTSUPP)
        {
            ec.assign(errno, get_posix_category());
            return false;
        }
#endif // TORRENT_LINUX

#if TORRENT_HAS_FALLOCATE
        // if fallocate failed, we have to use posix_fallocate
        // which can be painfully slow
        // if you get a compile error here, you might want to
        // define TORRENT_HAS_FALLOCATE to 0.
        ret = posix_fallocate(m_fd, 0, s);
        // posix_allocate fails with EINVAL in case the underlying
        // filesystem does bot support this operation
        if (ret != 0 && ret != EINVAL)
        {
            ec = error_code(ret, get_posix_category());
            return false;
        }
#endif // TORRENT_HAS_FALLOCATE
    }
#endif // TORRENT_WINDOWS
    return true;
}
コード例 #8
0
size_type file::writev(size_type file_offset, iovec_t const* bufs, int num_bufs, error_code& ec)
{
    TORRENT_ASSERT((m_open_mode & rw_mask) == write_only || (m_open_mode & rw_mask) == read_write);
    TORRENT_ASSERT(bufs);
    TORRENT_ASSERT(num_bufs > 0);
    TORRENT_ASSERT(is_open());

#if defined TORRENT_WINDOWS || defined TORRENT_LINUX || defined TORRENT_DEBUG
    // make sure m_page_size is initialized
    init_file();
#endif

#ifdef TORRENT_DEBUG
    if (m_open_mode & no_buffer)
    {
        bool eof = false;
        int size = 0;
        // when opened in no_buffer mode, the file_offset must
        // be aligned to pos_alignment()
        TORRENT_ASSERT((file_offset & (pos_alignment()-1)) == 0);
        for (file::iovec_t const* i = bufs, *end(bufs + num_bufs); i < end; ++i)
        {
            TORRENT_ASSERT((uintptr_t(i->iov_base) & (buf_alignment()-1)) == 0);
            // every buffer must be a multiple of the page size
            // except for the last one
            TORRENT_ASSERT((i->iov_len & (size_alignment()-1)) == 0 || i == end-1);
            if ((i->iov_len & (size_alignment()-1)) != 0) eof = true;
            size += i->iov_len;
        }
        error_code code;
        if (eof) TORRENT_ASSERT(file_offset + size >= get_size(code));
    }
#endif

#ifdef TORRENT_WINDOWS

    DWORD ret = 0;

    // since the ReadFileScatter requires the file to be opened
    // with no buffering, and no buffering requires page aligned
    // buffers, open the file in non-buffered mode in case the
    // buffer is not aligned. Most of the times the buffer should
    // be aligned though

    if ((m_open_mode & no_buffer) == 0)
    {
        // this means the buffer base or the buffer size is not aligned
        // to the page size. Use a regular file for this operation.

        LARGE_INTEGER offs;
        offs.QuadPart = file_offset;
        if (SetFilePointerEx(m_file_handle, offs, &offs, FILE_BEGIN) == FALSE)
        {
            ec = error_code(GetLastError(), get_system_category());
            return -1;
        }

        for (file::iovec_t const* i = bufs, *end(bufs + num_bufs); i < end; ++i)
        {
            DWORD intermediate = 0;
            if (WriteFile(m_file_handle, (char const*)i->iov_base
                          , (DWORD)i->iov_len, &intermediate, 0) == FALSE)
            {
                ec = error_code(GetLastError(), get_system_category());
                return -1;
            }
            ret += intermediate;
        }
        return ret;
    }

    int size = bufs_size(bufs, num_bufs);
    // number of pages for the write. round up
    int num_pages = (size + m_page_size - 1) / m_page_size;
    // allocate array of FILE_SEGMENT_ELEMENT for WriteFileGather
    FILE_SEGMENT_ELEMENT* segment_array = TORRENT_ALLOCA(FILE_SEGMENT_ELEMENT, num_pages + 1);
    FILE_SEGMENT_ELEMENT* cur_seg = segment_array;

    for (file::iovec_t const* i = bufs, *end(bufs + num_bufs); i < end; ++i)
    {
        for (int k = 0; k < i->iov_len; k += m_page_size)
        {
            cur_seg->Buffer = PtrToPtr64((((char*)i->iov_base) + k));
            ++cur_seg;
        }
    }
    // terminate the array
    cur_seg->Buffer = 0;

    OVERLAPPED ol;
    ol.Internal = 0;
    ol.InternalHigh = 0;
    ol.OffsetHigh = file_offset >> 32;
    ol.Offset = file_offset & 0xffffffff;
    ol.hEvent = CreateEvent(0, true, false, 0);

    ret += size;
    // if file_size is > 0, the file will be opened in unbuffered
    // mode after the write completes, and truncate the file to
    // file_size.
    size_type file_size = 0;

    if ((size & (m_page_size-1)) != 0)
    {
        // if size is not an even multiple, this must be the tail
        // of the file. Write the whole page and then open a new
        // file without FILE_FLAG_NO_BUFFERING and set the
        // file size to file_offset + size

        file_size = file_offset + size;
        size = num_pages * m_page_size;
    }

    if (WriteFileGather(m_file_handle, segment_array, size, 0, &ol) == 0)
    {
        if (GetLastError() != ERROR_IO_PENDING)
        {
            TORRENT_ASSERT(GetLastError() != ERROR_BAD_ARGUMENTS);
            ec = error_code(GetLastError(), get_system_category());
            CloseHandle(ol.hEvent);
            return -1;
        }
        DWORD tmp;
        if (GetOverlappedResult(m_file_handle, &ol, &tmp, true) == 0)
        {
            ec = error_code(GetLastError(), get_system_category());
            CloseHandle(ol.hEvent);
            return -1;
        }
        if (tmp < ret) ret = tmp;
    }
    CloseHandle(ol.hEvent);

    if (file_size > 0)
    {
#if TORRENT_USE_WPATH
#define CreateFile_ CreateFileW
#else
#define CreateFile_ CreateFileA
#endif
        HANDLE f = CreateFile_(m_path.c_str(), GENERIC_WRITE
                               , FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING
                               , FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, 0);

        if (f == INVALID_HANDLE_VALUE)
        {
            ec = error_code(GetLastError(), get_system_category());
            return -1;
        }

        LARGE_INTEGER offs;
        offs.QuadPart = file_size;
        if (SetFilePointerEx(f, offs, &offs, FILE_BEGIN) == FALSE)
        {
            CloseHandle(f);
            ec = error_code(GetLastError(), get_system_category());
            return -1;
        }
        if (::SetEndOfFile(f) == FALSE)
        {
            ec = error_code(GetLastError(), get_system_category());
            CloseHandle(f);
            return -1;
        }
        CloseHandle(f);
    }

    return ret;
#else
    size_type ret = lseek(m_fd, file_offset, SEEK_SET);
    if (ret < 0)
    {
        ec = error_code(errno, get_posix_category());
        return -1;
    }

#if TORRENT_USE_WRITEV

#ifdef TORRENT_LINUX
    bool aligned = false;
    int size = 0;
    // if we're not opened in no-buffer mode, we don't need alignment
    if ((m_open_mode & no_buffer) == 0) aligned = true;
    if (!aligned)
    {
        size = bufs_size(bufs, num_bufs);
        if ((size & (size_alignment()-1)) == 0) aligned = true;
    }
    if (aligned)
#endif
    {
        ret = ::writev(m_fd, bufs, num_bufs);
        if (ret < 0)
        {
            ec = error_code(errno, get_posix_category());
            return -1;
        }
        return ret;
    }
#ifdef TORRENT_LINUX
    file::iovec_t* temp_bufs = TORRENT_ALLOCA(file::iovec_t, num_bufs);
    memcpy(temp_bufs, bufs, sizeof(file::iovec_t) * num_bufs);
    iovec_t& last = temp_bufs[num_bufs-1];
    last.iov_len = (last.iov_len & ~(size_alignment()-1)) + size_alignment();
    ret = ::writev(m_fd, temp_bufs, num_bufs);
    if (ret < 0)
    {
        ec = error_code(errno, get_posix_category());
        return -1;
    }
    if (ftruncate(m_fd, file_offset + size) < 0)
    {
        ec = error_code(errno, get_posix_category());
        return -1;
    }
    return (std::min)(ret, size_type(size));
#endif // TORRENT_LINUX

#else // TORRENT_USE_WRITEV

    ret = 0;
    for (file::iovec_t const* i = bufs, *end(bufs + num_bufs); i < end; ++i)
    {
        int tmp = write(m_fd, i->iov_base, i->iov_len);
        if (tmp < 0)
        {
            ec = error_code(errno, get_posix_category());
            return -1;
        }
        ret += tmp;
        if (tmp < i->iov_len) break;
    }
    return ret;

#endif // TORRENT_USE_WRITEV

#endif // TORRENT_WINDOWS
}
コード例 #9
0
inline error_code make_error_code( windows_error_code e )
{
    return error_code( e, get_system_category() );
}
コード例 #10
0
ファイル: error.hpp プロジェクト: DevSlashNull/MaidSafe
inline const asio::error_category& get_addrinfo_category()
{
  return get_system_category();
}
コード例 #11
0
ファイル: error.hpp プロジェクト: DevSlashNull/MaidSafe
inline const asio::error_category& get_netdb_category()
{
  return get_system_category();
}
コード例 #12
0
 inline error_code make_error_code( linux_errno e )
   { return error_code( e, get_system_category() ); }
コード例 #13
0
  namespace system
  {

    class error_code;
    class error_condition;

    //  "Concept" helpers  ---------------------------------------------------//

    template< class T >
    struct is_error_code_enum { static const bool value = false; };

    template< class T >
    struct is_error_condition_enum { static const bool value = false; };

    //  generic error_conditions  --------------------------------------------//

    namespace errc
    {
      enum errc_t
      {
        success = 0,
        address_family_not_supported = EAFNOSUPPORT,
        address_in_use = EADDRINUSE,
        address_not_available = EADDRNOTAVAIL,
        already_connected = EISCONN,
        argument_list_too_long = E2BIG,
        argument_out_of_domain = EDOM,
        bad_address = EFAULT,
        bad_file_descriptor = EBADF,
        bad_message = EBADMSG,
        broken_pipe = EPIPE,
        connection_aborted = ECONNABORTED,
        connection_already_in_progress = EALREADY,
        connection_refused = ECONNREFUSED,
        connection_reset = ECONNRESET,
        cross_device_link = EXDEV,
        destination_address_required = EDESTADDRREQ,
        device_or_resource_busy = EBUSY,
        directory_not_empty = ENOTEMPTY,
        executable_format_error = ENOEXEC,
        file_exists = EEXIST,
        file_too_large = EFBIG,
        filename_too_long = ENAMETOOLONG,
        function_not_supported = ENOSYS,
        host_unreachable = EHOSTUNREACH,
        identifier_removed = EIDRM,
        illegal_byte_sequence = EILSEQ,
        inappropriate_io_control_operation = ENOTTY,
        interrupted = EINTR,
        invalid_argument = EINVAL,
        invalid_seek = ESPIPE,
        io_error = EIO,
        is_a_directory = EISDIR,
        message_size = EMSGSIZE,
        network_down = ENETDOWN,
        network_reset = ENETRESET,
        network_unreachable = ENETUNREACH,
        no_buffer_space = ENOBUFS,
        no_child_process = ECHILD,
        no_link = ENOLINK,
        no_lock_available = ENOLCK,
        no_message_available = ENODATA,
        no_message = ENOMSG,
        no_protocol_option = ENOPROTOOPT,
        no_space_on_device = ENOSPC,
        no_stream_resources = ENOSR,
        no_such_device_or_address = ENXIO,
        no_such_device = ENODEV,
        no_such_file_or_directory = ENOENT,
        no_such_process = ESRCH,
        not_a_directory = ENOTDIR,
        not_a_socket = ENOTSOCK,
        not_a_stream = ENOSTR,
        not_connected = ENOTCONN,
        not_enough_memory = ENOMEM,
        not_supported = ENOTSUP,
        operation_canceled = ECANCELED,
        operation_in_progress = EINPROGRESS,
        operation_not_permitted = EPERM,
        operation_not_supported = EOPNOTSUPP,
        operation_would_block = EWOULDBLOCK,
        owner_dead = EOWNERDEAD,
        permission_denied = EACCES,
        protocol_error = EPROTO,
        protocol_not_supported = EPROTONOSUPPORT,
        read_only_file_system = EROFS,
        resource_deadlock_would_occur = EDEADLK,
        resource_unavailable_try_again = EAGAIN,
        result_out_of_range = ERANGE,
        state_not_recoverable = ENOTRECOVERABLE,
        stream_timeout = ETIME,
        text_file_busy = ETXTBSY,
        timed_out = ETIMEDOUT,
        too_many_files_open_in_system = ENFILE,
        too_many_files_open = EMFILE,
        too_many_links = EMLINK,
        too_many_synbolic_link_levels = ELOOP,
        value_too_large = EOVERFLOW,
        wrong_protocol_type = EPROTOTYPE
      };

    } // namespace errc

# ifndef BOOST_SYSTEM_NO_DEPRECATED
    namespace posix = errc;
    namespace posix_error = errc;
# endif

    template<> struct is_error_condition_enum<errc::errc_t>
      { static const bool value = true; };


    //  ----------------------------------------------------------------------//

    //  Operating system specific interfaces  --------------------------------//


    //  The interface is divided into general and system-specific portions to
    //  meet these requirements:
    //
    //  * Code calling an operating system API can create an error_code with
    //    a single category (system_category), even for POSIX-like operating
    //    systems that return some POSIX errno values and some native errno
    //    values. This code should not have to pay the cost of distinguishing
    //    between categories, since it is not yet known if that is needed.
    //
    //  * Users wishing to write system-specific code should be given enums for
    //    at least the common error cases.
    //
    //  * System specific code should fail at compile time if moved to another
    //    operating system.

    //  The system specific portions of the interface are located in headers
    //  with names reflecting the operating system. For example,
    //
    //       <boost/system/cygwin_error.hpp>
    //       <boost/system/linux_error.hpp>
    //       <boost/system/windows_error.hpp>
    //
    //  These headers are effectively empty for compiles on operating systems
    //  where they are not applicable.

    //  ----------------------------------------------------------------------//

    //  class error_category  ------------------------------------------------//

    class error_category : public noncopyable
    {
    public:
      virtual ~error_category(){}
      virtual inline const char *    name() const;  // see implementation note below
      virtual inline std::string     message( int ev ) const;   // see implementation note below
      virtual inline error_condition default_error_condition( int ev ) const;
      virtual inline bool equivalent( int code, const error_condition & condition ) const;
      virtual inline bool equivalent( const error_code & code, int condition ) const;

      bool operator==(const error_category & rhs) const { return this == &rhs; }
      bool operator!=(const error_category & rhs) const { return this != &rhs; }
      bool operator<( const error_category & rhs ) const
      {
        return std::less<const error_category*>()( this, &rhs );
      }
    };

    //  predefined error categories  -----------------------------------------//

    BOOST_SYSTEM_DECL const error_category &  get_system_category();
    BOOST_SYSTEM_DECL const error_category &  get_generic_category();

    static const error_category &  system_category = get_system_category();
    static const error_category &  generic_category = get_generic_category();
    
# ifndef BOOST_SYSTEM_NO_DEPRECATED
    //  deprecated synonyms
    static const error_category &  posix_category = get_generic_category();
    static const error_category &  errno_ecat     = get_generic_category();
    static const error_category &  native_ecat    = get_system_category();
# endif

    //  class error_condition  -----------------------------------------------//

    //  error_conditions are portable, error_codes are system or lib specific

    class error_condition
    {
    public:

      // constructors:
      error_condition() : m_val(0), m_cat(&get_generic_category()) {}
      error_condition( int val, const error_category & cat ) : m_val(val), m_cat(&cat) {}

      template <class ConditionEnum>
        error_condition(ConditionEnum e,
          typename boost::enable_if<is_error_condition_enum<ConditionEnum> >::type* = 0)
      {
        *this = make_error_condition(e);
      }

      // modifiers:

      void assign( int val, const error_category & cat )
      { 
        m_val = val;
        m_cat = &cat;
      }
                                             
      template<typename ConditionEnum>
        typename boost::enable_if<is_error_condition_enum<ConditionEnum>, error_condition>::type &
          operator=( ConditionEnum val )
      { 
        *this = make_error_condition(val);
        return *this;
      }

      void clear()
      {
        m_val = 0;
        m_cat = &get_generic_category();
      }

      // observers:
      int                     value() const    { return m_val; }
      const error_category &  category() const { return *m_cat; }
      std::string             message() const  { return m_cat->message(value()); }

      typedef void (*unspecified_bool_type)();
      static void unspecified_bool_true() {}

      operator unspecified_bool_type() const  // true if error
      { 
        return m_val == 0 ? 0 : unspecified_bool_true;
      }

      bool operator!() const  // true if no error
      {
        return m_val == 0;
      }

      // relationals:
      //  the more symmetrical non-member syntax allows enum
      //  conversions work for both rhs and lhs.
      inline friend bool operator==( const error_condition & lhs,
                                     const error_condition & rhs )
      {
        return lhs.m_cat == rhs.m_cat && lhs.m_val == rhs.m_val;
      }                  

      inline friend bool operator<( const error_condition & lhs,
                                    const error_condition & rhs )
        //  the more symmetrical non-member syntax allows enum
        //  conversions work for both rhs and lhs.
      {
        return lhs.m_cat < rhs.m_cat
          || (lhs.m_cat == rhs.m_cat && lhs.m_val < rhs.m_val);
      }

    private:
      int                     m_val;
      const error_category *  m_cat;

    };

    //  class error_code  ----------------------------------------------------//

    //  We want error_code to be a value type that can be copied without slicing
    //  and without requiring heap allocation, but we also want it to have
    //  polymorphic behavior based on the error category. This is achieved by
    //  abstract base class error_category supplying the polymorphic behavior,
    //  and error_code containing a pointer to an object of a type derived
    //  from error_category.
    class error_code
    {
    public:

      // constructors:
      error_code() : m_val(0), m_cat(&get_system_category()) {}
      error_code( int val, const error_category & cat ) : m_val(val), m_cat(&cat) {}

      template <class CodeEnum>
        error_code(CodeEnum e,
          typename boost::enable_if<is_error_code_enum<CodeEnum> >::type* = 0)
      {
        *this = make_error_code(e);
      }

      // modifiers:
      void assign( int val, const error_category & cat )
      { 
        m_val = val;
        m_cat = &cat;
      }
                                             
      template<typename CodeEnum>
        typename boost::enable_if<is_error_code_enum<CodeEnum>, error_code>::type &
          operator=( CodeEnum val )
      { 
        *this = make_error_code(val);
        return *this;
      }

      void clear()
      {
        m_val = 0;
        m_cat = &get_system_category();
      }

      // observers:
      int                     value() const    { return m_val; }
      const error_category &  category() const { return *m_cat; }
      error_condition         default_error_condition() const  { return m_cat->default_error_condition(value()); }
      std::string             message() const  { return m_cat->message(value()); }

      typedef void (*unspecified_bool_type)();
      static void unspecified_bool_true() {}

      operator unspecified_bool_type() const  // true if error
      { 
        return m_val == 0 ? 0 : unspecified_bool_true;
      }

      bool operator!() const  // true if no error
      {
        return m_val == 0;
      }

      // relationals:
      inline friend bool operator==( const error_code & lhs,
                                     const error_code & rhs )
        //  the more symmetrical non-member syntax allows enum
        //  conversions work for both rhs and lhs.
      {
        return lhs.m_cat == rhs.m_cat && lhs.m_val == rhs.m_val;
      }

      inline friend bool operator<( const error_code & lhs,
                                    const error_code & rhs )
        //  the more symmetrical non-member syntax allows enum
        //  conversions work for both rhs and lhs.
      {
        return lhs.m_cat < rhs.m_cat
          || (lhs.m_cat == rhs.m_cat && lhs.m_val < rhs.m_val);
      }
                  
      private:
      int                     m_val;
      const error_category *  m_cat;

    };

    //  non-member functions  ------------------------------------------------//

    inline bool operator!=( const error_code & lhs,
                            const error_code & rhs )
    {
      return !(lhs == rhs);
    }

    inline bool operator!=( const error_condition & lhs,
                            const error_condition & rhs )
    {
      return !(lhs == rhs);
    }

    inline bool operator==( const error_code & code,
                            const error_condition & condition )
    {
      return code.category().equivalent( code.value(), condition )
        || condition.category().equivalent( code, condition.value() );
    }
                
    inline bool operator!=( const error_code & lhs,
                            const error_condition & rhs )
    {
      return !(lhs == rhs);
    }
                
    inline bool operator==( const error_condition & condition,
                            const error_code & code )
    {
      return condition.category().equivalent( code, condition.value() )
        || code.category().equivalent( code.value(), condition );
    }
                
    inline bool operator!=( const error_condition & lhs,
                            const error_code & rhs )
    {
      return !(lhs == rhs);
    }
                  
    // TODO: both of these may move elsewhere, but the LWG hasn't spoken yet.

    template <class charT, class traits>
    inline std::basic_ostream<charT,traits>&
      operator<< (std::basic_ostream<charT,traits>& os, error_code ec)
    {
      os << ec.category().name() << ':' << ec.value();
      return os;
    }

    inline std::size_t hash_value( const error_code & ec )
    {
      return static_cast<std::size_t>(ec.value())
        + reinterpret_cast<std::size_t>(&ec.category());
    }

    //  make_* functions for errc::errc_t  -----------------------------//

    namespace errc
    {
      //  explicit conversion:
      inline error_code make_error_code( errc_t e )
        { return error_code( e, get_generic_category() ); }

      //  implicit conversion:
      inline error_condition make_error_condition( errc_t e )
        { return error_condition( e, get_generic_category() ); }
    }

    //  error_category default implementation  -------------------------------//

    inline error_condition error_category::default_error_condition( int ev ) const
    { 
      return error_condition( ev, *this );
    }

    inline bool error_category::equivalent( int code,
      const error_condition & condition ) const
    {
      return default_error_condition( code ) == condition;
    }

    inline bool error_category::equivalent( const error_code & code,
      int condition ) const
    {
      return *this == code.category() && code.value() == condition;
    }

    //  error_category implementation note: VC++ 8.0 objects to name() and
    //  message() being pure virtual functions. Thus these implementations.
    inline const char * error_category::name() const
    { 
      return "error: should never be called";
    }

    inline std::string error_category::message( int ) const
    { 
      static std::string s("error: should never be called");
      return s;
    }

  } // namespace system
コード例 #14
0
 void clear()
 {
   m_val = 0;
   m_cat = &get_system_category();
 }
コード例 #15
0
 // constructors:
 error_code() : m_val(0), m_cat(&get_system_category()) {}
コード例 #16
0
ファイル: error.hpp プロジェクト: c-zheng/autowiring
inline const autoboost::system::error_category& get_addrinfo_category()
{
  return get_system_category();
}
コード例 #17
0
ファイル: error.hpp プロジェクト: eaglewei/panda-svrkit
inline asio::error_code make_error_code(basic_errors e)
{
  return asio::error_code(
      static_cast<int>(e), get_system_category());
}
コード例 #18
0
ファイル: error.hpp プロジェクト: 4ukuta/core
inline riakboost::system::error_code make_error_code(basic_errors e)
{
  return riakboost::system::error_code(
      static_cast<int>(e), get_system_category());
}