1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS system libraries 4 * FILE: lib/sdk/crt/mbstring/mbsncpy.c 5 * PURPOSE: Copies a string to a maximum of n bytes or characters 6 * PROGRAMERS: 7 * Copyright 1999 Ariadne 8 * Copyright 1999 Alexandre Julliard 9 * Copyright 2000 Jon Griffths 10 * 11 */ 12 13 #include <precomp.h> 14 #include <mbstring.h> 15 16 /********************************************************************* 17 * _mbsncpy(MSVCRT.@) 18 * REMARKS 19 * The parameter n is the number or characters to copy, not the size of 20 * the buffer. Use _mbsnbcpy for a function analogical to strncpy 21 */ 22 unsigned char* CDECL _mbsncpy(unsigned char* dst, const unsigned char* src, size_t n) 23 { 24 unsigned char* ret = dst; 25 if(!n) 26 return dst; 27 if (get_mbcinfo()->ismbcodepage) 28 { 29 while (*src && n) 30 { 31 n--; 32 if (_ismbblead(*src)) 33 { 34 if (!*(src+1)) 35 { 36 *dst++ = 0; 37 *dst++ = 0; 38 break; 39 } 40 41 *dst++ = *src++; 42 } 43 44 *dst++ = *src++; 45 } 46 } 47 else 48 { 49 while (n) 50 { 51 n--; 52 if (!(*dst++ = *src++)) break; 53 } 54 } 55 while (n--) *dst++ = 0; 56 return ret; 57 } 58 59 /********************************************************************* 60 * _mbsnbcpy_s(MSVCRT.@) 61 * REMARKS 62 * Unlike _mbsnbcpy this function does not pad the rest of the dest 63 * string with 0 64 */ 65 int CDECL _mbsnbcpy_s(unsigned char* dst, size_t size, const unsigned char* src, size_t n) 66 { 67 size_t pos = 0; 68 69 if(!dst || size == 0) 70 return EINVAL; 71 if(!src) 72 { 73 dst[0] = '\0'; 74 return EINVAL; 75 } 76 if(!n) 77 return 0; 78 79 if(get_mbcinfo()->ismbcodepage) 80 { 81 int is_lead = 0; 82 while (*src && n) 83 { 84 if(pos == size) 85 { 86 dst[0] = '\0'; 87 return ERANGE; 88 } 89 is_lead = (!is_lead && _ismbblead(*src)); 90 n--; 91 dst[pos++] = *src++; 92 } 93 94 if (is_lead) /* if string ends with a lead, remove it */ 95 dst[pos - 1] = 0; 96 } 97 else 98 { 99 while (n) 100 { 101 n--; 102 if(pos == size) 103 { 104 dst[0] = '\0'; 105 return ERANGE; 106 } 107 108 if(!(*src)) break; 109 dst[pos++] = *src++; 110 } 111 } 112 113 if(pos < size) 114 dst[pos] = '\0'; 115 else 116 { 117 dst[0] = '\0'; 118 return ERANGE; 119 } 120 121 return 0; 122 } 123 124 /********************************************************************* 125 * _mbsnbcpy(MSVCRT.@) 126 * REMARKS 127 * Like strncpy this function doesn't enforce the string to be 128 * NUL-terminated 129 */ 130 unsigned char* CDECL _mbsnbcpy(unsigned char* dst, const unsigned char* src, size_t n) 131 { 132 unsigned char* ret = dst; 133 if(!n) 134 return dst; 135 if(get_mbcinfo()->ismbcodepage) 136 { 137 int is_lead = 0; 138 while (*src && n) 139 { 140 is_lead = (!is_lead && _ismbblead(*src)); 141 n--; 142 *dst++ = *src++; 143 } 144 145 if (is_lead) /* if string ends with a lead, remove it */ 146 *(dst - 1) = 0; 147 } 148 else 149 { 150 while (n) 151 { 152 n--; 153 if (!(*dst++ = *src++)) break; 154 } 155 } 156 while (n--) *dst++ = 0; 157 return ret; 158 } 159 160