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