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