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 
00050 #ifndef WINSTL_INCL_WINSTL_TIME_HPP_FORMAT_FUNCTIONS
00051 #define WINSTL_INCL_WINSTL_TIME_HPP_FORMAT_FUNCTIONS
00052 
00053 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00054 # define WINSTL_VER_WINSTL_TIME_HPP_FORMAT_FUNCTIONS_MAJOR      5
00055 # define WINSTL_VER_WINSTL_TIME_HPP_FORMAT_FUNCTIONS_MINOR      0
00056 # define WINSTL_VER_WINSTL_TIME_HPP_FORMAT_FUNCTIONS_REVISION   4
00057 # define WINSTL_VER_WINSTL_TIME_HPP_FORMAT_FUNCTIONS_EDIT       58
00058 #endif 
00059 
00060 
00061 
00062 
00063 
00064 #ifndef WINSTL_INCL_WINSTL_H_WINSTL
00065 # include <winstl/winstl.h>
00066 #endif 
00067 #ifndef STLSOFT_INCL_STLSOFT_HPP_MEMORY_AUTO_BUFFER
00068 # include <stlsoft/memory/auto_buffer.hpp>
00069 #endif 
00070 #ifndef STLSOFT_INCL_STLSOFT_CONVERSION_HPP_INTEGER_TO_STRING
00071 # include <stlsoft/conversion/integer_to_string.hpp>
00072 #endif 
00073 #ifndef WINSTL_INCL_WINSTL_MEMORY_HPP_PROCESSHEAP_ALLOCATOR
00074 # include <winstl/memory/processheap_allocator.hpp>
00075 #endif 
00076 #ifndef WINSTL_INCL_WINSTL_REGISTRY_HPP_FUNCTIONS
00077 # include <winstl/registry/functions.hpp>   
00078 #endif 
00079 
00080 
00081 
00082 
00083 
00084 #ifndef _WINSTL_NO_NAMESPACE
00085 # if defined(_STLSOFT_NO_NAMESPACE) || \
00086      defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00087 
00088 namespace winstl
00089 {
00090 # else
00091 
00092 
00093 namespace stlsoft
00094 {
00095 
00096 namespace winstl_project
00097 {
00098 
00099 # endif 
00100 #endif 
00101 
00102 
00103 
00104 
00105 
00106 #ifndef STLSOFT_DOCUMENTATION_SKIP_SECTION
00107 
00108 template <ss_typename_param_k C>
00109 struct time_format_functions_traits;
00110 
00111 STLSOFT_TEMPLATE_SPECIALISATION
00112 struct time_format_functions_traits<ws_char_a_t>
00113 {
00114     typedef ws_char_a_t char_type;
00115 
00116     static int GetTimeFormat(LCID Locale, DWORD dwFlags, SYSTEMTIME const* lpTime, char_type const* lpFormat, char_type *lpTimeStr, int cchTime)
00117     {
00118         return ::GetTimeFormatA(Locale, dwFlags, lpTime, lpFormat, lpTimeStr, cchTime);
00119     }
00120     static int GetLocaleInfo(LCID Locale, LCTYPE LCType, char_type *lpLCData, int cchData)
00121     {
00122         return ::GetLocaleInfoA(Locale, LCType, lpLCData, cchData);
00123     }
00124     static ss_size_t lstrlen(char_type const* s)
00125     {
00126         return static_cast<ss_size_t>(::lstrlenA(s));
00127     }
00128     static char_type *lstrcpy(char_type *dest, char_type const* src)
00129     {
00130         return ::lstrcpyA(dest, src);
00131     }
00132 };
00133 
00134 STLSOFT_TEMPLATE_SPECIALISATION
00135 struct time_format_functions_traits<ws_char_w_t>
00136 {
00137     typedef ws_char_w_t char_type;
00138 
00139     static int GetTimeFormat(LCID Locale, DWORD dwFlags, SYSTEMTIME const* lpTime, char_type const* lpFormat, char_type *lpTimeStr, int cchTime)
00140     {
00141         return ::GetTimeFormatW(Locale, dwFlags, lpTime, lpFormat, lpTimeStr, cchTime);
00142     }
00143     static int GetLocaleInfo(LCID Locale, LCTYPE LCType, char_type *lpLCData, int cchData)
00144     {
00145         return ::GetLocaleInfoW(Locale, LCType, lpLCData, cchData);
00146     }
00147     static ss_size_t lstrlen(char_type const* s)
00148     {
00149         return static_cast<ss_size_t>(::lstrlenW(s));
00150     }
00151     static char_type *lstrcpy(char_type *dest, char_type const* src)
00152     {
00153         return ::lstrcpyW(dest, src);
00154     }
00155 };
00156 
00157 #endif 
00158 
00159 
00160 
00161 
00162 
00163 template <ss_typename_param_k C>
00164 inline int STLSOFT_STDCALL GetTimeFormat_ms_(   LCID                locale      
00165                                             ,   DWORD               dwFlags     
00166                                             ,   CONST SYSTEMTIME    *lpTime     
00167                                             ,   C const             *lpFormat   
00168                                             ,   C                   *lpTimeStr  
00169                                             ,   const int           cchTime)    
00170 {
00171     typedef C                                                               char_t;
00172     typedef time_format_functions_traits<char_t>                            traits_t;
00173     typedef stlsoft_ns_qual(auto_buffer_old)<   char_t
00174                                             ,   processheap_allocator<char_t>
00175                                             >                               buffer_t;
00176 
00177     if(dwFlags & (TIME_NOMINUTESORSECONDS | TIME_NOSECONDS))
00178     {
00179         return traits_t::GetTimeFormat(locale, dwFlags, lpTime, lpFormat, lpTimeStr, cchTime);
00180     }
00181 
00182     if(dwFlags & LOCALE_NOUSEROVERRIDE)
00183     {
00184         locale = LOCALE_SYSTEM_DEFAULT;
00185     }
00186 
00187     buffer_t            timePicture(1 + ((NULL == lpFormat) ? static_cast<ss_size_t>(::GetLocaleInfoA(locale, LOCALE_STIMEFORMAT, NULL, 0)) : 0));
00188 
00189     if(NULL == lpFormat)
00190     {
00191         ss_size_t   n = static_cast<ss_size_t>(traits_t::GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_STIMEFORMAT, &timePicture[0], static_cast<int>(timePicture.size())));
00192         lpFormat = &timePicture[0];
00193         if(n < timePicture.size())
00194         {
00195             timePicture[n] = static_cast<C>('\0');
00196         }
00197     }
00198 
00199     const ss_size_t     cchPicture  =   1 + traits_t::lstrlen(lpFormat);
00200 
00201     char_t         hours12_[]  =   { '0', '0', '\0' };                      
00202     char_t         hours24_[]  =   { '0', '0', '\0' };                      
00203     char_t         minutes_[]  =   { '0', '0', '\0' };                      
00204     char_t         seconds_[]  =   { '0', '0', '.', '0', '0', '0', '\0' };  
00205 
00206     char_t const   *hours12    =   stlsoft_ns_qual(integer_to_string)(&hours12_[0], STLSOFT_NUM_ELEMENTS(hours12_), (lpTime->wHour > 12) ? (lpTime->wHour - 12) : lpTime->wHour);
00207     char_t const   *hours24    =   stlsoft_ns_qual(integer_to_string)(&hours24_[0], STLSOFT_NUM_ELEMENTS(hours24_), lpTime->wHour);
00208     char_t const   *minutes    =   stlsoft_ns_qual(integer_to_string)(&minutes_[0], STLSOFT_NUM_ELEMENTS(minutes_), lpTime->wMinute);
00209                                    stlsoft_ns_qual(integer_to_string)(&seconds_[3], 4, lpTime->wMilliseconds);
00210     char_t const   *seconds    =   stlsoft_ns_qual(integer_to_string)(&seconds_[0], 3, lpTime->wSecond);
00211 
00212     seconds_[2] = '.';
00213 
00214     
00215     HKEY        hkey;
00216     LONG        res =   ::RegOpenKeyA(HKEY_CURRENT_USER, "Control Panel\\International", &hkey);
00217     buffer_t    am(0);
00218     buffer_t    pm(0);
00219 
00220     if(ERROR_SUCCESS == res)
00221     {
00222         static const char_t s1159[] =   { 's', '1', '1', '5', '9', '\0' };
00223         static const char_t s2359[] =   { 's', '2', '3', '5', '9', '\0' };
00224         ws_size_t           cchAM   =   0;
00225         ws_size_t           cchPM   =   0;
00226         LONG                r;
00227 
00228         if( ERROR_SUCCESS != (r = reg_get_string_value(hkey, s1159, static_cast<char_t*>(NULL), cchAM)) ||
00229             ERROR_SUCCESS != (r = (am.resize(cchAM), cchAM = am.size(), reg_get_string_value(hkey, s1159, &am[0], cchAM))))
00230         {
00231             res = r;
00232         }
00233         else if(ERROR_SUCCESS != (r = reg_get_string_value(hkey, s2359, static_cast<char_t*>(NULL), cchPM)) ||
00234                 ERROR_SUCCESS != (r = (pm.resize(cchPM), cchPM = pm.size(), reg_get_string_value(hkey, s2359, &pm[0], cchPM))))
00235         {
00236             res = r;
00237         }
00238 
00239         ::RegCloseKey(hkey);
00240     }
00241 
00242     if(ERROR_SUCCESS != res)
00243     {
00244         static const char_t AM[]    =   { 'A', 'M', '\0' };
00245         static const char_t PM[]    =   { 'P', 'M', '\0' };
00246 
00247         am.resize(3);
00248         pm.resize(3);
00249 
00250         traits_t::lstrcpy(&am[0], AM);
00251         traits_t::lstrcpy(&pm[0], PM);
00252     }
00253 
00254     char_t const    *timeMarker =   (lpTime->wHour < 12) ? &am[0] : &pm[0];
00255     const ws_size_t cchMarker   =   (am.size() < pm.size()) ? pm.size() : am.size();
00256     const ws_size_t cchTimeMax  =   (cchPicture - 1) + (2 - 1) + (2 - 1) + (6 - 1) + 1 + cchMarker;
00257     buffer_t        buffer(1 + cchTimeMax);
00258     ws_size_t       len         =   0;
00259 
00260     if(!buffer.empty())
00261     {
00262         char_t const    *r;
00263         char_t          *w          =   &buffer[0];
00264         char_t          prev        =   '\0';
00265         ws_bool_t       bMarker1    =   true;
00266 
00267         for(r = lpFormat; r != lpFormat + cchPicture; ++r)
00268         {
00269             const char_t    ch  =   *r;
00270 
00271             switch(ch)
00272             {
00273                 case    'h':
00274                     if( 'h' == prev &&
00275                         hours12 != &hours12_[0])
00276                     {
00277                         --hours12;
00278                     }
00279                     break;
00280                 case    'H':
00281                     if( 'H' == prev &&
00282                         hours24 != &hours24_[0])
00283                     {
00284                         --hours24;
00285                     }
00286                     break;
00287                 case    'm':
00288                     if( 'm' == prev &&
00289                         minutes != &minutes_[0])
00290                     {
00291                         --minutes;
00292                     }
00293                     break;
00294                 case    's':
00295                     if( 's' == prev &&
00296                         seconds != &seconds_[0])
00297                     {
00298                         --seconds;
00299                     }
00300                     break;
00301                 case    't':
00302                     if('t' == prev)
00303                     {
00304                         bMarker1 = false;
00305                     }
00306                     break;
00307                 default:
00308                     {
00309                         static const char_t s_emptyString[] = { '\0' };
00310                         char_t const        *p;
00311 
00312                         switch(prev)
00313                         {
00314                             case    'h':    p = hours12;        break;
00315                             case    'H':    p = hours24;        break;
00316                             case    'm':    p = minutes;        break;
00317                             case    's':    p = seconds;        break;
00318                             case    't':
00319                                 if(0 == (dwFlags & TIME_NOTIMEMARKER))
00320                                 {
00321                                     if(!bMarker1)
00322                                     {
00323                                         p = timeMarker;
00324                                         break;
00325                                     }
00326                                     else
00327                                     {
00328                                         
00329                                         *w++ = *timeMarker;
00330                                         ++len;
00331                                     }
00332                                 }
00333                                 
00334                             default:        p = s_emptyString;   break;
00335                         }
00336 
00337                         for(; '\0' != *p; *w++ = *p++, ++len)
00338                         {}
00339                     }
00340                     *w++ = ch;
00341                     ++len;
00342                     break;
00343             }
00344 
00345             if('\0' == ch)
00346             {
00347                 break;
00348             }
00349 
00350             prev = ch;
00351         }
00352     }
00353 
00354     
00355 
00356     if( 0 == cchTime ||
00357         len <= ws_size_t(cchTime))
00358     {
00359         if(0 != cchTime)
00360         {
00361             traits_t::lstrcpy(lpTimeStr, &buffer[0]);
00362         }
00363 
00364         return static_cast<int>(len);
00365     }
00366     else
00367     {
00368         return 0;
00369     }
00370 }
00371 
00388 inline int STLSOFT_STDCALL GetTimeFormat_msA(   LCID                locale      
00389                                             ,   DWORD               dwFlags     
00390                                             ,   CONST SYSTEMTIME    *lpTime     
00391                                             ,   ws_char_a_t const   *lpFormat   
00392                                             ,   ws_char_a_t         *lpTimeStr  
00393                                             ,   int                 cchTime)    
00394 {
00395     WINSTL_ASSERT(0 == cchTime || NULL != lpTimeStr);
00396 
00397     return GetTimeFormat_ms_<ws_char_a_t>(locale, dwFlags, lpTime, lpFormat, lpTimeStr, cchTime);
00398 }
00399 
00400 inline int STLSOFT_STDCALL GetTimeFormat_msW(   LCID                locale      
00401                                             ,   DWORD               dwFlags     
00402                                             ,   CONST SYSTEMTIME    *lpTime     
00403                                             ,   ws_char_w_t const   *lpFormat   
00404                                             ,   ws_char_w_t         *lpTimeStr  
00405                                             ,   int                 cchTime)    
00406 {
00407     WINSTL_ASSERT(0 == cchTime || NULL != lpTimeStr);
00408 
00409     return GetTimeFormat_ms_<ws_char_w_t>(locale, dwFlags, lpTime, lpFormat, lpTimeStr, cchTime);
00410 }
00411 
00413 
00414 
00415 #ifdef STLSOFT_UNITTEST
00416 # include "./unittest/format_functions_unittest_.h"
00417 #endif 
00418 
00419 
00420 
00421 #ifndef _WINSTL_NO_NAMESPACE
00422 # if defined(_STLSOFT_NO_NAMESPACE) || \
00423      defined(STLSOFT_DOCUMENTATION_SKIP_SECTION)
00424 } 
00425 # else
00426 } 
00427 } 
00428 # endif 
00429 #endif 
00430 
00431 
00432 
00433 #endif 
00434 
00435