xref: /reactos/sdk/lib/crt/mbstring/mbsncpy.c (revision dc0433f0)
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