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_CONVERSION_HPP_CHAR_CONVERSIONS
00049 #define WINSTL_INCL_WINSTL_CONVERSION_HPP_CHAR_CONVERSIONS
00050
00051 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00052 # define WINSTL_VER_WINSTL_CONVERSION_HPP_CHAR_CONVERSIONS_MAJOR 5
00053 # define WINSTL_VER_WINSTL_CONVERSION_HPP_CHAR_CONVERSIONS_MINOR 3
00054 # define WINSTL_VER_WINSTL_CONVERSION_HPP_CHAR_CONVERSIONS_REVISION 1
00055 # define WINSTL_VER_WINSTL_CONVERSION_HPP_CHAR_CONVERSIONS_EDIT 89
00056 #endif
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 #ifndef WINSTL_INCL_WINSTL_H_WINSTL
00074 # include <winstl/winstl.h>
00075 #endif
00076
00077 #if defined(STLSOFT_COMPILER_IS_GCC) && \
00078 __GNUC__ < 3
00079 # error winstl/conversion/char_conversions.hpp is not compatible with GNU C++ prior to 3.0
00080 #endif
00081 #if defined(STLSOFT_COMPILER_IS_MSVC) && \
00082 _MSC_VER < 1100
00083 # error winstl/conversion/char_conversions.hpp is not compatible with Visual C++ 5.0 or earlier
00084 #endif
00085
00086 #ifndef WINSTL_INCL_WINSTL_MEMORY_HPP_PROCESSHEAP_ALLOCATOR
00087 # include <winstl/memory/processheap_allocator.hpp>
00088 #endif
00089 #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING
00090 # include <stlsoft/shims/access/string.hpp>
00091 #endif
00092 #ifndef WINSTL_INCL_WINSTL_SHIMS_ACCESS_HPP_STRING
00093 # include <winstl/shims/access/string.hpp>
00094 #endif
00095 #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
00096 # include <stlsoft/memory/auto_buffer.hpp>
00097 #endif
00098 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00099 # ifndef WINSTL_INCL_WINSTL_ERROR_HPP_CONVERSION_ERROR
00100 # include <winstl/error/conversion_error.hpp>
00101 # endif
00102 # include <errno.h>
00103 #endif
00104
00105 #ifdef STLSOFT_UNITTEST
00106 # include <wchar.h>
00107 #endif
00108
00109
00110
00111 #ifndef _WINSTL_NO_NAMESPACE
00112 # if defined(_STLSOFT_NO_NAMESPACE) || \
00113 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00114
00115 namespace winstl
00116 {
00117 # else
00118
00119
00120 namespace stlsoft
00121 {
00122
00123 namespace winstl_project
00124 {
00125
00126 # endif
00127 #endif
00128
00129
00130
00131
00132
00138 template <ws_size_t CCH>
00139 class multibyte2wide
00140 : private auto_buffer_old<ws_char_w_t, processheap_allocator<ws_char_w_t>, CCH>
00141 {
00144 private:
00145 typedef auto_buffer_old<ws_char_w_t, processheap_allocator<ws_char_w_t>, CCH> parent_class_type;
00146 public:
00148 typedef ws_char_w_t char_type;
00150 typedef ws_char_a_t alt_char_type;
00152 typedef ss_typename_type_k parent_class_type::size_type size_type;
00154 typedef ss_typename_type_k parent_class_type::pointer pointer;
00156
00159 public:
00160 #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00161 template <ss_typename_param_k S>
00162 ss_explicit_k multibyte2wide(S const& s)
00163 #else
00164 ss_explicit_k multibyte2wide(alt_char_type const* s)
00165 #endif // STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00166 : parent_class_type(stlsoft_ns_qual(c_str_len)(s) + 1)
00167 {
00168 prepare_(stlsoft_ns_qual(c_str_ptr_a)(s));
00169 }
00170
00171 #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00172 template <ss_typename_param_k S>
00173 multibyte2wide(S const& s, size_type cch)
00174 #else
00175 multibyte2wide(alt_char_type const* s, size_type cch)
00176 #endif // STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00177 : parent_class_type(cch + 1)
00178 {
00179 prepare_(stlsoft_ns_qual(c_str_ptr_a)(s));
00180 }
00181
00182 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00184
00187 private:
00188 void prepare_(alt_char_type const* s)
00189 {
00190 const size_type size = parent_class_type::size();
00191 const pointer data = parent_class_type::data();
00192
00193
00194
00195 if(0 == size)
00196 {
00197
00198
00199 data[0] = '\0';
00200 }
00201 else
00202 {
00203
00204
00205 if(0 == ::MultiByteToWideChar(0, 0, s, static_cast<int>(size), data, static_cast<int>(size)))
00206 {
00207 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00208 STLSOFT_THROW_X(conversion_error("failed to convert multibyte string to wide string", ::GetLastError()));
00209 #else
00210 data[0] = '\0';
00211 #endif
00212 }
00213 else
00214 {
00215 data[size - 1] = '\0';
00216 }
00217 }
00218 }
00220
00223 public:
00224 char_type const* c_str() const
00225 {
00226 return parent_class_type::data();
00227 }
00228
00229 size_type size() const
00230 {
00231 size_type n = parent_class_type::size();
00232
00233 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00234 WINSTL_ASSERT(0 != n);
00235 #else
00236 if(0 == n)
00237 {
00238 return 0;
00239 }
00240 #endif
00241
00242 return n - 1;
00243 }
00245
00248 public:
00249 operator char_type const* () const
00250 {
00251 return parent_class_type::data();
00252 }
00254
00257 private:
00258 multibyte2wide(multibyte2wide const&);
00259 multibyte2wide& operator =(multibyte2wide const&);
00260
00261 #endif
00263 };
00264
00270 template <ws_size_t CCH>
00271 class wide2multibyte
00272 : private auto_buffer_old<ws_char_a_t, processheap_allocator<ws_char_a_t>, CCH>
00273 {
00276 private:
00277 typedef auto_buffer_old<ws_char_a_t, processheap_allocator<ws_char_a_t>, CCH> parent_class_type;
00278 public:
00280 typedef ws_char_a_t char_type;
00282 typedef ws_char_w_t alt_char_type;
00284 typedef ss_typename_type_k parent_class_type::size_type size_type;
00286 typedef ss_typename_type_k parent_class_type::pointer pointer;
00288
00291 public:
00292 #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00293 template <ss_typename_param_k S>
00294 ss_explicit_k wide2multibyte(S const& s)
00295 #else
00296 ss_explicit_k wide2multibyte(alt_char_type const* s)
00297 #endif // STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00298 : parent_class_type(stlsoft_ns_qual(c_str_len)(s) + 1)
00299 {
00300 prepare_(stlsoft_ns_qual(c_str_ptr_w)(s));
00301 }
00302
00303 #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00304 template <ss_typename_param_k S>
00305 ss_explicit_k wide2multibyte(S const& s, size_type cch)
00306 #else
00307 ss_explicit_k wide2multibyte(alt_char_type const* s, size_type cch)
00308 #endif // STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00309 : parent_class_type(cch + 1)
00310 {
00311 prepare_(stlsoft_ns_qual(c_str_ptr_w)(s));
00312 }
00314
00315 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00316
00319 private:
00320 void prepare_(alt_char_type const* s)
00321 {
00322 const size_type size = parent_class_type::size();
00323 const pointer data = parent_class_type::data();
00324
00325
00326
00327 if(0 == size)
00328 {
00329
00330
00331 data[0] = '\0';
00332 }
00333 else
00334 {
00335
00336
00337 if(0 == ::WideCharToMultiByte(0, 0, s, static_cast<int>(size), data, static_cast<int>(size), NULL, NULL))
00338 {
00339 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00340 STLSOFT_THROW_X(conversion_error("failed to convert multibyte string to wide string", ::GetLastError()));
00341 #else
00342 data[0] = '\0';
00343 #endif
00344 }
00345 else
00346 {
00347 data[size - 1] = '\0';
00348 }
00349 }
00350 }
00352
00355 public:
00356 char_type const* c_str() const
00357 {
00358 return parent_class_type::data();
00359 }
00360
00361 size_type size() const
00362 {
00363 size_type n = parent_class_type::size();
00364
00365 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00366 WINSTL_ASSERT(0 != n);
00367 #else
00368 if(0 == n)
00369 {
00370 return 0;
00371 }
00372 #endif
00373
00374 return n - 1;
00375 }
00377
00380 public:
00381 operator char_type const* () const
00382 {
00383 return parent_class_type::data();
00384 }
00386
00387
00388 private:
00389 wide2multibyte(wide2multibyte const&);
00390 wide2multibyte& operator =(wide2multibyte const&);
00391 #endif
00392 };
00393
00394 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00395 template <ss_typename_param_k C>
00396 class encoding2encoding
00397 {
00398 public:
00399 encoding2encoding(C const* s)
00400 : m_s(s)
00401 {}
00402 encoding2encoding(C *s)
00403 : m_s(s)
00404 {}
00405 template <ss_typename_param_k S>
00406 encoding2encoding(S const& s)
00407 : m_s(s.c_str())
00408 {}
00409
00410 public:
00411 C const* c_str() const
00412 {
00413 return m_s;
00414 }
00415 operator C const* () const
00416 {
00417 return m_s;
00418 }
00419
00420 private:
00421 C const* m_s;
00422 };
00423 #endif
00424
00425
00426
00431 typedef multibyte2wide<256> m2w;
00436 typedef wide2multibyte<256> w2m;
00437
00444 typedef multibyte2wide<256> a2w;
00451 typedef wide2multibyte<256> w2a;
00452
00453 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00454
00455 # if defined(UNICODE)
00456 typedef encoding2encoding<ws_char_w_t> t2w;
00457 typedef encoding2encoding<ws_char_w_t> w2t;
00458 typedef w2m t2m;
00459 typedef m2w m2t;
00460 typedef w2a t2a;
00461 typedef a2w a2t;
00462 # else
00463 typedef encoding2encoding<ws_char_a_t> t2a;
00464 typedef encoding2encoding<ws_char_a_t> a2t;
00465 typedef m2w t2w;
00466 typedef w2m w2t;
00467 typedef a2w t2w;
00468 typedef w2a w2t;
00469 # endif
00470
00471 #endif
00472
00473
00474
00475
00476
00481 template< ws_size_t CCH
00482 >
00483 inline ws_char_w_t const* c_str_ptr_null(winstl_ns_qual(multibyte2wide)<CCH> const& b)
00484 {
00485 return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
00486 }
00487
00488 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00489
00490 template< ws_size_t CCH
00491 >
00492 inline ws_char_w_t const* c_str_ptr_null_w(winstl_ns_qual(multibyte2wide)<CCH> const& b)
00493 {
00494 return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
00495 }
00496
00497 #endif
00498
00499
00504 template< ws_size_t CCH
00505 >
00506 inline ws_char_w_t const* c_str_ptr(winstl_ns_qual(multibyte2wide)<CCH> const& b)
00507 {
00508 return b.c_str();
00509 }
00510
00511 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00512
00513 template< ws_size_t CCH
00514 >
00515 inline ws_char_w_t const* c_str_ptr_w(winstl_ns_qual(multibyte2wide)<CCH> const& b)
00516 {
00517 return b.c_str();
00518 }
00519
00520 #endif
00521
00526 template< ws_size_t CCH
00527 >
00528 inline ws_char_w_t const* c_str_data(winstl_ns_qual(multibyte2wide)<CCH> const& b)
00529 {
00530 return b.c_str();
00531 }
00532
00533 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00534
00535 template< ws_size_t CCH
00536 >
00537 inline ws_char_w_t const* c_str_data_w(winstl_ns_qual(multibyte2wide)<CCH> const& b)
00538 {
00539 return b.c_str();
00540 }
00541
00542 #endif
00543
00548 template< ws_size_t CCH
00549 >
00550 inline ws_size_t c_str_len(winstl_ns_qual(multibyte2wide)<CCH> const& b)
00551 {
00552 return stlsoft_ns_qual(c_str_len)(b.c_str());
00553 }
00554
00555 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00556
00557 template< ws_size_t CCH
00558 >
00559 inline ws_size_t c_str_len_w(winstl_ns_qual(multibyte2wide)<CCH> const& b)
00560 {
00561 return stlsoft_ns_qual(c_str_len_w)(b.c_str());
00562 }
00563
00564 #endif
00565
00566
00567
00572 template< ws_size_t CCH
00573 >
00574 inline ws_char_a_t const* c_str_ptr_null(winstl_ns_qual(wide2multibyte)<CCH> const& b)
00575 {
00576 return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
00577 }
00578
00579 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00580
00581 template< ws_size_t CCH
00582 >
00583 inline ws_char_a_t const* c_str_ptr_null_a(winstl_ns_qual(wide2multibyte)<CCH> const& b)
00584 {
00585 return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
00586 }
00587
00588 #endif
00589
00594 template< ws_size_t CCH
00595 >
00596 inline ws_char_a_t const* c_str_ptr(winstl_ns_qual(wide2multibyte)<CCH> const& b)
00597 {
00598 return b.c_str();
00599 }
00600
00601 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00602
00603 template< ws_size_t CCH
00604 >
00605 inline ws_char_a_t const* c_str_ptr_a(winstl_ns_qual(wide2multibyte)<CCH> const& b)
00606 {
00607 return b.c_str();
00608 }
00609
00610 #endif
00611
00616 template< ws_size_t CCH
00617 >
00618 inline ws_char_a_t const* c_str_data(winstl_ns_qual(wide2multibyte)<CCH> const& b)
00619 {
00620 return b.c_str();
00621 }
00622
00623 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00624
00625 template< ws_size_t CCH
00626 >
00627 inline ws_char_a_t const* c_str_data_a(winstl_ns_qual(wide2multibyte)<CCH> const& b)
00628 {
00629 return b.c_str();
00630 }
00631
00632 #endif
00633
00638 template< ws_size_t CCH
00639 >
00640 inline ws_size_t c_str_len(winstl_ns_qual(wide2multibyte)<CCH> const& b)
00641 {
00642 return stlsoft_ns_qual(c_str_len)(b.c_str());
00643 }
00644
00645 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00646
00647 template< ws_size_t CCH
00648 >
00649 inline ws_size_t c_str_len_a(winstl_ns_qual(wide2multibyte)<CCH> const& b)
00650 {
00651 return stlsoft_ns_qual(c_str_len_a)(b.c_str());
00652 }
00653
00654 #endif
00655
00656
00657
00658
00663 template< ss_typename_param_k S
00664 , ws_size_t CCH
00665 >
00666 inline S& operator <<(S& s, winstl_ns_qual(multibyte2wide)<CCH> const& b)
00667 {
00668 s << b.c_str();
00669
00670 return s;
00671 }
00672
00677 template< ss_typename_param_k S
00678 , ws_size_t CCH
00679 >
00680 inline S& operator <<(S& s, winstl_ns_qual(wide2multibyte)<CCH> const& b)
00681 {
00682 s << b.c_str();
00683
00684 return s;
00685 }
00686
00688
00689
00690 #ifdef STLSOFT_UNITTEST
00691 # include "./unittest/char_conversions_unittest_.h"
00692 #endif
00693
00694
00695
00696 #ifndef _WINSTL_NO_NAMESPACE
00697 # if defined(_STLSOFT_NO_NAMESPACE) || \
00698 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00699 }
00700 # else
00701 }
00702 }
00703 # endif
00704 #endif
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714 #ifndef _WINSTL_NO_NAMESPACE
00715 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00716 !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00717 namespace stlsoft
00718 {
00719 # else
00720
00721 # endif
00722
00723 using ::winstl::c_str_data;
00724 using ::winstl::c_str_data_a;
00725 using ::winstl::c_str_data_w;
00726
00727 using ::winstl::c_str_len;
00728 using ::winstl::c_str_len_a;
00729 using ::winstl::c_str_len_w;
00730
00731 using ::winstl::c_str_ptr;
00732 using ::winstl::c_str_ptr_a;
00733 using ::winstl::c_str_ptr_w;
00734
00735 using ::winstl::c_str_ptr_null;
00736 using ::winstl::c_str_ptr_null_a;
00737 using ::winstl::c_str_ptr_null_w;
00738
00739 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00740 !defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00741 }
00742 # else
00743
00744 # endif
00745 #endif
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755 #if defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) && \
00756 STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION < STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1
00757
00758 # include <iosfwd>
00759
00760 template <winstl_ns_qual(ws_size_t) CCH>
00761 inline winstl_ns_qual_std(basic_ostream)<char>& operator <<(winstl_ns_qual_std(basic_ostream)<char> &stm, winstl_ns_qual(wide2multibyte)<CCH> const& b)
00762 {
00763 return stm << b.c_str();
00764 }
00765
00766 template <winstl_ns_qual(ws_size_t) CCH>
00767 inline winstl_ns_qual_std(basic_ostream)<wchar_t>& operator <<(winstl_ns_qual_std(basic_ostream)<wchar_t> &stm, winstl_ns_qual(multibyte2wide)<CCH> const& b)
00768 {
00769 return stm << b.c_str();
00770 }
00771
00772 #endif
00773
00774
00775
00776 #endif
00777
00778