Reactos
at master 177 lines 6.0 kB view raw
1// 2// inittime.cpp 3// 4// Copyright (c) Microsoft Corporation. All rights reserved. 5// 6// Functionality for initializing and destroying LC_TIME category data structures 7// 8#include <corecrt_internal.h> 9#include <locale.h> 10#include <stdlib.h> 11 12 13// Enclaves have no ability to create new locales. 14#ifndef _UCRT_ENCLAVE_BUILD 15 16_Success_(return != false) 17static bool __cdecl initialize_lc_time( 18 _Inout_ __crt_lc_time_data* const lc_time, 19 _In_ __crt_locale_data* const locale_data 20 ) throw() 21{ 22 wchar_t const* const locale_name = locale_data->locale_name[LC_TIME]; 23 24 __crt_locale_pointers locinfo = { locale_data, nullptr }; 25 26 lc_time->_W_ww_locale_name = __acrt_copy_locale_name(locale_name); 27 28 int ret = 0; 29 30 // The days of the week. Note that the OS days are numbered 1-7, starting 31 // with Monday, whereas the lc_time days are numbered (indexed, really) 0-6 32 // starting with Sunday (thus the adjustment to the index in the loop). 33 for (unsigned int i = 0; i != 7; ++i) 34 { 35 unsigned int const result_index = (i + 1) % 7; 36 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_STR_TYPE, locale_name, LOCALE_SABBREVDAYNAME1 + i, &lc_time->wday_abbr[result_index]); 37 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_STR_TYPE, locale_name, LOCALE_SDAYNAME1 + i, &lc_time->wday [result_index]); 38 39 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_WSTR_TYPE, locale_name, LOCALE_SABBREVDAYNAME1 + i, &lc_time->_W_wday_abbr[result_index]); 40 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_WSTR_TYPE, locale_name, LOCALE_SDAYNAME1 + i, &lc_time->_W_wday [result_index]); 41 } 42 43 // The months of the year 44 for (unsigned int i = 0; i != 12; ++i) 45 { 46 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_STR_TYPE, locale_name, LOCALE_SABBREVMONTHNAME1 + i, &lc_time->month_abbr[i]); 47 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_STR_TYPE, locale_name, LOCALE_SMONTHNAME1 + i, &lc_time->month [i]); 48 49 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_WSTR_TYPE, locale_name, LOCALE_SABBREVMONTHNAME1 + i, &lc_time->_W_month_abbr[i]); 50 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_WSTR_TYPE, locale_name, LOCALE_SMONTHNAME1 + i, &lc_time->_W_month [i]); 51 } 52 53 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_STR_TYPE, locale_name, LOCALE_S1159, &lc_time->ampm[0]); 54 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_STR_TYPE, locale_name, LOCALE_S2359, &lc_time->ampm[1]); 55 56 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_WSTR_TYPE, locale_name, LOCALE_S1159, &lc_time->_W_ampm[0]); 57 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_WSTR_TYPE, locale_name, LOCALE_S2359, &lc_time->_W_ampm[1]); 58 59 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_STR_TYPE, locale_name, LOCALE_SSHORTDATE, &lc_time->ww_sdatefmt); 60 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_STR_TYPE, locale_name, LOCALE_SLONGDATE, &lc_time->ww_ldatefmt); 61 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_STR_TYPE, locale_name, LOCALE_STIMEFORMAT, &lc_time->ww_timefmt); 62 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_INT_TYPE, locale_name, LOCALE_ICALENDARTYPE, &lc_time->ww_caltype); 63 64 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_WSTR_TYPE, locale_name, LOCALE_SSHORTDATE, &lc_time->_W_ww_sdatefmt); 65 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_WSTR_TYPE, locale_name, LOCALE_SLONGDATE, &lc_time->_W_ww_ldatefmt); 66 ret |= __acrt_GetLocaleInfoA(&locinfo, LC_WSTR_TYPE, locale_name, LOCALE_STIMEFORMAT, &lc_time->_W_ww_timefmt); 67 68 return ret == 0; 69} 70 71 72 73_Success_(return != nullptr) 74static __crt_lc_time_data const* __cdecl get_or_create_lc_time( 75 _In_ __crt_locale_data* const locale_data 76 ) throw() 77{ 78 // C Locale 79 if (!locale_data->locale_name[LC_TIME]) 80 { 81 return &__lc_time_c; 82 } 83 84 // Non-C Locale 85 __crt_unique_heap_ptr<__crt_lc_time_data> lc_time = _calloc_crt_t(__crt_lc_time_data, 1); 86 if (!lc_time) 87 { 88 return nullptr; 89 } 90 91 if (!initialize_lc_time(lc_time.get(), locale_data)) 92 { 93 __acrt_locale_free_time(lc_time.get()); 94 return nullptr; 95 } 96 97 lc_time.get()->refcount = 1; 98 99 return lc_time.detach(); 100} 101 102 103 104extern "C" int __cdecl __acrt_locale_initialize_time( 105 __crt_locale_data* const locale_data 106 ) 107{ 108 __crt_lc_time_data const* const lc_time = get_or_create_lc_time(locale_data); 109 if (!lc_time) 110 { 111 return 1; 112 } 113 114 if (__acrt_locale_release_lc_time_reference(locale_data->lc_time_curr) == 0) 115 { 116 _ASSERTE(("lc_time_curr unexpectedly has no remaining references", 0)); 117 } 118 119 locale_data->lc_time_curr = lc_time; 120 return 0; 121} 122 123#endif /* _UCRT_ENCLAVE_BUILD */ 124 125 126static void __cdecl free_crt_array_internal( 127 _Inout_updates_(array_count) void const** const array, 128 _In_ size_t const array_count 129 ) throw() 130{ 131 for (void const* const* it = array; it != array + array_count; ++it) 132 { 133 _free_crt(const_cast<void*>(*it)); 134 } 135} 136 137 138 139template <typename T, size_t N> 140static void __cdecl free_crt_array(_Inout_ T* (&array)[N]) throw() 141{ 142 return free_crt_array_internal(const_cast<void const**>(reinterpret_cast<void const* const*>(array)), N); 143} 144 145 146 147extern "C" void __cdecl __acrt_locale_free_time( 148 __crt_lc_time_data* const lc_time 149 ) 150{ 151 if (!lc_time) 152 { 153 return; 154 } 155 156 free_crt_array(lc_time->wday_abbr); 157 free_crt_array(lc_time->wday); 158 free_crt_array(lc_time->month_abbr); 159 free_crt_array(lc_time->month); 160 free_crt_array(lc_time->ampm); 161 162 _free_crt(lc_time->ww_sdatefmt); 163 _free_crt(lc_time->ww_ldatefmt); 164 _free_crt(lc_time->ww_timefmt); 165 166 free_crt_array(lc_time->_W_wday_abbr); 167 free_crt_array(lc_time->_W_wday); 168 free_crt_array(lc_time->_W_month_abbr); 169 free_crt_array(lc_time->_W_month); 170 free_crt_array(lc_time->_W_ampm); 171 172 _free_crt(lc_time->_W_ww_sdatefmt); 173 _free_crt(lc_time->_W_ww_ldatefmt); 174 _free_crt(lc_time->_W_ww_timefmt); 175 176 _free_crt(lc_time->_W_ww_locale_name); 177}