[ACR-1523][uidna] Module implementation 07/221907/18
authorHyunjee Kim <hj0426.kim@samsung.com>
Wed, 8 Jan 2020 07:54:43 +0000 (16:54 +0900)
committerHyunjee Kim <hj0426.kim@samsung.com>
Mon, 13 Apr 2020 04:31:27 +0000 (13:31 +0900)
Change-Id: I066908e2822efb9c208072e69957c6560146cc79
Signed-off-by: Hyunjee Kim <hj0426.kim@samsung.com>
src/CMakeLists.txt
src/include/utils_i18n.h
src/include/utils_i18n_types.h
src/include/utils_i18n_uidna.h [new file with mode: 0644]
src/utils_i18n_uidna.c [new file with mode: 0644]

index e7f9817..244746a 100755 (executable)
@@ -43,6 +43,7 @@ SET(BASEUTILS_SRCS
     utils_i18n_unumsys.c
     utils_i18n_utext.c
     utils_i18n_uscript.c
+    utils_i18n_uidna.c
     utils_i18n_plural_rules.cpp
     utils_i18n_plural_format.cpp
     utils_i18n_immutable_idx.cpp
@@ -107,5 +108,6 @@ INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${INC_DIR}/utils_i18n_loc_disp_names.h
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${INC_DIR}/utils_i18n_unumsys.h DESTINATION ${INCLUDE_INSTALL_DIR}/base)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${INC_DIR}/utils_i18n_utext.h DESTINATION ${INCLUDE_INSTALL_DIR}/base)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${INC_DIR}/utils_i18n_uscript.h DESTINATION ${INCLUDE_INSTALL_DIR}/base)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${INC_DIR}/utils_i18n_uidna.h DESTINATION ${INCLUDE_INSTALL_DIR}/base)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${INC_DIR}/utils_i18n.h DESTINATION ${INCLUDE_INSTALL_DIR}/base)
 INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${pc_name}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
index 5f7b95d..8c01610 100644 (file)
@@ -55,6 +55,7 @@
 #include <utils_i18n_unumsys.h>
 #include <utils_i18n_utext.h>
 #include <utils_i18n_uscript.h>
+#include <utils_i18n_uidna.h>
 
 /**
  * @file utils_i18n.h
@@ -103,6 +104,7 @@ extern "C" {
  *       - numbering system
  *       - utext
  *       - unicode Script Information
+ *       - IDNA
  *
  *        This module provides flexible generation of number or date format patterns and helps you format and parse dates/number for any locale.
  * The i18n module provides various features based on data from ICU. The following table shows the version of ICU used in each Tizen platform.
@@ -277,6 +279,10 @@ extern "C" {
  *     <td>@ref CAPI_BASE_UTILS_I18N_USCRIPT_MODULE</td>
  *     <td>Unicode Script Information</td>
  * </tr>
+ * <tr>
+ *     <td>@ref CAPI_BASE_UTILS_I18N_UIDNA_MODULE</td>
+ *     <td>Internationalizing Domain Names in Applications (IDNA)</td>
+ * </tr>
  * </table>
  *
  * @section CAPI_BASE_UTILS_I18N_MODULE_MAPPING_TABLE Mapping Table
@@ -4503,6 +4509,56 @@ extern "C" {
  *    <td>#i18n_uscript_is_cased</td>
  *    <td>uscript_isCased</td>
  * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UIDNA_MODULE</td>
+ *    <td>#i18n_uidna_create</td>
+ *    <td>uidna_openUTS46</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UIDNA_MODULE</td>
+ *    <td>#i18n_uidna_destroy</td>
+ *    <td>uidna_close</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UIDNA_MODULE</td>
+ *    <td>#i18n_uidna_label_to_ascii</td>
+ *    <td>uidna_labelToASCII</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UIDNA_MODULE</td>
+ *    <td>#i18n_uidna_label_to_unicode</td>
+ *    <td>uidna_labelToUnicode</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UIDNA_MODULE</td>
+ *    <td>#i18n_uidna_name_to_ascii</td>
+ *    <td>uidna_nameToASCII</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UIDNA_MODULE</td>
+ *    <td>#i18n_uidna_name_to_unicode</td>
+ *    <td>uidna_nameToUnicode</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UIDNA_MODULE</td>
+ *    <td>#i18n_uidna_label_to_ascii_UTF8</td>
+ *    <td>uidna_labelToASCII_UTF8</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UIDNA_MODULE</td>
+ *    <td>#i18n_uidna_label_to_unicode_UTF8</td>
+ *    <td>uidna_labelToUnicodeUTF8</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UIDNA_MODULE</td>
+ *    <td>#i18n_uidna_name_to_ascii_UTF8</td>
+ *    <td>uidna_nameToASCII_UTF8</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UIDNA_MODULE</td>
+ *    <td>#i18n_uidna_name_to_unicode_UTF8</td>
+ *    <td>uidna_nameToUnicodeUTF8</td>
+ * </tr>
  * </table>
  */
 
