Reactos
at master 143 lines 4.7 kB view raw
1/*** 2*mbsnset.c - Sets first n charcaters of string to given character (MBCS) 3* 4* Copyright (c) Microsoft Corporation. All rights reserved. 5* 6*Purpose: 7* Sets first n charcaters of string to given character (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/*** 20* _mbsnset - Sets first n charcaters of string to given character (MBCS) 21* 22*Purpose: 23* Sets the first n characters of string to the supplied 24* character value. If the length of string is less than n, 25* the length of string is used in place of n. Handles 26* MBCS chars correctly. 27* 28* There are several factors that make this routine complicated: 29* (1) The fill value may be 1 or 2 bytes long. 30* (2) The fill operation may end by hitting the count value 31* or by hitting the end of the string. 32* (3) A null terminating char is NOT placed at the end of 33* the string. 34* 35* Cases to be careful of (both of these can occur at once): 36* (1) Leaving an "orphaned" trail byte in the string (e.g., 37* overwriting a lead byte but not the corresponding trail byte). 38* (2) Writing only the 1st byte of a 2-byte fill value because the 39* end of string was encountered. 40* 41*Entry: 42* unsigned char *string = string to modify 43* unsigned int val = value to fill string with 44* size_t count = count of characters to fill 45* 46* 47*Exit: 48* Returns string = now filled with char val 49* 50*Uses: 51* 52*Exceptions: 53* Input parameters are validated. Refer to the validation section of the function. 54* 55*******************************************************************************/ 56 57extern "C" unsigned char * __cdecl _mbsnset_l( 58 unsigned char *string, 59 unsigned int val, 60 size_t count, 61 _locale_t plocinfo 62 ) 63{ 64 unsigned char *start = string; 65 unsigned int leadbyte = 0; 66 unsigned char highval, lowval; 67 _LocaleUpdate _loc_update(plocinfo); 68 69 /* validation section */ 70 _VALIDATE_RETURN(string != nullptr || count == 0, EINVAL, nullptr); 71 72 /* 73 * leadbyte flag indicates if the last byte we overwrote was 74 * a lead byte or not. 75 */ 76_BEGIN_SECURE_CRT_DEPRECATION_DISABLE 77 if (_loc_update.GetLocaleT()->mbcinfo->ismbcodepage == 0) 78 return (unsigned char *)_strnset((char *)string, val, count); 79_END_SECURE_CRT_DEPRECATION_DISABLE 80 81 highval = static_cast<unsigned char>(val >> 8); 82 if (highval != 0) 83 { 84 85 /* double byte value */ 86 87 lowval = (unsigned char)(val & 0x00ff); 88 89 if(lowval=='\0') 90 { 91 _ASSERTE(("invalid MBCS pair passed to mbsnset",0)); 92 93 /* Ideally we would return nullptr here and signal an error 94 condition. But since this function has no other 95 error modes, there would be a good chance of crashing 96 the caller. So instead we fill the string with spaces 97 to ensure that no information leaks through 98 unexpectedly. Anyway, we do set errno to EINVAL. 99 */ 100 errno = EINVAL; 101 lowval=highval=' '; 102 } 103 104 while (count-- && *string) { 105 leadbyte = _ismbbtruelead_l(leadbyte, *string, _loc_update.GetLocaleT()); 106 *string++ = highval; 107 108 if (*string) { 109 leadbyte = _ismbbtruelead_l(leadbyte, *string, _loc_update.GetLocaleT()); 110 *string++ = lowval; 111 } 112 else 113 /* overwrite orphaned highval byte */ 114 *(string-1) = ' '; 115 } 116 } 117 118 else { 119 /* single byte value */ 120 121 while (count-- && *string) { 122 leadbyte = _ismbbtruelead_l(leadbyte, *string, _loc_update.GetLocaleT()); 123 *string++ = (unsigned char)val; 124 } 125 } 126 127 /* overwrite orphaned trailing byte, if necessary */ 128 if(leadbyte && *string) 129 *string = ' '; 130 131 return( start ); 132} 133 134unsigned char * (__cdecl _mbsnset)( 135 unsigned char *string, 136 unsigned int val, 137 size_t count 138 ) 139{ 140_BEGIN_SECURE_CRT_DEPRECATION_DISABLE 141 return _mbsnset_l(string, val, count, nullptr); 142_END_SECURE_CRT_DEPRECATION_DISABLE 143}