1 /*** 2 *memicmp.cpp - compare memory, ignore case 3 * 4 * Copyright (c) Microsoft Corporation. All rights reserved. 5 * 6 *Purpose: 7 * defines _memicmp() - compare two blocks of memory for ordinal 8 * order. Case is ignored in the comparison. 9 * 10 *******************************************************************************/ 11 #include <corecrt_internal.h> 12 #include <ctype.h> 13 #include <locale.h> 14 #include <string.h> 15 16 /*** 17 *int _memicmp(lhs, rhs, count) - compare two blocks of memory, ignore case 18 * 19 *Purpose: 20 * Compares count bytes of the two blocks of memory stored at lhs 21 * and rhs. The characters are converted to lowercase before 22 * comparing (not permanently), so case is ignored in the search. 23 * 24 *Entry: 25 * char *lhs, *rhs - memory buffers to compare 26 * size_t count - maximum length to compare 27 * 28 *Exit: 29 * Returns < 0 if lhs < rhs 30 * Returns 0 if lhs == rhs 31 * Returns > 0 if lhs > rhs 32 * Returns _NLSCMPERROR if something went wrong 33 * 34 *Uses: 35 * 36 *Exceptions: 37 * Input parameters are validated. Refer to the validation section of the function. 38 * 39 *******************************************************************************/ 40 41 extern "C" int __cdecl _memicmp_l ( 42 void const * const lhs, 43 void const * const rhs, 44 size_t const count, 45 _locale_t const plocinfo 46 ) 47 { 48 /* validation section */ 49 _VALIDATE_RETURN(lhs != nullptr || count == 0, EINVAL, _NLSCMPERROR); 50 _VALIDATE_RETURN(rhs != nullptr || count == 0, EINVAL, _NLSCMPERROR); 51 52 if (count == 0) 53 { 54 return 0; 55 } 56 57 unsigned char const * lhs_ptr = static_cast<unsigned char const *>(lhs); 58 unsigned char const * rhs_ptr = static_cast<unsigned char const *>(rhs); 59 60 _LocaleUpdate _loc_update(plocinfo); 61 62 int result; 63 size_t remaining = count; 64 do 65 { 66 result = _tolower_fast_internal(*lhs_ptr++, _loc_update.GetLocaleT()) 67 - _tolower_fast_internal(*rhs_ptr++, _loc_update.GetLocaleT()); 68 } 69 while (result == 0 && --remaining != 0); 70 71 return result; 72 } 73 74 75 #if !defined(_M_IX86) || defined(_M_HYBRID_X86_ARM64) 76 77 extern "C" int __cdecl __ascii_memicmp ( 78 void const * const lhs, 79 void const * const rhs, 80 size_t const count 81 ) 82 { 83 if (count == 0) 84 { 85 return 0; 86 } 87 88 unsigned char const * lhs_ptr = static_cast<unsigned char const *>(lhs); 89 unsigned char const * rhs_ptr = static_cast<unsigned char const *>(rhs); 90 91 int result; 92 size_t remaining = count; 93 do 94 { 95 result = __ascii_tolower(*lhs_ptr++) - __ascii_tolower(*rhs_ptr++); 96 } 97 while (result == 0 && --remaining != 0); 98 99 return result; 100 } 101 102 #endif /* !_M_IX86 || _M_HYBRID_X86_ARM64 */ 103 104 extern "C" int __cdecl _memicmp ( 105 void const * const lhs, 106 void const * const rhs, 107 size_t const count 108 ) 109 { 110 if (!__acrt_locale_changed()) 111 { 112 /* validation section */ 113 _VALIDATE_RETURN(lhs != nullptr || count == 0, EINVAL, _NLSCMPERROR); 114 _VALIDATE_RETURN(rhs != nullptr || count == 0, EINVAL, _NLSCMPERROR); 115 116 return __ascii_memicmp(lhs, rhs, count); 117 } 118 119 return _memicmp_l(lhs, rhs, count, nullptr); 120 } 121