13d58139fSopenharmony_ci/* 23d58139fSopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2014-2021. All rights reserved. 33d58139fSopenharmony_ci * Licensed under Mulan PSL v2. 43d58139fSopenharmony_ci * You can use this software according to the terms and conditions of the Mulan PSL v2. 53d58139fSopenharmony_ci * You may obtain a copy of Mulan PSL v2 at: 63d58139fSopenharmony_ci * http://license.coscl.org.cn/MulanPSL2 73d58139fSopenharmony_ci * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 83d58139fSopenharmony_ci * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 93d58139fSopenharmony_ci * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 103d58139fSopenharmony_ci * See the Mulan PSL v2 for more details. 113d58139fSopenharmony_ci * Description: wcstok_s function 123d58139fSopenharmony_ci * Create: 2014-02-25 133d58139fSopenharmony_ci */ 143d58139fSopenharmony_ci 153d58139fSopenharmony_ci#include "securecutil.h" 163d58139fSopenharmony_ci 173d58139fSopenharmony_ciSECUREC_INLINE int SecIsInDelimitW(wchar_t ch, const wchar_t *strDelimit) 183d58139fSopenharmony_ci{ 193d58139fSopenharmony_ci const wchar_t *ctl = strDelimit; 203d58139fSopenharmony_ci while (*ctl != L'\0' && *ctl != ch) { 213d58139fSopenharmony_ci ++ctl; 223d58139fSopenharmony_ci } 233d58139fSopenharmony_ci return (int)(*ctl != L'\0'); 243d58139fSopenharmony_ci} 253d58139fSopenharmony_ci 263d58139fSopenharmony_ci/* 273d58139fSopenharmony_ci * Find beginning of token (skip over leading delimiters). 283d58139fSopenharmony_ci * Note that there is no token if this loop sets string to point to the terminal null. 293d58139fSopenharmony_ci */ 303d58139fSopenharmony_ciSECUREC_INLINE wchar_t *SecFindBeginW(wchar_t *strToken, const wchar_t *strDelimit) 313d58139fSopenharmony_ci{ 323d58139fSopenharmony_ci wchar_t *token = strToken; 333d58139fSopenharmony_ci while (*token != L'\0') { 343d58139fSopenharmony_ci if (SecIsInDelimitW(*token, strDelimit) != 0) { 353d58139fSopenharmony_ci ++token; 363d58139fSopenharmony_ci continue; 373d58139fSopenharmony_ci } 383d58139fSopenharmony_ci /* Don't find any delimiter in string header, break the loop */ 393d58139fSopenharmony_ci break; 403d58139fSopenharmony_ci } 413d58139fSopenharmony_ci return token; 423d58139fSopenharmony_ci} 433d58139fSopenharmony_ci 443d58139fSopenharmony_ci/* 453d58139fSopenharmony_ci * Find the end of the token. If it is not the end of the string, put a null there. 463d58139fSopenharmony_ci */ 473d58139fSopenharmony_ciSECUREC_INLINE wchar_t *SecFindRestW(wchar_t *strToken, const wchar_t *strDelimit) 483d58139fSopenharmony_ci{ 493d58139fSopenharmony_ci wchar_t *token = strToken; 503d58139fSopenharmony_ci while (*token != L'\0') { 513d58139fSopenharmony_ci if (SecIsInDelimitW(*token, strDelimit) != 0) { 523d58139fSopenharmony_ci /* Find a delimiter, set string terminator */ 533d58139fSopenharmony_ci *token = L'\0'; 543d58139fSopenharmony_ci ++token; 553d58139fSopenharmony_ci break; 563d58139fSopenharmony_ci } 573d58139fSopenharmony_ci ++token; 583d58139fSopenharmony_ci } 593d58139fSopenharmony_ci return token; 603d58139fSopenharmony_ci} 613d58139fSopenharmony_ci 623d58139fSopenharmony_ci/* 633d58139fSopenharmony_ci * Update Token wide character function 643d58139fSopenharmony_ci */ 653d58139fSopenharmony_ciSECUREC_INLINE wchar_t *SecUpdateTokenW(wchar_t *strToken, const wchar_t *strDelimit, wchar_t **context) 663d58139fSopenharmony_ci{ 673d58139fSopenharmony_ci /* Point to updated position. Record string position for next search in the context */ 683d58139fSopenharmony_ci *context = SecFindRestW(strToken, strDelimit); 693d58139fSopenharmony_ci /* Determine if a token has been found */ 703d58139fSopenharmony_ci if (*context == strToken) { 713d58139fSopenharmony_ci return NULL; 723d58139fSopenharmony_ci } 733d58139fSopenharmony_ci return strToken; 743d58139fSopenharmony_ci} 753d58139fSopenharmony_ci 763d58139fSopenharmony_ci/* 773d58139fSopenharmony_ci * <NAME> 783d58139fSopenharmony_ci * wcstok_s 793d58139fSopenharmony_ci * 803d58139fSopenharmony_ci * 813d58139fSopenharmony_ci * <FUNCTION DESCRIPTION> 823d58139fSopenharmony_ci * The wcstok_s function is the wide-character equivalent of the strtok_s function 833d58139fSopenharmony_ci * 843d58139fSopenharmony_ci * <INPUT PARAMETERS> 853d58139fSopenharmony_ci * strToken String containing token or tokens. 863d58139fSopenharmony_ci * strDelimit Set of delimiter characters. 873d58139fSopenharmony_ci * context Used to store position information between calls to 883d58139fSopenharmony_ci * wcstok_s. 893d58139fSopenharmony_ci * 903d58139fSopenharmony_ci * <OUTPUT PARAMETERS> 913d58139fSopenharmony_ci * context is updated 923d58139fSopenharmony_ci * <RETURN VALUE> 933d58139fSopenharmony_ci * The wcstok_s function is the wide-character equivalent of the strtok_s function 943d58139fSopenharmony_ci */ 953d58139fSopenharmony_ciwchar_t *wcstok_s(wchar_t *strToken, const wchar_t *strDelimit, wchar_t **context) 963d58139fSopenharmony_ci{ 973d58139fSopenharmony_ci wchar_t *orgToken = strToken; 983d58139fSopenharmony_ci /* Validation section */ 993d58139fSopenharmony_ci if (context == NULL || strDelimit == NULL) { 1003d58139fSopenharmony_ci return NULL; 1013d58139fSopenharmony_ci } 1023d58139fSopenharmony_ci if (orgToken == NULL && *context == NULL) { 1033d58139fSopenharmony_ci return NULL; 1043d58139fSopenharmony_ci } 1053d58139fSopenharmony_ci /* If string==NULL, continue with previous string */ 1063d58139fSopenharmony_ci if (orgToken == NULL) { 1073d58139fSopenharmony_ci orgToken = *context; 1083d58139fSopenharmony_ci } 1093d58139fSopenharmony_ci orgToken = SecFindBeginW(orgToken, strDelimit); 1103d58139fSopenharmony_ci return SecUpdateTokenW(orgToken, strDelimit, context); 1113d58139fSopenharmony_ci} 1123d58139fSopenharmony_ci 113