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