1 /*** 2 *strxfrm.c - Transform a string using locale information 3 * 4 * Copyright (c) Microsoft Corporation. All rights reserved. 5 * 6 *Purpose: 7 * Transform a string using the locale information as set by 8 * LC_COLLATE. 9 * 10 *******************************************************************************/ 11 #include <corecrt_internal.h> 12 #include <ctype.h> 13 #include <locale.h> 14 #include <string.h> 15 16 /*** 17 *size_t strxfrm() - Transform a string using locale information 18 * 19 *Purpose: 20 * Transform the string pointed to by _string2 and place the 21 * resulting string into the array pointed to by _string1. 22 * No more than _count characters are place into the 23 * resulting string (including the null). 24 * 25 * The transformation is such that if strcmp() is applied to 26 * the two transformed strings, the return value is equal to 27 * the result of strcoll() applied to the two original strings. 28 * Thus, the conversion must take the locale LC_COLLATE info 29 * into account. 30 * [ANSI] 31 * 32 * The value of the following expression is the size of the array 33 * needed to hold the transformation of the source string: 34 * 35 * 1 + strxfrm(nullptr,string,0) 36 * 37 *Entry: 38 * char *_string1 = result string 39 * const char *_string2 = source string 40 * size_t _count = max chars to move 41 * 42 * [If _count is 0, _string1 is permitted to be nullptr.] 43 * 44 *Exit: 45 * Length of the transformed string (not including the terminating 46 * null). If the value returned is >= _count, the contents of the 47 * _string1 array are indeterminate. 48 * 49 *Exceptions: 50 * Non-standard: if OM/API error, return INT_MAX. 51 * Input parameters are validated. Refer to the validation section of the function. 52 * 53 *******************************************************************************/ 54 55 extern "C" size_t __cdecl _strxfrm_l ( 56 char *_string1, 57 const char *_string2, 58 size_t _count, 59 _locale_t plocinfo 60 ) 61 { 62 int dstlen; 63 size_t retval = INT_MAX; /* NON-ANSI: default if OM or API error */ 64 _LocaleUpdate _loc_update(plocinfo); 65 66 /* validation section */ 67 _VALIDATE_RETURN(_count <= INT_MAX, EINVAL, INT_MAX); 68 _VALIDATE_RETURN(_string1 != nullptr || _count == 0, EINVAL, INT_MAX); 69 _VALIDATE_RETURN(_string2 != nullptr, EINVAL, INT_MAX); 70 71 /* pre-init output in case of error */ 72 if(_string1!=nullptr && _count>0) 73 { 74 *_string1='\0'; 75 } 76 77 if ( (_loc_update.GetLocaleT()->locinfo->locale_name[LC_COLLATE] == nullptr) && 78 (_loc_update.GetLocaleT()->locinfo->lc_collate_cp == CP_ACP) ) 79 { 80 _BEGIN_SECURE_CRT_DEPRECATION_DISABLE 81 strncpy(_string1, _string2, _count); 82 _END_SECURE_CRT_DEPRECATION_DISABLE 83 return strlen(_string2); 84 } 85 86 /* Inquire size of dst string in BYTES */ 87 if ( 0 == (dstlen = __acrt_LCMapStringA( 88 _loc_update.GetLocaleT(), 89 _loc_update.GetLocaleT()->locinfo->locale_name[LC_COLLATE], 90 LCMAP_SORTKEY, 91 _string2, 92 -1, 93 nullptr, 94 0, 95 _loc_update.GetLocaleT()->locinfo->lc_collate_cp, 96 TRUE )) ) 97 { 98 errno = EILSEQ; 99 return INT_MAX; 100 } 101 102 retval = (size_t)dstlen; 103 104 /* if not enough room, return amount needed */ 105 if ( retval > _count ) 106 { 107 if (_string1 != nullptr && _count > 0) 108 { 109 *_string1 = '\0'; 110 errno = ERANGE; 111 } 112 /* the return value is the string length (without the terminating 0) */ 113 retval--; 114 return retval; 115 } 116 117 /* Map src string to dst string */ 118 if ( 0 == __acrt_LCMapStringA( 119 _loc_update.GetLocaleT(), 120 _loc_update.GetLocaleT()->locinfo->locale_name[LC_COLLATE], 121 LCMAP_SORTKEY, 122 _string2, 123 -1, 124 _string1, 125 (int)_count, 126 _loc_update.GetLocaleT()->locinfo->lc_collate_cp, 127 TRUE ) ) 128 { 129 errno = EILSEQ; 130 return INT_MAX; 131 } 132 /* the return value is the string length (without the terminating 0) */ 133 retval--; 134 135 return retval; 136 } 137 138 extern "C" size_t __cdecl strxfrm ( 139 char *_string1, 140 const char *_string2, 141 size_t _count 142 ) 143 { 144 145 return _strxfrm_l(_string1, _string2, _count, nullptr); 146 147 } 148