1 /***
2 *mbsnicmp.c - Compare n characters of strings, ignoring case (MBCS)
3 *
4 * Copyright (c) Microsoft Corporation. All rights reserved.
5 *
6 *Purpose:
7 * Compare n characters of strings, ignoring case (MBCS)
8 *
9 *******************************************************************************/
10 #ifndef _MBCS
11 #error This file should only be compiled with _MBCS defined
12 #endif
13
14 #include <corecrt_internal_mbstring.h>
15 #include <locale.h>
16 #include <string.h>
17
18 /***
19 * _mbsnicmp - Compare n characters of strings, ignoring case (MBCS)
20 *
21 *Purpose:
22 * Compares up to n charcters of two strings for ordinal order.
23 * Strings are compared on a character basis, not a byte basis.
24 * Case of characters is not considered.
25 *
26 *Entry:
27 * unsigned char *s1, *s2 = strings to compare
28 * size_t n = maximum number of characters to compare
29 *
30 *Exit:
31 * Returns <0 if s1 < s2
32 * Returns 0 if s1 == s2
33 * Returns >0 if s1 > s2
34 * Returns _NLSCMPERROR is something went wrong
35 *
36 *Exceptions:
37 * Input parameters are validated. Refer to the validation section of the function.
38 *
39 *******************************************************************************/
40
_mbsnicmp_l(const unsigned char * s1,const unsigned char * s2,size_t n,_locale_t plocinfo)41 extern "C" int __cdecl _mbsnicmp_l(
42 const unsigned char *s1,
43 const unsigned char *s2,
44 size_t n,
45 _locale_t plocinfo
46 )
47 {
48 unsigned short c1, c2;
49
50 if (n==0)
51 return(0);
52
53 _LocaleUpdate _loc_update(plocinfo);
54 if (_loc_update.GetLocaleT()->mbcinfo->ismbcodepage == 0)
55 return _strnicmp((const char *)s1, (const char *)s2, n);
56
57 /* validation section */
58 _VALIDATE_RETURN(s1 != nullptr, EINVAL, _NLSCMPERROR);
59 _VALIDATE_RETURN(s2 != nullptr, EINVAL, _NLSCMPERROR);
60
61 while (n--) {
62
63 c1 = *s1++;
64 if ( _ismbblead_l(c1, _loc_update.GetLocaleT()) ) {
65 if (*s1 == '\0')
66 c1 = 0;
67 else {
68 c1 = ((c1<<8) | *s1++);
69
70 if ( ((c1 >= _MBUPPERLOW1_MT(_loc_update.GetLocaleT())) &&
71 (c1 <= _MBUPPERHIGH1_MT(_loc_update.GetLocaleT()))) )
72 c1 += _MBCASEDIFF1_MT(_loc_update.GetLocaleT());
73 else if ( ((c1 >= _MBUPPERLOW2_MT(_loc_update.GetLocaleT())) &&
74 (c1 <= _MBUPPERHIGH2_MT(_loc_update.GetLocaleT()))) )
75 c1 += _MBCASEDIFF2_MT(_loc_update.GetLocaleT());
76 }
77 }
78 else
79 c1 = _mbbtolower_l(c1, _loc_update.GetLocaleT());
80
81 c2 = *s2++;
82 if ( _ismbblead_l(c2, _loc_update.GetLocaleT()) ) {
83 if (*s2 == '\0')
84 c2 = 0;
85 else {
86 c2 = ((c2<<8) | *s2++);
87 if ( ((c2 >= _MBUPPERLOW1_MT(_loc_update.GetLocaleT())) &&
88 (c2 <= _MBUPPERHIGH1_MT(_loc_update.GetLocaleT()))) )
89 c2 += _MBCASEDIFF1_MT(_loc_update.GetLocaleT());
90 else if ( ((c2 >= _MBUPPERLOW2_MT(_loc_update.GetLocaleT())) &&
91 (c2 <= _MBUPPERHIGH2_MT(_loc_update.GetLocaleT()))) )
92 c2 += _MBCASEDIFF2_MT(_loc_update.GetLocaleT());
93 }
94 }
95 else
96 c2 = _mbbtolower_l(c2, _loc_update.GetLocaleT());
97
98 if (c1 != c2)
99 return( (c1 > c2) ? 1 : -1 );
100
101 if (c1 == 0)
102 return(0);
103 }
104
105 return(0);
106 }
107
108 extern "C" int (__cdecl _mbsnicmp)(
109 const unsigned char *s1,
110 const unsigned char *s2,
111 size_t n
112 )
113 {
114 return _mbsnicmp_l(s1, s2, n, nullptr);
115 }
116