index b7d59ac..4bba4f0 100644 (file)
@@ -4552,6 +4552,158 @@ typedef void *i18n_utext_h;
  * @}
  */
 
+/**
+* @addtogroup CAPI_BASE_UTILS_I18N_UIDNA_MODULE
+* @{
+*/
+
+/**
+ * @brief An #i18n_uidna_h handle.
+ * @details Use i18n_uidna_* functions to operate on #i18n_uidna_h objects.
+ * @since_tizen 6.0
+ */
+typedef void *i18n_uidna_h;
+
+/**
+ * @brief An #i18n_uidna_info_h handle.
+ * @since_tizen 6.0
+ */
+typedef void *i18n_uidna_info_h;
+
+/**
+ * @brief IDNA option bit set values.
+ * @since_tizen 6.0
+ */
+typedef enum {
+       I18N_UIDNA_DEFAULT=0,                                           /**< Default options value: None of the other options are set.
+                                                                                                        For use in static worker and factory methods. */
+       I18N_UIDNA_USE_STD3_RULES=2,                            /**< Option to check whether the input conforms to the STD3 ASCII rules,
+                                                                                                        for example the restriction of labels to LDH characters(ASCII Letters, Digits and Hyphen-Minus).
+                                                                                                        For use in static worker and factory methods. */
+       I18N_UIDNA_CHECK_BIDI=4,                                        /**< IDNA option to check for whether the input conforms to the BiDi rules.
+                                                                                                        For use in static worker and factory methods.
+                                                                                                        <p>This option is ignored by the IDNA2003 implementation.(IDNA2003 always performs a BiDi check.) */
+       I18N_UIDNA_CHECK_CONTEXTJ=8,                            /**< IDNA option to check for whether the input conforms to the CONTEXTJ rules.
+                                                                                                        For use in static worker and factory methods.
+                                                                                                        <p>This option is ignored by the IDNA2003 implementation.(CONTEXTJ check is new in IDNA2008.) */
+       I18N_UIDNA_NONTRANSITIONAL_TO_ASCII=0x10,       /**< IDNA option for nontransitional processing i18n_uidna_*_to_ascii().
+                                                                                                        For use in static worker and factory methods.
+                                                                                                        <p>By default, i18n_uidna_*_to_ascii() uses transitional processing.
+                                                                                                        <p>This option is ignored by the IDNA2003 implementation.
+                                                                                                        (This is only relevant for compatibility of newer IDNA implementations with IDNA2003.) */
+       I18N_UIDNA_NONTRANSITIONAL_TO_UNICODE=0x20,     /**< IDNA option for nontransitional processing in i18n_uidna_*_to_unicode().
+                                                                                                        For use in static worker and factory methods.
+                                                                                                        <p>By default, i18n_uidna_*_to_unicode() uses transitional processing.
+                                                                                                        <p>This option is ignored by the IDNA2003 implementation.
+                                                                                                        (This is only relevant for compatibility of newer IDNA implementations with IDNA2003.) */
+       I18N_UIDNA_CHECK_CONTEXTO=0x40                          /**< IDNA option to check for whether the input conforms to the CONTEXTO rules.
+                                                                                                        For use in static worker and factory methods.
+                                                                                                        <p>This option is ignored by the IDNA2003 implementation.(The CONTEXTO check is new in IDNA2008.)
+                                                                                                        <p>This is for use by registries for IDNA2008 conformance.
+                                                                                                        UTS #46 does not require the CONTEXTO check. */
+} i18n_uidna_option_e;
+
+/**
+ * @brief UIDNA error bit set values.
+ * @details When a domain name or label fails a processing step or does not meet the
+ *          validity criteria, then one or more of these error bits are set.
+ * @since_tizen 6.0
+ */
+typedef enum {
+       /**
+        * No errors
+        */
+       I18N_UIDNA_ERROR_NONE                   = 0,
+
+       /**
+        * A non-final domain name label (or the whole domain name) is empty.
+        */
+       I18N_UIDNA_ERROR_EMPTY_LABEL            = 1,
+
+       /**
+        * A domain name label is longer than 63 bytes.
+        * (See STD13/RFC1034 3.1. Name space specifications and terminology.)
+        * This is only checked in ToASCII operations, and only if the output label is all-ASCII.
+        */
+       I18N_UIDNA_ERROR_LABEL_TOO_LONG         = 2,
+
+       /**
+        * A domain name is longer than 255 bytes in its storage form.
+        * (See STD13/RFC1034 3.1. Name space specifications and terminology.)
+        * This is only checked in ToASCII operations, and only if the output domain name is all-ASCII.
+        */
+       I18N_UIDNA_ERROR_DOMAIN_NAME_TOO_LONG   = 4,
+
+       /**
+        * A label starts with a hyphen-minus ('-').
+       */
+       I18N_UIDNA_ERROR_LEADING_HYPHEN         = 8,
+
+       /**
+        * A label ends with a hyphen-minus ('-').
+        */
+       I18N_UIDNA_ERROR_TRAILING_HYPHEN        = 0x10,
+
+       /**
+        * A label contains hyphen-minus ('-') in the third and fourth positions.
+        */
+       I18N_UIDNA_ERROR_HYPHEN_3_4             = 0x20,
+
+       /**
+        * A label starts with a combining mark.
+        */
+       I18N_UIDNA_ERROR_LEADING_COMBINING_MARK = 0x40,
+
+       /**
+        * A label or domain name contains disallowed characters.
+        */
+       I18N_UIDNA_ERROR_DISALLOWED             = 0x80,
+
+       /**
+        * A label starts with "xn--" but does not contain valid Punycode.
+        * That is, an xn? label failed Punycode decoding.
+        */
+       I18N_UIDNA_ERROR_PUNYCODE               = 0x100,
+
+       /**
+        * A label contains a dot=full stop.
+        * This can occur in an input string for a single-label function.
+        */
+       I18N_UIDNA_ERROR_LABEL_HAS_DOT          = 0x200,
+
+       /**
+        * An ACE label does not contain a valid label string.
+        * The label was successfully ACE (Punycode) decoded but the resulting string had severe validation errors.
+        * For example, it might contain characters that are not allowed in ACE labels, or it might not be normalized.
+        */
+       I18N_UIDNA_ERROR_INVALID_ACE_LABEL      = 0x400,
+
+       /**
+        * A label does not meet the IDNA BiDi requirements (for right-to-left characters).
+        */
+       I18N_UIDNA_ERROR_BIDI                   = 0x800,
+
+       /**
+        * A label does not meet the IDNA CONTEXTJ requirements.
+        */
+       I18N_UIDNA_ERROR_CONTEXTJ               = 0x1000,
+
+       /**
+        * A label does not meet the IDNA CONTEXTO requirements for punctuation characters.
+        * Some punctuation characters "Would otherwise have been DISALLOWED" but are allowed in certain contexts. (RFC 5892)
+        */
+       I18N_UIDNA_ERROR_CONTEXTO_PUNCTUATION   = 0x2000,
+
+       /**
+        * A label does not meet the IDNA CONTEXTO requirements for digits.
+        * Arabic-Indic Digits (U+066x) must not be mixed with Extended Arabic-Indic Digits (U+06Fx).
+        */
+       I18N_UIDNA_ERROR_CONTEXTO_DIGITS        = 0x4000
+} i18n_uidna_error_e;
+/**
+ * @}
+ */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/include/utils_i18n_uidna.h b/src/include/utils_i18n_uidna.h
new file mode 100644 (file)
index 0000000..187db80
--- /dev/null
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+#ifndef __UTILS_I18N_UIDNA_H__
+#define __UTILS_I18N_UIDNA_H__
+
+#include <utils_i18n_types.h>
+
+/**
+ * @file utils_i18n_uidna.h
+ * @version 0.1
+ * @brief utils_i18n_uidna
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup CAPI_BASE_UTILS_I18N_MODULE
+ * @defgroup CAPI_BASE_UTILS_I18N_UIDNA_MODULE Uidna
+ * @brief Uidna module provides Internationalizing Domain Names in Applications.
+ * @section CAPI_BASE_UTILS_I18N_UIDNA_MODULE_HEADER Required Header
+ *  \#include <utils_i18n.h>
+ *
+ */
+
+/**
+ * @addtogroup CAPI_BASE_UTILS_I18N_UIDNA_MODULE
+ * @{
+ */
+
+/**
+ * @brief Returns a UIDNA instance which implements UTS #46.
+ * @details Returns an unmodifiable instance, owned by the caller. Cache it for multiple operations,
+ *          and i18n_uidna_destroy() it when done. The instance is thread-safe, that is, it can be used concurrently.
+ * @since_tizen 6.0
+ * @remarks The @a uidna should be released using i18n_uidna_destroy().
+ * @param[in] options   Bit set to modify the processing and error checking. See #i18n_uidna_option_e for options.
+ * @param[out] uidna    The UTS #46 UIDNA instance, if successful
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
+ * @retval #I18N_ERROR_OUT_OF_MEMORY Out of memory
+ * @see i18n_uidna_destroy
+ */
+int i18n_uidna_create(uint32_t options, i18n_uidna_h *uidna);
+
+/**
+ * @brief Destroys a UIDNA instance.
+ * @since_tizen 6.0
+ *
+ * @param[in] uidna UIDNA instance to be destroyed
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
+ * @see i18n_uidna_create
+ */
+int i18n_uidna_destroy(i18n_uidna_h uidna);
+
+/**
+ * @brief Converts a single domain name label into its ASCII form for DNS lookup.
+ * @details The label might be modified according to the types of errors. Labels with severe errors will be left in (or turned into) their Unicode form.
+ *          The #i18n_error_code_e indicates an error only in exceptional cases, such as a #I18N_ERROR_OUT_OF_MEMORY.
+ * @since_tizen 6.0
+ * @remarks @a info should be released with i18n_uidna_info_destroy().
+ *
+ * @param[in] uidna     A UIDNA instance
+ * @param[in] label     Input domain name label
+ * @param[in] length    Label length, or -1 if NUL-terminated
+ * @param[in] dest      Destination string buffer
+ * @param[in] capacity  Destination buffer capacity
+ * @param[out] info     Output container of IDNA processing details.
+ * @param[out] len      Destination string length
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
+ * @retval #I18N_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int i18n_uidna_label_to_ascii(i18n_uidna_h uidna, const i18n_uchar *label, int32_t length, i18n_uchar *dest, int32_t capacity, i18n_uidna_info_h *info, int32_t *len);
+
+/**
+ * @brief Converts a single domain name label into its Unicode form for human-readable display.
+ * @details The #i18n_error_code_e indicates an error only in exceptional cases, such as a #I18N_ERROR_OUT_OF_MEMORY.
+ * @since_tizen 6.0
+ * @remarks @a info should be released with i18n_uidna_info_destroy().
+ *
+ * @param[in] uidna     A UIDNA instance
+ * @param[in] label     Input domain name label
+ * @param[in] length    Label length, or -1 if NUL-terminated
+ * @param[in] dest      Destination string buffer
+ * @param[in] capacity  Destination buffer capacity
+ * @param[out] info     Output container of IDNA processing details.
+ * @param[out] len      Destination string length
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
+ * @retval #I18N_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int i18n_uidna_label_to_unicode(i18n_uidna_h uidna, const i18n_uchar *label, int32_t length, i18n_uchar *dest, int32_t capacity, i18n_uidna_info_h *info, int32_t *len);
+
+/**
+ * @brief Converts a whole domain name into its ASCII form for DNS lookup.
+ * @details The domain name might be modified according to the types of errors. Labels with severe errors will be left in (or turned into) their Unicode form.
+ *          The #i18n_error_code_e indicates an error only in exceptional cases, such as a #I18N_ERROR_OUT_OF_MEMORY.
+ * @since_tizen 6.0
+ * @remarks @a info should be released with i18n_uidna_info_destroy().
+ *
+ * @param[in] uidna     A UIDNA instance
+ * @param[in] name      Input domain name
+ * @param[in] length    Label length, or -1 if NUL-terminated
+ * @param[in] dest      Destination string buffer
+ * @param[in] capacity  Destination buffer capacity
+ * @param[out] info     Output container of IDNA processing details.
+ * @param[out] len      Destination string length
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
+ * @retval #I18N_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int i18n_uidna_name_to_ascii(i18n_uidna_h uidna, const i18n_uchar *name, int32_t length, i18n_uchar *dest, int32_t capacity, i18n_uidna_info_h *info, int32_t *len);
+
+/**
+ * @brief Converts a whole domain name into its Unicode form for human-readable display.
+ * @details The #i18n_error_code_e indicates an error only in exceptional cases, such as a #I18N_ERROR_OUT_OF_MEMORY.
+ * @since_tizen 6.0
+ * @remarks @a info should be released with i18n_uidna_info_destroy().
+ *
+ * @param[in] uidna     A UIDNA instance
+ * @param[in] name      Input domain name
+ * @param[in] length    Label length, or -1 if NUL-terminated
+ * @param[in] dest      Destination string buffer
+ * @param[in] capacity  Destination buffer capacity
+ * @param[out] info     Output container of IDNA processing details.
+ * @param[out] len      Destination string length
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
+ * @retval #I18N_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int i18n_uidna_name_to_unicode(i18n_uidna_h uidna, const i18n_uchar *name, int32_t length, i18n_uchar *dest, int32_t capacity, i18n_uidna_info_h *info, int32_t *len);
+
+/**
+ * @brief Converts a single domain name label (UTF8 encoded) into its ASCII form for DNS lookup.
+ * @since_tizen 6.0
+ * @remarks @a info should be released with i18n_uidna_info_destroy().
+ *
+ * @param[in] uidna     A UIDNA instance
+ * @param[in] label     Input domain name label
+ * @param[in] length    Label length, or -1 if NUL-terminated
+ * @param[in] dest      Destination string buffer
+ * @param[in] capacity  Destination buffer capacity
+ * @param[out] info     Output container of IDNA processing details.
+ * @param[out] len      Destination string length
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
+ * @retval #I18N_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int i18n_uidna_label_to_ascii_UTF8(i18n_uidna_h uidna, const char *label, int32_t length, char *dest, int32_t capacity, i18n_uidna_info_h *info, int32_t *len);
+
+/**
+ * @brief Converts a single domain name label into its Unicode form for human-readable display.
+ * @details UTF-8 version of i18n_uidna_label_to_unicode(), same behavior.
+ * @since_tizen 6.0
+ * @remarks @a info should be released with i18n_uidna_info_destroy().
+ *
+ * @param[in] uidna     A UIDNA instance
+ * @param[in] label     Input domain name label
+ * @param[in] length    Label length, or -1 if NUL-terminated
+ * @param[in] dest      Destination string buffer
+ * @param[in] capacity  Destination buffer capacity
+ * @param[out] info     Output container of IDNA processing details.
+ * @param[out] len      Destination string length
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
+ * @retval #I18N_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int i18n_uidna_label_to_unicode_UTF8 (i18n_uidna_h uidna, const char *label, int32_t length, char *dest, int32_t capacity, i18n_uidna_info_h *info, int32_t *len);
+
+/**
+ * @brief Converts a whole domain name into its ASCII form for DNS lookup.
+ * @details UTF-8 version of i18n_uidna_name_to_ascii(), same behavior.
+ * @since_tizen 6.0
+ * @remarks @a info should be released with i18n_uidna_info_destroy().
+ *
+ * @param[in] uidna     A UIDNA instance
+ * @param[in] name      Input domain name
+ * @param[in] length    Label length, or -1 if NUL-terminated
+ * @param[in] dest      Destination string buffer
+ * @param[in] capacity  Destination buffer capacity
+ * @param[out] info     Output container of IDNA processing details.
+ * @param[out] len      Destination string length
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
+ * @retval #I18N_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int i18n_uidna_name_to_ascii_UTF8(i18n_uidna_h uidna, const char *name, int32_t length, char *dest, int32_t capacity, i18n_uidna_info_h *info, int32_t *len);
+
+/**
+ * @brief Converts a whole domain name into its Unicode form for human-readable display.
+ * @details UTF-8 version of i18n_uidna_name_to_unicode(), same behavior.
+ * @since_tizen 6.0
+ * @remarks @a info should be released with i18n_uidna_info_destroy().
+ *
+ * @param[in] uidna     A UIDNA instance
+ * @param[in] name      Input domain name
+ * @param[in] length    Label length, or -1 if NUL-terminated
+ * @param[in] dest      Destination string buffer
+ * @param[in] capacity  Destination buffer capacity
+ * @param[out] info     Output container of IDNA processing details.
+ * @param[out] len      Destination string length
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
+ * @retval #I18N_ERROR_OUT_OF_MEMORY Out of memory
+ */
+int i18n_uidna_name_to_unicode_UTF8(i18n_uidna_h uidna, const char *name, int32_t length, char *dest, int32_t capacity, i18n_uidna_info_h *info, int32_t *len);
+
+/**
+ * @brief Gets whether transitional and nontransitional processing produce different results.
+ * @since_tizen 6.0
+ *
+ * @param[in] info                   UIDNA info handle
+ * @param[out] is_trans_different    TRUE if transitional and nontransitional processing produce different results.
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
+ */
+int i18n_uidna_info_get_is_trans_different(i18n_uidna_info_h info, i18n_ubool *is_trans_different);
+
+/**
+ * @brief Gets the bit set indicating UIDNA processing errors.
+ * @since_tizen 6.0
+ *
+ * @param[in] info       UIDNA info handle
+ * @param[out] errors    Bit set with UIDNA processing errors\n
+ *                       0 if no errors, see #i18n_uidna_error_e
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
+ */
+int i18n_uidna_info_get_errors(i18n_uidna_info_h info, uint32_t *errors);
+
+/**
+ * @brief Destroys a UIDNA info handle.
+ * @since_tizen 6.0
+ *
+ * @param[in] info    The UIDNA info handle to be destroyed
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
+ */
+int i18n_uidna_info_destroy(i18n_uidna_info_h info);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* __UTILS_I18N_UIDNA_H__*/
diff --git a/src/utils_i18n_uidna.c b/src/utils_i18n_uidna.c
new file mode 100644 (file)
index 0000000..cdcc4a5
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+* Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+*
+*       Licensed under the Apache License, Version 2.0 (the "License");
+*       you may not use this file except in compliance with the License.
+*       You may obtain a copy of the License at
+*
+*               http://www.apache.org/licenses/LICENSE-2.0
+*
+*       Unless required by applicable law or agreed to in writing, software
+*       distributed under the License is distributed on an "AS IS" BASIS,
+*       WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+*       See the License for the specific language governing permissions and
+*       limitations under the License.
+*/
+
+#include <unicode/idna.h>
+#include <unicode/uidna.h>
+
+#include <utils_i18n_uidna.h>
+#include <utils_i18n_private.h>
+
+UIDNAInfo *create_UIDNAInfo()
+{
+       UIDNAInfo *uinfo = (UIDNAInfo *)malloc((int16_t)sizeof(UIDNAInfo));
+       if (uinfo != NULL) {
+               uinfo->size = (int16_t)sizeof(UIDNAInfo);
+               uinfo->isTransitionalDifferent = FALSE;
+               uinfo->errors = 0;
+       }
+
+       return uinfo;
+}
+
+int i18n_uidna_create(uint32_t options, i18n_uidna_h *uts46)
+{
+       i18n_error_code_e i18n_error;
+       UErrorCode icu_error = U_ZERO_ERROR;
+
+       *uts46 = uidna_openUTS46(options, &icu_error);
+       ERR_MAPPING(icu_error, i18n_error);
+       I18N_ERR(i18n_error);
+
+       return i18n_error;
+}
+
+int i18n_uidna_destroy(i18n_uidna_h idna)
+{
+       retv_if(idna == NULL, I18N_ERROR_INVALID_PARAMETER);
+
+       uidna_close(idna);
+
+       return I18N_ERROR_NONE;
+}
+
+int i18n_uidna_label_to_ascii(const i18n_uidna_h idna, const i18n_uchar *label, int32_t length, i18n_uchar *dest, int32_t capacity, i18n_uidna_info_h *info, int32_t *len)
+{
+       retv_if((label==NULL ? length!=0 : length<-1) || (dest==NULL ? capacity!=0 : capacity<0) ||
+            (dest==label && label!=NULL), I18N_ERROR_INVALID_PARAMETER);
+
+       i18n_error_code_e i18n_error;
+       UErrorCode icu_error = U_ZERO_ERROR;
+
+       UIDNAInfo *uinfo = create_UIDNAInfo();
+
+       *len = uidna_labelToASCII(idna, label, length, dest, capacity, uinfo, &icu_error);
+       *info = (void *)uinfo;
+
+       ERR_MAPPING(icu_error, i18n_error);
+       I18N_ERR(i18n_error);
+
+       return i18n_error;
+}
+
+int i18n_uidna_label_to_unicode(const i18n_uidna_h idna, const i18n_uchar *label, int32_t length, i18n_uchar *dest, int32_t capacity, i18n_uidna_info_h *info, int32_t *len)
+{
+       retv_if((label==NULL ? length!=0 : length<-1) || (dest==NULL ? capacity!=0 : capacity<0) ||
+            (dest==label && label!=NULL), I18N_ERROR_INVALID_PARAMETER);
+
+       i18n_error_code_e i18n_error;
+       UErrorCode icu_error = U_ZERO_ERROR;
+
+       UIDNAInfo *uinfo = create_UIDNAInfo();
+       *len = uidna_labelToUnicode(idna, label, length, dest, capacity, uinfo, &icu_error);
+       *info = (void *)uinfo;
+
+       ERR_MAPPING(icu_error, i18n_error);
+       I18N_ERR(i18n_error);
+
+       return i18n_error;
+}
+
+int i18n_uidna_name_to_ascii(const i18n_uidna_h idna, const i18n_uchar *name, int32_t length, i18n_uchar *dest, int32_t capacity, i18n_uidna_info_h *info, int32_t *len)
+{
+       retv_if((name==NULL ? length!=0 : length<-1) || (dest==NULL ? capacity!=0 : capacity<0) ||
+                       (dest==name && name!=NULL), I18N_ERROR_INVALID_PARAMETER);
+
+       i18n_error_code_e i18n_error;
+       UErrorCode icu_error = U_ZERO_ERROR;
+
+       UIDNAInfo *uinfo = create_UIDNAInfo();
+       *len = uidna_nameToASCII(idna, name, length, dest, capacity, uinfo, &icu_error);
+       *info = (void *)uinfo;
+
+       ERR_MAPPING(icu_error, i18n_error);
+       I18N_ERR(i18n_error);
+
+       return i18n_error;
+}
+
+int i18n_uidna_name_to_unicode(const i18n_uidna_h idna, const i18n_uchar *name, int32_t length, i18n_uchar *dest, int32_t capacity, i18n_uidna_info_h *info, int32_t *len)
+{
+       retv_if((name==NULL ? length!=0 : length<-1) || (dest==NULL ? capacity!=0 : capacity<0) ||
+                       (dest==name && name!=NULL), I18N_ERROR_INVALID_PARAMETER);
+
+       i18n_error_code_e i18n_error;
+       UErrorCode icu_error = U_ZERO_ERROR;
+
+       UIDNAInfo *uinfo = create_UIDNAInfo();
+       *len = uidna_nameToUnicode(idna, name, length, dest, capacity, uinfo, &icu_error);
+       *info = (void *)uinfo;
+
+       ERR_MAPPING(icu_error, i18n_error);
+       I18N_ERR(i18n_error);
+
+       return i18n_error;
+}
+
+int i18n_uidna_label_to_ascii_UTF8(const i18n_uidna_h idna, const char *label, int32_t length, char *dest, int32_t capacity, i18n_uidna_info_h *info, int32_t *len)
+{
+       retv_if((label==NULL ? length!=0 : length<-1) || (dest==NULL ? capacity!=0 : capacity<0) ||
+                       (dest==label && label!=NULL), I18N_ERROR_INVALID_PARAMETER);
+
+       i18n_error_code_e i18n_error;
+       UErrorCode icu_error = U_ZERO_ERROR;
+
+       UIDNAInfo *uinfo = create_UIDNAInfo();
+       *len = uidna_labelToASCII_UTF8(idna, label, length, dest, capacity, uinfo, &icu_error);
+       *info = (void *)uinfo;
+
+       ERR_MAPPING(icu_error, i18n_error);
+       I18N_ERR(i18n_error);
+
+       return i18n_error;
+}
+
+int i18n_uidna_label_to_unicode_UTF8(const i18n_uidna_h idna, const char *label, int32_t length, char *dest, int32_t capacity, i18n_uidna_info_h *info, int32_t *len)
+{
+       retv_if((label==NULL ? length!=0 : length<-1) || (dest==NULL ? capacity!=0 : capacity<0) ||
+                       (dest==label && label!=NULL), I18N_ERROR_INVALID_PARAMETER);
+
+       i18n_error_code_e i18n_error;
+       UErrorCode icu_error = U_ZERO_ERROR;
+
+       UIDNAInfo *uinfo = create_UIDNAInfo();
+       *len = uidna_labelToUnicodeUTF8(idna, label, length, dest, capacity, uinfo, &icu_error);
+       *info = (void *)uinfo;
+
+       ERR_MAPPING(icu_error, i18n_error);
+       I18N_ERR(i18n_error);
+
+       return i18n_error;
+}
+
+int i18n_uidna_name_to_ascii_UTF8(const i18n_uidna_h idna, const char *name, int32_t length, char *dest, int32_t capacity, i18n_uidna_info_h *info, int32_t *len)
+       {
+       retv_if((name==NULL ? length!=0 : length<-1) || (dest==NULL ? capacity!=0 : capacity<0) ||
+                       (dest==name && name!=NULL), I18N_ERROR_INVALID_PARAMETER);
+
+       i18n_error_code_e i18n_error;
+       UErrorCode icu_error = U_ZERO_ERROR;
+
+       UIDNAInfo *uinfo = create_UIDNAInfo();
+       *len = uidna_nameToASCII_UTF8(idna, name, length, dest, capacity, uinfo, &icu_error);
+       *info = (void *)uinfo;
+
+       ERR_MAPPING(icu_error, i18n_error);
+       I18N_ERR(i18n_error);
+
+       return i18n_error;
+}
+
+int i18n_uidna_name_to_unicode_UTF8(const i18n_uidna_h idna, const char *name, int32_t length, char *dest, int32_t capacity, i18n_uidna_info_h *info, int32_t *len)
+{
+       retv_if((name==NULL ? length!=0 : length<-1) || (dest==NULL ? capacity!=0 : capacity<0) ||
+                       (dest==name && name!=NULL), I18N_ERROR_INVALID_PARAMETER);
+
+       i18n_error_code_e i18n_error;
+       UErrorCode icu_error = U_ZERO_ERROR;
+
+       UIDNAInfo *uinfo = create_UIDNAInfo();
+       *len = uidna_nameToUnicodeUTF8(idna, name, length, dest, capacity, uinfo, &icu_error);
+       *info = (void *)uinfo;
+
+       ERR_MAPPING(icu_error, i18n_error);
+       I18N_ERR(i18n_error);
+
+       return i18n_error;
+}
+
+///////////////////////////////////////////////
+int i18n_uidna_info_get_is_trans_different(i18n_uidna_info_h info, i18n_ubool *is_trans_different)
+{
+       retv_if(info == NULL || is_trans_different == NULL, I18N_ERROR_INVALID_PARAMETER);
+
+       UIDNAInfo *uinfo = (UIDNAInfo *)info;
+       *is_trans_different = uinfo->isTransitionalDifferent;
+
+       return I18N_ERROR_NONE;
+}
+
+int i18n_uidna_info_get_errors(i18n_uidna_info_h info, uint32_t *errors)
+{
+       retv_if(info == NULL || errors == NULL, I18N_ERROR_INVALID_PARAMETER);
+
+       UIDNAInfo *uinfo = (UIDNAInfo *)info;
+       *errors = uinfo->errors;
+
+       return I18N_ERROR_NONE;
+}
+
+int i18n_uidna_info_destroy(i18n_uidna_info_h info)
+{
+       retv_if(info == NULL, I18N_ERROR_INVALID_PARAMETER);
+
+       free((UIDNAInfo *)info);
+       info = NULL;
+
+       return I18N_ERROR_NONE;
+}