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_CONVERSION_HPP_CHAR_CONVERSIONS
00049 #define STLSOFT_INCL_STLSOFT_CONVERSION_HPP_CHAR_CONVERSIONS
00050
00051 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00052 # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_CHAR_CONVERSIONS_MAJOR 5
00053 # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_CHAR_CONVERSIONS_MINOR 1
00054 # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_CHAR_CONVERSIONS_REVISION 1
00055 # define STLSOFT_VER_STLSOFT_CONVERSION_HPP_CHAR_CONVERSIONS_EDIT 93
00056 #endif
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 #ifndef STLSOFT_INCL_STLSOFT_H_STLSOFT
00074 # include <stlsoft/stlsoft.h>
00075 #endif
00076
00077 #if defined(STLSOFT_COMPILER_IS_GCC) && \
00078 __GNUC__ < 3
00079 # error stlsoft/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 stlsoft/conversion/char_conversions.hpp is not compatible with Visual C++ 5.0 or earlier
00084 #endif
00085
00086 #ifndef STLSOFT_INCL_STLSOFT_SHIMS_ACCESS_HPP_STRING
00087 # include <stlsoft/shims/access/string.hpp>
00088 #endif
00089 #ifndef STLSOFT_INCL_STLSOFT_MEMORY_HPP_AUTO_BUFFER
00090 # include <stlsoft/memory/auto_buffer.hpp>
00091 #endif
00092 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00093 # ifndef STLSOFT_INCL_STLSOFT_ERROR_HPP_CONVERSION_ERROR
00094 # include <stlsoft/error/conversion_error.hpp>
00095 # endif
00096 # include <errno.h>
00097 #endif
00098 #ifndef STLSOFT_INCL_STLSOFT_INTERNAL_H_SAFESTR
00099 # include <stlsoft/internal/safestr.h>
00100 #endif
00101
00102 #ifdef STLSOFT_UNITTEST
00103 # include <wchar.h>
00104 #endif
00105
00106
00107
00108
00109
00110 #ifndef _STLSOFT_NO_NAMESPACE
00111 namespace stlsoft
00112 {
00113 #endif
00114
00115
00116
00117
00118
00124 template <ss_size_t CCH>
00125 class multibyte2wide
00126 : public auto_buffer<ss_char_w_t, CCH>
00127 {
00130 private:
00131 typedef auto_buffer<ss_char_w_t, CCH> parent_class_type;
00132 public:
00134 typedef ss_char_w_t char_type;
00136 typedef ss_char_a_t alt_char_type;
00138 typedef ss_typename_type_k parent_class_type::size_type size_type;
00140 typedef ss_typename_type_k parent_class_type::pointer pointer;
00142
00145 public:
00146 #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00147 template <ss_typename_param_k S>
00148 ss_explicit_k multibyte2wide(S const& s)
00149 #else
00150 ss_explicit_k multibyte2wide(alt_char_type const* s)
00151 #endif
00152 : parent_class_type(calc_length_(s) + 1)
00153 {
00154 prepare_(stlsoft_ns_qual(c_str_ptr_a)(s));
00155 }
00156
00157 #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00158 template <ss_typename_param_k S>
00159 multibyte2wide(S const& s, size_type cch)
00160 #else
00161 multibyte2wide(alt_char_type const* s, size_type cch)
00162 #endif // STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00163 : parent_class_type(cch + 1)
00164 {
00165 prepare_(stlsoft_ns_qual(c_str_data_a)(s), cch);
00166 }
00167
00168 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00170
00173 private:
00174 template <ss_typename_param_k S>
00175 static size_type calc_length_(S const& s)
00176 {
00177 return stlsoft_ns_qual(c_str_len_a)(s);
00178 }
00179
00180 void prepare_(alt_char_type const* s)
00181 {
00182 prepare_(s, parent_class_type::size() - 1);
00183 }
00184
00185 void prepare_(alt_char_type const* s, size_type size)
00186 {
00187 const pointer data = parent_class_type::data();
00188
00189
00190
00191 if(0 == size)
00192 {
00193
00194
00195 data[0] = '\0';
00196 }
00197 else
00198 {
00199 int err;
00200 #ifdef STLSOFT_USING_SAFE_STR_FUNCTIONS
00201 ss_size_t numConverted;
00202
00203 err = ::mbstowcs_s(&numConverted, data, size + 1, s, size);
00204
00205 if(0 != err)
00206 {
00207 #else
00208 if(static_cast<ss_size_t>(-1) == ::mbstowcs(data, s, size))
00209 {
00210 err = errno;
00211 #endif
00212
00213 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00214 STLSOFT_THROW_X(conversion_error("failed to convert multibyte string to wide string", err));
00215 #else
00216 data[0] = '\0';
00217 #endif
00218 }
00219 else
00220 {
00221 data[size] = '\0';
00222 }
00223 }
00224 }
00226
00229 public:
00230 char_type const* c_str() const
00231 {
00232 return parent_class_type::data();
00233 }
00235
00238 public:
00239 operator char_type const* () const
00240 {
00241 return parent_class_type::data();
00242 }
00244
00247 private:
00248 multibyte2wide(multibyte2wide const&);
00249 multibyte2wide& operator =(multibyte2wide const&);
00250
00251 #endif
00253 };
00254
00260 template <ss_size_t CCH>
00261 class wide2multibyte
00262 : public auto_buffer<ss_char_a_t, CCH>
00263 {
00266 private:
00267 typedef auto_buffer<ss_char_a_t, CCH> parent_class_type;
00268 public:
00270 typedef ss_char_a_t char_type;
00272 typedef ss_char_w_t alt_char_type;
00274 typedef ss_typename_type_k parent_class_type::size_type size_type;
00276 typedef ss_typename_type_k parent_class_type::pointer pointer;
00278
00281 public:
00282 #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00283 template <ss_typename_param_k S>
00284 ss_explicit_k wide2multibyte(S const& s)
00285 #else
00286 ss_explicit_k wide2multibyte(alt_char_type const* s)
00287 #endif // STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00288 : parent_class_type(stlsoft_ns_qual(c_str_len)(s) + 1)
00289 {
00290 prepare_(stlsoft_ns_qual(c_str_ptr_w)(s));
00291 }
00292
00293 #ifdef STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00294 template <ss_typename_param_k S>
00295 ss_explicit_k wide2multibyte(S const& s, size_type cch)
00296 #else
00297 ss_explicit_k wide2multibyte(alt_char_type const* s, size_type cch)
00298 #endif // STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00299 : parent_class_type(cch + 1)
00300 {
00301 prepare_(stlsoft_ns_qual(c_str_data_w)(s), cch);
00302 }
00304
00305 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00306
00307
00308 private:
00309 void prepare_(alt_char_type const* s)
00310 {
00311 prepare_(s, parent_class_type::size() - 1);
00312 }
00313
00314 void prepare_(alt_char_type const* s, size_type size)
00315 {
00316 const pointer data = parent_class_type::data();
00317
00318
00319
00320 if(0 == size)
00321 {
00322
00323
00324 data[0] = '\0';
00325 }
00326 else
00327 {
00328 int err;
00329 #ifdef STLSOFT_USING_SAFE_STR_FUNCTIONS
00330 ss_size_t numConverted;
00331
00332 err = ::wcstombs_s(&numConverted, data, size + 1, s, size);
00333
00334 if(0 != err)
00335 {
00336 #else
00337 if(static_cast<ss_size_t>(-1) == ::wcstombs(data, s, size))
00338 {
00339 err = errno;
00340 #endif
00341
00342 #ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00343 STLSOFT_THROW_X(conversion_error("failed to convert wide string to multibyte string", err));
00344 #else
00345 data[0] = '\0';
00346 #endif
00347 }
00348 else
00349 {
00350 data[size] = '\0';
00351 }
00352 }
00353 }
00354
00357 public:
00358 char_type const* c_str() const
00359 {
00360 return parent_class_type::data();
00361 }
00363
00366 public:
00367 operator char_type const* () const
00368 {
00369 return parent_class_type::data();
00370 }
00372
00373
00374 private:
00375 wide2multibyte(wide2multibyte const&);
00376 wide2multibyte& operator =(wide2multibyte const&);
00377 #endif
00378 };
00379
00380 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00381 template <ss_typename_param_k C>
00382 class encoding2encoding
00383 {
00384 public:
00385 encoding2encoding(C const* s)
00386 : m_s(s)
00387 {}
00388 encoding2encoding(C *s)
00389 : m_s(s)
00390 {}
00391 template <ss_typename_param_k S>
00392 encoding2encoding(S const& s)
00393 : m_s(s.c_str())
00394 {}
00395
00396 public:
00397 C const* c_str() const
00398 {
00399 return m_s;
00400 }
00401 operator C const* () const
00402 {
00403 return m_s;
00404 }
00405
00406 private:
00407 C const* m_s;
00408 };
00409 #endif
00410
00411
00412
00417 typedef multibyte2wide<256> m2w;
00422 typedef wide2multibyte<256> w2m;
00423
00430 typedef multibyte2wide<256> a2w;
00437 typedef wide2multibyte<256> w2a;
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00459 template< ss_size_t CCH
00460 >
00461 inline ss_char_w_t const* c_str_ptr_null(stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
00462 {
00463 return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
00464 }
00465
00466 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00467
00468 template< ss_size_t CCH
00469 >
00470 inline ss_char_w_t const* c_str_ptr_null_w(stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
00471 {
00472 return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
00473 }
00474
00475 #endif
00476
00477
00482 template< ss_size_t CCH
00483 >
00484 inline ss_char_w_t const* c_str_ptr(stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
00485 {
00486 return b.c_str();
00487 }
00488
00489 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00490
00491 template< ss_size_t CCH
00492 >
00493 inline ss_char_w_t const* c_str_ptr_w(stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
00494 {
00495 return b.c_str();
00496 }
00497
00498 #endif
00499
00504 template< ss_size_t CCH
00505 >
00506 inline ss_char_w_t const* c_str_data(stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
00507 {
00508 return b.c_str();
00509 }
00510
00511 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00512
00513 template< ss_size_t CCH
00514 >
00515 inline ss_char_w_t const* c_str_data_w(stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
00516 {
00517 return b.c_str();
00518 }
00519
00520 #endif
00521
00526 template< ss_size_t CCH
00527 >
00528 inline ss_size_t c_str_len(stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
00529 {
00530 return stlsoft_ns_qual(c_str_len)(b.c_str());
00531 }
00532
00533 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00534
00535 template< ss_size_t CCH
00536 >
00537 inline ss_size_t c_str_len_w(stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
00538 {
00539 return stlsoft_ns_qual(c_str_len_w)(b.c_str());
00540 }
00541
00542 #endif
00543
00544
00545
00550 template< ss_size_t CCH
00551 >
00552 inline ss_char_a_t const* c_str_ptr_null(stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
00553 {
00554 return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
00555 }
00556
00557 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00558
00559 template< ss_size_t CCH
00560 >
00561 inline ss_char_a_t const* c_str_ptr_null_a(stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
00562 {
00563 return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
00564 }
00565
00566 #endif
00567
00572 template< ss_size_t CCH
00573 >
00574 inline ss_char_a_t const* c_str_ptr(stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
00575 {
00576 return b.c_str();
00577 }
00578
00579 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00580
00581 template< ss_size_t CCH
00582 >
00583 inline ss_char_a_t const* c_str_ptr_a(stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
00584 {
00585 return b.c_str();
00586 }
00587
00588 #endif
00589
00594 template< ss_size_t CCH
00595 >
00596 inline ss_char_a_t const* c_str_data(stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
00597 {
00598 return b.c_str();
00599 }
00600
00601 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00602
00603 template< ss_size_t CCH
00604 >
00605 inline ss_char_a_t const* c_str_data_a(stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
00606 {
00607 return b.c_str();
00608 }
00609
00610 #endif
00611
00616 template< ss_size_t CCH
00617 >
00618 inline ss_size_t c_str_len(stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
00619 {
00620 return stlsoft_ns_qual(c_str_len)(b.c_str());
00621 }
00622
00623 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00624
00625 template< ss_size_t CCH
00626 >
00627 inline ss_size_t c_str_len_a(stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
00628 {
00629 return stlsoft_ns_qual(c_str_len_a)(b.c_str());
00630 }
00631
00632 #endif
00633
00634
00635
00636
00641 template< ss_typename_param_k S
00642 , ss_size_t CCH
00643 >
00644 inline S& operator <<(S& s, stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
00645 {
00646 s << b.c_str();
00647
00648 return s;
00649 }
00650
00655 template< ss_typename_param_k S
00656 , ss_size_t CCH
00657 >
00658 inline S& operator <<(S& s, stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
00659 {
00660 s << b.c_str();
00661
00662 return s;
00663 }
00664
00666
00667
00668 #ifdef STLSOFT_UNITTEST
00669 # include "./unittest/char_conversions_unittest_.h"
00670 #endif
00671
00672
00673
00674 #ifndef _STLSOFT_NO_NAMESPACE
00675 }
00676 #endif
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686 #if defined(STLSOFT_CF_STD_LIBRARY_IS_DINKUMWARE_VC) && \
00687 STLSOFT_CF_STD_LIBRARY_DINKUMWARE_VC_VERSION < STLSOFT_CF_DINKUMWARE_VC_VERSION_7_1
00688
00689 # include <iosfwd>
00690
00691 template <stlsoft_ns_qual(ss_size_t) CCH>
00692 inline stlsoft_ns_qual_std(basic_ostream)<char>& operator <<(stlsoft_ns_qual_std(basic_ostream)<char> &stm, stlsoft_ns_qual(wide2multibyte)<CCH> const& b)
00693 {
00694 return stm << b.c_str();
00695 }
00696
00697 template <stlsoft_ns_qual(ss_size_t) CCH>
00698 inline stlsoft_ns_qual_std(basic_ostream)<wchar_t>& operator <<(stlsoft_ns_qual_std(basic_ostream)<wchar_t> &stm, stlsoft_ns_qual(multibyte2wide)<CCH> const& b)
00699 {
00700 return stm << b.c_str();
00701 }
00702
00703 #endif
00704
00705
00706
00707 #endif
00708
00709