00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00050 #ifndef WINSTL_INCL_WINSTL_ERROR_HPP_EXCEPTIONS
00051 #define WINSTL_INCL_WINSTL_ERROR_HPP_EXCEPTIONS
00052
00053 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00054 # define WINSTL_VER_WINSTL_ERROR_HPP_EXCEPTIONS_MAJOR 4
00055 # define WINSTL_VER_WINSTL_ERROR_HPP_EXCEPTIONS_MINOR 4
00056 # define WINSTL_VER_WINSTL_ERROR_HPP_EXCEPTIONS_REVISION 3
00057 # define WINSTL_VER_WINSTL_ERROR_HPP_EXCEPTIONS_EDIT 61
00058 #endif
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 #ifndef WINSTL_INCL_WINSTL_H_WINSTL
00073 # include <winstl/winstl.h>
00074 #endif
00075 #ifndef STLSOFT_INCL_STLSOFT_ERROR_HPP_EXCEPTIONS
00076 # include <stlsoft/error/exceptions.hpp>
00077 #endif
00078 #ifndef WINSTL_INCL_WINSTL_ERROR_H_ERROR_FUNCTIONS
00079 # include <winstl/error/error_functions.h>
00080 #endif
00081 #ifndef STLSOFT_INCL_STLSOFT_UTIL_HPP_EXCEPTION_STRING
00082 # include <stlsoft/util/exception_string.hpp>
00083 #endif
00084 #ifndef STLSOFT_INCL_STLSOFT_SMARTPTR_HPP_SCOPED_HANDLE
00085 # include <stlsoft/smartptr/scoped_handle.hpp>
00086 #endif
00087
00088 #ifndef STLSOFT_INCL_H_STRING
00089 # define STLSOFT_INCL_H_STRING
00090 # include <string.h>
00091 #endif
00092
00093
00094
00095
00096
00097 #ifndef _WINSTL_NO_NAMESPACE
00098 # if defined(_STLSOFT_NO_NAMESPACE) || \
00099 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00100
00101 namespace winstl
00102 {
00103 # else
00104
00105
00106 namespace stlsoft
00107 {
00108
00109 namespace winstl_project
00110 {
00111
00112 # endif
00113 #endif
00114
00115
00116
00117
00118
00124 class windows_exception
00125 : public stlsoft_ns_qual(os_exception)
00126 {
00129 protected:
00130 typedef stlsoft_ns_qual(exception_string) string_type;
00131 public:
00133 typedef stlsoft_ns_qual(os_exception) parent_class_type;
00135 typedef ws_dword_t error_code_type;
00137 typedef windows_exception class_type;
00139 typedef ws_size_t size_type;
00141
00144 public:
00146 ss_explicit_k windows_exception(error_code_type err)
00147 : m_reason()
00148 , m_strerror(NULL)
00149 , m_errorCode(err)
00150 {}
00152 windows_exception(class_type const& rhs)
00153 : m_reason(rhs.m_reason)
00154 , m_strerror(NULL)
00155 , m_errorCode(rhs.m_errorCode)
00156 {}
00158 windows_exception(char const* reason, error_code_type err)
00159 : m_reason(class_type::create_reason_(reason, err))
00160 , m_strerror(NULL)
00161 , m_errorCode(err)
00162 {}
00164 windows_exception(char const* reason)
00165 : m_reason(reason)
00166 , m_strerror(NULL)
00167 , m_errorCode(ERROR_SUCCESS)
00168 {}
00169 protected:
00171 windows_exception(string_type const& reason, error_code_type err)
00172 : m_reason(reason)
00173 , m_strerror(NULL)
00174 , m_errorCode(err)
00175 {}
00176 public:
00177 virtual ~windows_exception() stlsoft_throw_0()
00178 {
00179 if( NULL != m_strerror &&
00180 m_reason.c_str() != m_strerror)
00181 {
00182 format_message_free_buff(m_strerror);
00183 }
00184 }
00186
00189 public:
00190 virtual char const* what() const stlsoft_throw_0()
00191 {
00192 if(!m_reason.empty())
00193 {
00194 return m_reason.c_str();
00195 }
00196 else
00197 {
00198 return this->strerror();
00199 }
00200 }
00201
00203 error_code_type get_error_code() const
00204 {
00205 return m_errorCode;
00206 }
00207
00211 error_code_type last_error() const
00212 {
00213 return get_error_code();
00214 }
00215
00216 char const* strerror() const
00217 {
00218 if(NULL == m_strerror)
00219 {
00220 if(is_memory_error_(m_errorCode))
00221 {
00222 return "Out of memory";
00223 }
00224 else
00225 {
00226 char*& s = stlsoft_ns_qual(remove_const)(this->m_strerror);
00227
00228 if(0 == format_message(m_errorCode, NULL, &s))
00229 {
00230 return "Windows system error";
00231 }
00232 }
00233 }
00234
00235 return m_strerror;
00236 }
00238
00241 private:
00242 static bool is_memory_error_(error_code_type code)
00243 {
00244 switch(code)
00245 {
00246 default:
00247 return false;
00248 #ifdef _HRESULT_DEFINED
00249 case static_cast<error_code_type>(E_OUTOFMEMORY):
00250 #else
00251 case static_cast<error_code_type>(0x8007000EL):
00252 #endif
00253 case static_cast<error_code_type>(ERROR_OUTOFMEMORY):
00254 return true;
00255 }
00256 }
00257
00258 static string_type create_reason_(char const* reason, error_code_type err)
00259 {
00260 if( is_memory_error_(err) ||
00261 NULL == reason ||
00262 '\0' == reason[0])
00263 {
00264 return string_type();
00265 }
00266 else
00267 {
00268 #if 0
00269 size_type const len = ::strlen(reason);
00270 stlsoft_ns_qual(exception_string_creator) creator(len + 100u);
00271
00272 creator.append(reason);
00273
00274 char* s;
00275
00276 if(0 != format_message(err, NULL, &s))
00277 {
00278 stlsoft_ns_qual(scoped_handle)<char*> scoper(s, format_message_free_buff);
00279
00280 creator.append(": ").append(s);
00281 }
00282
00283 return creator.create();
00284 #else
00285 string_type r(reason);
00286 char* s;
00287
00288 if(0 != format_message(err, NULL, &s))
00289 {
00290 stlsoft_ns_qual(scoped_handle)<char*> scoper(s, format_message_free_buff);
00291
00292 return r + ": " + s;
00293 }
00294 else
00295 {
00296 return r;
00297 }
00298 #endif
00299 }
00300 }
00302
00305 private:
00306 const string_type m_reason;
00307 char* m_strerror;
00308 const error_code_type m_errorCode;
00310
00313 private:
00314 class_type& operator =(class_type const&);
00316 };
00317
00325 class resource_exception
00326 : public windows_exception
00327 {
00330 public:
00331 typedef windows_exception parent_class_type;
00332 typedef resource_exception class_type;
00334
00337 public:
00338 resource_exception( char const* reason
00339 , error_code_type err
00340 , LPCTSTR resourceId = NULL
00341 , LPCTSTR resourceType = NULL)
00342 : parent_class_type(reason, err)
00343 , m_resourceId(resourceId)
00344 , m_resourceType(resourceType)
00345 {}
00347
00350 public:
00351 LPCTSTR get_resource_id() const
00352 {
00353 return m_resourceId;
00354 }
00355 LPCTSTR get_resource_type() const
00356 {
00357 return m_resourceType;
00358 }
00360
00363 private:
00364 const LPCTSTR m_resourceId;
00365 const LPCTSTR m_resourceType;
00367
00370 private:
00371 class_type& operator =(class_type const&);
00373 };
00374
00379 class access_exception
00380 : public windows_exception
00381 {
00384 public:
00385 typedef windows_exception parent_class_type;
00386 typedef access_exception class_type;
00387 typedef parent_class_type::error_code_type error_code_type;
00389
00392 public:
00393 access_exception( char const* reason
00394 , error_code_type err)
00395 : parent_class_type(reason, err)
00396 {}
00397 access_exception(error_code_type err)
00398 : parent_class_type(err)
00399 {}
00401
00404 private:
00405 class_type& operator =(class_type const&);
00407 };
00408
00409
00410
00411
00412
00418
00419 struct windows_exception_policy
00420 {
00423 public:
00425 typedef windows_exception thrown_type;
00426 typedef ws_dword_t error_code_type;
00428
00431 public:
00433 void operator ()() const
00434 {
00435 STLSOFT_THROW_X(thrown_type(::GetLastError()));
00436 }
00438 void operator ()(error_code_type err) const
00439 {
00440 STLSOFT_THROW_X(thrown_type(err));
00441 }
00443 void operator ()(char const* reason, error_code_type err) const
00444 {
00445 STLSOFT_THROW_X(thrown_type(reason, err));
00446 }
00448 };
00449
00455
00456 struct resource_exception_policy
00457 {
00460 public:
00462 typedef resource_exception thrown_type;
00463 typedef ws_dword_t error_code_type;
00465
00468 public:
00470 void operator ()(char const* reason, error_code_type err) const
00471 {
00472 STLSOFT_THROW_X(thrown_type(reason, err));
00473 }
00475 void operator ()(char const* reason, error_code_type err, LPCTSTR resourceId) const
00476 {
00477 STLSOFT_THROW_X(thrown_type(reason, err, resourceId));
00478 }
00480 void operator ()(char const* reason, error_code_type err, LPCTSTR resourceId, LPCTSTR resourceType) const
00481 {
00482 STLSOFT_THROW_X(thrown_type(reason, err, resourceId, resourceType));
00483 }
00485 };
00486
00488
00489
00490 #ifdef STLSOFT_UNITTEST
00491 # include "./unittest/exceptions_unittest_.h"
00492 #endif
00493
00494
00495
00496 #ifndef _WINSTL_NO_NAMESPACE
00497 # if defined(_STLSOFT_NO_NAMESPACE) || \
00498 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00499 }
00500 # else
00501 }
00502 }
00503 # endif
00504 #endif
00505
00506
00507
00508 #endif
00509
00510