1 /*** 2 *mbsnbcat.c - concatenate string2 onto string1, max length n bytes 3 * 4 * Copyright (c) Microsoft Corporation. All rights reserved. 5 * 6 *Purpose: 7 * defines mbsnbcat() - concatenate maximum of n bytes 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 <locale.h> 17 #include <string.h> 18 19 20 /*** 21 * _mbsnbcat - concatenate max cnt bytes onto dst 22 * 23 *Purpose: 24 * Concatenates src onto dst, with a maximum of cnt bytes copied. 25 * Handles 2-byte MBCS characters correctly. 26 * 27 *Entry: 28 * unsigned char *dst - string to concatenate onto 29 * unsigned char *src - string to concatenate from 30 * int cnt - number of bytes to copy 31 * 32 *Exit: 33 * returns dst, with src (at least part) concatenated on 34 * 35 *Exceptions: 36 * Input parameters are validated. Refer to the validation section of the function. 37 * 38 *******************************************************************************/ 39 40 extern "C" unsigned char * __cdecl _mbsnbcat_l( 41 unsigned char *dst, 42 const unsigned char *src, 43 size_t cnt, 44 _locale_t plocinfo 45 ) 46 { 47 unsigned char *start; 48 49 if (!cnt) 50 return(dst); 51 52 /* validation section */ 53 _VALIDATE_RETURN(dst != nullptr, EINVAL, nullptr); 54 _VALIDATE_RETURN(src != nullptr, EINVAL, nullptr); 55 56 _LocaleUpdate _loc_update(plocinfo); 57 58 _BEGIN_SECURE_CRT_DEPRECATION_DISABLE 59 if (_loc_update.GetLocaleT()->mbcinfo->ismbcodepage == 0) 60 return (unsigned char *)strncat((char *)dst, (const char *)src, cnt); 61 _END_SECURE_CRT_DEPRECATION_DISABLE 62 63 start = dst; 64 while (*dst++) 65 ; 66 --dst; // dst now points to end of dst string 67 68 /* if last char in string is a lead byte, back up pointer */ 69 if ( dst!=start && _mbsbtype_l(start, (int) ((dst - start) - 1), _loc_update.GetLocaleT()) == _MBC_LEAD ) 70 { 71 --dst; 72 } 73 74 /* copy over the characters */ 75 76 while (cnt--) { 77 78 if ( _ismbblead_l(*src, _loc_update.GetLocaleT()) ) { 79 *dst++ = *src++; 80 if (cnt == 0) { /* write null if cnt exhausted */ 81 dst[-1] = '\0'; 82 break; 83 } 84 cnt--; 85 if ((*dst++ = *src++)=='\0') { /* or if no trail byte */ 86 dst[-2] = '\0'; 87 break; 88 } 89 } 90 else if ((*dst++ = *src++) == '\0') 91 break; 92 93 } 94 95 if ( dst!=start && _mbsbtype_l(start, (int) ((dst - start) - 1), _loc_update.GetLocaleT()) == _MBC_LEAD ) 96 { 97 dst[-1] = '\0'; 98 } 99 else 100 { 101 *dst = '\0'; 102 } 103 104 return(start); 105 } 106 107 extern "C" unsigned char * (__cdecl _mbsnbcat)( 108 unsigned char *dst, 109 const unsigned char *src, 110 size_t cnt 111 ) 112 { 113 _BEGIN_SECURE_CRT_DEPRECATION_DISABLE 114 return _mbsnbcat_l(dst, src, cnt, nullptr); 115 _END_SECURE_CRT_DEPRECATION_DISABLE 116 } 117