From b61491c939c2098cd1935eac2468a3882f65ee02 Mon Sep 17 00:00:00 2001 From: Damian Pietruchowski Date: Tue, 8 Nov 2016 14:10:56 +0100 Subject: [PATCH] [Base-utils][Uchar Iter][ACR-888] Module implementation added. Change-Id: I1f5ddbc93501195f1abc8eb610826971a08e4521 Signed-off-by: Damian Pietruchowski Signed-off-by: Tomasz Bochenski Signed-off-by: Jakub Siewierski --- packaging/capi-base-utils.spec | 2 +- src/CMakeLists.txt | 2 + src/include/utils_i18n.h | 67 ++++++++ src/include/utils_i18n_types.h | 56 ++++++ src/include/utils_i18n_uchar_iter.h | 328 ++++++++++++++++++++++++++++++++++++ src/utils_i18n_uchar_iter.c | 154 +++++++++++++++++ 6 files changed, 608 insertions(+), 1 deletion(-) create mode 100644 src/include/utils_i18n_uchar_iter.h create mode 100644 src/utils_i18n_uchar_iter.c diff --git a/packaging/capi-base-utils.spec b/packaging/capi-base-utils.spec index cb89430..c23590e 100755 --- a/packaging/capi-base-utils.spec +++ b/packaging/capi-base-utils.spec @@ -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 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c635129..132126c 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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) diff --git a/src/include/utils_i18n.h b/src/include/utils_i18n.h index 4767ae8..c635aa0 100644 --- a/src/include/utils_i18n.h +++ b/src/include/utils_i18n.h @@ -44,6 +44,7 @@ #include #include #include +#include /** * @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" { * @ref CAPI_BASE_UTILS_I18N_UVERSION_MODULE * Uversion module provides API for accessing ICU version numbers. * + * + * @ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE + * The Uchar Iterator module provides API for code unit iteration. + * * * * @section CAPI_BASE_UTILS_I18N_MODULE_MAPPING_TABLE Mapping Table @@ -3196,6 +3202,67 @@ extern "C" { * #i18n_uversion_to_string * u_versionToString * + * + * + * @ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE + * #i18n_uchar_iter_set_string + * uiter_setString + * + * + * @ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE + * #i18n_uchar_iter_set_utf16be + * uiter_setUTF16BE + * + * + * @ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE + * #i18n_uchar_iter_set_utf8 + * uiter_setUTF8 + * + * + * @ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE + * #i18n_uchar_iter_get_index + * UCharIteratorGetIndex + * + * + * @ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE + * #i18n_uchar_iter_move + * UCharIteratorMove + * + * + * @ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE + * #i18n_uchar_iter_has_next + * UCharIteratorHasNext + * + * + * @ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE + * #i18n_uchar_iter_has_previous + * UCharIteratorHasPrevious + * + * + * @ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE + * #i18n_uchar_iter_current + * UCharIteratorCurrent + * + * + * @ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE + * #i18n_uchar_iter_next + * UCharIteratorNext + * + * + * @ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE + * #i18n_uchar_iter_previous + * UCharIteratorPrevious + * + * + * @ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE + * #i18n_uchar_iter_get_state + * UCharIteratorGetState + * + * + * @ref CAPI_BASE_UTILS_I18N_UCHAR_ITER_MODULE + * #i18n_uchar_iter_set_state + * UCharIteratorSetState + * * */ diff --git a/src/include/utils_i18n_types.h b/src/include/utils_i18n_types.h index 0f85c3b..0f7bd58 100644 --- a/src/include/utils_i18n_types.h +++ b/src/include/utils_i18n_types.h @@ -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 index 0000000..2d49e64 --- /dev/null +++ b/src/include/utils_i18n_uchar_iter.h @@ -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 + +/** + * @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 + * + * @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 index 0000000..58762a6 --- /dev/null +++ b/src/utils_i18n_uchar_iter.c @@ -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 +#include + +#include +#include + + +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; +} -- 2.7.4