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
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 #ifndef WINSTL_INCL_H_WINSTL
00070 # include "winstl.h"
00071 #endif
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
00077
00078 #ifndef STLSOFT_INCL_H_STLSOFT_STRING_TRAITS
00079 # include "stlsoft_string_traits.h"
00080 #endif
00081 #ifndef STLSOFT_INCL_H_STLSOFT_EXCEPTIONS
00082 # include "stlsoft_exceptions.h"
00083 #endif
00084 #ifdef STLSOFT_UNITTEST
00085 # include <string>
00086 #endif
00087 #include <exception>
00088
00089
00090
00091
00092
00093 #ifndef _WINSTL_NO_NAMESPACE
00094 # if defined(_STLSOFT_NO_NAMESPACE) || \
00095 defined(__STLSOFT_DOCUMENTATION_SKIP_SECTION)
00096
00097 namespace winstl
00098 {
00099 # else
00100
00101
00102 namespace stlsoft
00103 {
00104
00105 namespace winstl_project
00106 {
00107
00108 # endif
00109 #endif
00110
00111
00112
00115
00119
00124
00125
00126
00127
00128
00129
00135
00136 #ifdef __STLSOFT_CF_TEMPLATE_CLASS_DEFAULT_CLASS_ARGUMENT_SUPPORT
00137 , ss_typename_param_k X = stlsoft_ns_qual(null_exception_policy)
00138 #else
00139 , ss_typename_param_k X
00140 #endif
00141 >
00142 class basic_resource_string
00143 : public S
00144 , protected X
00145 {
00146 private:
00147 typedef S parent_class_type;
00148
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
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
00213
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
00225 }
00226 else
00227 {
00228 parent_class_type::operator =(sz);
00229 }
00230 }
00231 };
00232
00234
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 &)
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 &)
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 &)
00361 {}
00362 }
00363 }
00364
00365 return bSuccess;
00366 }
00367
00368 unittest_registrar unittest_mfcstl_resource_string(test_mfcstl_resource_string);
00369
00370 }
00371
00372 #endif
00373
00374
00375
00376
00377
00378 #if 0
00379
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
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
00401
00402
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
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
00431
00432
00433
00434
00435
00436
00437
00438 #endif
00439
00440
00441
00442
00443
00444