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
00048 #ifndef WINSTL_INCL_WINSTL_ERROR_HPP_ERROR_DESC
00049 #define WINSTL_INCL_WINSTL_ERROR_HPP_ERROR_DESC
00050
00051 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00052 # define WINSTL_VER_WINSTL_ERROR_HPP_ERROR_DESC_MAJOR 4
00053 # define WINSTL_VER_WINSTL_ERROR_HPP_ERROR_DESC_MINOR 5
00054 # define WINSTL_VER_WINSTL_ERROR_HPP_ERROR_DESC_REVISION 2
00055 # define WINSTL_VER_WINSTL_ERROR_HPP_ERROR_DESC_EDIT 77
00056 #endif
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 #ifndef WINSTL_INCL_WINSTL_H_WINSTL
00071 # include <winstl/winstl.h>
00072 #endif
00073 #ifndef WINSTL_INCL_WINSTL_ERROR_H_ERROR_FUNCTIONS
00074 # include <winstl/error/error_functions.h>
00075 #endif
00076 #ifndef WINSTL_INCL_WINSTL_SYSTEM_HPP_SYSTEM_TRAITS
00077 # include <winstl/system/system_traits.hpp>
00078 #endif
00079 #ifndef WINSTL_INCL_WINSTL_SHIMS_ACCESS_HPP_STRING
00080 # include <winstl/shims/access/string.hpp>
00081 #endif
00082 #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_CHAR_ALT_TRAITS
00083 # include <stlsoft/string/char_alt_traits.hpp>
00084 #endif
00085
00086
00087
00088
00089
00090 #ifndef _WINSTL_NO_NAMESPACE
00091 # if defined(_STLSOFT_NO_NAMESPACE) || \
00092 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00093
00094 namespace winstl
00095 {
00096 # else
00097
00098
00099 namespace stlsoft
00100 {
00101
00102 namespace winstl_project
00103 {
00104
00105 # endif
00106 #endif
00107
00108
00109
00110
00111
00145 template< ss_typename_param_k C
00146 , ss_typename_param_k T = system_traits<C>
00147 >
00148 class basic_error_desc
00149 {
00152 private:
00153 typedef
00154 #if !defined(STLSOFT_COMPILER_IS_BORLAND)
00155 ss_typename_type_k
00156 #endif
00157 stlsoft_ns_qual(char_alt_traits)<C>::alt_char_type alt_char_type;
00158 public:
00160 typedef C char_type;
00162 typedef T traits_type;
00164 typedef basic_error_desc<C, T> class_type;
00166 typedef ws_dword_t error_type;
00168 typedef ws_size_t size_type;
00170 typedef ws_bool_t bool_type;
00172
00175 public:
00183 ss_explicit_k basic_error_desc(error_type error = GetLastError(), char_type const* modulePath = NULL);
00184
00185 private:
00188 basic_error_desc(error_type error, alt_char_type const* modulePath);
00189 public:
00190
00198 basic_error_desc(HRESULT hr, char_type const* modulePath = NULL);
00199
00200
00201 private:
00204 basic_error_desc(HRESULT error, alt_char_type const* modulePath);
00205 public:
00206
00217 template <ss_typename_param_k S>
00218 basic_error_desc(error_type error, S const& modulePaths)
00219 : m_length(0)
00220 , m_message(NULL)
00221 {
00222 ss_typename_type_k S::const_iterator b = modulePaths.begin();
00223 ss_typename_type_k S::const_iterator e = modulePaths.end();
00224
00225 for(; b != e && NULL == (m_message = find_message_(error, stlsoft_ns_qual(c_str_ptr)(*b), &m_length)); ++b)
00226 {}
00227
00228 if(NULL == m_message)
00229 {
00230 m_message = find_message_(error, NULL, &m_length);
00231 }
00232 }
00234 ~basic_error_desc() stlsoft_throw_0();
00235
00236 #if defined(STLSOFT_COMPILER_IS_GCC) || \
00237 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00243 basic_error_desc(class_type& rhs) stlsoft_throw_0();
00244 #endif
00246
00249 public:
00251 char_type const* get_description() const;
00253
00256 public:
00258 char_type const* c_str() const;
00259 #if !defined(WINSTL_ERROR_DESC_NO_IMPLICIT_CONVERSION)
00263 operator char_type const* () const;
00264 #endif
00266 size_type length() const stlsoft_throw_0();
00268 size_type size() const stlsoft_throw_0();
00270 bool_type empty() const stlsoft_throw_0();
00272
00275 private:
00276 char_type *find_message_(error_type error, char_type const* modulePath, size_type *length);
00278
00281 private:
00282 size_type m_length;
00283 char_type *m_message;
00285
00288 private:
00289 #if !defined(STLSOFT_COMPILER_IS_GCC)
00290 basic_error_desc(class_type const&);
00291 #endif
00292 basic_error_desc& operator =(class_type const&);
00294 };
00295
00296
00301 typedef basic_error_desc<ws_char_a_t> error_desc_a;
00306 typedef basic_error_desc<ws_char_w_t> error_desc_w;
00311 typedef basic_error_desc<TCHAR> error_desc;
00312
00313
00314
00315
00316
00317 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00318
00319 template< ss_typename_param_k C
00320 , ss_typename_param_k T
00321 >
00322 inline ss_typename_type_ret_k basic_error_desc<C, T>::char_type *basic_error_desc<C, T>::find_message_(ss_typename_type_k basic_error_desc<C, T>::error_type error, ss_typename_type_k basic_error_desc<C, T>::char_type const* modulePath, ss_typename_type_k basic_error_desc<C, T>::size_type *length)
00323 {
00324 WINSTL_ASSERT(NULL != length);
00325 WINSTL_MESSAGE_ASSERT("Constructor initialisation order error", 0 == *length);
00326
00327 ws_dword_t cch = 0;
00328 char_type *message = NULL;
00329
00330 STLSOFT_SUPPRESS_UNUSED(message);
00331
00332 if(NULL != modulePath)
00333 {
00334 HINSTANCE hinstSource = traits_type::load_library(modulePath);
00335
00336 if(NULL != hinstSource)
00337 {
00338 cch = format_message(error, hinstSource, &message);
00339
00340 traits_type::free_library(hinstSource);
00341 }
00342 }
00343 else
00344 {
00345 cch = format_message(error, NULL, &message);
00346 }
00347
00348 if(0 == cch)
00349 {
00350 message = NULL;
00351 }
00352
00353 *length = cch;
00354
00355 return message;
00356 }
00357
00358
00359 template< ss_typename_param_k C
00360 , ss_typename_param_k T
00361 >
00362 inline basic_error_desc<C, T>::basic_error_desc(ss_typename_type_k basic_error_desc<C, T>::error_type error , char_type const* modulePath )
00363 : m_length(0)
00364 , m_message(find_message_(error, modulePath, &m_length))
00365 {
00366 if(NULL == m_message)
00367 {
00368 if(0 == format_message(error, NULL, &m_message))
00369 {
00370 m_message = NULL;
00371 }
00372 }
00373 }
00374
00375 template< ss_typename_param_k C
00376 , ss_typename_param_k T
00377 >
00378 inline basic_error_desc<C, T>::basic_error_desc(HRESULT hr, char_type const* modulePath )
00379 : m_length(0)
00380 , m_message(find_message_(static_cast<DWORD>(hr), modulePath, &m_length))
00381 {
00382 if(NULL == m_message)
00383 {
00384 if(0 == format_message(static_cast<DWORD>(hr), NULL, &m_message))
00385 {
00386 m_message = NULL;
00387 }
00388 }
00389 }
00390
00391 template< ss_typename_param_k C
00392 , ss_typename_param_k T
00393 >
00394 inline basic_error_desc<C, T>::~basic_error_desc() stlsoft_throw_0()
00395 {
00396 #ifdef STLSOFT_CF_USE_RAW_OFFSETOF_IN_STATIC_ASSERT
00397 STLSOFT_STATIC_ASSERT(STLSOFT_RAW_OFFSETOF(class_type, m_length) < STLSOFT_RAW_OFFSETOF(class_type, m_message));
00398 #endif
00399
00400 if(m_message != NULL)
00401 {
00402 ::LocalFree(m_message);
00403 }
00404 }
00405
00406 #if defined(STLSOFT_COMPILER_IS_GCC)
00407 template< ss_typename_param_k C
00408 , ss_typename_param_k T
00409 >
00410 inline basic_error_desc<C, T>::basic_error_desc(ss_typename_type_k basic_error_desc<C, T>::class_type& rhs) stlsoft_throw_0()
00411 {
00412 m_length = rhs.m_length;
00413 rhs.m_length = 0;
00414 m_message = rhs.m_message;
00415 rhs.m_message = NULL;
00416 }
00417 #endif
00418
00419 template< ss_typename_param_k C
00420 , ss_typename_param_k T
00421 >
00422 inline ss_typename_type_ret_k basic_error_desc<C, T>::char_type const* basic_error_desc<C, T>::get_description() const
00423 {
00424 static const char_type s_nullMessage[1] = { '\0' };
00425
00426 return (NULL != m_message) ? m_message : s_nullMessage;
00427 }
00428
00429 template< ss_typename_param_k C
00430 , ss_typename_param_k T
00431 >
00432 inline ss_typename_type_ret_k basic_error_desc<C, T>::char_type const* basic_error_desc<C, T>::c_str() const
00433 {
00434 return get_description();
00435 }
00436
00437 #if !defined(WINSTL_ERROR_DESC_NO_IMPLICIT_CONVERSION)
00438 template< ss_typename_param_k C
00439 , ss_typename_param_k T
00440 >
00441 #if defined(STLSOFT_COMPILER_IS_GCC)
00442 inline basic_error_desc<C, T>::operator C const* () const
00443 #else
00444 inline basic_error_desc<C, T>::operator ss_typename_type_k basic_error_desc<C, T>::char_type const* () const
00445 #endif
00446 {
00447 return get_description();
00448 }
00449 #endif
00450
00451 template< ss_typename_param_k C
00452 , ss_typename_param_k T
00453 >
00454 inline ss_typename_type_ret_k basic_error_desc<C, T>::size_type basic_error_desc<C, T>::length() const stlsoft_throw_0()
00455 {
00456 return m_length;
00457 }
00458
00459 template< ss_typename_param_k C
00460 , ss_typename_param_k T
00461 >
00462 inline ss_typename_type_ret_k basic_error_desc<C, T>::size_type basic_error_desc<C, T>::size() const stlsoft_throw_0()
00463 {
00464 return length();
00465 }
00466
00467 template< ss_typename_param_k C
00468 , ss_typename_param_k T
00469 >
00470 inline ss_typename_type_ret_k basic_error_desc<C, T>::bool_type basic_error_desc<C, T>::empty() const stlsoft_throw_0()
00471 {
00472 return 0 == length();
00473 }
00474
00475 #endif
00476
00477
00478
00479
00480
00481 #ifndef STLSOFT_CF_TEMPLATE_SHIMS_NOT_SUPPORTED
00482
00487 template< ss_typename_param_k C
00488 , ss_typename_param_k T
00489 >
00490 inline C const* c_str_ptr_null(winstl_ns_qual(basic_error_desc)<C, T> const& e)
00491 {
00492 C const* p = e;
00493
00494 return ('\0' != *e) ? p : NULL;
00495 }
00496 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00497 template <ss_typename_param_k T>
00498 inline ws_char_a_t const* c_str_ptr_null_a(winstl_ns_qual(basic_error_desc)<ws_char_a_t, T> const& e)
00499 {
00500 ws_char_a_t const* p = e;
00501
00502 return ('\0' != *e) ? p : NULL;
00503 }
00504 template <ss_typename_param_k T>
00505 inline ws_char_w_t const* c_str_ptr_null_w(winstl_ns_qual(basic_error_desc)<ws_char_w_t, T> const& e)
00506 {
00507 ws_char_w_t const* p = e;
00508
00509 return (L'\0' != *e) ? p : NULL;
00510 }
00511 #endif
00512
00517 template< ss_typename_param_k C
00518 , ss_typename_param_k T
00519 >
00520 inline C const* c_str_ptr(winstl_ns_qual(basic_error_desc)<C, T> const& e)
00521 {
00522 return e.c_str();
00523 }
00524 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00525 template <ss_typename_param_k T>
00526 inline ws_char_a_t const* c_str_ptr_a(winstl_ns_qual(basic_error_desc)<ws_char_a_t, T> const& e)
00527 {
00528 return e.c_str();
00529 }
00530 template <ss_typename_param_k T>
00531 inline ws_char_w_t const* c_str_ptr_w(winstl_ns_qual(basic_error_desc)<ws_char_w_t, T> const& e)
00532 {
00533 return e.c_str();
00534 }
00535 #endif
00536
00541 template< ss_typename_param_k C
00542 , ss_typename_param_k T
00543 >
00544 inline C const* c_str_data(winstl_ns_qual(basic_error_desc)<C, T> const& e)
00545 {
00546 return e.c_str();
00547 }
00548 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00549 template <ss_typename_param_k T>
00550 inline ws_char_a_t const* c_str_data_a(winstl_ns_qual(basic_error_desc)<ws_char_a_t, T> const& e)
00551 {
00552 return e.c_str();
00553 }
00554 template <ss_typename_param_k T>
00555 inline ws_char_w_t const* c_str_data_w(winstl_ns_qual(basic_error_desc)<ws_char_w_t, T> const& e)
00556 {
00557 return e.c_str();
00558 }
00559 #endif
00560
00565 template< ss_typename_param_k C
00566 , ss_typename_param_k T
00567 >
00568 inline ws_size_t c_str_len(winstl_ns_qual(basic_error_desc)<C, T> const& e)
00569 {
00570 return e.length();
00571 }
00572
00573 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00574 template< ss_typename_param_k T
00575 >
00576 inline ws_size_t c_str_len_a(winstl_ns_qual(basic_error_desc)<ws_char_a_t, T> const& e)
00577 {
00578 return e.length();
00579 }
00580 template< ss_typename_param_k T
00581 >
00582 inline ws_size_t c_str_len_w(winstl_ns_qual(basic_error_desc)<ws_char_w_t, T> const& e)
00583 {
00584 return e.length();
00585 }
00586 #endif
00587
00588
00593 template< ss_typename_param_k C
00594 , ss_typename_param_k T
00595 >
00596 inline C const* get_ptr(winstl_ns_qual(basic_error_desc)<C, T> const& e)
00597 {
00598 return e;
00599 }
00600
00601
00606 template< ss_typename_param_k S
00607 , ss_typename_param_k C
00608 , ss_typename_param_k T
00609 >
00610 inline S& operator <<(S& s, winstl_ns_qual(basic_error_desc)<C, T> const& e)
00611 {
00612 s << e.get_description();
00613
00614 return s;
00615 }
00616
00617 #endif
00618
00620
00621
00622 #ifdef STLSOFT_UNITTEST
00623 # include "./unittest/error_desc_unittest_.h"
00624 #endif
00625
00626
00627
00628 #ifndef _WINSTL_NO_NAMESPACE
00629 # if defined(_STLSOFT_NO_NAMESPACE) || \
00630 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00631 }
00632 # else
00633 }
00634 }
00635 # endif
00636 #endif
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646 #ifndef _WINSTL_NO_NAMESPACE
00647 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00648 !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00649 namespace stlsoft
00650 {
00651 # else
00652
00653 # endif
00654
00655 using ::winstl::c_str_data;
00656 using ::winstl::c_str_data_a;
00657 using ::winstl::c_str_data_w;
00658
00659 using ::winstl::c_str_len;
00660 using ::winstl::c_str_len_a;
00661 using ::winstl::c_str_len_w;
00662
00663 using ::winstl::c_str_ptr;
00664 using ::winstl::c_str_ptr_a;
00665 using ::winstl::c_str_ptr_w;
00666
00667 using ::winstl::c_str_ptr_null;
00668 using ::winstl::c_str_ptr_null_a;
00669 using ::winstl::c_str_ptr_null_w;
00670
00671 using ::winstl::get_ptr;
00672
00673 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00674 !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00675 }
00676 # else
00677
00678 # endif
00679 #endif
00680
00681
00682
00683 #endif
00684
00685