xref: /reactos/sdk/lib/ucrt/mbstring/mbsnicmp.cpp (revision 04e0dc4a)
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