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 STLSOFT_INCL_STLSOFT_ERROR_HPP_ERROR_DESC
00049 #define STLSOFT_INCL_STLSOFT_ERROR_HPP_ERROR_DESC
00050
00051 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00052 # define STLSOFT_VER_STLSOFT_ERROR_HPP_ERROR_DESC_MAJOR 1
00053 # define STLSOFT_VER_STLSOFT_ERROR_HPP_ERROR_DESC_MINOR 2
00054 # define STLSOFT_VER_STLSOFT_ERROR_HPP_ERROR_DESC_REVISION 2
00055 # define STLSOFT_VER_STLSOFT_ERROR_HPP_ERROR_DESC_EDIT 21
00056 #endif
00057
00058
00059
00060
00061
00062 #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
00063 # include <stlsoft/stlsoft.h>
00064 #endif
00065 #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_ALLOCATOR_SELECTOR
00066 # include <stlsoft/memory/allocator_selector.hpp>
00067 #endif
00068 #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
00069 # include <stlsoft/memory/auto_buffer.hpp>
00070 #endif
00071 #ifndef STLSOFT_INCL_STLSOFT_STRING_HPP_CSTRING_FUNCTIONS
00072 # include <stlsoft/string/cstring_functions.hpp>
00073 #endif
00074 #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_STRING_H_FWD
00075 # include <stlsoft/shims/access/string/fwd.h>
00076 #endif
00077 #ifndef STLSOFT_INCL_STLSOFT_INTERNAL_H_SAFESTR
00078 # include <stlsoft/internal/safestr.h>
00079 #endif
00080
00081 #ifndef STLSOFT_INCL_H_STDLIB
00082 # define STLSOFT_INCL_H_STDLIB
00083 # include <stdlib.h>
00084 #endif
00085 #ifndef STLSOFT_INCL_H_STRING
00086 # define STLSOFT_INCL_H_STRING
00087 # include <string.h>
00088 #endif
00089 #ifndef STLSOFT_INCL_H_WCHAR
00090 # define STLSOFT_INCL_H_WCHAR
00091 # include <wchar.h>
00092 #endif
00093
00094 #ifdef STLSOFT_UNITTEST
00095 # include <errno.h>
00096 #endif
00097
00098
00099
00100
00101
00102 #if ( defined(STLSOFT_COMPILER_IS_MSVC) || \
00103 defined(STLSOFT_COMPILER_IS_INTEL)) && \
00104 _MSC_VER >= 1300
00105 # define STLSOFT_ERROR_DESC_wcserror ::_wcserror
00106 #endif
00107
00108 #if ( defined(STLSOFT_COMPILER_IS_MSVC) || \
00109 defined(STLSOFT_COMPILER_IS_INTEL)) && \
00110 _MSC_VER >= 1400
00111 # define STLSOFT_ERROR_DESC_wcserror_s ::_wcserror_s
00112 #endif
00113
00114 #ifdef STLSOFT_USING_SAFE_STR_FUNCTIONS
00115 # ifdef STLSOFT_ERROR_DESC_wcserror_s
00116 # define STLSOFT_ERROR_DESC_WIDE_STRING_SUPPORT_
00117 # endif
00118 #else
00119 # ifdef STLSOFT_ERROR_DESC_wcserror
00120 # define STLSOFT_ERROR_DESC_WIDE_STRING_SUPPORT_
00121 # endif
00122 #endif
00123
00124 #if !defined(STLSOFT_ERROR_DESC_wcserror_s) && \
00125 !defined(STLSOFT_ERROR_DESC_wcserror)
00126 # include <stlsoft/string/shim_string.hpp>
00127 # include <string>
00128 #endif
00129
00130
00131
00132
00133
00134 #ifndef _STLSOFT_NO_NAMESPACE
00135 namespace stlsoft
00136 {
00137 #endif
00138
00139
00140
00141
00142
00143 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00144
00145 template <ss_typename_param_k C>
00146 struct error_desc_traits;
00147
00148 STLSOFT_TEMPLATE_SPECIALISATION
00149 struct error_desc_traits<ss_char_a_t>
00150 {
00151 # ifdef STLSOFT_USING_SAFE_STR_FUNCTIONS
00152
00153 static int invoke_strerror_s_(ss_char_a_t* buff, size_t n, int code)
00154 {
00155 return ::strerror_s(buff, n, code);
00156 }
00157
00158 # else
00159
00160 static ss_char_a_t const* invoke_strerror_(int code, ss_char_a_t const*)
00161 {
00162 return ::strerror(code);
00163 }
00164
00165 # endif
00166 };
00167
00168 # ifdef STLSOFT_USING_SAFE_STR_FUNCTIONS
00169
00170 # ifdef STLSOFT_ERROR_DESC_wcserror_s
00171
00172 STLSOFT_TEMPLATE_SPECIALISATION
00173 struct error_desc_traits<ss_char_w_t>
00174 {
00175 static int invoke_strerror_s_(ss_char_w_t* buff, size_t n, int code)
00176 {
00177 return STLSOFT_ERROR_DESC_wcserror_s(buff, n, code);
00178 }
00179 };
00180
00181 # else
00182
00183 STLSOFT_TEMPLATE_SPECIALISATION
00184 struct error_desc_traits<ss_char_w_t>;
00185
00186 # endif
00187
00188 # else
00189
00190 # ifdef STLSOFT_ERROR_DESC_wcserror
00191
00192 STLSOFT_TEMPLATE_SPECIALISATION
00193 struct error_desc_traits<ss_char_w_t>
00194 {
00195 static ss_char_w_t const* invoke_strerror_(int code, ss_char_w_t const*)
00196 {
00197 return STLSOFT_ERROR_DESC_wcserror(code);
00198 }
00199 };
00200
00201 # else
00202
00203 STLSOFT_TEMPLATE_SPECIALISATION
00204 struct error_desc_traits<ss_char_w_t>
00205 {
00206 static basic_shim_string<ss_char_w_t, 64> invoke_strerror_(int code, ss_char_w_t const*)
00207 {
00208 typedef basic_shim_string<ss_char_w_t, 64> return_t;
00209
00210 std::string const s(::strerror(code));
00211 return_t ss(s.size());
00212 size_t const n = ::mbstowcs(ss.data(), s.data(), s.size());
00213
00214 if(size_t(-1) == n)
00215 {
00216 ss.swap(return_t(L"could not determine error"));
00217 }
00218 else
00219 {
00220 ;
00221 }
00222
00223 return ss;
00224 }
00225 };
00226
00227 # endif
00228
00229 # endif
00230
00231 #endif
00232
00233
00234
00235
00236
00269 template <ss_typename_param_k C>
00270 class basic_error_desc
00271 #if defined(STLSOFT_COMPILER_IS_DMC)
00272 : protected allocator_selector<C>::allocator_type
00273 #else
00274 : private allocator_selector<C>::allocator_type
00275 #endif
00276 {
00279 private:
00280 typedef ss_typename_type_k allocator_selector<C>::allocator_type parent_class_type;
00281 typedef ss_typename_type_k allocator_selector<C>::allocator_type allocator_type;
00282 public:
00284 typedef C char_type;
00286 typedef basic_error_desc<C> class_type;
00288 typedef int error_type;
00290 typedef ss_size_t size_type;
00291 private:
00292 typedef error_desc_traits<char_type> traits_type;
00294
00297 public:
00301 ss_explicit_k basic_error_desc(error_type error = errno);
00303 ~basic_error_desc() stlsoft_throw_0();
00305
00308 public:
00310 char_type const* get_description() const stlsoft_throw_0();
00312
00315 public:
00317 char_type const* c_str() const stlsoft_throw_0();
00319 size_type length() const stlsoft_throw_0();
00321 size_type size() const stlsoft_throw_0();
00323
00326 private:
00327 allocator_type& get_allocator_();
00329
00332 private:
00333 char_type* m_str;
00334 size_type m_length;
00336
00339 private:
00340 basic_error_desc(class_type const&);
00341 basic_error_desc& operator =(class_type const&);
00343 };
00344
00345
00350 typedef basic_error_desc<ss_char_a_t> error_desc_a;
00355 typedef basic_error_desc<ss_char_w_t> error_desc_w;
00360 typedef basic_error_desc<char> error_desc;
00361
00362
00363
00364
00365
00366 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00367
00368 template <ss_typename_param_k C>
00369 inline ss_typename_type_ret_k basic_error_desc<C>::allocator_type &basic_error_desc<C>::get_allocator_()
00370 {
00371 return *this;
00372 }
00373
00374 template <ss_typename_param_k C>
00375 inline basic_error_desc<C>::basic_error_desc(ss_typename_type_k basic_error_desc<C>::error_type error )
00376 #ifdef STLSOFT_USING_SAFE_STR_FUNCTIONS
00377 : m_length(0)
00378 {
00379 stlsoft::auto_buffer<char_type, 128, allocator_type> buff(128);
00380
00381 for(;;)
00382 {
00383
00384
00385
00386
00387
00388
00389 int n = traits_type::invoke_strerror_s_(&buff[0], buff.size() - 1, error);
00390
00391 buff[buff.size() - 1u] = '\0';
00392
00393 if(0 == n)
00394 {
00395 size_t cch = c_str_len(buff.data());
00396
00397 if(cch < buff.size() - 2u)
00398 {
00399 m_length = cch;
00400 buff.resize(cch + 1u);
00401 break;
00402 }
00403 }
00404
00405 if(!buff.resize(1u + buff.size() * 2u))
00406 {
00407 buff.resize(1u);
00408 break;
00409 }
00410 }
00411
00412 m_str = string_dup(buff.data(), m_length, get_allocator_());
00413 }
00414 #else
00415
00416
00417
00418
00419
00420
00421 : m_str(string_dup(static_cast<char_type const*>(traits_type::invoke_strerror_(error, static_cast<char_type const*>(0))), get_allocator_(), &m_length))
00422 {}
00423 #endif
00424
00425 template <ss_typename_param_k C>
00426 inline basic_error_desc<C>::~basic_error_desc() stlsoft_throw_0()
00427 {
00428 get_allocator_().deallocate(m_str, m_length);
00429 }
00430
00431 template <ss_typename_param_k C>
00432 inline ss_typename_type_ret_k basic_error_desc<C>::char_type const* basic_error_desc<C>::get_description() const stlsoft_throw_0()
00433 {
00434 static const char_type s_nullMessage[1] = { '\0' };
00435
00436 return (NULL != m_str) ? m_str : s_nullMessage;
00437 }
00438
00439 template <ss_typename_param_k C>
00440 inline ss_typename_type_ret_k basic_error_desc<C>::char_type const* basic_error_desc<C>::c_str() const stlsoft_throw_0()
00441 {
00442 return get_description();
00443 }
00444
00445 template <ss_typename_param_k C>
00446 inline ss_typename_type_ret_k basic_error_desc<C>::size_type basic_error_desc<C>::length() const stlsoft_throw_0()
00447 {
00448 return m_length;
00449 }
00450
00451 template <ss_typename_param_k C>
00452 inline ss_typename_type_ret_k basic_error_desc<C>::size_type basic_error_desc<C>::size() const stlsoft_throw_0()
00453 {
00454 return length();
00455 }
00456
00457 #endif
00458
00459
00460
00461
00462
00463 #ifndef STLSOFT_CF_TEMPLATE_SHIMS_NOT_SUPPORTED
00464
00469 template <ss_typename_param_k C>
00470 inline C const* c_str_ptr_null(stlsoft_ns_qual(basic_error_desc)<C> const& e)
00471 {
00472 return (0 != e.length()) ? e.c_str() : NULL;
00473 }
00474 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00475 inline ss_char_a_t const* c_str_ptr_null_a(stlsoft_ns_qual(basic_error_desc)<ss_char_a_t> const& e)
00476 {
00477 return (0 != e.length()) ? e.c_str() : NULL;
00478 }
00479 inline ss_char_w_t const* c_str_ptr_null_w(stlsoft_ns_qual(basic_error_desc)<ss_char_w_t> const& e)
00480 {
00481 return (0 != e.length()) ? e.c_str() : NULL;
00482 }
00483 #endif
00484
00489 template <ss_typename_param_k C>
00490 inline C const* c_str_ptr(stlsoft_ns_qual(basic_error_desc)<C> const& e)
00491 {
00492 return e.c_str();
00493 }
00494 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00495 inline ss_char_a_t const* c_str_ptr_a(stlsoft_ns_qual(basic_error_desc)<ss_char_a_t> const& e)
00496 {
00497 return e.c_str();
00498 }
00499 inline ss_char_w_t const* c_str_ptr_w(stlsoft_ns_qual(basic_error_desc)<ss_char_w_t> const& e)
00500 {
00501 return e.c_str();
00502 }
00503 #endif
00504
00509 template <ss_typename_param_k C>
00510 inline C const* c_str_data(stlsoft_ns_qual(basic_error_desc)<C> const& e)
00511 {
00512 return e.c_str();
00513 }
00514 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00515 inline ss_char_a_t const* c_str_data_a(stlsoft_ns_qual(basic_error_desc)<ss_char_a_t> const& e)
00516 {
00517 return e.c_str();
00518 }
00519 inline ss_char_w_t const* c_str_data_w(stlsoft_ns_qual(basic_error_desc)<ss_char_w_t> const& e)
00520 {
00521 return e.c_str();
00522 }
00523 #endif
00524
00529 template <ss_typename_param_k C>
00530 inline ss_size_t c_str_len(stlsoft_ns_qual(basic_error_desc)<C> const& e)
00531 {
00532 return e.length();
00533 }
00534
00535 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00536 inline ss_size_t c_str_len_a(stlsoft_ns_qual(basic_error_desc)<ss_char_a_t> const& e)
00537 {
00538 return e.length();
00539 }
00540 inline ss_size_t c_str_len_w(stlsoft_ns_qual(basic_error_desc)<ss_char_w_t> const& e)
00541 {
00542 return e.length();
00543 }
00544 #endif
00545
00546
00551 template <ss_typename_param_k C>
00552 inline C const* get_ptr(stlsoft_ns_qual(basic_error_desc)<C> const& e)
00553 {
00554 return e;
00555 }
00556
00557
00562 template< ss_typename_param_k S
00563 , ss_typename_param_k C
00564 >
00565 inline S& operator <<(S& s, stlsoft_ns_qual(basic_error_desc)<C> const& e)
00566 {
00567 s << e.get_description();
00568
00569 return s;
00570 }
00571
00572 #endif
00573
00575
00576
00577 #ifdef STLSOFT_UNITTEST
00578 # include "./unittest/error_desc_unittest_.h"
00579 #endif
00580
00581
00582
00583 #ifndef _STLSOFT_NO_NAMESPACE
00584 }
00585 #endif
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595 #if defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) && \
00596 STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION < STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1
00597
00598 # include <iosfwd>
00599
00600 #if 0
00601 template <ss_typename_param_k C>
00602 inline stlsoft_ns_qual_std(basic_ostream)<C>& operator <<(stlsoft_ns_qual_std(basic_ostream)<C> &stm, stlsoft_ns_qual(basic_error_desc)<C> const& desc)
00603 {
00604 return stm << desc.c_str();
00605 }
00606 #endif
00607
00608 #endif
00609
00610
00611
00612 #endif
00613
00614