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