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: wcstok_s function
12 * Author: lishunda
13 * Create: 2014-02-25
14 */
15
16 #include "securecutil.h"
17
SecIsInDelimitW(wchar_t ch,const wchar_t * strDelimit)18 SECUREC_INLINE int SecIsInDelimitW(wchar_t ch, const wchar_t *strDelimit)
19 {
20 const wchar_t *ctl = strDelimit;
21 while (*ctl != L'\0' && *ctl != ch) {
22 ++ctl;
23 }
24 return (int)(*ctl != L'\0');
25 }
26
27 /*
28 * Find beginning of token (skip over leading delimiters).
29 * Note that there is no token if this loop sets string to point to the terminal null.
30 */
SecFindBeginW(wchar_t * strToken,const wchar_t * strDelimit)31 SECUREC_INLINE wchar_t *SecFindBeginW(wchar_t *strToken, const wchar_t *strDelimit)
32 {
33 wchar_t *token = strToken;
34 while (*token != L'\0') {
35 if (SecIsInDelimitW(*token, strDelimit) != 0) {
36 ++token;
37 continue;
38 }
39 /* Don't find any delimiter in string header, break the loop */
40 break;
41 }
42 return token;
43 }
44
45 /*
46 * Find the end of the token. If it is not the end of the string, put a null there.
47 */
SecFindRestW(wchar_t * strToken,const wchar_t * strDelimit)48 SECUREC_INLINE wchar_t *SecFindRestW(wchar_t *strToken, const wchar_t *strDelimit)
49 {
50 wchar_t *token = strToken;
51 while (*token != L'\0') {
52 if (SecIsInDelimitW(*token, strDelimit) != 0) {
53 /* Find a delimiter, set string termintor */
54 *token = L'\0';
55 ++token;
56 break;
57 }
58 ++token;
59 }
60 return token;
61 }
62
63 /*
64 * Update Token wide character function
65 */
SecUpdateTokenW(wchar_t * strToken,const wchar_t * strDelimit,wchar_t ** context)66 SECUREC_INLINE wchar_t *SecUpdateTokenW(wchar_t *strToken, const wchar_t *strDelimit, wchar_t **context)
67 {
68 /* Point to updated position. Record string position for next search in the context */
69 *context = SecFindRestW(strToken, strDelimit);
70 /* Determine if a token has been found */
71 if (*context == strToken) {
72 return NULL;
73 }
74 return strToken;
75 }
76
77 /*
78 * <NAME>
79 * wcstok_s
80 *
81 *
82 * <FUNCTION DESCRIPTION>
83 * The wcstok_s function is the wide-character equivalent of the strtok_s function
84 *
85 * <INPUT PARAMETERS>
86 * strToken String containing token or tokens.
87 * strDelimit Set of delimiter characters.
88 * context Used to store position information between calls to
89 * wcstok_s.
90 *
91 * <OUTPUT PARAMETERS>
92 * context is updated
93 * <RETURN VALUE>
94 * The wcstok_s function is the wide-character equivalent of the strtok_s function
95 */
wcstok_s(wchar_t * strToken,const wchar_t * strDelimit,wchar_t ** context)96 wchar_t *wcstok_s(wchar_t *strToken, const wchar_t *strDelimit, wchar_t **context)
97 {
98 wchar_t *orgToken = strToken;
99 /* Validation section */
100 if (context == NULL || strDelimit == NULL) {
101 return NULL;
102 }
103 if (orgToken == NULL && *context == NULL) {
104 return NULL;
105 }
106 /* If string==NULL, continue with previous string */
107 if (orgToken == NULL) {
108 orgToken = *context;
109 }
110 orgToken = SecFindBeginW(orgToken, strDelimit);
111 return SecUpdateTokenW(orgToken, strDelimit, context);
112 }
113
114