/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

/*----------------------------------------------------------------------------*/
/*! @file c_uc_str.h 
 *  $RCSfile: $
 *  $Revision: #3 $
 *  $Date: 2015/06/20 $
 *  $Author: jingbo.kuang $
 *  
 *  @par Description:
 *         This contains exported 'Unicode String' manipulation functions.
 */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*! @addtogroup groupMW_UNICODE
 *  @{ 
 */
/*----------------------------------------------------------------------------*/

#ifndef _C_UC_STR_H_
#define _C_UC_STR_H_


/*-----------------------------------------------------------------------------
                    include files
 ----------------------------------------------------------------------------*/
#include "u_common.h"
#include "u_uc_str.h"


/*-----------------------------------------------------------------------------
                    functions
 ----------------------------------------------------------------------------*/
/**
    Convert
 **/
/*------------------------------------------------------------------*/
/*! @brief c_uc_ps_to_w2s
 *              This API convert a UTF-8 string to UTF-16 string.
 *              String is NULL-terminated.
 *  @param [in] ps_src                  Source string to be converted.
 *  @param [in] ui4_dst_len             Buffer size of w2s_dst, in character units.
 *  @param [out] w2s_dst                 The converted string.
 *  @return Return the error code.
 *  @retval UCR_ERR_ARG             Argument error.
 *  @retval UCR_INV_CHAR            The source string contains invalid character(s).
 *  @retval UCR_NO_ENOUGH_BUFFER    Buffer overflow.
 *  @retval UCR_INTERNAL            Unicode internal error.
 *  @retval UCR_OK                  Success.
 */
/*------------------------------------------------------------------*/
INT32 c_uc_ps_to_w2s(
    const CHAR*     ps_src,
    UTF16_T*        w2s_dst,
    UINT32          ui4_dst_len);

/*------------------------------------------------------------------*/
/*! @brief   c_uc_w2s_to_ps
 *              This API convert a UTF-16 string to UTF-8 string.
 *              String is NULL-terminated.
 *  @param [in] w2s_src                 Source string to be converted.
 *  @param [in] ui4_dst_len             Buffer size of ps_dst, in character units. 
 *  @param [out] ps_dst                  The converted string.
 *  @return Return the error code.
 *  @retval UCR_ERR_ARG             Argument error.
 *  @retval UCR_INV_CHAR            The source string contains invalid character(s).
 *  @retval UCR_NO_ENOUGH_BUFFER    Buffer overflow.
 *  @retval UCR_INTERNAL            Unicode internal error.
 *  @retval UCR_OK                  Success.
 */
/*------------------------------------------------------------------*/
INT32 c_uc_w2s_to_ps(
    const UTF16_T*  w2s_src,
    CHAR*           ps_dst,
    UINT32          ui4_dst_len);


/**
    Count
 **/
/*------------------------------------------------------------------*/
/*! @brief   c_uc_w2s_strlen
 *              This API counts the number of UTF16_T characters in a string.
 *              String is NULL-terminated.
 *  @param [in] w2s_str                 UTF-16 string to be counted.
 *  @return Return length of the string.
 *  @retval string length (UTF16_T characters).
 *             return 0 if w2s_str is NULL
 */
/*------------------------------------------------------------------*/
SIZE_T c_uc_w2s_strlen(
    const UTF16_T*  w2s_str);



/**
    Compare
 **/
/*------------------------------------------------------------------*/
/*! @brief  c_uc_w2s_strcmp
 *              This API compare two UTF-16 strings.
 *  @param [in] w2s_str1                UTF-16 string 1 to be compared.
 *  @param [in] w2s_str2                UTF-16 string 2 to be compared.
 *  @return
                > 0, w2s_str1 is larger than w2s_str2
 *             = 0, w2s_str1 is equal to w2s_str2
 *             < 0, w2s_str2 is larger than w2s_str1
 */
/*------------------------------------------------------------------*/
INT32 c_uc_w2s_strcmp(
    const UTF16_T*  w2s_str1,
    const UTF16_T*  w2s_str2);


/*------------------------------------------------------------------*/
/*! @brief   c_uc_w2s_strncmp
 *              This API compare the first ui4_len characters of two
 *              UTF-16 strings.
 *  @param [in] w2s_str1                UTF-16 string 1 to be compared.
 *  @param [in] w2s_str2                UTF-16 string 2 to be compared.
 *  @param [in] ui4_len                 The maximum length to be compared.
 *  @return
                > 0, w2s_str1 is larger than w2s_str2
 *             = 0, w2s_str1 is equal to w2s_str2
 *             < 0, w2s_str2 is larger than w2s_str1
 */
/*------------------------------------------------------------------*/
INT32 c_uc_w2s_strncmp(
    const UTF16_T*  w2s_str1,
    const UTF16_T*  w2s_str2,
    UINT32          ui4_len);



/**
    Cascade
 **/
/*------------------------------------------------------------------*/
/*! @brief   c_uc_w2s_strcat
 *               This API cascade source string to the end of destination string.
 *  @param [in] w2s_dst                 Null-terminated destination string.
 *  @param [in] w2s_src                 Null-terminated source string.
 *  @param [out] w2s_dst                 Null-terminated combined string.
 *  @return  pointer of combined string
 */
/*------------------------------------------------------------------*/
UTF16_T* c_uc_w2s_strcat(
    UTF16_T*        w2s_dst,
    const UTF16_T*  w2s_src);

/*------------------------------------------------------------------*/
/*! @brief   c_uc_w2s_strncat
 *              This API cascade ui4_len characters of source string to
 *              the end of destination string.
 *  @param [in] w2s_dst                 Null-terminated destination string.
 *  @param [in] w2s_src                 Null-terminated source string.
 *  @param [in] ui4_len                   Maximum length of source strings to be cascaded.
 *  @param [out] w2s_dst                 Null-terminated combined string.
 *  @return pointer of combined string
 */
/*------------------------------------------------------------------*/
UTF16_T* c_uc_w2s_strncat(
    UTF16_T*        w2s_dst,
    const UTF16_T*  w2s_src,
    UINT32          ui4_len);



/**
    Copy
 **/
/*------------------------------------------------------------------*/
/*! @brief   c_uc_w2s_strcpy
 *               The c_uc_w2s_strcpy function copies w2s_src, including the
 *              terminating null character, to the location w2s_dst.
 *              The original data in w2s_dst (if any) will be overrided.
 *  @param [in] w2s_dst                 Null-terminated destination string.
 *  @param [in] w2s_src                 Null-terminated source string.
 *  @param [out] w2s_dst                 Null-terminated combined string.
 *  @return pointer of w2s_dst
 */
/*------------------------------------------------------------------*/
UTF16_T* c_uc_w2s_strcpy(
    UTF16_T*        w2s_dst,
    const UTF16_T*  w2s_src);


/*------------------------------------------------------------------*/
/*! @brief   c_uc_w2s_strncpy
 *              The c_uc_w2s_strncpy function copies the initial ui4_len
 *              characters of w2s_src to w2s_dst and returns w2s_dst. If
 *              ui4_len is less than or equal to the length of w2s_src, a null
 *              character is NOT appended automatically to the copied string.
 *              If ui4_len is greater than the length of w2s_src, the
 *              destination string is padded with null characters up to length
 *              ui4_len.
 *  @param [in] w2s_dst                 Null-terminated destination string.
 *  @param [in] w2s_src                 Null-terminated source string.
 *  @param [in]  ui4_len                 Number of characters to be copied.
 *  @param [out] w2s_dst                 Null-terminated destination string.
 *  @return pointer of w2s_dst
 */
/*------------------------------------------------------------------*/
UTF16_T* c_uc_w2s_strncpy(
    UTF16_T*        w2s_dst,
    const UTF16_T*  w2s_src,
    UINT32          ui4_len);



/**
    Index
 **/

/*------------------------------------------------------------------*/
/*! @brief  c_uc_w2s_get
 *              Get the specified index character of a string.
 *  @param [in] w2s_str                 String to be indexed.
 *  @param [in] ui4_idx                 The index of the needed character. Begin from 0.
 *  @return
 *             The character in the specified index.
 *             if w2s_str is NULL, return 0
 */
/*------------------------------------------------------------------*/
UTF16_T c_uc_w2s_get(
    const UTF16_T*  w2s_str,
    UINT32          ui4_idx);


/*------------------------------------------------------------------*/
/*! @brief   c_uc_w2s_get_ptr
 *              Get pointer of the specified index character of a string.
 *  @param [in] w2s_str                 String to be indexed.
 *  @param [in] ui4_idx                   The index of the needed character. Begin from 0.
 *  @return The pointer of the character in the specified index.
 */
/*------------------------------------------------------------------*/
UTF16_T* c_uc_w2s_get_ptr(
    const UTF16_T*  w2s_str,
    UINT32          ui4_idx);


/*------------------------------------------------------------------*/
/*! @brief  c_uc_w2s_set
 *              Modify the specified index character of a string.
 *  @param [in] w2s_str                 String to be modified.
 *  @param [in] ui4_idx                   The character index to be modified.Begin from 0.
 *  @param [in] w2_char                 New character to replace the old one.
 *  @return Return the error code.
 *  @retval UCR_OK                     Success.
 *  @retval UCR_ERR_ARG             Parameter error.
 */
/*------------------------------------------------------------------*/
INT32 c_uc_w2s_set(
    UTF16_T*        w2s_str,
    UINT32          ui4_idx,
    UTF16_T         w2_char);

/**
    Reverse
 **/

/*------------------------------------------------------------------*/
/*! @brief  c_uc_w2s_reverse
 *              Reverse a string.
 *  @param [in] w2s_str                 String to be reversed.
 *  @return Return the error code.
 *  @retval UCR_OK                  Success.
 *  @retval UCR_ERR_ARG             Parameter error.
 */
/*------------------------------------------------------------------*/
INT32 c_uc_w2s_reverse(
    UTF16_T*  w2s_str);


/**
    Search
 **/

/*------------------------------------------------------------------*/
/*! @brief   c_uc_w2s_chr
 *               Find a character in a string.
 *  @param [in] w2s_str                 String to be searched in.
 *  @param [in] w2_ch                   The character to find.
 *  @return The pointer of the character.
 *  @retval if found                The pointer of the character.
 *  @retval  if not                   NULL
 */
/*------------------------------------------------------------------*/
UTF16_T* c_uc_w2s_chr(
    const UTF16_T*  w2s_str,
    UTF16_T         w2_ch);


/*------------------------------------------------------------------*/
/*! @brief  c_uc_w2s_chr_ex
 *              Find a character in a string.
 *  @param [in] w2s_str                 String to be searched in.
 *  @param [in] w2_ch                   The character to find.
 *  @param [out] pui4_pos                Position of the character. Begin from 0.
 *  @return The pointer of the character.
 *  @retval if found                The pointer of the character.
 *  @retval if not or error         NULL
 */
/*------------------------------------------------------------------*/
UTF16_T* c_uc_w2s_chr_ex(
    const UTF16_T*  w2s_str,
    UTF16_T         w2_ch,
    UINT32*         pui4_pos);

/*------------------------------------------------------------------*/
/*! @brief  c_uc_w2s_rchr
 *              Find a character in a string from end of string.
 *  @param [in] w2s_str                 String to be searched in.
 *  @param [in] w2_ch                   The character to find.
 *  @return The pointer of the character.
 *  @retval if found                The pointer of the character.
 *  @retval if not                  NULL
 */
/*------------------------------------------------------------------*/
UTF16_T* c_uc_w2s_rchr(
    const UTF16_T*  w2s_str,
    UTF16_T         w2_ch);


/**
    Case
 **/
/* Because upper/lower case is 'Locale-Dependent', clients should provide the
   locale parameter.
   Set locale to NULL will use the 'default locale'.
   Note! This parameter is ignored in current implementation */
/*------------------------------------------------------------------*/
/*! @brief   c_uc_w2s_toupper
 *               Convert the string to Upper case.
 *  @param [in] ui4_dst_len             Destination string buffer length.
 *  @param [in] w2s_src                 Null-terminated source string.
 *  @param [in] ps_locale                Specify the locale when convert case.
 *                                               Reserved for future. Only NULL is valid.
 *  @param [out] w2s_dst                 Converted string.
 *  @return Return the error code.
 *  @retval UCR_NO_SUPPORT          Specified locale is not supported.
 *  @retval UCR_NO_ENOUGH_BUFFER    Size of w2s_dst is not enough.
 *  @retval UCR_NO_MEMORY           Run out of system memory.
 *  @retval UCR_CNV_FAIL            Fail to convert.
 *  @retval UCR_ERR_ARG             Parameter error.
 *  @retval UCR_OK                  Success.
 */
/*------------------------------------------------------------------*/
INT32 c_uc_w2s_toupper(
    UTF16_T*        w2s_dst,
    UINT32          ui4_dst_len,
    const UTF16_T*  w2s_src,
    const CHAR*     ps_locale);

/*------------------------------------------------------------------*/
/*! @brief   c_uc_w2s_tolower
 *              Convert the string to Lower case.
 *  @param [in] ui4_dst_len             Destination string buffer length.
 *  @param [in] w2s_src                 Null-terminated source string.
 *  @param [in] ps_locale               Specify the locale when convert case.
 *                                              Reserved for future. Only NULL is valid.
 *  @param [out] w2s_dst                 Converted string.
 *  @return Return the error code.
 *  @retval UCR_NO_SUPPORT          Specified locale is not supported.
 *  @retval UCR_NO_ENOUGH_BUFFER    Size of w2s_dst is not enough.
 *  @retval  UCR_NO_MEMORY           Run out of system memory.
 *  @retval UCR_CNV_FAIL            Fail to convert.
 *  @retval UCR_OK                  Success
 */
/*------------------------------------------------------------------*/
INT32 c_uc_w2s_tolower(
    UTF16_T*        w2s_dst,
    UINT32          ui4_dst_len,
    const UTF16_T*  w2s_src,
    const CHAR*     ps_locale);

/*------------------------------------------------------------------*/
/*! @brief   c_multi_byte_to_unicode
 *              Convert multi byte to unicode.
 *  @param [in] pui2_multi_byte             string of multi bytes.
 *  @param [in] ui4_len                 length of multi bytes string.
 *  @param [in] e_multi_type          Specify code type of the multi bytes, GB2312 BIG5 SHIFT_JIS or KR.
 *                                              Reserved for future. Only NULL is valid.
 *  @param [out] pui2_unicode       Converted string.
 *  @return Return the error code.
 *  @retval -1          Converter failed.
 *  @retval 0            success.
 */
/*------------------------------------------------------------------*/

INT32 c_multi_byte_to_unicode(UINT16* pui2_multi_byte, UINT32 ui4_len, 
                           E_MUL_BYTE_TYPE e_multi_type, UINT16* pui2_unicode);

/*------------------------------------------------------------------*/
/*! @brief   c_multi_byte_to_unicode
 *              Convert multi byte to unicode.
 *  @param [in] pv_multi_byte             string of multi bytes.
 *  @param [in] ui4_src_len                 length of multi bytes string.
 *  @param [OUT] pui4_cut_pos            processed number bytes of multi bytes.
 *  @param [in] e_multi_type          Specify code type of the multi bytes, GB2312 BIG5 SHIFT_JIS or KR.
 *                                              Reserved for future. Only NULL is valid.
 *  @param [out] pui2_unicode       Converted string.
 *  @param [out] pui4_dst_len       destination string length.
 *  @param [in] pui2_unicode       MAX out buffer length.
 *  @return Return the error code.
 *  @retval -1          Converter failed.
 *  @retval 0            success.
 */
/*------------------------------------------------------------------*/

INT32 c_multi_byte_to_unicode_ex(VOID* pv_multi_byte, UINT32 ui4_src_len, UINT32* pui4_cut_pos, 
                           E_MUL_BYTE_TYPE e_multi_type, UINT16* pui2_unicode, UINT32* pui4_dst_len);


/*-----------------------------------------------------------------------------
 * Name:  c_surrogate_to_utf32
 *
 * Description: Convert the surrogate pair utf16 to utf32.
 *
 * Inputs:  lead             First UTF16 value.
 *          trail            Second UTF16 value.
 * Outputs: dest             Dest UTF32 value.
 *
 *
 * Returns: UCR_CNV_FAIL            Fail to convert.
 *          UCR_OK                  Success
 ----------------------------------------------------------------------------*/
INT32 c_surrogate_to_utf32(const UTF16_T lead,
             const UTF16_T trail,
             UINT32 *dest);

/*-----------------------------------------------------------------------------
 * Name:  c_utf_is_surrogate
 *
 * Description: Judge whether the utf-16 value is surrogate or not.
 *
 * Inputs:  src              UTF16 value.
 * Outputs: NULL
 *
 *
 * Returns: TRUE            surrogate.
 *          UCR_OK          not surrogate.
 ----------------------------------------------------------------------------*/
BOOL c_utf_is_surrogate(const UTF16_T src);

/*-----------------------------------------------------------------------------
 * Name:  c_utf_is_lead
 *
 * Description: Judge whether the utf-16 value is lead or not.
 *
 * Inputs:  src              UTF16 value.
 * Outputs: NULL
 *
 *
 * Returns: TRUE            lead.
 *          UCR_OK          not lead.
 ----------------------------------------------------------------------------*/
BOOL c_utf_is_lead(const UTF16_T src);

/*-----------------------------------------------------------------------------
 * Name:  c_utf_is_trail
 *
 * Description: Judge whether the utf-16 value is trail or not.
 *
 * Inputs:  src              UTF16 value.
 * Outputs: NULL
 *
 *
 * Returns: TRUE            trail.
 *          UCR_OK          not trail.
 ----------------------------------------------------------------------------*/
BOOL c_utf_is_trail(const UTF16_T src);

/*-----------------------------------------------------------------------------
 * Name:  c_utf32_cvt_to_pua
 *
 * Description: convert utf-32 to utf-16 with hk map.
 *
 * Inputs:  ui4_src              utf-32 value.
 * Outputs: NULL
 *
 *
 * Returns: 0               Sucess.
 *          other           fail(not found in map).
 ----------------------------------------------------------------------------*/
INT32 c_utf32_cvt_to_pua(UINT32 ui4_src, UINT32* pui2_unicode);


#endif  /* _C_UC_STR_H */
/*----------------------------------------------------------------------------*/
/*! @} */   /* end of  groupMW_UNICODE*/
/*----------------------------------------------------------------------------*/

