xref: /reactos/sdk/lib/ucrt/mbstring/mbslwr.cpp (revision 53d808d2)
1 /***
2 *mbslwr.c - Convert string lower case (MBCS)
3 *
4 *       Copyright (c) Microsoft Corporation.  All rights reserved.
5 *
6 *Purpose:
7 *       Convert string lower 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.h>
15 #include <corecrt_internal_mbstring.h>
16 #include <corecrt_internal_securecrt.h>
17 #include <locale.h>
18 #include <string.h>
19 
20 #pragma warning(disable:__WARNING_POTENTIAL_BUFFER_OVERFLOW_NULLTERMINATED) // 26018
21 
22 /***
23 * _mbslwr - Convert string lower case (MBCS)
24 *
25 *Purpose:
26 *       Convrts all the upper case characters in a string
27 *       to lower case in place.  MBCS chars are handled
28 *       correctly.
29 *
30 *Entry:
31 *       unsigned char *string = pointer to string
32 *
33 *Exit:
34 *       Returns a pointer to the input string.
35 *       Returns nullptr on error.
36 *
37 *Exceptions:
38 *       Input parameters are validated. Refer to the validation section of the function.
39 *
40 *******************************************************************************/
41 
42 errno_t __cdecl _mbslwr_s_l(
43         unsigned char *string,
44         size_t sizeInBytes,
45         _locale_t plocinfo
46         )
47 {
48         size_t stringlen;
49 
50         /* validation section */
51         _VALIDATE_RETURN_ERRCODE((string != nullptr && sizeInBytes > 0) || (string == nullptr && sizeInBytes == 0), EINVAL);
52 
53         if (string == nullptr)
54         {
55             /* nothing to do */
56             return 0;
57         }
58 
59         stringlen = strnlen((char *)string, sizeInBytes);
60         if (stringlen >= sizeInBytes)
61         {
62             _RESET_STRING(string, sizeInBytes);
63             _RETURN_DEST_NOT_NULL_TERMINATED(string, sizeInBytes);
64         }
65         _FILL_STRING(string, sizeInBytes, stringlen + 1);
66 
67         unsigned char *cp, *dst;
68         _LocaleUpdate _loc_update(plocinfo);
69 
70         for (cp = string, dst = string; *cp != '\0'; ++cp)
71         {
72             if (_ismbblead_l(*cp, _loc_update.GetLocaleT()))
73             {
74 
75 
76                 int retval;
77                 unsigned char ret[4];
78                 if ((retval = __acrt_LCMapStringA(
79                                 _loc_update.GetLocaleT(),
80                                 _loc_update.GetLocaleT()->mbcinfo->mblocalename,
81                                 LCMAP_LOWERCASE,
82                                 (const char *)cp,
83                                 2,
84                                 (char *)ret,
85                                 2,
86                                 _loc_update.GetLocaleT()->mbcinfo->mbcodepage,
87                                 TRUE )) == 0 )
88                 {
89                     errno = EILSEQ;
90                     _RESET_STRING(string, sizeInBytes);
91                     return errno;
92                 }
93 
94                 *(dst++) = ret[0];
95                 ++cp;
96                 if (retval > 1)
97                 {
98                     *(dst++) = ret[1];
99                 }
100 
101 
102             }
103             else
104             {
105                 /* single byte, macro version */
106                 *(dst++) = (unsigned char) _mbbtolower_l(*cp, _loc_update.GetLocaleT());
107             }
108         }
109         /* null terminate the string */
110         *dst = '\0';
111 
112         return 0;
113 }
114 
115 errno_t (__cdecl _mbslwr_s)(
116         unsigned char *string,
117         size_t sizeInBytes
118         )
119 {
120     return _mbslwr_s_l(string, sizeInBytes, nullptr);
121 }
122 
123 unsigned char * (__cdecl _mbslwr_l)(
124         unsigned char *string,
125         _locale_t plocinfo
126         )
127 {
128     return (_mbslwr_s_l(string, (string == nullptr ? 0 : (size_t)-1), plocinfo) == 0 ? string : nullptr);
129 }
130 
131 unsigned char * (__cdecl _mbslwr)(
132         unsigned char *string
133         )
134 {
135     return (_mbslwr_s_l(string, (string == nullptr ? 0 : (size_t)-1), nullptr) == 0 ? string : nullptr);
136 }
137