407a8204cda276c24cc63197485ffe9259e67e23
[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 extern int g_mbcp_is_multibyte;
17
18 /*
19 * @implemented
20 */
21 unsigned char* _mbsncpy(unsigned char *dst, const unsigned char *src, size_t n)
22 {
23 unsigned char* ret = dst;
24 if(!n)
25 return dst;
26 if (g_mbcp_is_multibyte)
27 {
28 while (*src && n)
29 {
30 n--;
31 if (_ismbblead(*src))
32 {
33 if (!*(src+1))
34 {
35 *dst++ = 0;
36 *dst++ = 0;
37 break;
38 }
39
40 *dst++ = *src++;
41 }
42
43 *dst++ = *src++;
44 }
45 }
46 else
47 {
48 while (n)
49 {
50 n--;
51 if (!(*dst++ = *src++)) break;
52 }
53 }
54 while (n--) *dst++ = 0;
55 return ret;
56 }
57
58
59 /*
60 * The _mbsnbcpy function copies count bytes from src to dest. If src is shorter
61 * than dest, the string is padded with null characters. If dest is less than or
62 * equal to count it is not terminated with a null character.
63 *
64 * @implemented
65 */
66 unsigned char * _mbsnbcpy(unsigned char *dst, const unsigned char *src, size_t n)
67 {
68 unsigned char* ret = dst;
69 if(!n)
70 return dst;
71 if(g_mbcp_is_multibyte)
72 {
73 int is_lead = 0;
74 while (*src && n)
75 {
76 is_lead = (!is_lead && _ismbblead(*src));
77 n--;
78 *dst++ = *src++;
79 }
80
81 if (is_lead) /* if string ends with a lead, remove it */
82 *(dst - 1) = 0;
83 }
84 else
85 {
86 while (n)
87 {
88 n--;
89 if (!(*dst++ = *src++)) break;
90 }
91 }
92 while (n--) *dst++ = 0;
93 return ret;
94 }
95
96 /*
97 * Unlike _mbsnbcpy this function does not pad the rest of the dest
98 * string with 0
99 */
100 int CDECL _mbsnbcpy_s(unsigned char* dst, size_t size, const unsigned char* src, size_t n)
101 {
102 size_t pos = 0;
103
104 if(!dst || size == 0)
105 return EINVAL;
106 if(!src)
107 {
108 dst[0] = '\0';
109 return EINVAL;
110 }
111 if(!n)
112 return 0;
113
114 if(g_mbcp_is_multibyte)
115 {
116 int is_lead = 0;
117 while (*src && n)
118 {
119 if(pos == size)
120 {
121 dst[0] = '\0';
122 return ERANGE;
123 }
124 is_lead = (!is_lead && _ismbblead(*src));
125 n--;
126 dst[pos++] = *src++;
127 }
128
129 if (is_lead) /* if string ends with a lead, remove it */
130 dst[pos - 1] = 0;
131 }
132 else
133 {
134 while (n)
135 {
136 n--;
137 if(pos == size)
138 {
139 dst[0] = '\0';
140 return ERANGE;
141 }
142
143 if(!(*src)) break;
144 dst[pos++] = *src++;
145 }
146 }
147
148 if(pos < size)
149 dst[pos] = '\0';
150 else
151 {
152 dst[0] = '\0';
153 return ERANGE;
154 }
155
156 return 0;
157 }