101 lines
3.5 KiB
C
101 lines
3.5 KiB
C
/*******************************************************************************
|
|
* Copyright @ Huawei Technologies Co., Ltd. 1998-2014. All rights reserved.
|
|
* File name: vsnprintf.c
|
|
* History:
|
|
* 1. Date: 2014/5/20
|
|
* Author: LiShunda
|
|
* Modification: change #include "securectype.h" to #include "securec.h", which
|
|
* will cause link error under C++ compiler.
|
|
********************************************************************************
|
|
*/
|
|
|
|
#include "securec.h"
|
|
#include "securecutil.h"
|
|
#include <stdarg.h>
|
|
|
|
/*******************************************************************************
|
|
* <NAME>
|
|
* vsnprintf_s
|
|
*
|
|
* <SYNOPSIS>
|
|
* int vsnprintf_s(char* strDest, size_t destMax, size_t count, const char* format, valist ap);
|
|
*
|
|
* <FUNCTION DESCRIPTION>
|
|
* The vsnprintf_s function takes a pointer to an argument list, then formats
|
|
* and writes up to count characters of the given data to the memory pointed
|
|
* to by strDest and appends a terminating null.
|
|
*
|
|
* <INPUT PARAMETERS>
|
|
* strDest Storage location for the output.
|
|
* destMax The size of the strDest for output.
|
|
* count Maximum number of character to write(not including
|
|
* the terminating NULL)
|
|
* format Format-control string.
|
|
* ap pointer to list of arguments.
|
|
*
|
|
* <OUTPUT PARAMETERS>
|
|
* strDest is updated
|
|
*
|
|
* <RETURN VALUE>
|
|
* vsnprintf_s returns the number of characters written, not including the
|
|
* terminating null, or a negative value if an output error occurs. vsnprintf_s
|
|
* is included for compliance to the ANSI standard.
|
|
* If the storage required to store the data and a terminating null exceeds
|
|
* destMax, the function set strDest to an empty strDest, and return -1.
|
|
* If strDest or format is a NULL pointer, or if count is less than or equal
|
|
* to zero, the function return -1.
|
|
*
|
|
* ERROR CONDITIONS:
|
|
* Condition Return
|
|
* strDest is NULL -1
|
|
* format is NULL -1
|
|
* count <= 0 -1
|
|
* destMax too small -1(and strDest set to an empty string)
|
|
*******************************************************************************
|
|
*/
|
|
|
|
|
|
int vsnprintf_s(char *strDest, size_t destMax, size_t count, const char *format, va_list arglist)
|
|
{
|
|
int retvalue = -1;
|
|
|
|
if (format == NULL || strDest == NULL || destMax == 0 || destMax > SECUREC_STRING_MAX_LEN || (count > (SECUREC_STRING_MAX_LEN - 1) && count != (size_t) - 1)) {
|
|
if (strDest != NULL && destMax > 0) {
|
|
strDest[0] = '\0';
|
|
}
|
|
SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_s");
|
|
return -1;
|
|
}
|
|
|
|
if (destMax > count) {
|
|
retvalue = vsnprintf_helper(strDest, count + 1, format, arglist);
|
|
if (retvalue == -2) { /* lsd add to keep dest buffer not destroyed 2014.2.18 */
|
|
/* the string has been truncated, return -1 */
|
|
return -1; /* to skip error handler, return strlen(strDest) or -1 */
|
|
}
|
|
} else { /* destMax <= count */
|
|
retvalue = vsnprintf_helper(strDest, destMax, format, arglist);
|
|
strDest[destMax - 1] = 0;
|
|
#ifdef COMPATIBLE_WIN_FORMAT
|
|
if (retvalue == -2 && count == (size_t) - 1) {
|
|
return -1;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
if (retvalue < 0) {
|
|
strDest[0] = '\0'; /* empty the dest strDest */
|
|
|
|
if (retvalue == -2) {
|
|
/* Buffer too small */
|
|
SECUREC_ERROR_INVALID_RANGE("vsnprintf_s");
|
|
}
|
|
|
|
SECUREC_ERROR_INVALID_PARAMTER("vsnprintf_s");
|
|
return -1;
|
|
}
|
|
|
|
return retvalue;
|
|
}
|
|
|
|
|