STLSoft - ... Robust, Lightweight, Cross-platform, Template Software ... ATLSTL - Template Software for the Active Template Library COMSTL - The Standard Template Library meets the Component Object Model .netSTL - Standard Template Library meets the Microsoft.NET Common Language Runtime InetSTL - The Standard Template Library meets WinInet MFCSTL - Template Software for the Microsoft Foundation Classes UNIXSTL - Template Software for the UNIX Operating System WinSTL - where the Standard Template Library meets the Win32 API

Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

winstl_char_conversions.h

Go to the documentation of this file.
00001 /* 
00002  * File:        winstl_char_conversions.h (originally MLStrCnv.h, ::SynesisStd)
00003  *
00004  * Purpose:     Type conversions for Windows.
00005  *
00006  * Created:
00007  * Updated:     11th September 2004
00008  *
00009  * Home:        http://stlsoft.org/
00010  *
00011  * Copyright (c) 2002-2004, Matthew Wilson and Synesis Software
00012  * All rights reserved.
00013  *
00014  * Redistribution and use in source and binary forms, with or without
00015  * modification, are permitted provided that the following conditions are met:
00016  *
00017  * - Redistributions of source code must retain the above copyright notice, this
00018  *   list of conditions and the following disclaimer.
00019  * - Redistributions in binary form must reproduce the above copyright notice,
00020  *   this list of conditions and the following disclaimer in the documentation
00021  *   and/or other materials provided with the distribution.
00022  * - Neither the name(s) of Matthew Wilson and Synesis Software nor the names of
00023  *   any contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00027  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00029  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00030  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00031  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00032  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00033  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00034  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00035  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00036  * POSSIBILITY OF SUCH DAMAGE.
00037  *
00038  * 
00039 
00040 
00044 
00045 #ifndef WINSTL_INCL_H_WINSTL_CHAR_CONVERSIONS
00046 #define WINSTL_INCL_H_WINSTL_CHAR_CONVERSIONS
00047 
00048 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00049 # define WINSTL_VER_H_WINSTL_CHAR_CONVERSIONS_MAJOR       2
00050 # define WINSTL_VER_H_WINSTL_CHAR_CONVERSIONS_MINOR       0
00051 # define WINSTL_VER_H_WINSTL_CHAR_CONVERSIONS_REVISION    1
00052 # define WINSTL_VER_H_WINSTL_CHAR_CONVERSIONS_EDIT        34
00053 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00054 
00055 /* 
00056  * Compatibility
00057  */
00058 
00059 /*
00060 [Incompatibilies-start]
00061 __STLSOFT_COMPILER_IS_GCC: __GNUC__<3
00062 __STLSOFT_COMPILER_IS_MSVC: _MSC_VER<1200
00063 [Incompatibilies-end]
00064  */
00065 
00066 /* 
00067  * Includes
00068  */
00069 
00070 #ifndef WINSTL_INCL_H_WINSTL
00071 # include "winstl.h"                        // Include the WinSTL root header
00072 #endif /* !WINSTL_INCL_H_WINSTL */
00073 
00074 #if defined(__STLSOFT_COMPILER_IS_GCC) && \
00075     __GNUC__ < 3
00076 # error winstl_char_conversions.h is not compatible with GNU C++ prior to 3.0
00077 #endif /* compiler */
00078 #if defined(__STLSOFT_COMPILER_IS_MSVC) && \
00079     _MSC_VER < 1100
00080 # error winstl_char_conversions.h is not compatible with Visual C++ 5.0 or earlier
00081 #endif /* _MSC_VER < 1200 */
00082 
00083 
00084 #ifndef WINSTL_INCL_H_WINSTL_PROCESSHEAP_ALLOCATOR
00085 # include "winstl_processheap_allocator.h"  // winstl::processheap_allocator
00086 #endif /* !WINSTL_INCL_H_WINSTL_PROCESSHEAP_ALLOCATOR */
00087 #ifndef STLSOFT_INCL_H_STLSOFT_STRING_ACCESS
00088 # include "stlsoft_string_access.h"         // stlsoft::c_str_ptr
00089 #endif /* !STLSOFT_INCL_H_STLSOFT_STRING_ACCESS */
00090 #ifndef WINSTL_INCL_H_WINSTL_STRING_ACCESS
00091 # include "winstl_string_access.h"          // winstl::c_str_ptr
00092 #endif /* !WINSTL_INCL_H_WINSTL_STRING_ACCESS */
00093 #ifndef STLSOFT_INCL_H_STLSOFT_AUTO_BUFFER
00094 # include "stlsoft_auto_buffer.h"           // stlsoft::auto_buffer
00095 #endif /* !STLSOFT_INCL_H_STLSOFT_AUTO_BUFFER */
00096 #ifdef STLSOFT_UNITTEST
00097 # include <wchar.h>
00098 #endif /* STLSOFT_UNITTEST */
00099 
00100 /* 
00101 
00102 #ifndef _WINSTL_NO_NAMESPACE
00103 # if defined(_STLSOFT_NO_NAMESPACE) || \
00104      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00105 /* There is no stlsoft namespace, so must define ::winstl */
00106 namespace winstl
00107 {
00108 # else
00109 /* Define stlsoft::winstl_project */
00110 
00111 namespace stlsoft
00112 {
00113 
00114 namespace winstl_project
00115 {
00116 
00117 # endif /* _STLSOFT_NO_NAMESPACE */
00118 #endif /* !_WINSTL_NO_NAMESPACE */
00119 
00120 #if !defined(__STLSOFT_COMPILER_IS_MWERKS)
00121 stlsoft_ns_using(c_str_ptr)
00122 stlsoft_ns_using(c_str_len)
00123 #endif /* compiler */
00124 
00125 /* 
00126  * Classes
00127  */
00128 
00130 template <ws_size_t CCH>
00131 class ansi2Unicode
00132     : public auto_buffer<ws_char_w_t, processheap_allocator<ws_char_w_t>, CCH>
00133 {
00134 private:
00135     typedef auto_buffer<ws_char_w_t, processheap_allocator<ws_char_w_t>, CCH>   parent_class_type;
00136 public:
00137     typedef ws_char_w_t                                                         char_type;
00138     typedef ss_typename_type_k parent_class_type::size_type                     size_type;
00139     typedef ss_typename_type_k parent_class_type::pointer                       pointer;
00140 
00141 public:
00142 #ifdef __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00143     template <ss_typename_param_k S>
00144     ss_explicit_k ansi2Unicode(S const &s)
00145 #else
00146     ss_explicit_k ansi2Unicode(ws_char_a_t const *s)
00147 #endif // __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00148         : parent_class_type(stlsoft_ns_qual(c_str_len)(s) + 1)
00149     {
00150         prepare_(s);
00151     }
00152 
00153 #ifdef __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00154     template <ss_typename_param_k S>
00155     ansi2Unicode(S const &s, size_type cch)
00156 #else
00157     ansi2Unicode(ws_char_a_t const *s, size_type cch)
00158 #endif // __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00159         : parent_class_type(cch + 1)
00160     {
00161         prepare_(s);
00162     }
00163 
00164 // Implementation
00165 private:
00166 #ifdef __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00167     template <ss_typename_param_k S>
00168     void prepare_(S const &s)
00169 #else
00170     void prepare_(ws_char_a_t const *s)
00171 #endif // __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00172     {
00173         // If the auto_buffer failed to allocate the required memory, and
00174         // we're not in an exception-environment, then size() will be zero
00175         if(0 == parent_class_type::size())
00176         {
00177             // Since we know that auto_buffer's parameterising size must
00178             // always be greater that 0, then
00179             parent_class_type::data()[0] = '\0';
00180         }
00181         else
00182         {
00183             size_type   size    =   parent_class_type::size();
00184             pointer     p       =   parent_class_type::data();
00185 
00186             // Note: cannot use -1 for length, since s might be a type that
00187             // could change length
00188             p[(0 == ::MultiByteToWideChar(0, 0, stlsoft_ns_qual(c_str_ptr)(s), static_cast<int>(size), p, static_cast<int>(size))) ? 0 : size - 1] = '\0';
00189         }
00190     }
00191 
00194 public:
00195     char_type const *c_str() const
00196     {
00197         return parent_class_type::data();
00198     }
00200 
00201 // Not to be implemented
00202 private:
00203     ansi2Unicode(ansi2Unicode const &);
00204     ansi2Unicode &operator =(ansi2Unicode const &);
00205 };
00206 
00208 template <ws_size_t CCH>
00209 class unicode2Ansi
00210     : public auto_buffer<ws_char_a_t, processheap_allocator<ws_char_a_t>, CCH>
00211 {
00212 private:
00213     typedef auto_buffer<ws_char_a_t, processheap_allocator<ws_char_a_t>, CCH>   parent_class_type;
00214 public:
00215     typedef ws_char_a_t                                                         char_type;
00216     typedef ss_typename_type_k parent_class_type::size_type                     size_type;
00217     typedef ss_typename_type_k parent_class_type::pointer                       pointer;
00218 
00219 public:
00220 #ifdef __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00221     template <ss_typename_param_k S>
00222     ss_explicit_k unicode2Ansi(S const &s)
00223 #else
00224     ss_explicit_k unicode2Ansi(ws_char_w_t const *s)
00225 #endif // __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00226         : parent_class_type(stlsoft_ns_qual(c_str_len)(s) + 1)
00227     {
00228         prepare_(s);
00229     }
00230 
00231 #ifdef __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00232     template <ss_typename_param_k S>
00233     ss_explicit_k unicode2Ansi(S const &s, size_type cch)
00234 #else
00235     ss_explicit_k unicode2Ansi(ws_char_w_t const *s, size_type cch)
00236 #endif // __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00237         : parent_class_type(cch + 1)
00238     {
00239         prepare_(s);
00240     }
00241 
00242 // Implementation
00243 private:
00244 #ifdef __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00245     template <ss_typename_param_k S>
00246     void prepare_(S const &s)
00247 #else
00248     void prepare_(ws_char_a_t const *s)
00249 #endif // __STLSOFT_CF_MEMBER_TEMPLATE_CTOR_SUPPORT
00250     {
00251         // If the auto_buffer failed to allocate the required memory, and
00252         // we're not in an exception-environment, then size() will be zero
00253         if(0 == parent_class_type::size())
00254         {
00255             // Since we know that auto_buffer's parameterising size must
00256             // always be greater that 0, then
00257             parent_class_type::data()[0] = '\0';
00258         }
00259         else
00260         {
00261             size_type   size    =   parent_class_type::size();
00262             pointer     p       =   parent_class_type::data();
00263 
00264             // Note: cannot use -1 for length, since s might be a type that
00265             // could change length
00266             p[(0 == ::WideCharToMultiByte(0, 0, stlsoft_ns_qual(c_str_ptr)(s), static_cast<int>(size), p, static_cast<int>(size), NULL, NULL)) ? 0 : size - 1] = '\0';
00267         }
00268     }
00269 
00272 public:
00273     char_type const *c_str() const
00274     {
00275         return parent_class_type::data();
00276     }
00278 
00279 // Not to be implemented
00280 private:
00281     unicode2Ansi(unicode2Ansi const &);
00282     unicode2Ansi &operator =(unicode2Ansi const &);
00283 };
00284 
00285 /* 
00286 
00287 typedef ansi2Unicode<256>     a2w;
00288 typedef unicode2Ansi<256>     w2a;
00289 
00290 /* 
00291  * Shims
00292  */
00293 
00294 template<   ws_size_t           CCH
00295         >
00296 inline ws_char_w_t const *c_str_ptr_null(ansi2Unicode<CCH> const &b)
00297 {
00298     return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
00299 }
00300 
00301 template<   ws_size_t           CCH
00302         >
00303 inline ws_char_w_t const *c_str_ptr(ansi2Unicode<CCH> const &b)
00304 {
00305     return stlsoft_ns_qual(c_str_ptr)(b.c_str());
00306 }
00307 
00308 template<   ws_size_t           CCH
00309         >
00310 inline ws_size_t c_str_len(ansi2Unicode<CCH> const &b)
00311 {
00312     return stlsoft_ns_qual(c_str_len)(b.c_str());
00313 }
00314 
00315 template<   ws_size_t           CCH
00316         >
00317 inline ws_size_t c_str_size(ansi2Unicode<CCH> const &b)
00318 {
00319     return stlsoft_ns_qual(c_str_size)(b.c_str());
00320 }
00321 
00322 template<   ss_typename_param_k S
00323         ,   ws_size_t           CCH
00324         >
00325 inline S &operator <<(S & s, ansi2Unicode<CCH> const &b)
00326 {
00327     s << b.c_str();
00328 
00329     return s;
00330 }
00331 
00332 template<   ws_size_t           CCH
00333         >
00334 inline ws_char_a_t const *c_str_ptr_null(unicode2Ansi<CCH> const &b)
00335 {
00336     return stlsoft_ns_qual(c_str_ptr_null)(b.c_str());
00337 }
00338 
00339 template<   ws_size_t           CCH
00340         >
00341 inline ws_char_a_t const *c_str_ptr(unicode2Ansi<CCH> const &b)
00342 {
00343     return stlsoft_ns_qual(c_str_ptr)(b.c_str());
00344 }
00345 
00346 template<   ws_size_t           CCH
00347         >
00348 inline ws_size_t c_str_len(unicode2Ansi<CCH> const &b)
00349 {
00350     return stlsoft_ns_qual(c_str_len)(b.c_str());
00351 }
00352 
00353 template<   ws_size_t           CCH
00354         >
00355 inline ws_size_t c_str_size(unicode2Ansi<CCH> const &b)
00356 {
00357     return stlsoft_ns_qual(c_str_size)(b.c_str());
00358 }
00359 
00360 template<   ss_typename_param_k S
00361         ,   ws_size_t           CCH
00362         >
00363 inline S &operator <<(S & s, unicode2Ansi<CCH> const &b)
00364 {
00365     s << b.c_str();
00366 
00367     return s;
00368 }
00369 
00371 // Unit-testing
00372 
00373 #ifdef STLSOFT_UNITTEST
00374 
00375 namespace unittest
00376 {
00377     ss_bool_t test_winstl_char_conversions(unittest_reporter *r)
00378     {
00379         using stlsoft::unittest::unittest_initialiser;
00380 
00381         ss_bool_t               bSuccess    =   true;
00382 
00383         unittest_initialiser    init(r, "WinSTL", "char_conversion", __FILE__);
00384 
00385         if(0 != strcmp("String #1", w2a(L"String #1")))
00386         {
00387             r->report("w2a failed ", __LINE__);
00388             bSuccess = false;
00389         }
00390 
00391         if(0 != wcscmp(L"String #1", a2w("String #1")))
00392         {
00393             r->report("a2w failed ", __LINE__);
00394             bSuccess = false;
00395         }
00396 
00397         return bSuccess;
00398     }
00399 
00400     unittest_registrar    unittest_winstl_char_conversions(test_winstl_char_conversions);
00401 
00402 } // namespace unittest
00403 
00404 #endif /* STLSOFT_UNITTEST */
00405 
00406 /* 
00407 
00408 #ifndef _WINSTL_NO_NAMESPACE
00409 # if defined(_STLSOFT_NO_NAMESPACE) || \
00410      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00411 } // namespace winstl
00412 # else
00413 } // namespace winstl_project
00414 } // namespace stlsoft
00415 # endif /* _STLSOFT_NO_NAMESPACE */
00416 #endif /* !_WINSTL_NO_NAMESPACE */
00417 
00418 /* 
00419  * Namespace
00420  *
00421  * The string access shims exist either in the stlsoft namespace, or in the
00422  * global namespace. This is required by the lookup rules.
00423  *
00424  */
00425 
00426 #ifndef _WINSTL_NO_NAMESPACE
00427 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00428      !defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00429 namespace stlsoft
00430 {
00431 # else /* ? _STLSOFT_NO_NAMESPACE */
00432 /* There is no stlsoft namespace, so must define in the global namespace */
00433 # endif /* !_STLSOFT_NO_NAMESPACE */
00434 
00435 using ::winstl::c_str_ptr_null;
00436 
00437 using ::winstl::c_str_ptr;
00438 
00439 using ::winstl::c_str_len;
00440 
00441 using ::winstl::c_str_size;
00442 
00443 # if !defined(_STLSOFT_NO_NAMESPACE) && \
00444      !defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00445 } // namespace stlsoft
00446 # else /* ? _STLSOFT_NO_NAMESPACE */
00447 /* There is no stlsoft namespace, so must define in the global namespace */
00448 # endif /* !_STLSOFT_NO_NAMESPACE */
00449 #endif /* !_WINSTL_NO_NAMESPACE */
00450 
00451 /* 
00452 
00453 #endif /* WINSTL_INCL_H_WINSTL_CHAR_CONVERSIONS */
00454 
00455 /* 

STLSoft Libraries documentation © Synesis Software Pty Ltd, 2001-2004