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_resource_string.h

Go to the documentation of this file.
00001 /* 
00002  * File:        winstl_resource_string.h (Formerly MWResStr.h: ::SynesisWin)
00003  *
00004  * Purpose:     basic_resource_string class.
00005  *
00006  * Created:     1st November 1994
00007  * Updated:     11th September 2004
00008  *
00009  * Home:        http://stlsoft.org/
00010  *
00011  * Copyright (c) 1994-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_RESOURCE_STRING
00046 #define WINSTL_INCL_H_WINSTL_RESOURCE_STRING
00047 
00048 #ifndef __STLSOFT_DOCUMENTATION_SKIP_SECTION
00049 # define WINSTL_VER_H_WINSTL_RESOURCE_STRING_MAJOR      2
00050 # define WINSTL_VER_H_WINSTL_RESOURCE_STRING_MINOR      0
00051 # define WINSTL_VER_H_WINSTL_RESOURCE_STRING_REVISION   1
00052 # define WINSTL_VER_H_WINSTL_RESOURCE_STRING_EDIT       41
00053 #endif /* !__STLSOFT_DOCUMENTATION_SKIP_SECTION */
00054 
00055 /* 
00056  * Compatibility
00057  */
00058 
00059 /*
00060 [Incompatibilies-start]
00061 __STLSOFT_COMPILER_IS_MSVC: _MSC_VER<1200
00062 [Incompatibilies-end]
00063  */
00064 
00065 /* 
00066  * Includes
00067  */
00068 
00069 #ifndef WINSTL_INCL_H_WINSTL
00070 # include "winstl.h"                // Include the WinSTL root header
00071 #endif /* !WINSTL_INCL_H_WINSTL */
00072 
00073 #if defined(__STLSOFT_COMPILER_IS_MSVC) && \
00074     _MSC_VER < 1200
00075 # error winstl_resource_string.h is not compatible with Visual C++ 5.0 or earlier
00076 #endif /* _MSC_VER < 1200 */
00077 
00078 #ifndef STLSOFT_INCL_H_STLSOFT_STRING_TRAITS
00079 # include "stlsoft_string_traits.h" // stlsoft::string_traits
00080 #endif /* !STLSOFT_INCL_H_STLSOFT_STRING_TRAITS */
00081 #ifndef STLSOFT_INCL_H_STLSOFT_EXCEPTIONS
00082 # include "stlsoft_exceptions.h"    // stlsoft::null_exception_policy
00083 #endif /* !STLSOFT_INCL_H_STLSOFT_EXCEPTIONS */
00084 #ifdef STLSOFT_UNITTEST
00085 # include <string>                  // std::string, std::wstring
00086 #endif /* STLSOFT_UNITTEST */
00087 #include <exception>
00088 
00089 /* 
00090  * Namespace
00091  */
00092 
00093 #ifndef _WINSTL_NO_NAMESPACE
00094 # if defined(_STLSOFT_NO_NAMESPACE) || \
00095      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00096 /* There is no stlsoft namespace, so must define ::winstl */
00097 namespace winstl
00098 {
00099 # else
00100 /* Define stlsoft::winstl_project */
00101 
00102 namespace stlsoft
00103 {
00104 
00105 namespace winstl_project
00106 {
00107 
00108 # endif /* _STLSOFT_NO_NAMESPACE */
00109 #endif /* !_WINSTL_NO_NAMESPACE */
00110 
00111 /* 
00112 
00115 
00119 
00124 
00125 /* 
00126  * Classes
00127  */
00128 
00129 // class basic_resource_string
00135 template<   ss_typename_param_k S
00136 #ifdef __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00137         ,   ss_typename_param_k X = stlsoft_ns_qual(null_exception_policy)
00138 #else /* ? __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
00139         ,   ss_typename_param_k X /* = stlsoft_ns_qual(null_exception_policy) */
00140 #endif /* __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT */
00141         >
00142 class basic_resource_string
00143     : public S
00144     , protected X
00145 {
00146 private:
00147     typedef S                                          parent_class_type;
00148 //    typedef C                                          value_type;
00149 public:
00150     typedef S                                          string_type;
00151     typedef basic_resource_string<S, X>                class_type;
00152     typedef X                                          exception_type;
00153     typedef stlsoft_ns_qual(string_traits)<S>          string_traits_type;
00154 
00155     typedef ss_typename_type_k string_type::value_type value_type;
00156 
00159 public:
00161     ss_explicit_k basic_resource_string(ws_int_t id) winstl_throw_1(ss_typename_type_k exception_type::thrown_type)
00162     {
00163         load(::GetModuleHandle(NULL), id);
00164     }
00165 
00167     basic_resource_string(HINSTANCE hinst, ws_int_t id) winstl_throw_1(ss_typename_type_k exception_type::thrown_type)
00168     {
00169         load(hinst, id);
00170     }
00171 
00173     basic_resource_string(const basic_resource_string &rhs)
00174         : parent_class_type(rhs)
00175     {}
00176 
00178     basic_resource_string(const string_type &rhs)
00179         : parent_class_type(rhs)
00180     {}
00181 
00183     const basic_resource_string &operator =(const basic_resource_string &rhs)
00184     {
00185         parent_class_type::operator =(rhs);
00186 
00187         return *this;
00188     }
00190     const basic_resource_string &operator =(const string_type &rhs)
00191     {
00192         parent_class_type::operator =(rhs);
00193 
00194         return *this;
00195     }
00196 
00198 
00199 // Implementation
00200 private:
00201     ws_int_t LoadString(HINSTANCE hinst, int uID, ws_char_a_t *buffer, ws_size_t cchBuffer)
00202     {
00203         return ::LoadStringA(hinst, uID, buffer, cchBuffer);
00204     }
00205     ws_int_t LoadString(HINSTANCE hinst, int uID, ws_char_w_t *buffer, ws_size_t cchBuffer)
00206     {
00207         return ::LoadStringW(hinst, uID, buffer, cchBuffer);
00208     }
00209 
00210     void load(HINSTANCE hinst, ws_int_t id) winstl_throw_1(ss_typename_type_k exception_type::thrown_type)
00211     {
00212         // TODO: Verify that it's not possible to load string resources of >256. If that's
00213         // wrong, then need to fix this to use auto_buffer
00214         value_type  sz[1024];
00215 
00216         if(0 == LoadString(hinst, id, sz, winstl_num_elements(sz)))
00217         {
00218             exception_type()(hinst, id);
00219 
00220 #if 0
00221             parent_class_type::operator =(string_traits_type::empty_string());
00222 #else
00223             parent_class_type::operator =(string_type());
00224 #endif /* 0 */
00225         }
00226         else
00227         {
00228             parent_class_type::operator =(sz);
00229         }
00230     }
00231 };
00232 
00234 // Unit-testing
00235 
00236 #ifdef STLSOFT_UNITTEST
00237 
00238 namespace unittest
00239 {
00240     namespace
00241     {
00242         struct throw_exception
00243         {
00244         public:
00246             class thrown_type
00247                 : public std::exception
00248             {
00249             public:
00250                 thrown_type(char const *reason) throw()
00251                     : m_reason(reason)
00252                 {}
00253 
00254                 ~thrown_type() throw()
00255                 {}
00256 
00257                 char const *what() const throw()
00258                 {
00259                     return m_reason.c_str();
00260                 }
00261 
00262             private:
00263                 stlsoft_ns_qual_std(string) m_reason;
00264             };
00265 
00266         public:
00267             void operator ()(HINSTANCE hinst, int id)
00268             {
00269                 char    message[101];
00270 
00271                 wsprintfA(message, "Failed to load resource %d from module 0x%084", id, hinst);
00272 
00273                 throw thrown_type(message);
00274             }
00275         };
00276     }
00277 
00278 
00279     ss_bool_t test_mfcstl_resource_string(unittest_reporter *r)
00280     {
00281         using stlsoft::unittest::unittest_initialiser;
00282         using stlsoft::null_exception_policy;
00283 
00284         ss_bool_t               bSuccess    =   true;
00285 
00286         unittest_initialiser    init(r, "WinSTL", "resource_string", __FILE__);
00287 
00288         typedef basic_resource_string<stlsoft_ns_qual_std(string), null_exception_policy>  rsn_a_t;
00289         typedef basic_resource_string<stlsoft_ns_qual_std(wstring), null_exception_policy> rsn_w_t;
00290 
00291         HINSTANCE   hinst   =   ::LoadLibrary("USER32");
00292         int         iBad    =   -1;
00293         int         iGood   =   -1;
00294 
00295         for(int i = 0; i < 10000; ++i)
00296         {
00297             rsn_a_t     rsn_a_2(hinst, i);
00298             rsn_w_t     rsn_w_2(hinst, i);
00299 
00300             if(0 == rsn_a_2.length())
00301             {
00302                 if(-1 == iBad)
00303                 {
00304                     iBad = i;
00305                 }
00306             }
00307             else
00308             {
00309                 if(-1 == iGood)
00310                 {
00311                     iGood = i;
00312                 }
00313             }
00314 
00315             if(rsn_a_2.length() != rsn_w_2.length())
00316             {
00317                 r->report("resource string (null exception) length mismatch between ANSI and Unicode instantiations", __LINE__);
00318                 bSuccess = false;
00319             }
00320         }
00321 
00322         if(bSuccess)
00323         {
00324             typedef basic_resource_string<stlsoft_ns_qual_std(string), throw_exception>     rsx_a_t;
00325             typedef basic_resource_string<stlsoft_ns_qual_std(wstring), throw_exception>    rsx_w_t;
00326 
00327             if(-1 != iGood)
00328             {
00329                 try
00330                 {
00331                     rsx_a_t     rsn_a_2(hinst, iGood);
00332                     rsx_w_t     rsn_w_2(hinst, iGood);
00333                 }
00334                 catch(std::exception &/* x */)
00335                 {
00336                     r->report("resource string (std::exception) failed to load known resource from USER32", __LINE__);
00337                     bSuccess = false;
00338                 }
00339             }
00340 
00341             if(-1 != iBad)
00342             {
00343                 try
00344                 {
00345                     rsx_a_t     rsn_a_2(hinst, iBad);
00346 
00347                     r->report("resource string (std::exception) loaded known invalid resource from USER32", __LINE__);
00348                     bSuccess = false;
00349                 }
00350                 catch(std::exception &/* x */)
00351                 {}
00352 
00353                 try
00354                 {
00355                     rsx_w_t     rsn_w_2(hinst, iBad);
00356 
00357                     r->report("resource string (std::exception) loaded known invalid resource from USER32", __LINE__);
00358                     bSuccess = false;
00359                 }
00360                 catch(std::exception &/* x */)
00361                 {}
00362             }
00363         }
00364 
00365         return bSuccess;
00366     }
00367 
00368     unittest_registrar    unittest_mfcstl_resource_string(test_mfcstl_resource_string);
00369 
00370 } // namespace unittest
00371 
00372 #endif /* STLSOFT_UNITTEST */
00373 
00374 /* 
00375  * String access shims
00376  */
00377 
00378 #if 0
00379 /* c_str_ptr_null */
00380 
00382 template<   ss_typename_param_k S
00383         ,   ss_typename_param_k X
00384         >
00385 inline C const *c_str_ptr_null(basic_resource_string<S, X> const &s)
00386 {
00387     return (s.length() == 0) ? 0 : s.c_str();
00388 }
00389 
00390 /* c_str_ptr */
00391 
00393 template<   ss_typename_param_k S
00394         ,   ss_typename_param_k X
00395         >
00396 inline C const *c_str_ptr(basic_resource_string<S, X> const &s)
00397 {
00398     return s.c_str();
00399 }
00400 #endif /* 0 */
00401 
00402 /* c_str_ptr_len */
00403 
00405 template<   ss_typename_param_k S
00406         ,   ss_typename_param_k X
00407         >
00408 inline ss_size_t c_str_len(basic_resource_string<S, X> const &s)
00409 {
00410     return s.length();
00411 }
00412 
00413 /* c_str_ptr_size */
00414 
00416 template<   ss_typename_param_k S
00417         ,   ss_typename_param_k X
00418         >
00419 inline ss_size_t c_str_size(basic_resource_string<S, X> const &s)
00420 {
00421     return c_str_len(s) * sizeof(ss_typename_type_k basic_resource_string<S, X>::value_type);
00422 }
00423 
00424 /* 
00425 
00427 
00428 /* 
00429 
00430 #ifndef _WINSTL_NO_NAMESPACE
00431 # if defined(_STLSOFT_NO_NAMESPACE) || \
00432      defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00433 } // namespace winstl
00434 # else
00435 } // namespace winstl_project
00436 } // namespace stlsoft
00437 # endif /* _STLSOFT_NO_NAMESPACE */
00438 #endif /* !_WINSTL_NO_NAMESPACE */
00439 
00440 /* 
00441 
00442 #endif /* !WINSTL_INCL_H_WINSTL_RESOURCE_STRING */
00443 
00444 /* 

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