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 0
00054 # define STLSOFT_VER_STLSOFT_ERROR_HPP_ERROR_DESC_REVISION 8
00055 # define STLSOFT_VER_STLSOFT_ERROR_HPP_ERROR_DESC_EDIT 19
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_STRING
00082 # define STLSOFT_INCL_H_STRING
00083 # include <string.h>
00084 #endif
00085
00086 #ifdef STLSOFT_UNITTEST
00087 # include <errno.h>
00088 #endif
00089
00090
00091
00092
00093
00094 #if ( defined(STLSOFT_COMPILER_IS_MSVC) || \
00095 defined(STLSOFT_COMPILER_IS_INTEL)) && \
00096 _MSC_VER >= 1300
00097 # define STLSOFT_ERROR_DESC_wcserror ::_wcserror
00098 #endif
00099
00100 #if ( defined(STLSOFT_COMPILER_IS_MSVC) || \
00101 defined(STLSOFT_COMPILER_IS_INTEL)) && \
00102 _MSC_VER >= 1400
00103 # define STLSOFT_ERROR_DESC_wcserror_s ::_wcserror_s
00104 #endif
00105
00106 #ifdef STLSOFT_USING_SAFE_STR_FUNCTIONS
00107 # ifdef STLSOFT_ERROR_DESC_wcserror_s
00108 # define STLSOFT_ERROR_DESC_WIDE_STRING_SUPPORT_
00109 # endif
00110 #else
00111 # ifdef STLSOFT_ERROR_DESC_wcserror
00112 # define STLSOFT_ERROR_DESC_WIDE_STRING_SUPPORT_
00113 # endif
00114 #endif
00115
00116
00117
00118
00119
00120 #ifndef _STLSOFT_NO_NAMESPACE
00121 namespace stlsoft
00122 {
00123 #endif
00124
00125
00126
00127
00128
00129 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00130
00131 template <ss_typename_param_k C>
00132 struct error_desc_traits;
00133
00134 STLSOFT_TEMPLATE_SPECIALISATION
00135 struct error_desc_traits<ss_char_a_t>
00136 {
00137 # ifdef STLSOFT_USING_SAFE_STR_FUNCTIONS
00138
00139 static int invoke_strerror_s_(ss_char_a_t* buff, size_t n, int code)
00140 {
00141 return ::strerror_s(buff, n, code);
00142 }
00143
00144 # else
00145
00146 static ss_char_a_t const* invoke_strerror_(int code, ss_char_a_t const*)
00147 {
00148 return ::strerror(code);
00149 }
00150
00151 # endif
00152 };
00153
00154 # ifdef STLSOFT_USING_SAFE_STR_FUNCTIONS
00155
00156 # ifdef STLSOFT_ERROR_DESC_wcserror_s
00157
00158 STLSOFT_TEMPLATE_SPECIALISATION
00159 struct error_desc_traits<ss_char_w_t>
00160 {
00161 static int invoke_strerror_s_(ss_char_w_t* buff, size_t n, int code)
00162 {
00163 return STLSOFT_ERROR_DESC_wcserror_s(buff, n, code);
00164 }
00165 };
00166
00167 # else
00168
00169 STLSOFT_TEMPLATE_SPECIALISATION
00170 struct error_desc_traits<ss_char_a_t>;
00171
00172 # endif
00173
00174 # else
00175
00176 # ifdef STLSOFT_ERROR_DESC_wcserror
00177
00178 STLSOFT_TEMPLATE_SPECIALISATION
00179 struct error_desc_traits<ss_char_w_t>
00180 {
00181 static ss_char_w_t const* invoke_strerror_(int code, ss_char_w_t const*)
00182 {
00183 return STLSOFT_ERROR_DESC_wcserror(code);
00184 }
00185 };
00186
00187 # else
00188
00189 STLSOFT_TEMPLATE_SPECIALISATION
00190 struct error_desc_traits<ss_char_w_t>;
00191
00192 # endif
00193
00194 # endif
00195
00196 #endif
00197
00198
00199
00200
00201
00234 template <ss_typename_param_k C>
00235 class basic_error_desc
00236 #if defined(STLSOFT_COMPILER_IS_DMC)
00237 : protected allocator_selector<C>::allocator_type
00238 #else
00239 : private allocator_selector<C>::allocator_type
00240 #endif
00241 {
00244 private:
00245 typedef ss_typename_type_k allocator_selector<C>::allocator_type parent_class_type;
00246 typedef ss_typename_type_k allocator_selector<C>::allocator_type allocator_type;
00247 public:
00249 typedef C char_type;
00251 typedef basic_error_desc<C> class_type;
00253 typedef int error_type;
00255 typedef ss_size_t size_type;
00256 private:
00257 typedef error_desc_traits<char_type> traits_type;
00259
00262 public:
00266 ss_explicit_k basic_error_desc(error_type error = errno);
00268 ~basic_error_desc() stlsoft_throw_0();
00270
00273 public:
00275 char_type const* get_description() const stlsoft_throw_0();
00277
00280 public:
00282 char_type const* c_str() const stlsoft_throw_0();
00284 size_type length() const stlsoft_throw_0();
00286 size_type size() const stlsoft_throw_0();
00288
00291 private:
00292 allocator_type& get_allocator_();
00294
00297 private:
00298 char_type* m_str;
00299 size_type m_length;
00301
00304 private:
00305 basic_error_desc(class_type const&);
00306 basic_error_desc& operator =(class_type const&);
00308 };
00309
00310
00315 typedef basic_error_desc<ss_char_a_t> error_desc_a;
00320 typedef basic_error_desc<ss_char_w_t> error_desc_w;
00325 typedef basic_error_desc<char> error_desc;
00326
00327
00328
00329
00330
00331 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00332
00333 template <ss_typename_param_k C>
00334 inline ss_typename_type_ret_k basic_error_desc<C>::allocator_type &basic_error_desc<C>::get_allocator_()
00335 {
00336 return *this;
00337 }
00338
00339 template <ss_typename_param_k C>
00340 inline basic_error_desc<C>::basic_error_desc(ss_typename_type_k basic_error_desc<C>::error_type error )
00341 #ifdef STLSOFT_USING_SAFE_STR_FUNCTIONS
00342 : m_length(0)
00343 {
00344 stlsoft::auto_buffer<char_type, 128, allocator_type> buff(128);
00345
00346 for(;;)
00347 {
00348
00349
00350
00351
00352
00353
00354 int n = traits_type::invoke_strerror_s_(&buff[0], buff.size() - 1, error);
00355
00356 buff[buff.size() - 1u] = '\0';
00357
00358 if(0 == n)
00359 {
00360 size_t cch = c_str_len(buff.data());
00361
00362 if(cch < buff.size() - 2u)
00363 {
00364 m_length = cch;
00365 buff.resize(cch + 1u);
00366 break;
00367 }
00368 }
00369
00370 if(!buff.resize(1u + buff.size() * 2u))
00371 {
00372 buff.resize(1u);
00373 break;
00374 }
00375 }
00376
00377 m_str = string_dup(buff.data(), m_length, get_allocator_());
00378 }
00379 #else
00380
00381
00382
00383
00384
00385
00386 : m_str(string_dup(traits_type::invoke_strerror_(error, static_cast<char_type const*>(0)), get_allocator_(), &m_length))
00387 {}
00388 #endif
00389
00390 template <ss_typename_param_k C>
00391 inline basic_error_desc<C>::~basic_error_desc() stlsoft_throw_0()
00392 {
00393 get_allocator_().deallocate(m_str, m_length);
00394 }
00395
00396 template <ss_typename_param_k C>
00397 inline ss_typename_type_ret_k basic_error_desc<C>::char_type const* basic_error_desc<C>::get_description() const stlsoft_throw_0()
00398 {
00399 static const char_type s_nullMessage[1] = { '\0' };
00400
00401 return (NULL != m_str) ? m_str : s_nullMessage;
00402 }
00403
00404 template <ss_typename_param_k C>
00405 inline ss_typename_type_ret_k basic_error_desc<C>::char_type const* basic_error_desc<C>::c_str() const stlsoft_throw_0()
00406 {
00407 return get_description();
00408 }
00409
00410 template <ss_typename_param_k C>
00411 inline ss_typename_type_ret_k basic_error_desc<C>::size_type basic_error_desc<C>::length() const stlsoft_throw_0()
00412 {
00413 return m_length;
00414 }
00415
00416 template <ss_typename_param_k C>
00417 inline ss_typename_type_ret_k basic_error_desc<C>::size_type basic_error_desc<C>::size() const stlsoft_throw_0()
00418 {
00419 return length();
00420 }
00421
00422 #endif
00423
00424
00425
00426
00427
00428 #ifndef STLSOFT_CF_TEMPLATE_SHIMS_NOT_SUPPORTED
00429
00434 template <ss_typename_param_k C>
00435 inline C const* c_str_ptr_null(stlsoft_ns_qual(basic_error_desc)<C> const& e)
00436 {
00437 return (0 != e.length()) ? e.c_str() : NULL;
00438 }
00439 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00440 inline ss_char_a_t const* c_str_ptr_null_a(stlsoft_ns_qual(basic_error_desc)<ss_char_a_t> const& e)
00441 {
00442 return (0 != e.length()) ? e.c_str() : NULL;
00443 }
00444 inline ss_char_w_t const* c_str_ptr_null_w(stlsoft_ns_qual(basic_error_desc)<ss_char_w_t> const& e)
00445 {
00446 return (0 != e.length()) ? e.c_str() : NULL;
00447 }
00448 #endif
00449
00454 template <ss_typename_param_k C>
00455 inline C const* c_str_ptr(stlsoft_ns_qual(basic_error_desc)<C> const& e)
00456 {
00457 return e.c_str();
00458 }
00459 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00460 inline ss_char_a_t const* c_str_ptr_a(stlsoft_ns_qual(basic_error_desc)<ss_char_a_t> const& e)
00461 {
00462 return e.c_str();
00463 }
00464 inline ss_char_w_t const* c_str_ptr_w(stlsoft_ns_qual(basic_error_desc)<ss_char_w_t> const& e)
00465 {
00466 return e.c_str();
00467 }
00468 #endif
00469
00474 template <ss_typename_param_k C>
00475 inline C const* c_str_data(stlsoft_ns_qual(basic_error_desc)<C> const& e)
00476 {
00477 return e.c_str();
00478 }
00479 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00480 inline ss_char_a_t const* c_str_data_a(stlsoft_ns_qual(basic_error_desc)<ss_char_a_t> const& e)
00481 {
00482 return e.c_str();
00483 }
00484 inline ss_char_w_t const* c_str_data_w(stlsoft_ns_qual(basic_error_desc)<ss_char_w_t> const& e)
00485 {
00486 return e.c_str();
00487 }
00488 #endif
00489
00494 template <ss_typename_param_k C>
00495 inline ss_size_t c_str_len(stlsoft_ns_qual(basic_error_desc)<C> const& e)
00496 {
00497 return e.length();
00498 }
00499
00500 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00501 inline ss_size_t c_str_len_a(stlsoft_ns_qual(basic_error_desc)<ss_char_a_t> const& e)
00502 {
00503 return e.length();
00504 }
00505 inline ss_size_t c_str_len_w(stlsoft_ns_qual(basic_error_desc)<ss_char_w_t> const& e)
00506 {
00507 return e.length();
00508 }
00509 #endif
00510
00511
00516 template <ss_typename_param_k C>
00517 inline C const* get_ptr(stlsoft_ns_qual(basic_error_desc)<C> const& e)
00518 {
00519 return e;
00520 }
00521
00522
00527 template< ss_typename_param_k S
00528 , ss_typename_param_k C
00529 >
00530 inline S& operator <<(S& s, stlsoft_ns_qual(basic_error_desc)<C> const& e)
00531 {
00532 s << e.get_description();
00533
00534 return s;
00535 }
00536
00537 #endif
00538
00540
00541
00542 #ifdef STLSOFT_UNITTEST
00543 # include "./unittest/error_desc_unittest_.h"
00544 #endif
00545
00546
00547
00548 #ifndef _STLSOFT_NO_NAMESPACE
00549 }
00550 #endif
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 #if defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) && \
00561 STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION < STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1
00562
00563 # include <iosfwd>
00564
00565 #if 0
00566 template <ss_typename_param_k C>
00567 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)
00568 {
00569 return stm << desc.c_str();
00570 }
00571 #endif
00572
00573 #endif
00574
00575
00576
00577 #endif
00578
00579