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