[MSVCRT]
[reactos.git] / reactos / lib / sdk / crt / mbstring / mbsncpy.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/msvcrt/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