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
00041
00042
00043
00044
00052 #ifndef WINSTL_INCL_WINSTL_SYSTEM_HPP_SYSTEM_TRAITS
00053 #define WINSTL_INCL_WINSTL_SYSTEM_HPP_SYSTEM_TRAITS
00054
00055 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00056 # define WINSTL_VER_WINSTL_SYSTEM_HPP_SYSTEM_TRAITS_MAJOR 5
00057 # define WINSTL_VER_WINSTL_SYSTEM_HPP_SYSTEM_TRAITS_MINOR 4
00058 # define WINSTL_VER_WINSTL_SYSTEM_HPP_SYSTEM_TRAITS_REVISION 1
00059 # define WINSTL_VER_WINSTL_SYSTEM_HPP_SYSTEM_TRAITS_EDIT 124
00060 #endif
00061
00062
00063
00064
00065
00066 #ifndef WINSTL_INCL_WINSTL_H_WINSTL
00067 # include <winstl/winstl.h>
00068 #endif
00069 #ifndef STLSOFT_INCL_STLSOFT_INTERNAL_H_SAFESTR
00070 # include <stlsoft/internal/safestr.h>
00071 #endif
00072
00073 #if defined(WINSTL_OS_IS_WIN64) || \
00074 defined(_Wp64)
00075 # define _WINSTL_SYSTEM_TRAITS_USE_TRUNCATION_TESTING
00076 #endif
00077
00078 #ifdef _WINSTL_SYSTEM_TRAITS_USE_TRUNCATION_TESTING
00079 # ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00080 # ifndef STLSOFT_INCL_STLSOFT_CONVERSION_HPP_TRUNCATION_CAST
00081 # include <stlsoft/conversion/truncation_cast.hpp>
00082 # endif
00083 # else
00084 # ifndef STLSOFT_INCL_STLSOFT_CONVERSION_HPP_TRUNCATION_TEST
00085 # include <stlsoft/conversion/truncation_test.hpp>
00086 # endif
00087 # endif
00088 #endif
00089
00090 #ifndef STLSOFT_INCL_H_STRING
00091 # define STLSOFT_INCL_H_STRING
00092 # include <string.h>
00093 #endif
00094 #ifndef STLSOFT_INCL_H_WCHAR
00095 # define STLSOFT_INCL_H_WCHAR
00096 # include <wchar.h>
00097 #endif
00098
00099
00100
00101
00102
00103 #ifndef _WINSTL_NO_NAMESPACE
00104 # if defined(_STLSOFT_NO_NAMESPACE) || \
00105 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00106
00107 namespace winstl
00108 {
00109 # else
00110
00111
00112 namespace stlsoft
00113 {
00114
00115 namespace winstl_project
00116 {
00117
00118 # endif
00119 #endif
00120
00121
00122
00123
00124
00125 #ifdef STLSOFT_DOCUMENTATION_SKIP_SECTION
00126
00136 template <ss_typename_param_k C>
00137 struct system_traits
00138 {
00141 public:
00143 typedef C char_type;
00145 typedef ws_size_t size_type;
00147 typedef ws_ptrdiff_t difference_type;
00149 typedef system_traits<C> class_type;
00151 typedef ws_int_t int_type;
00153 typedef ws_bool_t bool_type;
00155 typedef HINSTANCE module_type;
00157 typedef HANDLE handle_type;
00159 typedef DWORD error_type;
00161
00164 public:
00166 static char_type* char_copy(char_type* dest, char_type const* src, size_type n);
00167 #if !defined(STLSOFT_USING_SAFE_STR_FUNCTIONS) || \
00168 defined(_CRT_SECURE_NO_DEPRECATE)
00170 static char_type* str_copy(char_type* dest, char_type const* src);
00172 static char_type* str_n_copy(char_type* dest, char_type const* src, size_type cch);
00174 static char_type* str_cat(char_type* dest, char_type const* src);
00176 static char_type* str_n_cat(char_type* dest, char_type const* src, size_type cch);
00177 #endif
00179 static int_type str_compare(char_type const* s1, char_type const* s2);
00181 static int_type str_compare_no_case(char_type const* s1, char_type const* s2);
00183 static int_type str_n_compare(char_type const* s1, char_type const* s2, size_type cch);
00185 static size_type str_len(char_type const* src);
00187 static char_type* str_chr(char_type const* s, char_type ch);
00189 static char_type* str_rchr(char_type const* s, char_type ch);
00191 static char_type* str_str(char_type const* s, char_type const* sub);
00193 static char_type* str_pbrk(char_type const* s, char_type const* charSet);
00195 static char_type* str_end(char_type const* s);
00199 static char_type* str_set(char_type* s, size_type n, char_type c);
00201
00204 public:
00206 #ifndef NONLS
00207 static int_type get_locale_info(LCID locale, LCTYPE type, char_type* data, int_type cchData);
00208 #endif
00210
00213 public:
00215 static size_type get_module_filename(HINSTANCE hModule, char_type* buffer, size_type cchBuffer);
00217 static size_type get_module_directory(HINSTANCE hModule, char_type* buffer, size_type cchBuffer);
00219 static size_type get_system_directory(char_type* buffer, size_type cchBuffer);
00221 static size_type get_windows_directory(char_type* buffer, size_type cchBuffer);
00223
00226 public:
00228 static module_type load_library(char_type const* name);
00230 static bool_type free_library(module_type hModule);
00232 static FARPROC find_symbol(module_type hModule, char const* symbolName);
00234
00237 public:
00239 static bool_type close_handle(handle_type h);
00241
00244 public:
00246 static error_type get_last_error();
00248 static void set_last_error(error_type er = error_type());
00250
00253 public:
00261 static size_type get_environment_variable(char_type const* name, char_type* buffer, size_type cchBuffer);
00263 static size_type expand_environment_strings(char_type const* src, char_type* buffer, size_type cchBuffer);
00265 };
00266
00267 #else
00268
00269 template <ss_typename_param_k C>
00270 struct system_traits;
00271
00272 struct system_traits_
00273 {
00274 public:
00275 typedef ws_size_t size_type;
00276 typedef ws_ptrdiff_t difference_type;
00277 typedef system_traits_ class_type;
00278 typedef ws_int_t int_type;
00279 typedef ws_bool_t bool_type;
00280 typedef HINSTANCE module_type;
00281 typedef HANDLE handle_type;
00282 typedef DWORD error_type;
00283
00284 class scoped_mem_block
00285 {
00286 public:
00287 ss_explicit_k scoped_mem_block(void* block)
00288 : m_block(block)
00289 {}
00290 ~scoped_mem_block() stlsoft_throw_0()
00291 {
00292 ::HeapFree(::GetProcessHeap(), 0, m_block);
00293 }
00294 private:
00295 scoped_mem_block(scoped_mem_block const&);
00296 scoped_mem_block& operator =(scoped_mem_block const&);
00297
00298 public:
00299 static ws_char_a_t* allocate_string_buffer_a(size_type n)
00300 {
00301 return static_cast<ws_char_a_t*>(::HeapAlloc(::GetProcessHeap(), 0, sizeof(ws_char_a_t) * (1 + n)));
00302 }
00303
00304 static ws_char_w_t* allocate_string_buffer_w(size_type n)
00305 {
00306 return static_cast<ws_char_w_t*>(::HeapAlloc(::GetProcessHeap(), 0, sizeof(ws_char_w_t) * (1 + n)));
00307 }
00308
00309 public:
00310 void* get() const
00311 {
00312 return m_block;
00313 }
00314
00315 private:
00316 void* m_block;
00317 };
00318
00319 public:
00320 static bool_type close_handle(handle_type h)
00321 {
00322 return FALSE != ::CloseHandle(h);
00323 }
00324
00325 public:
00326 static bool_type free_library(module_type hModule)
00327 {
00328 return FALSE != ::FreeLibrary(hModule);
00329 }
00330
00331 static FARPROC find_symbol(module_type hModule, char const* symbolName)
00332 {
00333 return ::GetProcAddress(hModule, symbolName);
00334 }
00335
00336 public:
00337 static error_type get_last_error()
00338 {
00339 return ::GetLastError();
00340 }
00341
00342 static void set_last_error(error_type er)
00343 {
00344 ::SetLastError(er);
00345 }
00346 };
00347
00348 STLSOFT_TEMPLATE_SPECIALISATION
00349 struct system_traits<ws_char_a_t>
00350 {
00351 public:
00352 typedef ws_char_a_t char_type;
00353 typedef ws_size_t size_type;
00354 typedef ws_ptrdiff_t difference_type;
00355 typedef system_traits<char_type> class_type;
00356 typedef ws_int_t int_type;
00357 typedef ws_bool_t bool_type;
00358 typedef HINSTANCE module_type;
00359 typedef HANDLE handle_type;
00360 typedef DWORD error_type;
00361
00362 public:
00363 static char_type* char_copy(char_type* dest, char_type const* src, size_type n)
00364 {
00365 WINSTL_ASSERT(NULL != dest);
00366 WINSTL_ASSERT(0 == n || NULL != src);
00367
00368 return static_cast<char_type*>(::memcpy(dest, src, sizeof(char_type) * n));
00369 }
00370
00371 #if !defined(STLSOFT_USING_SAFE_STR_FUNCTIONS) || \
00372 defined(_CRT_SECURE_NO_DEPRECATE)
00373 static char_type* str_copy(char_type* dest, char_type const* src)
00374 {
00375 WINSTL_ASSERT(NULL != dest);
00376 WINSTL_ASSERT(NULL != src);
00377
00378 # ifdef STLSOFT_MIN_CRT
00379 return ::lstrcpyA(dest, src);
00380 # else
00381 return ::strcpy(dest, src);
00382 # endif
00383 }
00384
00385 static char_type* str_n_copy(char_type* dest, char_type const* src, size_type cch)
00386 {
00387 WINSTL_ASSERT(NULL != dest);
00388 WINSTL_ASSERT(0 == cch || NULL != src);
00389
00390 return ::strncpy(dest, src, cch);
00391 }
00392
00393 static char_type* str_cat(char_type* dest, char_type const* src)
00394 {
00395 WINSTL_ASSERT(NULL != dest);
00396 WINSTL_ASSERT(NULL != src);
00397
00398 # ifdef STLSOFT_MIN_CRT
00399 return ::lstrcatA(dest, src);
00400 # else
00401 return ::strcat(dest, src);
00402 # endif
00403 }
00404
00405 static char_type* str_n_cat(char_type* dest, char_type const* src, size_type cch)
00406 {
00407 WINSTL_ASSERT(NULL != dest);
00408 WINSTL_ASSERT(NULL != src);
00409
00410 return ::strncat(dest, src, cch);
00411 }
00412 #endif
00413
00414 static int_type str_compare(char_type const* s1, char_type const* s2)
00415 {
00416 WINSTL_ASSERT(NULL != s1);
00417 WINSTL_ASSERT(NULL != s2);
00418
00419 #ifdef STLSOFT_MIN_CRT
00420 return ::lstrcmpA(s1, s2);
00421 #else
00422 return ::strcmp(s1, s2);
00423 #endif
00424 }
00425
00426 static int_type str_compare_no_case(char_type const* s1, char_type const* s2)
00427 {
00428 WINSTL_ASSERT(NULL != s1);
00429 WINSTL_ASSERT(NULL != s2);
00430
00431 return ::lstrcmpiA(s1, s2);
00432 }
00433
00434 static int_type str_n_compare(char_type const* s1, char_type const* s2, size_type cch)
00435 {
00436 WINSTL_ASSERT(NULL != s1);
00437 WINSTL_ASSERT(NULL != s2);
00438
00439 return ::strncmp(s1, s2, cch);
00440 }
00441
00442 static size_type str_len(char_type const* src)
00443 {
00444 WINSTL_ASSERT(NULL != src);
00445
00446 #ifdef STLSOFT_MIN_CRT
00447 return static_cast<size_type>(::lstrlenA(src));
00448 #else
00449 return ::strlen(src);
00450 #endif
00451 }
00452
00453 static char_type* str_chr(char_type const* s, char_type ch)
00454 {
00455 WINSTL_ASSERT(NULL != s);
00456
00457 return const_cast<char_type*>(::strchr(s, ch));
00458 }
00459
00460 static char_type* str_rchr(char_type const* s, char_type ch)
00461 {
00462 WINSTL_ASSERT(NULL != s);
00463
00464 return const_cast<char_type*>(::strrchr(s, ch));
00465 }
00466
00467 static char_type* str_str(char_type const* s, char_type const* sub)
00468 {
00469 WINSTL_ASSERT(NULL != s);
00470 WINSTL_ASSERT(NULL != sub);
00471
00472 return const_cast<char_type*>(::strstr(s, sub));
00473 }
00474
00475 static char_type* str_pbrk(char_type const* s, char_type const* charSet)
00476 {
00477 WINSTL_ASSERT(NULL != s);
00478 WINSTL_ASSERT(NULL != charSet);
00479
00480 return const_cast<char_type*>(::strpbrk(s, charSet));
00481 }
00482
00483 static char_type* str_end(char_type const* s)
00484 {
00485 WINSTL_ASSERT(NULL != s);
00486
00487 for(; *s != '\0'; ++s)
00488 {}
00489
00490 return const_cast<char_type*>(s);
00491 }
00492
00493 static char_type* str_set(char_type* s, size_type n, char_type c)
00494 {
00495 WINSTL_ASSERT(NULL != s || 0u == n);
00496
00497 for(; 0u != n; --n, ++s)
00498 {
00499 *s = c;
00500 }
00501
00502 return s;
00503 }
00504
00505 public:
00506 #ifndef NONLS
00507 static int_type get_locale_info(LCID locale, LCTYPE type, char_type* data, int cchData)
00508 {
00509 return ::GetLocaleInfoA(locale, type, data, cchData);
00510 }
00511 #endif
00512
00513 public:
00514 static size_type get_module_filename(HINSTANCE hModule, char_type* buffer, size_type cchBuffer)
00515 {
00516 WINSTL_ASSERT(NULL != buffer || 0 == cchBuffer);
00517
00518 if(0 == cchBuffer)
00519 {
00520 char_type buff[1 + WINSTL_CONST_MAX_PATH];
00521
00522 return get_module_filename(hModule, &buff[0], STLSOFT_NUM_ELEMENTS(buff));
00523 }
00524
00525 return class_type::GetModuleFileNameA(hModule, buffer, cchBuffer);
00526 }
00527
00528 static size_type get_module_directory(HINSTANCE hModule, char_type* buffer, size_type cchBuffer)
00529 {
00530 WINSTL_ASSERT(NULL != buffer || 0 == cchBuffer);
00531
00532 size_type cch = get_module_filename(hModule, buffer, cchBuffer);
00533
00534 if( 0 != cch &&
00535 cch < cchBuffer)
00536 {
00537 buffer[cch] = '\0';
00538
00539 char_type *s = str_rchr(buffer, '\\');
00540
00541 if(NULL != s)
00542 {
00543 *s = '\0';
00544
00545 cch = static_cast<size_type>(s - buffer);
00546 }
00547 }
00548
00549 return cch;
00550 }
00551
00552 static size_type get_system_directory(char_type* buffer, size_type cchBuffer)
00553 {
00554 WINSTL_ASSERT(NULL != buffer || 0 == cchBuffer);
00555
00556 return class_type::GetSystemDirectoryA(buffer, cchBuffer);
00557 }
00558
00559 static size_type get_windows_directory(char_type* buffer, size_type cchBuffer)
00560 {
00561 WINSTL_ASSERT(NULL != buffer || 0 == cchBuffer);
00562
00563 return class_type::GetWindowsDirectoryA(buffer, cchBuffer);
00564 }
00565
00566 public:
00567 static module_type load_library(char_type const* name)
00568 {
00569 WINSTL_ASSERT(NULL != name);
00570
00571 return ::LoadLibraryA(name);
00572 }
00573
00574 static bool_type free_library(module_type hModule)
00575 {
00576 return system_traits_::free_library(hModule);
00577 }
00578
00579 static FARPROC find_symbol(module_type hModule, char const* symbolName)
00580 {
00581 WINSTL_ASSERT(NULL != symbolName);
00582
00583 return system_traits_::find_symbol(hModule, symbolName);
00584 }
00585
00586 static bool_type close_handle(handle_type h)
00587 {
00588 return system_traits_::close_handle(h);
00589 }
00590
00591 public:
00592 static error_type get_last_error()
00593 {
00594 return system_traits_::get_last_error();
00595 }
00596
00597 static void set_last_error(error_type er = error_type())
00598 {
00599 system_traits_::set_last_error(er);
00600 }
00601
00602 public:
00603 static size_type get_environment_variable(char_type const* name, char_type* buffer, size_type cchBuffer)
00604 {
00605 WINSTL_ASSERT(NULL != name);
00606 WINSTL_ASSERT(NULL != buffer || 0 == cchBuffer);
00607
00608 char_type dummy[1];
00609
00610
00611
00612
00613 if(NULL == buffer)
00614 {
00615 buffer = &dummy[0];
00616 cchBuffer = 0u;
00617 }
00618
00619 size_type n = class_type::GetEnvironmentVariableA(name, buffer, cchBuffer);
00620
00621 if(n > cchBuffer)
00622 {
00623 --n;
00624 }
00625
00626 if( 0u != cchBuffer &&
00627 n >= cchBuffer)
00628 {
00629 typedef system_traits_::scoped_mem_block scoped_mem_block;
00630
00631 char_type* buffer2 = scoped_mem_block::allocate_string_buffer_a(n);
00632
00633 if(NULL == buffer2)
00634 {
00635 return 0;
00636 }
00637 else
00638 {
00639 scoped_mem_block block(buffer2);
00640 size_type n2 = class_type::GetEnvironmentVariableA(name, buffer2, 1 + n);
00641
00642 if(n2 > cchBuffer)
00643 {
00644 n2 = cchBuffer;
00645 }
00646
00647 char_copy(buffer, buffer2, n2);
00648
00649 return n2;
00650 }
00651 }
00652
00653 return n;
00654 }
00655
00656 static size_type expand_environment_strings(char_type const* src, char_type* dest, size_type cch_dest)
00657 {
00658 WINSTL_ASSERT(NULL != src);
00659 WINSTL_ASSERT(NULL != dest || 0 == cch_dest);
00660
00661 return class_type::ExpandEnvironmentStringsA(src, dest, cch_dest);
00662 }
00663
00664 private:
00665 static size_type GetModuleFileNameA(HINSTANCE hModule, char_type* buffer, size_type cchBuffer)
00666 {
00667 #ifdef _WINSTL_SYSTEM_TRAITS_USE_TRUNCATION_TESTING
00668 # ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00669 return ::GetModuleFileNameA(hModule, buffer, stlsoft_ns_qual(truncation_cast)<DWORD>(cchBuffer));
00670 # else
00671 WINSTL_MESSAGE_ASSERT("buffer size out of range", stlsoft_ns_qual(truncation_test)<DWORD>(cchBuffer));
00672
00673 return ::GetModuleFileNameA(hModule, buffer, static_cast<DWORD>(cchBuffer));
00674 # endif
00675 #else
00676 return ::GetModuleFileNameA(hModule, buffer, cchBuffer);
00677 #endif
00678 }
00679
00680 static size_type GetSystemDirectoryA(char_type* buffer, size_type cchBuffer)
00681 {
00682 #ifdef _WINSTL_SYSTEM_TRAITS_USE_TRUNCATION_TESTING
00683 # ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00684 return ::GetSystemDirectoryA(buffer, stlsoft_ns_qual(truncation_cast)<DWORD>(cchBuffer));
00685 # else
00686 WINSTL_MESSAGE_ASSERT("buffer size out of range", stlsoft_ns_qual(truncation_test)<DWORD>(cchBuffer));
00687
00688 return ::GetSystemDirectoryA(buffer, static_cast<DWORD>(cchBuffer));
00689 # endif
00690 #else
00691 return ::GetSystemDirectoryA(buffer, cchBuffer);
00692 #endif
00693 }
00694
00695 static size_type GetWindowsDirectoryA(char_type* buffer, size_type cchBuffer)
00696 {
00697 #ifdef _WINSTL_SYSTEM_TRAITS_USE_TRUNCATION_TESTING
00698 # ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00699 return ::GetWindowsDirectoryA(buffer, stlsoft_ns_qual(truncation_cast)<DWORD>(cchBuffer));
00700 # else
00701 WINSTL_MESSAGE_ASSERT("buffer size out of range", stlsoft_ns_qual(truncation_test)<DWORD>(cchBuffer));
00702
00703 return ::GetWindowsDirectoryA(buffer, static_cast<DWORD>(cchBuffer));
00704 # endif
00705 #else
00706 return ::GetWindowsDirectoryA(buffer, cchBuffer);
00707 #endif
00708 }
00709
00710 static size_type GetEnvironmentVariableA(char_type const* name, char_type* buffer, size_type cchBuffer)
00711 {
00712 #ifdef _WINSTL_SYSTEM_TRAITS_USE_TRUNCATION_TESTING
00713 # ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00714 return ::GetEnvironmentVariableA(name, buffer, stlsoft_ns_qual(truncation_cast)<DWORD>(cchBuffer));
00715 # else
00716 WINSTL_MESSAGE_ASSERT("buffer size out of range", stlsoft_ns_qual(truncation_test)<DWORD>(cchBuffer));
00717
00718 return ::GetEnvironmentVariableA(name, buffer, static_cast<DWORD>(cchBuffer));
00719 # endif
00720 #else
00721 return ::GetEnvironmentVariableA(name, buffer, cchBuffer);
00722 #endif
00723 }
00724
00725 static size_type ExpandEnvironmentStringsA(char_type const* src, char_type* dest, size_type cch_dest)
00726 {
00727 #ifdef _WINSTL_SYSTEM_TRAITS_USE_TRUNCATION_TESTING
00728 # ifdef STLSOFT_CF_EXCEPTION_SUPPORT
00729 return ::ExpandEnvironmentStringsA(src, dest, stlsoft_ns_qual(truncation_cast)<DWORD>(cch_dest));
00730 # else
00731 WINSTL_MESSAGE_ASSERT("buffer size out of range", stlsoft_ns_qual(truncation_test)<DWORD>(cch_dest));
00732
00733 return ::ExpandEnvironmentStringsA(src, dest, static_cast<DWORD>(cch_dest));
00734 # endif
00735 #else
00736 return ::ExpandEnvironmentStringsA(src, dest, cch_dest);
00737 #endif
00738 }
00739 };
00740
00741 STLSOFT_TEMPLATE_SPECIALISATION
00742 struct system_traits<ws_char_w_t>
00743 {
00744 public:
00745 typedef ws_char_w_t char_type;
00746 typedef ws_size_t size_type;
00747 typedef ws_ptrdiff_t difference_type;
00748 typedef system_traits<char_type> class_type;
00749 typedef ws_int_t int_type;
00750 typedef ws_bool_t bool_type;
00751 typedef HINSTANCE module_type;
00752 typedef HANDLE handle_type;
00753 typedef DWORD error_type;
00754
00755 public:
00756 static char_type* char_copy(char_type* dest, char_type const* src, size_type n)
00757 {
00758 WINSTL_ASSERT(NULL != dest);
00759 WINSTL_ASSERT(0 == n || NULL != src);
00760
00761 return static_cast<char_type*>(::memcpy(dest, src, sizeof(char_type) * n));
00762 }
00763
00764 #if !defined(STLSOFT_USING_SAFE_STR_FUNCTIONS) || \
00765 defined(_CRT_SECURE_NO_DEPRECATE)
00766 static char_type* str_copy(char_type* dest, char_type const* src)
00767 {
00768 WINSTL_ASSERT(NULL != dest);
00769 WINSTL_ASSERT(NULL != src);
00770
00771 # ifdef STLSOFT_MIN_CRT
00772 return ::lstrcpyW(dest, src);
00773 # else
00774 return ::wcscpy(dest, src);
00775 # endif
00776 }
00777
00778 static char_type* str_n_copy(char_type* dest, char_type const* src, size_type cch)
00779 {
00780 WINSTL_ASSERT(NULL != dest);
00781 WINSTL_ASSERT(0 == cch || NULL != src);
00782
00783 return ::wcsncpy(dest, src, cch);
00784 }
00785
00786 static char_type* str_cat(char_type* dest, char_type const* src)
00787 {
00788 WINSTL_ASSERT(NULL != dest);
00789 WINSTL_ASSERT(NULL != src);
00790
00791 # ifdef STLSOFT_MIN_CRT
00792 return ::lstrcatW(dest, src);
00793 # else
00794 return ::wcscat(dest, src);
00795 # endif
00796 }
00797
00798 static char_type* str_n_cat(char_type* dest, char_type const* src, size_type cch)
00799 {
00800 WINSTL_ASSERT(NULL != dest);
00801 WINSTL_ASSERT(NULL != src);
00802
00803 return ::wcsncat(dest, src, cch);
00804 }
00805 #endif
00806
00807 static int_type str_compare(char_type const* s1, char_type const* s2)
00808 {
00809 WINSTL_ASSERT(NULL != s1);
00810 WINSTL_ASSERT(NULL != s2);
00811
00812 #ifdef STLSOFT_MIN_CRT
00813 return ::lstrcmpW(s1, s2);
00814 #else
00815 return ::wcscmp(s1, s2);
00816 #endif
00817 }
00818
00819 static int_type str_compare_no_case(char_type const* s1, char_type const* s2)
00820 {
00821 WINSTL_ASSERT(NULL != s1);
00822 WINSTL_ASSERT(NULL != s2);
00823
00824 return ::lstrcmpiW(s1, s2);
00825 }
00826
00827 static int_type str_n_compare(char_type const* s1, char_type const* s2, size_type cch)
00828 {
00829 WINSTL_ASSERT(NULL != s1);
00830 WINSTL_ASSERT(NULL != s2);
00831
00832 return ::wcsncmp(s1, s2, cch);
00833 }
00834
00835 static size_type str_len(char_type const* src)
00836 {
00837 WINSTL_ASSERT(NULL != src);
00838
00839 #ifdef STLSOFT_MIN_CRT
00840 return static_cast<size_type>(::lstrlenW(src));
00841 #else
00842 return ::wcslen(src);
00843 #endif
00844 }
00845
00846 static char_type* str_chr(char_type const* s, char_type ch)
00847 {
00848 WINSTL_ASSERT(NULL != s);
00849
00850 return const_cast<char_type*>(::wcschr(s, ch));
00851 }
00852
00853 static char_type* str_rchr(char_type const* s, char_type ch)
00854 {
00855 WINSTL_ASSERT(NULL != s);
00856
00857 return const_cast<char_type*>(::wcsrchr(s, ch));
00858 }
00859
00860 static char_type* str_str(char_type const* s, char_type const* sub)
00861 {
00862 WINSTL_ASSERT(NULL != s);
00863 WINSTL_ASSERT(NULL != sub);
00864
00865 return const_cast<char_type*>(::wcsstr(s, sub));
00866 }
00867
00868 static char_type* str_pbrk(char_type const* s, char_type const* charSet)
00869 {
00870 WINSTL_ASSERT(NULL != s);
00871 WINSTL_ASSERT(NULL != charSet);
00872
00873 return const_cast<char_type*>(::wcspbrk(s, charSet));
00874 }
00875
00876 static char_type* str_end(char_type const* s)
00877 {
00878 WINSTL_ASSERT(NULL != s);
00879
00880 for(; *s != L'\0'; ++s)
00881 {}
00882
00883 return const_cast<char_type*>(s);
00884 }
00885
00886 static char_type* str_set(char_type* s, size_type n, char_type c)
00887 {
00888 WINSTL_ASSERT(NULL != s || 0u == n);
00889
00890 for(; 0u != n; --n, ++s)
00891 {
00892 *s = c;
00893 }
00894
00895 return s;
00896 }
00897
00898 public:
00899 #ifndef NONLS
00900 static int_type get_locale_info(LCID locale, LCTYPE type, char_type* data, int cchData)
00901 {
00902 return ::GetLocaleInfoW(locale, type, data, cchData);
00903 }
00904 #endif
00905
00906 public:
00907 static size_type get_module_filename(HINSTANCE hModule, char_type* buffer, size_type cchBuffer)
00908 {
00909 WINSTL_ASSERT(NULL != buffer || 0 == cchBuffer);
00910
00911 if(0 == cchBuffer)
00912 {
00913 char_type buff[1 + WINSTL_CONST_MAX_PATH];
00914 size_type cch = get_module_filename(hModule, &buff[0], STLSOFT_NUM_ELEMENTS(buff));
00915
00916 if(0 == str_compare(L"\\\\?\\", buff))
00917 {
00918 return 1 + CONST_NT_MAX_PATH;
00919 }
00920 else
00921 {
00922 return cch;
00923 }
00924 }
00925
00926 return class_type::GetModuleFileNameW(hModule, buffer, cchBuffer);
00927 }
00928
00929 static size_type get_module_directory(HINSTANCE hModule, char_type* buffer, size_type cchBuffer)
00930 {
00931 WINSTL_ASSERT(NULL != buffer || 0 == cchBuffer);
00932
00933 size_type cch = get_module_filename(hModule, buffer, cchBuffer);
00934
00935 if( 0 != cch &&
00936 cch < cchBuffer)
00937 {
00938 buffer[cch] = '\0';
00939
00940 char_type *s = str_rchr(buffer, '\\');
00941
00942 if(NULL != s)
00943 {
00944 *s = '\0';
00945
00946 cch = static_cast<size_type>(s - buffer);
00947 }
00948 }
00949
00950 return cch;
00951 }
00952
00953 static size_type get_system_directory(char_type* buffer, size_type cchBuffer)
00954 {
00955 WINSTL_ASSERT(NULL != buffer || 0 == cchBuffer);
00956
00957 return class_type::GetSystemDirectoryW(buffer, cchBuffer);
00958 }
00959
00960 static size_type get_windows_directory(char_type* buffer, size_type cchBuffer)
00961 {
00962 WINSTL_ASSERT(NULL != buffer || 0 == cchBuffer);
00963
00964 return class_type::GetWindowsDirectoryW(buffer, cchBuffer);
00965 }
00966
00967 public:
00968 static module_type load_library(char_type const* name)
00969 {
00970 WINSTL_ASSERT(NULL != name);
00971
00972 return ::LoadLibraryW(name);
00973 }
00974
00975 static bool_type free_library(module_type hModule)
00976 {
00977 return system_traits_::free_library(hModule);
00978 }
00979
00980 static FARPROC find_symbol(module_type hModule, char const* symbolName)
00981 {
00982 WINSTL_ASSERT(NULL != symbolName);
00983
00984 return system_traits_::find_symbol(hModule, symbolName);
00985 }
00986
00987 public:
00988 static bool_type close_handle(handle_type h)
00989 {
00990 return system_traits_::close_handle(h);
00991 }
00992
00993 public:
00994 static error_type get_last_error()
00995 {
00996 return system_traits_::get_last_error();
00997 }
00998
00999 static void set_last_error(error_type er = error_type())
01000 {
01001 system_traits_::set_last_error(er);
01002 }
01003
01004 public:
01005 static size_type get_environment_variable(char_type const* name, char_type* buffer, size_type cchBuffer)
01006 {
01007 WINSTL_ASSERT(NULL != name);
01008 WINSTL_ASSERT(NULL != buffer || 0 == cchBuffer);
01009
01010 char_type dummy[1];
01011
01012
01013
01014
01015 if(NULL == buffer)
01016 {
01017 buffer = &dummy[0];
01018 cchBuffer = 0u;
01019 }
01020
01021 size_type n = class_type::GetEnvironmentVariableW(name, buffer, cchBuffer);
01022
01023 if(n > cchBuffer)
01024 {
01025 --n;
01026 }
01027
01028 if( 0u != cchBuffer &&
01029 n >= cchBuffer)
01030 {
01031 typedef system_traits_::scoped_mem_block scoped_mem_block;
01032
01033 char_type* buffer2 = scoped_mem_block::allocate_string_buffer_w(n);
01034
01035 if(NULL == buffer2)
01036 {
01037 return 0;
01038 }
01039 else
01040 {
01041 scoped_mem_block block(buffer2);
01042 size_type n2 = class_type::GetEnvironmentVariableW(name, buffer2, 1 + n);
01043
01044 if(n2 > cchBuffer)
01045 {
01046 n2 = cchBuffer;
01047 }
01048
01049 char_copy(buffer, buffer2, n2);
01050
01051 return n2;
01052 }
01053 }
01054
01055 return n;
01056 }
01057
01058 static size_type expand_environment_strings(char_type const* src, char_type* dest, size_type cch_dest)
01059 {
01060 WINSTL_ASSERT(NULL != src);
01061 WINSTL_ASSERT(NULL != dest || 0 == cch_dest);
01062
01063 return class_type::ExpandEnvironmentStringsW(src, dest, cch_dest);
01064 }
01065
01066 private:
01067 static size_type GetModuleFileNameW(HINSTANCE hModule, char_type* buffer, size_type cchBuffer)
01068 {
01069 #ifdef _WINSTL_SYSTEM_TRAITS_USE_TRUNCATION_TESTING
01070 # ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01071 return ::GetModuleFileNameW(hModule, buffer, stlsoft_ns_qual(truncation_cast)<DWORD>(cchBuffer));
01072 # else
01073 WINSTL_MESSAGE_ASSERT("buffer size out of range", stlsoft_ns_qual(truncation_test)<DWORD>(cchBuffer));
01074
01075 return ::GetModuleFileNameW(hModule, buffer, static_cast<DWORD>(cchBuffer));
01076 # endif
01077 #else
01078 return ::GetModuleFileNameW(hModule, buffer, cchBuffer);
01079 #endif
01080 }
01081
01082 static size_type GetSystemDirectoryW(char_type* buffer, size_type cchBuffer)
01083 {
01084 #ifdef _WINSTL_SYSTEM_TRAITS_USE_TRUNCATION_TESTING
01085 # ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01086 return ::GetSystemDirectoryW(buffer, stlsoft_ns_qual(truncation_cast)<DWORD>(cchBuffer));
01087 # else
01088 WINSTL_MESSAGE_ASSERT("buffer size out of range", stlsoft_ns_qual(truncation_test)<DWORD>(cchBuffer));
01089
01090 return ::GetSystemDirectoryW(buffer, static_cast<DWORD>(cchBuffer));
01091 # endif
01092 #else
01093 return ::GetSystemDirectoryW(buffer, cchBuffer);
01094 #endif
01095 }
01096
01097 static size_type GetWindowsDirectoryW(char_type* buffer, size_type cchBuffer)
01098 {
01099 #ifdef _WINSTL_SYSTEM_TRAITS_USE_TRUNCATION_TESTING
01100 # ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01101 return ::GetWindowsDirectoryW(buffer, stlsoft_ns_qual(truncation_cast)<DWORD>(cchBuffer));
01102 # else
01103 WINSTL_MESSAGE_ASSERT("buffer size out of range", stlsoft_ns_qual(truncation_test)<DWORD>(cchBuffer));
01104
01105 return ::GetWindowsDirectoryW(buffer, static_cast<DWORD>(cchBuffer));
01106 # endif
01107 #else
01108 return ::GetWindowsDirectoryW(buffer, cchBuffer);
01109 #endif
01110 }
01111
01112 static size_type GetEnvironmentVariableW(char_type const* name, char_type* buffer, size_type cchBuffer)
01113 {
01114 #ifdef _WINSTL_SYSTEM_TRAITS_USE_TRUNCATION_TESTING
01115 # ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01116 return ::GetEnvironmentVariableW(name, buffer, stlsoft_ns_qual(truncation_cast)<DWORD>(cchBuffer));
01117 # else
01118 WINSTL_MESSAGE_ASSERT("buffer size out of range", stlsoft_ns_qual(truncation_test)<DWORD>(cchBuffer));
01119
01120 return ::GetEnvironmentVariableW(name, buffer, static_cast<DWORD>(cchBuffer));
01121 # endif
01122 #else
01123 return ::GetEnvironmentVariableW(name, buffer, cchBuffer);
01124 #endif
01125 }
01126
01127 static size_type ExpandEnvironmentStringsW(char_type const* src, char_type* dest, size_type cch_dest)
01128 {
01129 #ifdef _WINSTL_SYSTEM_TRAITS_USE_TRUNCATION_TESTING
01130 # ifdef STLSOFT_CF_EXCEPTION_SUPPORT
01131 return ::ExpandEnvironmentStringsW(src, dest, stlsoft_ns_qual(truncation_cast)<DWORD>(cch_dest));
01132 # else
01133 WINSTL_MESSAGE_ASSERT("buffer size out of range", stlsoft_ns_qual(truncation_test)<DWORD>(cch_dest));
01134
01135 return ::ExpandEnvironmentStringsW(src, dest, static_cast<DWORD>(cch_dest));
01136 # endif
01137 #else
01138 return ::ExpandEnvironmentStringsW(src, dest, cch_dest);
01139 #endif
01140 }
01141 };
01142
01143 #endif
01144
01145
01146
01147
01148
01149 #ifdef STLSOFT_UNITTEST
01150 # include "./unittest/system_traits_unittest_.h"
01151 #endif
01152
01153
01154
01155 #ifndef _WINSTL_NO_NAMESPACE
01156 # if defined(_STLSOFT_NO_NAMESPACE) || \
01157 defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
01158 }
01159 # else
01160 }
01161 }
01162 # endif
01163 #endif
01164
01165
01166
01167 #endif
01168
01169