reactos/sdk/lib/crt/mbstring/mbsncpy.c

160 lines
3.2 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS system libraries
* FILE: lib/sdk/crt/mbstring/mbsncpy.c
* PURPOSE: Copies a string to a maximum of n bytes or characters
* PROGRAMERS:
* Copyright 1999 Ariadne
* Copyright 1999 Alexandre Julliard
* Copyright 2000 Jon Griffths
*
*/
#include <precomp.h>
#include <mbstring.h>
/*********************************************************************
* _mbsncpy(MSVCRT.@)
* REMARKS
* The parameter n is the number or characters to copy, not the size of
* the buffer. Use _mbsnbcpy for a function analogical to strncpy
*/
unsigned char* CDECL _mbsncpy(unsigned char* dst, const unsigned char* src, size_t n)
{
unsigned char* ret = dst;
if(!n)
return dst;
if (get_mbcinfo()->ismbcodepage)
{
while (*src && n)
{
n--;
if (_ismbblead(*src))
{
if (!*(src+1))
{
*dst++ = 0;
*dst++ = 0;
break;
}
*dst++ = *src++;
}
*dst++ = *src++;
}
}
else
{
while (n)
{
n--;
if (!(*dst++ = *src++)) break;
}
}
while (n--) *dst++ = 0;
return ret;
}
/*********************************************************************
* _mbsnbcpy_s(MSVCRT.@)
* REMARKS
* Unlike _mbsnbcpy this function does not pad the rest of the dest
* string with 0
*/
int CDECL _mbsnbcpy_s(unsigned char* dst, size_t size, const unsigned char* src, size_t n)
{
size_t pos = 0;
if(!dst || size == 0)
return EINVAL;
if(!src)
{
dst[0] = '\0';
return EINVAL;
}
if(!n)
return 0;
if(get_mbcinfo()->ismbcodepage)
{
int is_lead = 0;
while (*src && n)
{
if(pos == size)
{
dst[0] = '\0';
return ERANGE;
}
is_lead = (!is_lead && _ismbblead(*src));
n--;
dst[pos++] = *src++;
}
if (is_lead) /* if string ends with a lead, remove it */
dst[pos - 1] = 0;
}
else
{
while (n)
{
n--;
if(pos == size)
{
dst[0] = '\0';
return ERANGE;
}
if(!(*src)) break;
dst[pos++] = *src++;
}
}
if(pos < size)
dst[pos] = '\0';
else
{
dst[0] = '\0';
return ERANGE;
}
return 0;
}
/*********************************************************************
* _mbsnbcpy(MSVCRT.@)
* REMARKS
* Like strncpy this function doesn't enforce the string to be
* NUL-terminated
*/
unsigned char* CDECL _mbsnbcpy(unsigned char* dst, const unsigned char* src, size_t n)
{
unsigned char* ret = dst;
if(!n)
return dst;
if(get_mbcinfo()->ismbcodepage)
{
int is_lead = 0;
while (*src && n)
{
is_lead = (!is_lead && _ismbblead(*src));
n--;
*dst++ = *src++;
}
if (is_lead) /* if string ends with a lead, remove it */
*(dst - 1) = 0;
}
else
{
while (n)
{
n--;
if (!(*dst++ = *src++)) break;
}
}
while (n--) *dst++ = 0;
return ret;
}