xref: /reactos/sdk/lib/ucrt/mbstring/mbsncoll.cpp (revision e3e520d1)
1 /***
2 *mbsncol.c - Collate n characters of two MBCS strings
3 *
4 *       Copyright (c) Microsoft Corporation. All rights reserved.
5 *
6 *Purpose:
7 *       Collate n characters of two MBCS strings
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 <limits.h>
16 #include <locale.h>
17 #include <string.h>
18 
19 /***
20 * _mbsncoll(s1, s2, n) - Collate n characters of two MBCS strings
21 *
22 *Purpose:
23 *       Collates up to n charcters of two strings for lexical order.
24 *       Strings are collated on a character basis, not a byte basis.
25 *
26 *Entry:
27 *       unsigned char *s1, *s2 = strings to collate
28 *       size_t n = maximum number of characters to collate
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 
41 extern "C" int __cdecl _mbsncoll_l(
42         const unsigned char *s1,
43         const unsigned char *s2,
44         size_t n,
45         _locale_t plocinfo
46         )
47 {
48         int ret;
49         size_t bcnt1, bcnt2;
50         _LocaleUpdate _loc_update(plocinfo);
51 
52         if (n == 0)
53             return 0;
54 
55         /* validation section */
56         _VALIDATE_RETURN(s1 != nullptr, EINVAL, _NLSCMPERROR);
57         _VALIDATE_RETURN(s2 != nullptr, EINVAL, _NLSCMPERROR);
58         _VALIDATE_RETURN(n <= INT_MAX, EINVAL, _NLSCMPERROR);
59 
60         if (_loc_update.GetLocaleT()->mbcinfo->ismbcodepage == 0)
61             return _strncoll_l((const char *)s1, (const char *)s2, n, plocinfo);
62 
63         bcnt1 = _mbsnbcnt_l(s1, n, _loc_update.GetLocaleT());
64         bcnt2 = _mbsnbcnt_l(s2, n, _loc_update.GetLocaleT());
65 
66         if ( 0 == (ret = __acrt_CompareStringA(
67                         _loc_update.GetLocaleT(),
68                         _loc_update.GetLocaleT()->mbcinfo->mblocalename,
69                         SORT_STRINGSORT,
70                         (const char *)s1,
71                         (int)bcnt1,
72                         (char *)s2,
73                         (int)bcnt2,
74                         _loc_update.GetLocaleT()->mbcinfo->mbcodepage )) )
75         {
76             errno = EINVAL;
77             return _NLSCMPERROR;
78         }
79 
80         return ret - 2;
81 
82 }
83 
84 extern "C" int (__cdecl _mbsncoll)(
85         const unsigned char *s1,
86         const unsigned char *s2,
87         size_t n
88         )
89 {
90     return _mbsncoll_l(s1, s2, n, nullptr);
91 }
92