1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2014-2020. All rights reserved.
3 * Licensed under Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
8 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
9 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 * Description: By defining corresponding macro for UNICODE string and including "output.inl",
12 * this file generates real underlying function used by printf family API.
13 * Author: lishunda
14 * Create: 2014-02-25
15 */
16
17 /* If some platforms don't have wchar.h, dont't include it */
18 #if !(defined(SECUREC_VXWORKS_PLATFORM))
19 /* If there is no macro above, it will cause compiling alarm */
20 #if defined(_MSC_VER) && (_MSC_VER >= 1400)
21 #ifndef _CRTIMP_ALTERNATIVE
22 #define _CRTIMP_ALTERNATIVE /* Comment microsoft *_s function */
23 #endif
24 #ifndef __STDC_WANT_SECURE_LIB__
25 #define __STDC_WANT_SECURE_LIB__ 0
26 #endif
27 #endif
28 #include <wchar.h>
29 #endif
30
31 /* fix redefined */
32 #undef SECUREC_ENABLE_WCHAR_FUNC
33 /* Disable wchar func to clear vs warning */
34 #define SECUREC_ENABLE_WCHAR_FUNC 0
35 #define SECUREC_FORMAT_OUTPUT_INPUT 1
36
37 #ifndef SECUREC_FOR_WCHAR
38 #define SECUREC_FOR_WCHAR
39 #endif
40
41 #if defined(SECUREC_WARP_OUTPUT) && SECUREC_WARP_OUTPUT
42 #undef SECUREC_WARP_OUTPUT
43 #define SECUREC_WARP_OUTPUT 0
44 #endif
45
46 #include "secureprintoutput.h"
47
48 SECUREC_INLINE void SecWriteCharW(wchar_t ch, SecPrintfStream *f, int *pnumwritten);
49 SECUREC_INLINE int SecPutWcharStrEndingZero(SecPrintfStream *str, int zeroCount);
50
51 #include "output.inl"
52
53 /*
54 * Wide character formatted output implementation
55 */
SecVswprintfImpl(wchar_t * string,size_t sizeInWchar,const wchar_t * format,va_list argList)56 int SecVswprintfImpl(wchar_t *string, size_t sizeInWchar, const wchar_t *format, va_list argList)
57 {
58 SecPrintfStream str;
59 int retVal; /* If initialization causes e838 */
60
61 str.cur = (char *)string;
62 /* This count include \0 character, Must be greater than zero */
63 str.count = (int)(sizeInWchar * sizeof(wchar_t));
64
65 retVal = SecOutputSW(&str, format, argList);
66 if (retVal >= 0) {
67 if (SecPutWcharStrEndingZero(&str, (int)sizeof(wchar_t)) == 0) {
68 return retVal;
69 }
70 }
71 if (str.count < 0) {
72 /* The buffer was too small, then truncate */
73 string[sizeInWchar - 1] = L'\0';
74 return SECUREC_PRINTF_TRUNCATE;
75 }
76 string[0] = L'\0'; /* Empty the dest string */
77 return -1;
78 }
79
80 /*
81 * Output a wide character zero end into the SecPrintfStream structure
82 */
SecPutWcharStrEndingZero(SecPrintfStream * str,int zeroCount)83 SECUREC_INLINE int SecPutWcharStrEndingZero(SecPrintfStream *str, int zeroCount)
84 {
85 int count;
86 for (count = zeroCount; count > 0; --count) {
87 if (SecPutZeroChar(str) != 0) {
88 return -1;
89 }
90 }
91 return 0;
92 }
93
94 /*
95 * Output a wide character into the SecPrintfStream structure
96 */
SecPutCharW(wchar_t ch,SecPrintfStream * f)97 SECUREC_INLINE int SecPutCharW(wchar_t ch, SecPrintfStream *f)
98 {
99 f->count -= (int)sizeof(wchar_t); /* f -> count may be negative,indicating insufficient space */
100 if (f->count >= 0) {
101 *(wchar_t *)(void *)(f->cur) = ch;
102 f->cur += sizeof(wchar_t);
103 return 0;
104 }
105 return -1;
106 }
107
108 /*
109 * Output a wide character into the SecPrintfStream structure, returns the number of characters written
110 */
SecWriteCharW(wchar_t ch,SecPrintfStream * f,int * pnumwritten)111 SECUREC_INLINE void SecWriteCharW(wchar_t ch, SecPrintfStream *f, int *pnumwritten)
112 {
113 if (SecPutCharW(ch, f) == 0) {
114 *pnumwritten = *pnumwritten + 1;
115 } else {
116 *pnumwritten = -1;
117 }
118 }
119
120 /*
121 * Output multiple wide character into the SecPrintfStream structure, returns the number of characters written
122 */
SecWriteMultiCharW(wchar_t ch,int num,SecPrintfStream * f,int * pnumwritten)123 SECUREC_INLINE void SecWriteMultiCharW(wchar_t ch, int num, SecPrintfStream *f, int *pnumwritten)
124 {
125 int count;
126 for (count = num; count > 0; --count) {
127 SecWriteCharW(ch, f, pnumwritten);
128 if (*pnumwritten == -1) {
129 break;
130 }
131 }
132 }
133
134 /*
135 * Output a wide string into the SecPrintfStream structure, returns the number of characters written
136 */
SecWriteStringW(const wchar_t * string,int len,SecPrintfStream * f,int * pnumwritten)137 SECUREC_INLINE void SecWriteStringW(const wchar_t *string, int len, SecPrintfStream *f, int *pnumwritten)
138 {
139 const wchar_t *str = string;
140 int count;
141 for (count = len; count > 0; --count) {
142 SecWriteCharW(*str, f, pnumwritten);
143 ++str;
144 if (*pnumwritten == -1) {
145 break;
146 }
147 }
148 }
149
150