[Base-utils][Uchar Iter][ACR-888] Module implementation added. 30/96330/23 accepted/tizen/common/20170317.094637 accepted/tizen/ivi/20170317.083722 accepted/tizen/mobile/20170317.083635 accepted/tizen/tv/20170317.083651 accepted/tizen/unified/20170317.083741 accepted/tizen/wearable/20170317.083707 submit/tizen/20170317.052939
authorDamian Pietruchowski <d.pietruchow@samsung.com>
Tue, 8 Nov 2016 13:10:56 +0000 (14:10 +0100)
committerTomasz Bochenski <t.bochenski@samsung.com>
Wed, 15 Mar 2017 08:36:02 +0000 (09:36 +0100)
Change-Id: I1f5ddbc93501195f1abc8eb610826971a08e4521
Signed-off-by: Damian Pietruchowski <d.pietruchow@samsung.com>
Signed-off-by: Tomasz Bochenski <t.bochenski@samsung.com>
Signed-off-by: Jakub Siewierski <j.siewierski@samsung.com>
packaging/capi-base-utils.spec
src/CMakeLists.txt
src/include/utils_i18n.h
src/include/utils_i18n_types.h
src/include/utils_i18n_uchar_iter.h [new file with mode: 0644]
src/utils_i18n_uchar_iter.c [new file with mode: 0644]

index cb89430..c23590e 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       capi-base-utils
 Summary:    Base Utils
-Version:    2.0.1
+Version:    2.0.2
 Release:    1
 Group:      Base
 License:    Apache-2.0 and ICU
index c635129..132126c 100755 (executable)
@@ -39,6 +39,7 @@ SET(BASEUTILS_SRCS
     utils_i18n_utmscale.c
     utils_i18n_ubidi.c
     utils_i18n_uversion.c
+    utils_i18n_uchar_iter.c
 )
 
 ADD_LIBRARY(${target_name} SHARED ${BASEUTILS_SRCS}
@@ -85,5 +86,6 @@ INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${INC_DIR}/utils_i18n_ushape.h DESTINA
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${INC_DIR}/utils_i18n_utmscale.h DESTINATION ${INCLUDE_INSTALL_DIR}/base)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${INC_DIR}/utils_i18n_ubidi.h DESTINATION ${INCLUDE_INSTALL_DIR}/base)
 INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${INC_DIR}/utils_i18n_uversion.h DESTINATION ${INCLUDE_INSTALL_DIR}/base)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${INC_DIR}/utils_i18n_uchar_iter.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 4767ae8..c635aa0 100644 (file)
@@ -44,6 +44,7 @@
 #include <utils_i18n_utmscale.h>
 #include <utils_i18n_ubidi.h>
 #include <utils_i18n_uversion.h>
+#include <utils_i18n_uchar_iter.h>
 
 /**
  * @file utils_i18n.h
@@ -81,6 +82,7 @@ extern "C" {
  *       - utmscale
  *       - ubidi
  *       - uversion
+ *       - uchar iter
  *
  *        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.
@@ -211,6 +213,10 @@ extern "C" {
  *     <td>@ref CAPI_BASE_UTILS_I18N_UVERSION_MODULE</td>
  *     <td>Uversion module provides API for accessing ICU version numbers.</td>
  * </tr>
+ * <tr>
+ *     <td>@ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE</td>
+ *     <td>The Uchar Iterator module provides API for code unit iteration.</td>
+ * </tr>
  * </table>
  *
  * @section CAPI_BASE_UTILS_I18N_MODULE_MAPPING_TABLE Mapping Table
@@ -3196,6 +3202,67 @@ extern "C" {
  *    <td>#i18n_uversion_to_string</td>
  *    <td>u_versionToString</td>
  * </tr>
+ *
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE</td>
+ *    <td>#i18n_uchar_iter_set_string</td>
+ *    <td>uiter_setString</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE</td>
+ *    <td>#i18n_uchar_iter_set_utf16be</td>
+ *    <td>uiter_setUTF16BE</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE</td>
+ *    <td>#i18n_uchar_iter_set_utf8</td>
+ *    <td>uiter_setUTF8</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE</td>
+ *    <td>#i18n_uchar_iter_get_index</td>
+ *    <td>UCharIteratorGetIndex</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE</td>
+ *    <td>#i18n_uchar_iter_move</td>
+ *    <td>UCharIteratorMove</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE</td>
+ *    <td>#i18n_uchar_iter_has_next</td>
+ *    <td>UCharIteratorHasNext</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE</td>
+ *    <td>#i18n_uchar_iter_has_previous</td>
+ *    <td>UCharIteratorHasPrevious</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE</td>
+ *    <td>#i18n_uchar_iter_current</td>
+ *    <td>UCharIteratorCurrent</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE</td>
+ *    <td>#i18n_uchar_iter_next</td>
+ *    <td>UCharIteratorNext</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE</td>
+ *    <td>#i18n_uchar_iter_previous</td>
+ *    <td>UCharIteratorPrevious</td>
+ * </tr>
+  * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE</td>
+ *    <td>#i18n_uchar_iter_get_state</td>
+ *    <td>UCharIteratorGetState</td>
+ * </tr>
+ * <tr>
+ *    <td>@ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE</td>
+ *    <td>#i18n_uchar_iter_set_state</td>
+ *    <td>UCharIteratorSetState</td>
+ * </tr>
  * </table>
  */
 
