Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/filesystem/src/exception.cpp @ 12

Last change on this file since 12 was 12, checked in by landauf, 17 years ago

added boost

File size: 9.0 KB
Line 
1//  Exception implementation file  -------------------------------------------//
2
3//  Copyright © 2002 Beman Dawes
4//  Copyright © 2001 Dietmar Kühl
5//  Use, modification, and distribution is subject to the Boost Software
6//  License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy
7//  at http://www.boost.org/LICENSE_1_0.txt)
8
9//  See library home page at http://www.boost.org/libs/filesystem
10
11//----------------------------------------------------------------------------//
12
13// define BOOST_FILESYSTEM_SOURCE so that <boost/filesystem/config.hpp> knows
14// the library is being built (possibly exporting rather than importing code)
15#define BOOST_FILESYSTEM_SOURCE
16
17#include <boost/filesystem/config.hpp>
18#include <boost/filesystem/exception.hpp>
19
20namespace fs = boost::filesystem;
21
22#include <cstring> // SGI MIPSpro compilers need this
23#include <string>
24
25# ifdef BOOST_NO_STDC_NAMESPACE
26    namespace std { using ::strerror; }
27# endif
28
29// BOOST_POSIX or BOOST_WINDOWS specify which API to use.
30# if !defined( BOOST_WINDOWS ) && !defined( BOOST_POSIX )
31#   if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)
32#     define BOOST_WINDOWS
33#   else
34#     define BOOST_POSIX
35#   endif
36# endif
37
38# if defined( BOOST_WINDOWS )
39#   include "windows.h"
40# else
41#   include <errno.h> // for POSIX error codes
42# endif
43
44#include <boost/config/abi_prefix.hpp> // must be the last header
45
46//----------------------------------------------------------------------------//
47
48namespace
49{
50# ifdef BOOST_WINDOWS
51  std::string system_message( int sys_err_code )
52  {
53    std::string str;
54    LPVOID lpMsgBuf;
55    ::FormatMessageA( 
56        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
57        FORMAT_MESSAGE_FROM_SYSTEM | 
58        FORMAT_MESSAGE_IGNORE_INSERTS,
59        NULL,
60        sys_err_code,
61        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
62        (LPSTR) &lpMsgBuf,
63        0,
64        NULL 
65    );
66    str += static_cast<LPCSTR>(lpMsgBuf);
67    ::LocalFree( lpMsgBuf ); // free the buffer
68    while ( str.size()
69      && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') )
70        str.erase( str.size()-1 );
71    return str;
72  }
73# else
74  std::string system_message( int )
75  {
76    std::string str;
77    str += std::strerror( errno );
78    return str;
79  }
80# endif
81
82  struct ec_xlate { int sys_ec; fs::error_code ec; };
83  const ec_xlate ec_table[] =
84  {
85#     ifdef BOOST_WINDOWS
86    { ERROR_ACCESS_DENIED, fs::security_error },
87    { ERROR_INVALID_ACCESS, fs::security_error },
88    { ERROR_SHARING_VIOLATION, fs::security_error },
89    { ERROR_LOCK_VIOLATION, fs::security_error },
90    { ERROR_LOCKED, fs::security_error },
91    { ERROR_NOACCESS, fs::security_error },
92    { ERROR_WRITE_PROTECT, fs::read_only_error },
93    { ERROR_NOT_READY, fs::io_error },
94    { ERROR_SEEK, fs::io_error },
95    { ERROR_READ_FAULT, fs::io_error },
96    { ERROR_WRITE_FAULT, fs::io_error },
97    { ERROR_CANTOPEN, fs::io_error },
98    { ERROR_CANTREAD, fs::io_error },
99    { ERROR_CANTWRITE, fs::io_error },
100    { ERROR_DIRECTORY, fs::path_error },
101    { ERROR_INVALID_NAME, fs::path_error },
102    { ERROR_FILE_NOT_FOUND, fs::not_found_error },
103    { ERROR_PATH_NOT_FOUND, fs::not_found_error },
104    { ERROR_DEV_NOT_EXIST, fs::not_found_error },
105    { ERROR_DEVICE_IN_USE, fs::busy_error },
106    { ERROR_OPEN_FILES, fs::busy_error },
107    { ERROR_BUSY_DRIVE, fs::busy_error },
108    { ERROR_BUSY, fs::busy_error },
109    { ERROR_FILE_EXISTS, fs::already_exists_error },
110    { ERROR_ALREADY_EXISTS, fs::already_exists_error },
111    { ERROR_DIR_NOT_EMPTY, fs::not_empty_error },
112    { ERROR_HANDLE_DISK_FULL, fs::out_of_space_error },
113    { ERROR_DISK_FULL, fs::out_of_space_error },
114    { ERROR_OUTOFMEMORY, fs::out_of_memory_error },
115    { ERROR_NOT_ENOUGH_MEMORY, fs::out_of_memory_error },
116    { ERROR_TOO_MANY_OPEN_FILES, fs::out_of_resource_error }
117#     else
118    { EACCES, fs::security_error },
119    { EROFS, fs::read_only_error },
120    { EIO, fs::io_error },
121    { ENAMETOOLONG, fs::path_error },
122    { ENOENT, fs::not_found_error },
123    { ENOTDIR, fs::not_directory_error },
124    { EAGAIN, fs::busy_error },
125    { EBUSY, fs::busy_error },
126    { ETXTBSY, fs::busy_error },
127    { EEXIST, fs::already_exists_error },
128    { ENOTEMPTY, fs::not_empty_error },
129    { EISDIR, fs::is_directory_error },
130    { ENOSPC, fs::out_of_space_error },
131    { ENOMEM, fs::out_of_memory_error },
132    { EMFILE, fs::out_of_resource_error }
133#     endif
134  };
135
136  fs::error_code lookup_error( int sys_err_code )
137  {
138    for ( const ec_xlate * cur = &ec_table[0];
139      cur != ec_table
140        + sizeof(ec_table)/sizeof(ec_xlate); ++cur )
141    {
142      if ( sys_err_code == cur->sys_ec ) return cur->ec;
143    }
144    return fs::system_error; // general system error code
145  }
146
147  // These helper functions work for POSIX and Windows. For systems where
148  // path->native_file_string() != path->native_directory_string(), more
149  // care would be required to get the right form for the function involved.
150
151  std::string other_error_prep(
152    const std::string & who,
153    const std::string & message )
154  {
155    return who + ": " + message;
156  }
157
158  std::string other_error_prep(
159    const std::string & who,
160    const fs::path & path1,
161    const std::string & message )
162  {
163    return who + ": \"" + path1.native_file_string() + "\": " + message;
164  }
165
166  std::string system_error_prep(
167    const std::string & who,
168    const fs::path & path1,
169    int sys_err_code )
170  {
171    return who + ": \"" + path1.native_file_string() + "\": "
172      + system_message( sys_err_code );
173  }
174
175  std::string system_error_prep(
176    const std::string & who,
177    const fs::path & path1,
178    const fs::path & path2,
179    int sys_err_code )
180  {
181    return who + ": \"" + path1.native_file_string()
182      + "\", \"" + path2.native_file_string() + "\": "
183      + system_message( sys_err_code );
184  }
185
186  const fs::path empty_path;
187  const std::string empty_string;
188} // unnamed namespace
189
190namespace boost
191{
192  namespace filesystem
193  {
194//  filesystem_error m_imp class  --------------------------------------------//
195//  see www.boost.org/more/error_handling.html for implementation rationale
196
197    class filesystem_error::m_imp
198    {
199    public:
200      std::string     m_who;
201      path            m_path1;
202      path            m_path2;
203      std::string     m_what;
204    };
205
206
207//  filesystem_error implementation  -----------------------------------------//
208
209    filesystem_error::filesystem_error(
210      const std::string & who,
211      const std::string & message )
212      : m_sys_err(0), m_err(other_error)
213    {
214      try
215      {
216        m_imp_ptr.reset( new m_imp );
217        m_imp_ptr->m_who = who;
218        m_imp_ptr->m_what = other_error_prep( who, message );
219      }
220      catch (...) { m_imp_ptr.reset(); }
221    }
222 
223    filesystem_error::filesystem_error(
224      const std::string & who,
225      const path & path1,
226      const std::string & message,
227      error_code ec )
228      : m_sys_err(0), m_err(ec)
229    {
230      try
231      {
232        m_imp_ptr.reset( new m_imp );
233        m_imp_ptr->m_who = who;
234        m_imp_ptr->m_what = other_error_prep( who, path1, message );
235        m_imp_ptr->m_path1 = path1;
236      }
237      catch (...) { m_imp_ptr.reset(); }
238    }
239 
240    filesystem_error::filesystem_error(
241      const std::string & who,
242      const path & path1,
243      int sys_err_code )
244      : m_sys_err(sys_err_code), m_err(lookup_error(sys_err_code))
245    {
246      try
247      {
248        m_imp_ptr.reset( new m_imp );
249        m_imp_ptr->m_who = who;
250        m_imp_ptr->m_what = system_error_prep( who, path1, sys_err_code );
251        m_imp_ptr->m_path1 = path1;
252      }
253      catch (...) { m_imp_ptr.reset(); }
254    }
255
256    filesystem_error::filesystem_error(
257      const std::string & who,
258      const path & path1,
259      const path & path2,
260      int sys_err_code )
261      : m_sys_err(sys_err_code), m_err(lookup_error(sys_err_code))
262    {
263      try
264      {
265        m_imp_ptr.reset( new m_imp );
266        m_imp_ptr->m_who = who;
267        m_imp_ptr->m_what = system_error_prep( who, path1, path2, sys_err_code );
268        m_imp_ptr->m_path1 = path1;
269        m_imp_ptr->m_path2 = path2;
270      }
271      catch (...) { m_imp_ptr.reset(); }
272    }
273
274    filesystem_error::~filesystem_error() throw()
275    {
276    }
277
278    const std::string & filesystem_error::who() const
279    {
280      return m_imp_ptr.get() == 0 ? empty_string : m_imp_ptr->m_who;
281    }
282
283    const path & filesystem_error::path1() const
284    {
285      return m_imp_ptr.get() == 0 ? empty_path : m_imp_ptr->m_path1;
286    }
287
288    const path & filesystem_error::path2() const
289    {
290      return m_imp_ptr.get() == 0 ? empty_path : m_imp_ptr->m_path2;
291    }
292
293    const char * filesystem_error::what() const throw()
294    {
295      return m_imp_ptr.get() == 0 ? empty_string.c_str()
296                                  : m_imp_ptr->m_what.c_str();
297    }
298
299    namespace detail
300    {
301      BOOST_FILESYSTEM_DECL int system_error_code() // artifact of POSIX and WINDOWS error reporting
302      {
303  #   ifdef BOOST_WINDOWS
304        return ::GetLastError();
305  #   else
306        return errno; // GCC 3.1 won't accept ::errno
307  #   endif
308      }
309    } // namespace detail
310  } // namespace filesystem
311} // namespace boost
312 
Note: See TracBrowser for help on using the repository browser.