ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

c_wlocale_win32.c
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2007 2008
00003  * Francois Dumont
00004  *
00005  * This material is provided "as is", with absolutely no warranty expressed
00006  * or implied. Any use is at your own risk.
00007  *
00008  * Permission to use or copy this software for any purpose is hereby granted
00009  * without fee, provided the above notices are retained on all copies.
00010  * Permission to modify the code and to distribute modified code is granted,
00011  * provided the above notices are retained, and a notice that the code was
00012  * modified is included with the above copyright notice.
00013  *
00014  */
00015 
00016 #if defined (_STLP_USE_SAFE_STRING_FUNCTIONS)
00017 #  define _STLP_WCSNCPY(D, DS, S, C) wcsncpy_s(D, DS, S, C)
00018 #else
00019 #  define _STLP_WCSNCPY(D, DS, S, C) wcsncpy(D, S, C)
00020 #endif
00021 
00022 static const wchar_t* __wtrue_name = L"true";
00023 static const wchar_t* __wfalse_name = L"false";
00024 
00025 typedef struct _Locale_codecvt {
00026   _Locale_lcid_t lc;
00027   UINT cp;
00028   unsigned char cleads[256 / CHAR_BIT];
00029   unsigned char max_char_size;
00030   DWORD mbtowc_flags;
00031   DWORD wctomb_flags;
00032 } _Locale_codecvt_t;
00033 
00034 /* Ctype */
00035 _Locale_mask_t _WLocale_ctype(_Locale_ctype_t* ltype, wint_t c,
00036                               _Locale_mask_t which_bits) {
00037   wchar_t buf[2];
00038   WORD out[2];
00039   buf[0] = c; buf[1] = 0;
00040   GetStringTypeW(CT_CTYPE1, buf, -1, out);
00041   _STLP_MARK_PARAMETER_AS_UNUSED(ltype)
00042   return (_Locale_mask_t)(MapCtypeMask(out[0]) & which_bits);
00043 }
00044 
00045 wint_t _WLocale_tolower(_Locale_ctype_t* ltype, wint_t c) {
00046   wchar_t in_c = c;
00047   wchar_t res;
00048 
00049   LCMapStringW(ltype->lc.id, LCMAP_LOWERCASE, &in_c, 1, &res, 1);
00050   return res;
00051 }
00052 
00053 wint_t _WLocale_toupper(_Locale_ctype_t* ltype, wint_t c) {
00054   wchar_t in_c = c;
00055   wchar_t res;
00056 
00057   LCMapStringW(ltype->lc.id, LCMAP_UPPERCASE, &in_c, 1, &res, 1);
00058   return res;
00059 }
00060 
00061 _Locale_codecvt_t* _Locale_codecvt_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) {
00062   char cp_name[MAX_CP_LEN + 1];
00063   unsigned char *ptr;
00064   CPINFO CPInfo;
00065   int i;
00066 
00067   _Locale_codecvt_t *lcodecvt = (_Locale_codecvt_t*)malloc(sizeof(_Locale_codecvt_t));
00068 
00069   if (!lcodecvt) { *__err_code = _STLP_LOC_NO_MEMORY; return lcodecvt; }
00070   memset(lcodecvt, 0, sizeof(_Locale_codecvt_t));
00071 
00072   if (__GetLCIDFromName(name, &lcodecvt->lc.id, cp_name, lc_hint) == -1)
00073   { free(lcodecvt); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; }
00074 
00075   lcodecvt->cp = atoi(cp_name);
00076   if (!GetCPInfo(lcodecvt->cp, &CPInfo)) { free(lcodecvt); return NULL; }
00077 
00078   if (lcodecvt->cp != CP_UTF7 && lcodecvt->cp != CP_UTF8) {
00079     lcodecvt->mbtowc_flags = MB_PRECOMPOSED;
00080     lcodecvt->wctomb_flags = WC_COMPOSITECHECK | WC_SEPCHARS;
00081   }
00082   lcodecvt->max_char_size = CPInfo.MaxCharSize;
00083 
00084   if (CPInfo.MaxCharSize > 1) {
00085     for (ptr = (unsigned char*)CPInfo.LeadByte; *ptr && *(ptr + 1); ptr += 2)
00086       for (i = *ptr; i <= *(ptr + 1); ++i) lcodecvt->cleads[i / CHAR_BIT] |= (0x01 << i % CHAR_BIT);
00087   }
00088 
00089   return lcodecvt;
00090 }
00091 
00092 char const* _Locale_codecvt_name(const _Locale_codecvt_t* lcodecvt, char* buf) {
00093   char cp_buf[MAX_CP_LEN + 1];
00094   my_ltoa(lcodecvt->cp, cp_buf);
00095   return __GetLocaleName(lcodecvt->lc.id, cp_buf, buf);
00096 }
00097 
00098 void _Locale_codecvt_destroy(_Locale_codecvt_t* lcodecvt) {
00099   if (!lcodecvt) return;
00100 
00101   free(lcodecvt);
00102 }
00103 
00104 int _WLocale_mb_cur_max (_Locale_codecvt_t * lcodecvt)
00105 { return lcodecvt->max_char_size; }
00106 
00107 int _WLocale_mb_cur_min (_Locale_codecvt_t *lcodecvt) {
00108   _STLP_MARK_PARAMETER_AS_UNUSED(lcodecvt)
00109   return 1;
00110 }
00111 
00112 int _WLocale_is_stateless (_Locale_codecvt_t * lcodecvt)
00113 { return (lcodecvt->max_char_size == 1) ? 1 : 0; }
00114 
00115 static int __isleadbyte(int i, unsigned char *ctable) {
00116   unsigned char c = (unsigned char)i;
00117   return (ctable[c / CHAR_BIT] & (0x01 << c % CHAR_BIT));
00118 }
00119 
00120 static int __mbtowc(_Locale_codecvt_t *l, wchar_t *dst, const char *from, unsigned int count) {
00121   int result;
00122 
00123   if (l->cp == CP_UTF7 || l->cp == CP_UTF8) {
00124     result = MultiByteToWideChar(l->cp, l->mbtowc_flags, from, count, dst, 1);
00125     if (result == 0) {
00126       switch (GetLastError()) {
00127         case ERROR_NO_UNICODE_TRANSLATION:
00128           return -2;
00129         default:
00130           return -1;
00131       }
00132     }
00133   }
00134   else {
00135     if (count == 1 && __isleadbyte(*from, l->cleads)) return (size_t)-2;
00136     result = MultiByteToWideChar(l->cp, l->mbtowc_flags, from, count, dst, 1);
00137     if (result == 0) return -1;
00138   }
00139 
00140   return result;
00141 }
00142 
00143 size_t _WLocale_mbtowc(_Locale_codecvt_t *lcodecvt, wchar_t *to,
00144                        const char *from, size_t n, mbstate_t *shift_state) {
00145   int result;
00146   _STLP_MARK_PARAMETER_AS_UNUSED(shift_state)
00147   if (lcodecvt->max_char_size == 1) { /* Single byte encoding. */
00148     result = MultiByteToWideChar(lcodecvt->cp, lcodecvt->mbtowc_flags, from, 1, to, 1);
00149     if (result == 0) return (size_t)-1;
00150     return result;
00151   }
00152   else { /* Multi byte encoding. */
00153     int retval;
00154     unsigned int count = 1;
00155     while (n--) {
00156       retval = __mbtowc(lcodecvt, to, from, count);
00157       if (retval == -2)
00158       { if (++count > ((unsigned int)lcodecvt->max_char_size)) return (size_t)-1; }
00159       else if (retval == -1)
00160       { return (size_t)-1; }
00161       else
00162       { return count; }
00163     }
00164     return (size_t)-2;
00165   }
00166 }
00167 
00168 size_t _WLocale_wctomb(_Locale_codecvt_t *lcodecvt, char *to, size_t n,
00169                        const wchar_t c, mbstate_t *shift_state) {
00170   int size = WideCharToMultiByte(lcodecvt->cp, lcodecvt->wctomb_flags, &c, 1, NULL, 0, NULL, NULL);
00171 
00172   if (!size) return (size_t)-1;
00173   if ((size_t)size > n) return (size_t)-2;
00174 
00175   if (n > INT_MAX)
00176     /* Limiting the output buf size to INT_MAX seems like reasonable to transform a single wchar_t. */
00177     n = INT_MAX;
00178 
00179   WideCharToMultiByte(lcodecvt->cp,  lcodecvt->wctomb_flags, &c, 1, to, (int)n, NULL, NULL);
00180 
00181   _STLP_MARK_PARAMETER_AS_UNUSED(shift_state)
00182   return (size_t)size;
00183 }
00184 
00185 size_t _WLocale_unshift(_Locale_codecvt_t *lcodecvt, mbstate_t *st,
00186                         char *buf, size_t n, char **next) {
00187   /* _WLocale_wctomb do not even touch to st, there is nothing to unshift in this localization implementation. */
00188   _STLP_MARK_PARAMETER_AS_UNUSED(lcodecvt)
00189   _STLP_MARK_PARAMETER_AS_UNUSED(st)
00190   _STLP_MARK_PARAMETER_AS_UNUSED(&n)
00191   *next = buf;
00192   return 0;
00193 }
00194 
00195 /* Collate */
00196 /* This function takes care of the potential size_t DWORD different size. */
00197 static int _WLocale_strcmp_aux(_Locale_collate_t* lcol,
00198                                const wchar_t* s1, size_t n1,
00199                                const wchar_t* s2, size_t n2) {
00200   int result = CSTR_EQUAL;
00201   while (n1 > 0 || n2 > 0) {
00202     DWORD size1 = trim_size_t_to_DWORD(n1);
00203     DWORD size2 = trim_size_t_to_DWORD(n2);
00204     result = CompareStringW(lcol->lc.id, 0, s1, size1, s2, size2);
00205     if (result != CSTR_EQUAL)
00206       break;
00207     n1 -= size1;
00208     n2 -= size2;
00209   }
00210   return result;
00211 }
00212 
00213 int _WLocale_strcmp(_Locale_collate_t* lcol,
00214                     const wchar_t* s1, size_t n1,
00215                     const wchar_t* s2, size_t n2) {
00216   int result;
00217   result = _WLocale_strcmp_aux(lcol, s1, n1, s2, n2);
00218   return (result == CSTR_EQUAL) ? 0 : (result == CSTR_LESS_THAN) ? -1 : 1;
00219 }
00220 
00221 size_t _WLocale_strxfrm(_Locale_collate_t* lcol,
00222                         wchar_t* dst, size_t dst_size,
00223                         const wchar_t* src, size_t src_size) {
00224   int result, i;
00225 
00226   /* see _Locale_strxfrm: */
00227   if (src_size > INT_MAX) {
00228     if (dst != 0) {
00229       _STLP_WCSNCPY(dst, dst_size, src, src_size);
00230     }
00231     return src_size;
00232   }
00233   if (dst_size > INT_MAX) {
00234     dst_size = INT_MAX;
00235   }
00236   result = LCMapStringW(lcol->lc.id, LCMAP_SORTKEY, src, (int)src_size, dst, (int)dst_size);
00237   if (result != 0 && dst != 0) {
00238     for (i = result - 1; i >= 0; --i) {
00239       dst[i] = ((unsigned char*)dst)[i];
00240     }
00241   }
00242   return result != 0 ? result - 1 : 0;
00243 }
00244 
00245 /* Numeric */
00246 wchar_t _WLocale_decimal_point(_Locale_numeric_t* lnum) {
00247   wchar_t buf[4];
00248   GetLocaleInfoW(lnum->lc.id, LOCALE_SDECIMAL, buf, 4);
00249   return buf[0];
00250 }
00251 
00252 wchar_t _WLocale_thousands_sep(_Locale_numeric_t* lnum) {
00253   wchar_t buf[4];
00254   GetLocaleInfoW(lnum->lc.id, LOCALE_STHOUSAND, buf, 4);
00255   return buf[0];
00256 }
00257 
00258 const wchar_t * _WLocale_true(_Locale_numeric_t* lnum, wchar_t* buf, size_t bufSize) {
00259   _STLP_MARK_PARAMETER_AS_UNUSED(lnum)
00260   _STLP_MARK_PARAMETER_AS_UNUSED(buf)
00261   _STLP_MARK_PARAMETER_AS_UNUSED(&bufSize)
00262   return __wtrue_name;
00263 }
00264 
00265 const wchar_t * _WLocale_false(_Locale_numeric_t* lnum, wchar_t* buf, size_t bufSize) {
00266   _STLP_MARK_PARAMETER_AS_UNUSED(lnum)
00267   _STLP_MARK_PARAMETER_AS_UNUSED(buf)
00268   _STLP_MARK_PARAMETER_AS_UNUSED(&bufSize)
00269   return __wfalse_name;
00270 }
00271 
00272 /* Monetary */
00273 const wchar_t* _WLocale_int_curr_symbol(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize)
00274 { GetLocaleInfoW(lmon->lc.id, LOCALE_SINTLSYMBOL, buf, (int)bufSize); return buf; }
00275 
00276 const wchar_t* _WLocale_currency_symbol(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize)
00277 { GetLocaleInfoW(lmon->lc.id, LOCALE_SCURRENCY, buf, (int)bufSize); return buf; }
00278 
00279 wchar_t _WLocale_mon_decimal_point(_Locale_monetary_t * lmon)
00280 { return lmon->decimal_point[0]; }
00281 
00282 wchar_t _WLocale_mon_thousands_sep(_Locale_monetary_t * lmon)
00283 { return lmon->thousands_sep[0]; }
00284 
00285 const wchar_t* _WLocale_positive_sign(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize)
00286 { GetLocaleInfoW(lmon->lc.id, LOCALE_SPOSITIVESIGN, buf, (int)bufSize); return buf; }
00287 
00288 const wchar_t* _WLocale_negative_sign(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize)
00289 { GetLocaleInfoW(lmon->lc.id, LOCALE_SNEGATIVESIGN, buf, (int)bufSize); return buf; }
00290 
00291 /* Time */
00292 const wchar_t * _WLocale_full_monthname(_Locale_time_t * ltime, int month,
00293                                         wchar_t* buf, size_t bufSize)
00294 { GetLocaleInfoW(ltime->lc.id, LOCALE_SMONTHNAME1 + month, buf, (int)bufSize); return buf; }
00295 
00296 const wchar_t * _WLocale_abbrev_monthname(_Locale_time_t * ltime, int month,
00297                                           wchar_t* buf, size_t bufSize)
00298 { GetLocaleInfoW(ltime->lc.id, LOCALE_SABBREVMONTHNAME1 + month, buf, (int)bufSize); return buf; }
00299 
00300 const wchar_t * _WLocale_full_dayofweek(_Locale_time_t * ltime, int day,
00301                                         wchar_t* buf, size_t bufSize)
00302 { GetLocaleInfoW(ltime->lc.id, LOCALE_SDAYNAME1 + day, buf, (int)bufSize); return buf; }
00303 
00304 const wchar_t * _WLocale_abbrev_dayofweek(_Locale_time_t * ltime, int day,
00305                                           wchar_t* buf, size_t bufSize)
00306 { GetLocaleInfoW(ltime->lc.id, LOCALE_SABBREVDAYNAME1 + day, buf, (int)bufSize); return buf; }
00307 
00308 const wchar_t* _WLocale_am_str(_Locale_time_t* ltime,
00309                                wchar_t* buf, size_t bufSize)
00310 { GetLocaleInfoW(ltime->lc.id, LOCALE_S1159, buf, (int)bufSize); return buf; }
00311 
00312 const wchar_t* _WLocale_pm_str(_Locale_time_t* ltime,
00313                                wchar_t* buf, size_t bufSize)
00314 { GetLocaleInfoW(ltime->lc.id, LOCALE_S2359, buf, (int)bufSize); return buf; }

Generated on Mon May 28 2012 04:34:57 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.