index 0f85c3b..0f7bd58 100644 (file)
@@ -3961,6 +3961,62 @@ typedef uint8_t i18n_uversion_info[I18N_UVERSION_MAX_VERSION_LENGTH];
  * @}
  */
 
+
+ /**
+ * @addtogroup CAPI_BASE_UTILS_I18N_UCHAR_ITERATOR_MODULE
+ * @{
+ */
+
+/**
+ * @brief Origin constants for i18n_uchar_iter_get_index() and i18n_uchar_iter_move().
+ * @since_tizen 4.0
+ */
+typedef enum {
+    I18N_UCHAR_ITER_START,                     /**< The 'start' origin */
+    I18N_UCHAR_ITER_CURRENT,           /**< The 'current' origin */
+    I18N_UCHAR_ITER_LIMIT,                     /**< The 'limit' origin */
+    I18N_UCHAR_ITER_ZERO,                      /**< The 'zero' origin */
+    I18N_UCHAR_ITER_LENGTH,                    /**< The 'length' origin */
+} i18n_uchar_iter_origin_e;
+
+/**
+ * @brief Constant value that may be returned by i18n_uchar_iter_move() indicating that the final
+ *        UTF-16 index is not known, but that the move succeeded.
+ * @details This can occur when moving relative to limit or length, or when moving relative to the
+ *          current index after an i18n_uchar_iter_set_state() call when the current UTF-16 index is not
+ *          known. It would be very inefficient to have to count from the beginning of the text just
+ *          to get the current/limit/length index after moving relative to it. The actual index can be
+ *          determined by calling i18n_uchar_iter_get_index() with #I18N_UCHAR_ITER_CURRENT, which will
+ *          count the #i18n_uchar characters if necessary.
+ * @since_tizen 4.0
+ */
+#define I18N_UCHAR_ITER_UNKNOWN_INDEX -2
+
+/**
+ * @brief Constant that refers to an error or an unknown state.
+ * @since_tizen 4.0
+ */
+#define I18N_UCHAR_ITER_NO_STATE ((uint32_t) 0xffffffff)
+
+/**
+ * @brief An #i18n_uchar_iter_h handle.
+ * @details Use i18n_uchar_iter_* functions to operate on #i18n_uchar_iter_h objects.
+ * @since_tizen 4.0
+ */
+typedef void *i18n_uchar_iter_h;
+
+/**
+ * @}
+ */
+
+/**
+ * @brief This value is intended for sentinel values for APIs that take or return single code points (#i18n_uchar32).
+ * @details It is outside of the Unicode code point range 0..0x10ffff. For example, a "done" or "error" value in a new
+ *                     API could be indicated with #I18N_SENTINEL.
+ * @since_tizen 4.0
+ */
+#define I18N_SENTINEL (-1)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/include/utils_i18n_uchar_iter.h b/src/include/utils_i18n_uchar_iter.h
new file mode 100644 (file)
index 0000000..2d49e64
--- /dev/null
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 2017 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_UCHAR_ITER_H__
+#define __UTILS_I18N_UCHAR_ITER_H__
+
+#include <utils_i18n_types.h>
+
+/**
+ * @file utils_i18n_uchar_iterator.h
+ * @version 0.1
+ * @brief utils_i18n_uchar_iterator
+ */
+
+/**
+ * @ingroup CAPI_BASE_UTILS_I18N_MODULE
+ * @defgroup CAPI_BASE_UTILS_I18N_UCHAR_ITERATOR_MODULE UChar Iterator
+ * @brief The UChar Iterator module provides API for code unit iteration.
+ * @section CAPI_BASE_UTILS_I18N_UCHAR_ITERATOR_MODULE Required Header
+ *          \#include <utils_i18n.h>
+ *
+ * @section CAPI_BASE_UTILS_I18N_UCHAR_ITERATOR_MODULE_OVERVIEW Overview
+ * @details C API for code unit iteration.
+ *          This can be implemented using simple strings, etc.
+ *          The current() and next() functions only check the current index against the limit,
+ *          and previous() only checks the current index against the start, to see if the iterator
+ *          already reached the end of the iteration range.
+ *          The assumption - in all iterators - is that the index is moved via the API, which means
+ *          it won't go out of bounds, or the index is modified by user code that knows enough
+ *          about the iterator implementation to set valid index values.
+ *          UCharIterator functions return code unit values 0..0xffff.
+ *          Before any functions operating on strings are called, the string must be set with
+ *          i18n_uchar_iter_set_string(), i18n_uchar_iter_set_UTF16BE() or i18n_uchar_iter_set_UTF8().
+ */
+
+/**
+ * @addtogroup CAPI_BASE_UTILS_I18N_UCHAR_ITERATOR_MODULE
+ * @{
+ */
+
+/**
+ * @brief Creates an #i18n_uchar_iter_h object.
+ * @since_tizen 4.0
+ * @remarks To delete this object call i18n_uchar_iter_destroy() function.
+ *
+ * @param[out] iter                            The #i18n_uchar_iter_h handle
+ *
+ * @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_uchar_iter_create(i18n_uchar_iter_h *iter);
+
+/**
+ * @brief Deletes an #i18n_uchar_iter_h object.
+ * @since_tizen 4.0
+ *
+ * @param[in]  iter                            The #i18n_uchar_iter_h object
+ *
+ * @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_uchar_iter_destroy(i18n_uchar_iter_h iter);
+
+/**
+ * @brief Sets up an #i18n_uchar_iter_h to iterate over a string.
+ * @details Sets the #i18n_uchar_iter_h function pointers for iteration over the string @a s with
+ *          iteration boundaries (start == index == 0) and (length == limit == string length).
+ *          The "provider" may set the start, index, and limit values at any time within the range 0..@a length.
+ * @since_tizen 4.0
+ * @remarks The string @a s will not be copied or reallocated.
+ *
+ * @param[in]  iter                    The #i18n_uchar_iter_h structure to be set for iteration
+ * @param[in]  s                               String to iterate over
+ * @param[in]  length                  Length of @a s, or @c -1 if @c NULL-terminated
+ *
+ * @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_uchar_iter_set_string(i18n_uchar_iter_h iter, const i18n_uchar *s, int32_t length);
+
+/**
+ * @brief Sets up an #i18n_uchar_iter_h to iterate over a UTF-16BE string (byte vector with a
+ *        big-endian pair of bytes per #i18n_uchar).
+ * @details Everything works just like with a normal #i18n_uchar iterator, except that #i18n_uchar characters
+ *          are assembled from byte pairs, and that the @a length argument here indicates an even number
+ *          of bytes.
+ * @since_tizen 4.0
+ *
+ * @param[in]  iter                    #i18n_uchar_iter_h structure to be set for iteration
+ * @param[in]  s                               UTF-16BE string to iterate over
+ * @param[in]  length                  Length of @a s as an even number of bytes, or @c -1 if
+ *                                                             @c NULL-terminated (@c NULL means pair of 0 bytes at even
+ *                                                             index from @a s)
+ *
+ * @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_uchar_iter_set_utf16be(i18n_uchar_iter_h iter, const char *s, int32_t length);
+
+/**
+ * @brief Sets up an #i18n_uchar_iter_h to iterate over a UTF-8 string.
+ * @details Sets the #i18n_uchar_iter_h function pointers for iteration over the UTF-8 string @a s
+ *          with UTF-8 iteration boundaries 0 and @a length. The implementation counts the UTF-16
+ *          index on the fly and lazily evaluates the UTF-16 length of the text.
+ * @since_tizen 4.0
+ * @remarks The string @a s will not be copied or reallocated.
+ *          i18n_uchar_iter_get_state() returns a state value consisting of the current UTF-8 source
+ *          byte index (bits 31..1) a flag (bit 0) that indicates whether the UChar position is in the
+ *          middle of a surrogate pair (from a 4-byte UTF-8 sequence for the corresponding supplementary code point).
+ *          i18n_uchar_iter_get_state() cannot also encode the UTF-16 index in the state value.
+ *
+ * @param[in]  iter                            #i18n_uchar_iter_h structure to be set for iteration
+ * @param[in]  s                                       UTF-8 string to iterate over
+ * @param[in]  length                          Length of @a s, or @c -1 if @c NULL-terminated
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE                            Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER       Invalid function parameter
+ * @pre        The string must be set with one of: i18n_uchar_iter_set_string(), i18n_uchar_iter_set_UTF16BE(),
+ *                     i18n_uchar_iter_set_UTF8().
+ */
+int i18n_uchar_iter_set_utf8(i18n_uchar_iter_h iter, const char *s, int32_t length);
+
+/**
+ * @brief Gets the current position, or the start or limit of the iteration range.
+ * @details This function may perform slowly for #I18N_UCHAR_ITER_CURRENT after i18n_uchar_iter_set_state()
+ *          was called, or for #I18N_UCHAR_ITER_LENGTH, because an iterator implementation may have to count
+ *          UChars if the underlying storage is not UTF-16.
+ * @since_tizen 4.0
+ *
+ * @param[in]  iter                            The #i18n_uchar_iter_h object
+ * @param[in]  origin                          Origin defining action to perform
+ * @param[out] index                           The requested index, or #I18N_SENTINEL in an error condition
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE                            Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER       Invalid function parameter
+ * @pre        The string must be set with one of: i18n_uchar_iter_set_string(), i18n_uchar_iter_set_UTF16BE(),
+ *                     i18n_uchar_iter_set_UTF8().
+ */
+int i18n_uchar_iter_get_index(i18n_uchar_iter_h iter, i18n_uchar_iter_origin_e origin, int32_t *index);
+
+/**
+ * @brief Moves the current position relative to the start or limit of the iteration range, or relative to the
+ *        current position itself. The movement is expressed in numbers of code units forward or backward by specifying
+ *        a positive or negative delta. Out of bounds movement will be pinned to the start or limit.
+ * @details This function may perform slowly for moving relative to #I18N_UCHAR_ITER_LENGTH because an iterator
+ *          implementation may have to count the rest of the UChars if the native storage is not UTF-16.
+ *          When moving relative to the limit or length, or relative to the current position after i18n_uchar_iter_set_state()
+ *          was called, i18n_uchar_iter_move() may return #I18N_UCHAR_ITER_UNKNOWN_INDEX to avoid an inefficient
+ *          determination of the actual UTF-16 index. The actual index can be determined with
+ *          i18n_uchar_iter_get_index(#I18N_UCHAR_ITER_CURRENT) which will count the UChars if necessary.
+ * @since_tizen 4.0
+ *
+ * @param[in]  iter                            The #i18n_uchar_iter_h object
+ * @param[in]  delta                           Movement
+ * @param[in]  origin                          Origin defining action to perform
+ * @param[out] new_index                       The new index or #I18N_UCHAR_ITER_UNKNOWN_INDEX when the index is not known,
+ *                                                                     or #I18N_SENTINEL on an error condition
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE                            Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER       Invalid function parameter
+ * @pre        The string must be set with one of: i18n_uchar_iter_set_string(), i18n_uchar_iter_set_UTF16BE(),
+ *                     i18n_uchar_iter_set_UTF8().
+ */
+int i18n_uchar_iter_move(i18n_uchar_iter_h iter, int32_t delta, i18n_uchar_iter_origin_e origin, int32_t *new_index);
+
+/**
+ * @brief Checks if i18n_uchar_iter_current() and i18n_uchar_iter_next() can still return another code unit.
+ * @since_tizen 4.0
+ *
+ * @param[in]  iter                    The #i18n_uchar_iter_h object
+ * @param[out] has_next                @c true if another code unit can be returned, @c false otherwise
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE                            Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER       Invalid function parameter
+ * @pre        The string must be set with one of: i18n_uchar_iter_set_string(), i18n_uchar_iter_set_UTF16BE(),
+ *                     i18n_uchar_iter_set_UTF8().
+ */
+int i18n_uchar_iter_has_next(i18n_uchar_iter_h iter, bool *has_next);
+
+/**
+ * @brief Checks if i18n_uchar_iter_previous() can still return another code unit.
+ * @since_tizen 4.0
+ *
+ * @param[in]  iter                    The #i18n_uchar_iter_h object
+ * @param[out] has_previous    @c true if another code unit can be returned, @c false otherwise
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE                            Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER       Invalid function parameter
+ * @pre        The string must be set with one of: i18n_uchar_iter_set_string(), i18n_uchar_iter_set_UTF16BE(),
+ *                     i18n_uchar_iter_set_UTF8().
+ */
+int i18n_uchar_iter_has_previous(i18n_uchar_iter_h iter, bool *has_previous);
+
+/**
+ * @brief Returns the code unit at the current position, or #I18N_SENTINEL if there is none
+ *                     (index is at the limit).
+ * @since_tizen 4.0
+ *
+ * @param[in]  iter                    The #i18n_uchar_iter_h object
+ * @param[out] current                 The current code unit
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE                            Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER       Invalid function parameter
+ * @pre        The string must be set with one of: i18n_uchar_iter_set_string(), i18n_uchar_iter_set_UTF16BE(),
+ *                     i18n_uchar_iter_set_UTF8().
+ */
+int i18n_uchar_iter_current(i18n_uchar_iter_h iter, i18n_uchar32 *current);
+
+/**
+ * @brief Returns the code unit at the current index and increments the index (post-increment, like s[i++]),
+ *                     or returns #I18N_SENTINEL if there is none (index is at the limit).
+ * @since_tizen 4.0
+ *
+ * @param[in]  iter                    The #i18n_uchar_iter_h object
+ * @param[out] current                 The current code unit
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE                            Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER       Invalid function parameter
+ * @pre        The string must be set with one of: i18n_uchar_iter_set_string(), i18n_uchar_iter_set_UTF16BE(),
+ *                     i18n_uchar_iter_set_UTF8().
+ */
+int i18n_uchar_iter_next(i18n_uchar_iter_h iter, i18n_uchar32 *current);
+
+/**
+ * @brief Decrements the index and returns the code unit from there (pre-decrement, like s[--i]),
+ *                     or returns #I18N_SENTINEL if there is none (index is at the start).
+ * @since_tizen 4.0
+ *
+ * @param[in]  iter                    The #i18n_uchar_iter_h object
+ * @param[out] current                 The current code unit
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE                            Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER       Invalid function parameter
+ * @pre        The string must be set with one of: i18n_uchar_iter_set_string(), i18n_uchar_iter_set_UTF16BE(),
+ *                     i18n_uchar_iter_set_UTF8().
+ */
+int i18n_uchar_iter_previous(i18n_uchar_iter_h iter, i18n_uchar32 *previous);
+
+/**
+ * @brief Gets the "state" of the iterator in the form of a single 32-bit word.
+ * @details It is recommended that the state value be calculated to be as small as is feasible. For strings
+ *          with limited lengths, fewer than 32 bits may be sufficient.
+ *
+ *          This is used together with i18n_uchar_iter_set_state() to save and restore the iterator position
+ *          more efficiently than with i18n_uchar_iter_get_index() or i18n_uchar_iter_move().
+ *
+ *          The iterator state is defined as a @c uint32_t value because it is designed for use in
+ *          i18n_ucol_next_sort_key_part() which provides 32 bits to store the state of the character iterator.
+ *
+ *          With some UCharIterator implementations (e.g., UTF-8), getting and setting the UTF-16 index with existing
+ *          functions (i18n_uchar_iter_get_index(#I18N_UCHAR_ITER_CURRENT) followed by
+ *          i18n_uchar_iter_move(pos, #I18N_UCHAR_ITER_ZERO)) is possible but relatively slow because the iterator
+ *          has to "walk" from a known index to the requested one. This takes more time the farther it needs to go.
+ *
+ *          An opaque state value allows an iterator implementation to provide an internal index (UTF-8: the source
+ *          byte array index) for fast, constant-time restoration.
+ *
+ *          After calling i18n_uchar_iter_set_state(), i18n_uchar_iter_get_index(#I18N_UCHAR_ITER_CURRENT) calls may be
+ *          slow because the UTF-16 index may not be restored as well, but the iterator can deliver the correct text
+ *          contents and move relative to the current position without performance degradation.
+ *
+ *          Some UCharIterator implementations may not be able to return a valid state for each position, in which case
+ *          they return #I18N_UCHAR_ITER_NO_STATE instead.
+ * @since_tizen 4.0
+ *
+ * @param[in]  iter                    The #i18n_uchar_iter_h object
+ * @param[out] state                   The state word
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE                            Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER       Invalid function parameter
+ * @pre        The string must be set with one of: i18n_uchar_iter_set_string(), i18n_uchar_iter_set_UTF16BE(),
+ *                     i18n_uchar_iter_set_UTF8().
+ */
+int i18n_uchar_iter_get_state(const i18n_uchar_iter_h iter, uint32_t *state);
+
+/**
+ * @brief Restores the "state" of the iterator using a state word from a i18n_uchar_iter_get_state() call.
+ *        The iterator object need not be the same one as for which i18n_uchar_iter_get_state() was called,
+ *        but it must be of the same type (set up using the same i18n_uchar_iter_set_* function) and it must iterate
+ *        over the same string (binary identical regardless of memory address).
+ * @details After calling i18n_uchar_iter_set_state(), an i18n_uchar_iter_get_index(#I18N_UCHAR_ITER_CURRENT)
+ *          may be slow because the UTF-16 index may not be restored as well, but the iterator can deliver
+ *          the correct text contents and move relative to the current position without performance degradation.
+ * @since_tizen 4.0
+ *
+ * @param[in]  iter                            The #i18n_uchar_iter_h object
+ * @param[in]  state                           The state word from an i18n_uchar_iter_get_state() call on a same-type,
+ *                                                                     same-string iterator
+ *
+ * @return @c 0 on success, otherwise a negative error value
+ * @retval #I18N_ERROR_NONE                            Successful
+ * @retval #I18N_ERROR_INVALID_PARAMETER       Invalid function parameter
+ * @pre        The string must be set with one of: i18n_uchar_iter_set_string(), i18n_uchar_iter_set_UTF16BE(),
+ *                     i18n_uchar_iter_set_UTF8().
+ */
+int i18n_uchar_iter_set_state(i18n_uchar_iter_h iter, uint32_t state);
+
+/**
+ * @}
+ */
+
+#endif /* __UTILS_I18N_UCHAR_ITER_H__ */
diff --git a/src/utils_i18n_uchar_iter.c b/src/utils_i18n_uchar_iter.c
new file mode 100644 (file)
index 0000000..58762a6
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2017 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/uiter.h>
+#include <malloc.h>
+
+#include <utils_i18n_uchar_iter.h>
+#include <utils_i18n_private.h>
+
+
+int i18n_uchar_iter_create(i18n_uchar_iter_h *iter)
+{
+       retv_if(iter == NULL, I18N_ERROR_INVALID_PARAMETER);
+
+       *iter = malloc(sizeof(UCharIterator));
+
+       return I18N_ERROR_NONE;
+}
+
+int i18n_uchar_iter_destroy(i18n_uchar_iter_h iter)
+{
+       retv_if(iter == NULL, I18N_ERROR_INVALID_PARAMETER);
+
+       free(iter);
+
+       return I18N_ERROR_NONE;
+}
+
+int i18n_uchar_iter_set_string(i18n_uchar_iter_h iter, const i18n_uchar *s, int32_t length)
+{
+       retv_if(iter == NULL || length < -1, I18N_ERROR_INVALID_PARAMETER);
+
+       uiter_setString((UCharIterator *) iter, s, length);
+
+       return I18N_ERROR_NONE;
+}
+
+int i18n_uchar_iter_set_utf16be(i18n_uchar_iter_h iter, const char *s, int32_t length)
+{
+       retv_if(iter == NULL || length < -1, I18N_ERROR_INVALID_PARAMETER);
+
+       uiter_setUTF16BE((UCharIterator *) iter, s, length);
+
+       return I18N_ERROR_NONE;
+}
+
+int i18n_uchar_iter_set_utf8(i18n_uchar_iter_h iter, const char *s, int32_t length)
+{
+       retv_if(iter == NULL || length < -1, I18N_ERROR_INVALID_PARAMETER);
+
+       uiter_setUTF8((UCharIterator *) iter, s, length);
+
+       return I18N_ERROR_NONE;
+}
+
+int i18n_uchar_iter_get_index(i18n_uchar_iter_h iter, i18n_uchar_iter_origin_e origin, int32_t *index)
+{
+       retv_if(iter == NULL || index == NULL, I18N_ERROR_INVALID_PARAMETER);
+
+       *index = ((UCharIterator *) iter)->getIndex((UCharIterator *) iter, origin);
+
+       return I18N_ERROR_NONE;
+}
+
+int i18n_uchar_iter_move(i18n_uchar_iter_h iter, int32_t delta, i18n_uchar_iter_origin_e origin, int32_t *new_index)
+{
+       retv_if(iter == NULL || new_index == NULL, I18N_ERROR_INVALID_PARAMETER);
+
+       *new_index = ((UCharIterator *) iter)->move((UCharIterator *) iter, delta, origin);
+
+       return I18N_ERROR_NONE;
+}
+
+int i18n_uchar_iter_has_next(i18n_uchar_iter_h iter, bool *has_next)
+{
+       retv_if(iter == NULL || has_next == NULL, I18N_ERROR_INVALID_PARAMETER);
+
+       UBool _has_next = ((UCharIterator *) iter)->hasNext((UCharIterator *) iter);
+       *has_next = _has_next == TRUE ? true : false;
+
+       return I18N_ERROR_NONE;
+}
+
+int i18n_uchar_iter_has_previous(i18n_uchar_iter_h iter, bool *has_previous)
+{
+       retv_if(iter == NULL || has_previous == NULL, I18N_ERROR_INVALID_PARAMETER);
+
+       UBool _has_previous = ((UCharIterator *) iter)->hasPrevious((UCharIterator *) iter);
+       *has_previous = _has_previous == TRUE ? true : false;
+
+       return I18N_ERROR_NONE;
+}
+
+int i18n_uchar_iter_current(i18n_uchar_iter_h iter, i18n_uchar32 *current)
+{
+       retv_if(iter == NULL || current == NULL, I18N_ERROR_INVALID_PARAMETER);
+
+       *current = ((UCharIterator *) iter)->current((UCharIterator *) iter);
+
+       return I18N_ERROR_NONE;
+}
+
+int i18n_uchar_iter_next(i18n_uchar_iter_h iter, i18n_uchar32 *current)
+{
+       retv_if(iter == NULL || current == NULL, I18N_ERROR_INVALID_PARAMETER);
+
+       *current = ((UCharIterator *) iter)->next((UCharIterator *) iter);
+
+       return I18N_ERROR_NONE;
+}
+
+int i18n_uchar_iter_previous(i18n_uchar_iter_h iter, i18n_uchar32 *previous)
+{
+       retv_if(iter == NULL || previous == NULL, I18N_ERROR_INVALID_PARAMETER);
+
+       *previous = ((UCharIterator *) iter)->previous((UCharIterator *) iter);
+
+       return I18N_ERROR_NONE;
+}
+
+int i18n_uchar_iter_get_state(const i18n_uchar_iter_h iter, uint32_t *state)
+{
+       retv_if(iter == NULL || state == NULL, I18N_ERROR_INVALID_PARAMETER);
+
+       *state = ((UCharIterator *) iter)->getState((UCharIterator *) iter);
+
+       return I18N_ERROR_NONE;
+}
+
+int i18n_uchar_iter_set_state(i18n_uchar_iter_h iter, uint32_t state)
+{
+       retv_if(iter == NULL, I18N_ERROR_INVALID_PARAMETER);
+
+       i18n_error_code_e i18n_error;
+       UErrorCode icu_error = U_ZERO_ERROR;
+       ((UCharIterator *) iter)->setState((UCharIterator *) iter, state, &icu_error);
+       ERR_MAPPING(icu_error, i18n_error);
+       I18N_ERR(i18n_error);
+
+       return i18n_error;
+}