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