Reactos
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
42errno_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
115errno_t (__cdecl _mbslwr_s)(
116 unsigned char *string,
117 size_t sizeInBytes
118 )
119{
120 return _mbslwr_s_l(string, sizeInBytes, nullptr);
121}
122
123unsigned 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
131unsigned 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}