[Base-utils][Measure Format][ACR-986] Missing functions added 27/132527/11
authorDamian Pietruchowski <d.pietruchow@samsung.com>
Tue, 6 Jun 2017 09:54:51 +0000 (11:54 +0200)
committerDamian Pietruchowski <d.pietruchow@samsung.com>
Wed, 14 Jun 2017 10:50:59 +0000 (12:50 +0200)
Change-Id: Ie6e02de7247932d2ad6b309b6b838183d286a6a6
Signed-off-by: Damian Pietruchowski <d.pietruchow@samsung.com>
packaging/capi-base-utils.spec
src/include/utils_i18n.h
src/include/utils_i18n_measure_format.h
src/utils_i18n_measure_format.cpp

index 6d92d9b..8727710 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       capi-base-utils
 Summary:    Base Utils
-Version:    3.0.2
+Version:    3.0.3
 Release:    1
 Group:      Base
 License:    Apache-2.0 and ICU
index dbc4994..a165334 100644 (file)
@@ -3043,6 +3043,21 @@ extern "C" {
  *       <td>createCurrencyFormat</td>
  * </tr>
  * <tr>
+ *       <td>@ref CAPI_BASE_UTILS_I18N_MEASURE_FORMAT_MODULE</td>
+ *       <td>#i18n_measure_format_format_buff</td>
+ *       <td>format</td>
+ * </tr>
+ * <tr>
+ *       <td>@ref CAPI_BASE_UTILS_I18N_MEASURE_FORMAT_MODULE</td>
+ *       <td>#i18n_measure_format_format_measures</td>
+ *       <td>formatMeasures</td>
+ * </tr>
+ * <tr>
+ *       <td>@ref CAPI_BASE_UTILS_I18N_MEASURE_FORMAT_MODULE</td>
+ *       <td>#i18n_measure_format_format_measure_per_unit</td>
+ *       <td>formatMeasurePerUnit</td>
+ * </tr>
+ * <tr>
  *       <td>@ref CAPI_BASE_UTILS_I18N_FIELD_POSITION_MODULE</td>
  *       <td>#i18n_field_position_create</td>
  *       <td>FieldPosition</td>
index 6f409de..1b2b5f6 100644 (file)
@@ -1,17 +1,17 @@
 /*
  * Copyright (c) 2015 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
+ *      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
+ *          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.
+ *      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_MEASURE_FORMAT_H__
@@ -34,7 +34,7 @@ extern "C" {
  * @defgroup CAPI_BASE_UTILS_I18N_MEASURE_FORMAT_MODULE MeasureFormat
  * @brief The MeasureFormat is a formatter for Measure objects.
  * @section CAPI_BASE_UTILS_I18N_MEASURE_FORMAT_MODULE_HEADER Required Header
- *              \#include <utils_i18n.h>
+ *         \#include <utils_i18n.h>
  *
  * @section CAPI_BASE_UTILS_I18N_MEASURE_FORMAT_MODULE_OVERVIEW Overview
  * @details
@@ -49,29 +49,31 @@ extern "C" {
  * @brief Creates the measure format object using given locale.
  * @since_tizen 2.3.2 and 3.0
  * @remarks The created object should be released by the caller with the
- *                     i18n_measure_format_destroy() function.
+ *            i18n_measure_format_destroy() function.
  *
- * @param[in] language            The language of the locale
- * @param[in] country             The country of the locale
- * @param[in] width                       The format width
- * @param[out] measure_format  The created measure format object
+ * @param[in]  language         The language of the locale
+ * @param[in]  country          The country of the locale
+ * @param[in]  width            The format width
+ * @param[out] measure_format   The created measure format object
  *
  * @return @c 0 on success, otherwise a negative error value
- * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_NONE              Successful
  * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
  * @retval #I18N_ERROR_OUT_OF_MEMORY Out of memory
  */
-int i18n_measure_format_create(const char *language, const char *country,
-                                                          i18n_umeasure_format_width_e width, i18n_measure_format_h *measure_format);
+int i18n_measure_format_create(const char *language,
+                                                          const char *country,
+                                                          i18n_umeasure_format_width_e width,
+                                                          i18n_measure_format_h *measure_format);
 
 /**
  * @brief Destroys the measure format object
  * @since_tizen 2.3.2 and 3.0
  *
- * @param[in] measure_format  The measure format object to destroy
+ * @param[in] measure_format    The measure format object to destroy
  *
  * @return @c 0 on success, otherwise a negative error value
- * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_NONE              Successful
  * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
  */
 int i18n_measure_format_destroy(i18n_measure_format_h measure_format);
@@ -80,13 +82,13 @@ int i18n_measure_format_destroy(i18n_measure_format_h measure_format);
  * @brief Creates a polymorphic clone of the given @a measure_format object.
  * @since_tizen 2.3.2 and 3.0
  * @remarks The @a clone object should be released by the caller with the
- *                     i18n_measure_format_destroy() function.
+ *          i18n_measure_format_destroy() function.
  *
- * @param[in]  measure_format  The measure format object to be cloned
- * @param[out] clone              The created measure format object
+ * @param[in]  measure_format   The measure format object to be cloned
+ * @param[out] clone            The created measure format object
  *
  * @return @c 0 on success, otherwise a negative error value
- * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_NONE              Successful
  * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
  * @retval #I18N_ERROR_OUT_OF_MEMORY Out of memory
  */
@@ -96,82 +98,199 @@ int i18n_measure_format_clone(i18n_measure_format_h measure_format, i18n_format_
  * @brief Formats an object to produce a string.
  * @since_tizen 2.3.2 and 3.0
  * @remarks The obtained @a append_to string is actually a concatenation of the given input string and
- *                     the result of the function (appended to the string). Actually, the @a append_to
- *                     buffer is being reallocated inside the function which means that the buffer is not
- *                     at the same place in memory as it was on the input. Please note that the @a append_to
- *                     buffer should be released by the caller with the free() function.
- *
- * @param[in]  measure_format  The format object
- * @param[in]  formattable        The object to format
- * @param[out] append_to          Input/output parameter to receive the result.
- *                                                        The result is appended to the existing contents.
- * @param[out] field_position  On input: an alignment field, if desired.
- *                                                        On output: the offsets of the alignment field.
+ *          the result of the function (appended to the string). Actually, the @a append_to
+ *          buffer is being reallocated inside the function which means that the buffer is not
+ *          at the same place in memory as it was on the input. Please note that the @a append_to
+ *          buffer should be released by the caller with the free() function. @a append_to buffer
+ *          should be allocated on the heap.
+ *
+ * @param[in]     measure_format    The format object
+ * @param[in]     formattable       The object to format
+ * @param[in,out] append_to         Input/output parameter to receive the result.
+ *                                  The result is appended to the existing contents.
+ * @param[in]     field_position    The #i18n_field_position_h object
  *
  * @return @c 0 on success, otherwise a negative error value
- * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_NONE              Successful
  * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
  * @retval #I18N_ERROR_OUT_OF_MEMORY Out of memory
  */
-int i18n_measure_format_format(i18n_measure_format_h measure_format, i18n_formattable_h formattable,
-                                                          char **append_to, i18n_field_position_h field_position);
+int i18n_measure_format_format(i18n_measure_format_h measure_format,
+                                                          i18n_formattable_h formattable,
+                                                          char **append_to,
+                                                          i18n_field_position_h field_position);
 
 /**
  * @brief Parses a string to produce an object.
  * @since_tizen 2.3.2 and 3.0
  * @remarks The obtained @a result object should be released by the caller
- *                     with the i18n_formattable_destroy() function.
- *
- * @param[in]  measure_format     The format object
- * @param[in]  source                     The string to be parsed into an object
- * @param[out] parse_position     The position to start parsing at. Upon return
- *                                                                this parameter is set to the position after the
- *                                                                last character successfully parsed. If the
- *                                                                source is not parsed successfully, this parameter
- *                                                                will remain unchanged.
- * @param[out] result                     The formattable object to be set to the parse result.
- *                                                                If parse fails, return contents are undefined.
+ *          with the i18n_formattable_destroy() function.
+ *
+ * @param[in]  measure_format       The format object
+ * @param[in]  source               The string to be parsed into an object
+ * @param[out] parse_position       The position to start parsing at. Upon return
+ *                                  this parameter is set to the position after the
+ *                                  last character successfully parsed. If the
+ *                                  source is not parsed successfully, this parameter
+ *                                  will remain unchanged.
+ * @param[out] result               The formattable object to be set to the parse result.
+ *                                  If parse fails, return contents are undefined.
  *
  * @return @c 0 on success, otherwise a negative error value
- * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_NONE              Successful
  * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
  * @retval #I18N_ERROR_OUT_OF_MEMORY Out of memory
  */
-int i18n_measure_format_parse_object(i18n_measure_format_h measure_format, const char *source, i18n_parse_position_h parse_position, i18n_formattable_h *result);
+int i18n_measure_format_parse_object(i18n_measure_format_h measure_format,
+                                                                        const char *source,
+                                                                        i18n_parse_position_h parse_position,
+                                                                        i18n_formattable_h *result);
 
 /**
  * @brief Gets a formatter for currency amount objects in the given locale.
  * @since_tizen 2.3.2 and 3.0
  * @remarks The created object should be released by the caller with the
- *                     i18n_measure_format_destroy() function.
+ *          i18n_measure_format_destroy() function.
  *
- * @param[in] language            The language of the locale
- * @param[in] country             The country of the locale
- * @param[out] measure_format  The measure format object
+ * @param[in]  language         The language of the locale
+ * @param[in]  country          The country of the locale
+ * @param[out] measure_format   The measure format object
  *
  * @return @c 0 on success, otherwise a negative error value
- * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_NONE              Successful
  * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
  * @retval #I18N_ERROR_OUT_OF_MEMORY Out of memory
  */
-int i18n_measure_format_create_currency_format_from_locale(const char *language, const char *country, i18n_measure_format_h *measure_format);
+int i18n_measure_format_create_currency_format_from_locale(const char *language,
+                                                                                                                  const char *country,
+                                                                                                                  i18n_measure_format_h *measure_format);
 
 /**
  * @brief Gets a formatter for currency amount objects in the default locale.
  * @since_tizen 2.3.2 and 3.0
  * @remarks The created object should be released by the caller with the
- *                     i18n_measure_format_destroy() function.
+ *          i18n_measure_format_destroy() function.
  *
- * @param[out] measure_format  The measure format object
+ * @param[out] measure_format   The measure format object
  *
  * @return @c 0 on success, otherwise a negative error value
- * @retval #I18N_ERROR_NONE Successful
+ * @retval #I18N_ERROR_NONE              Successful
  * @retval #I18N_ERROR_INVALID_PARAMETER Invalid function parameter
  * @retval #I18N_ERROR_OUT_OF_MEMORY Out of memory
  */
 int i18n_measure_format_create_currency_format(i18n_measure_format_h *measure_format);
 
 /**
+ * @brief Formats an object to produce a string.
+ * @since_tizen 4.0
+ * @remarks If @a output_length is lower than @a append_to_size then formatted string is not
+ *          appended to the @a append_to buffer and #I18N_ERROR_BUFFER_OVERFLOW is returned.
+ *          Otherwise the obtained @a append_to string is a concatenation of the given input string and
+ *          formatted string. If @a output_length is equal to @a append_to_size then output string
+ *          is not NULL terminated.
+ *
+ * @param[in]     measure_format    The format object
+ * @param[in]     formattable       The object to format
+ * @param[in]     field_position    The #i18n_field_position_h object
+ * @param[in]     append_to_size    The size of the @a append_to buffer.
+ *                                  If <code>@a append_to_size <= 0</code> then output string is not
+ *                                  appended to the @a append_to buffer and #I18N_ERROR_BUFFER_OVERFLOW
+ *                                  is returned.
+ * @param[in,out] append_to         The buffer to which formatted string will be appended.
+ *                                  Can be NULL if <code>@a append_to_size <= 0</code>. Otherwise
+ *                                  must be NULL terminated.
+ * @param[out]    output_length     The length of the output string, which is the string in
+ *                                  @a append_to buffer with formatted string.
+ *
+ * @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_BUFFER_OVERFLOW Buffer overflow
+ */
+int i18n_measure_format_format_buff(const i18n_measure_format_h measure_format,
+                                                                       const i18n_formattable_h formattable,
+                                                                       i18n_field_position_h field_position,
+                                                                       int32_t append_to_size,
+                                                                       i18n_uchar *append_to,
+                                                                       int32_t *output_length);
+
+/**
+ * @brief Formats measure objects to produce a string.
+ * @details #i18n_measure_h objects appear in the formatted string in the same order they appear in
+ *          the @a measures array.
+ * @since_tizen 4.0
+ * @remarks If @a output_length is lower than @a append_to_size then formatted string is not
+ *          appended to the @a append_to buffer and #I18N_ERROR_BUFFER_OVERFLOW is returned.
+ *          Otherwise the obtained @a append_to string is a concatenation of the given input string
+ *          and formatted string. If @a output_length is equal to @a append_to_size then output
+ *          string is not NULL terminated.
+ *
+ * @param[in]     measure_format    The format object
+ * @param[in]     measures          The array of the #i18n_measure_h objects to format
+ * @param[in]     measures_count    The number of the #i18n_measure_h objects in the @a measures
+ *                                  array
+ * @param[in]     field_position    The #i18n_field_position_h object
+ * @param[in]     append_to_size    The size of the @a append_to buffer.
+ *                                  If <code>@a append_to_size <= 0</code> then output string is not
+ *                                  appended to the @a append_to buffer and #I18N_ERROR_BUFFER_OVERFLOW
+ *                                  is returned.
+ * @param[in,out] append_to         The buffer to which formatted string will be appended.
+ *                                  Can be NULL if <code>@a append_to_size <= 0</code>. Otherwise
+ *                                  must be NULL terminated.
+ * @param[out]    output_length     The length of the output string, which is the string in
+                                    @a append_to buffer with formatted string.
+ *
+ * @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_BUFFER_OVERFLOW Buffer overflow
+ */
+int i18n_measure_format_format_measures(const i18n_measure_format_h measure_format,
+                                                                               const i18n_measure_h *measures,
+                                                                               int32_t measures_count,
+                                                                               i18n_field_position_h field_position,
+                                                                               int32_t append_to_size,
+                                                                               i18n_uchar *append_to,
+                                                                               int32_t *output_length);
+
+/**
+ * @brief Formats a single measure per unit.
+ * @since_tizen 4.0
+ * @remarks If @a output_length is lower than @a append_to_size then formatted string is not
+ *          appended to the @a append_to buffer and #I18N_ERROR_BUFFER_OVERFLOW is returned.
+ *          Otherwise the obtained @a append_to string is a concatenation of the given input string
+ *          and formatted string. If @a output_length is equal to @a append_to_size then output
+ *          string is not NULL terminated.
+ *
+ * @param[in]     measure_format    The format object
+ * @param[in]     measure           The #i18n_measure_h object to format
+ * @param[in]     measure_unit      The #i18n_measure_unit_h object
+ * @param[in]     field_position    The #i18n_field_position_h object
+ * @param[in]     append_to_size    The size of the @a append_to buffer.
+ *                                  If <code>@a append_to_size <= 0</code> then output string is not
+ *                                  appended to the @a append_to buffer and #I18N_ERROR_BUFFER_OVERFLOW
+ *                                  is returned.
+ * @param[in,out] append_to         The buffer to which formatted string will be appended.
+ *                                  Can be NULL if <code>@a append_to_size <= 0</code>. Otherwise
+ *                                  must be NULL terminated.
+ * @param[out]    output_length     The length of the output string, which is the string in
+                                    @a append_to buffer with formatted string.
+ *
+ * @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_BUFFER_OVERFLOW Buffer overflow
+ */
+int i18n_measure_format_format_measure_per_unit(const i18n_measure_format_h measure_format,
+                                                                                               const i18n_measure_h measure,
+                                                                                               const i18n_measure_unit_h measure_unit,
+                                                                                               i18n_field_position_h field_position,
+                                                                                               int32_t append_to_size,
+                                                                                               i18n_uchar *append_to,
+                                                                                               int32_t *output_length);
+
+
+/**
  * @}
  */
 
index b4e473b..c5244f7 100644 (file)
 /*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2015 - 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
+ *     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
+ *             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.
+ *     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 <utils_i18n_measure_format.h>
 #include <utils_i18n_private.h>
 
 #include <malloc.h>
+#include <vector>
 #include <unicode/measfmt.h>
 #include <unicode/measure.h>
 
-int i18n_measure_format_create(const char *language, const char *country, i18n_umeasure_format_width_e width, i18n_measure_format_h *measure_format)
+int i18n_measure_format_create(const char *language,
+                                                          const char *country,
+                                                          i18n_umeasure_format_width_e width,
+                                                          i18n_measure_format_h *measure_format)
 {
-    retv_if(measure_format == NULL, I18N_ERROR_INVALID_PARAMETER);
-    retv_if(width < I18N_UMEASFMT_WIDTH_WIDE, I18N_ERROR_INVALID_PARAMETER);
-    retv_if(width > I18N_UMEASFMT_WIDTH_COUNT, I18N_ERROR_INVALID_PARAMETER);
-    UErrorCode status = U_ZERO_ERROR;
-    Locale locale(language, country, 0, 0);
-    UMeasureFormatWidth icu_width = (UMeasureFormatWidth) width;
+       retv_if(measure_format == NULL, I18N_ERROR_INVALID_PARAMETER);
+       UErrorCode status = U_ZERO_ERROR;
+       Locale locale(language, country, 0, 0);
+       UMeasureFormatWidth icu_width = (UMeasureFormatWidth) width;
 
-    *measure_format = new MeasureFormat(locale, icu_width, status);
-    retv_if(*measure_format == NULL, I18N_ERROR_OUT_OF_MEMORY);
+       *measure_format = new MeasureFormat(locale, icu_width, status);
+       retv_if(*measure_format == NULL, I18N_ERROR_OUT_OF_MEMORY);
 
-    return _i18n_error_mapping(status);
+       return _i18n_error_mapping(status);
 }
 
 int i18n_measure_format_destroy(i18n_measure_format_h measure_format)
 {
-    retv_if(measure_format == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(measure_format == NULL, I18N_ERROR_INVALID_PARAMETER);
 
-    delete((MeasureFormat *) measure_format);
+       delete((MeasureFormat *) measure_format);
 
-    return I18N_ERROR_NONE;
+       return I18N_ERROR_NONE;
 }
 
 int i18n_measure_format_clone(i18n_measure_format_h measure_format, i18n_format_h *clone)
 {
-    retv_if(measure_format == NULL || clone == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(measure_format == NULL || clone == NULL, I18N_ERROR_INVALID_PARAMETER);
 
-    *clone = ((MeasureFormat *) measure_format)->clone();
-    retv_if(*clone == NULL, I18N_ERROR_OUT_OF_MEMORY);
+       *clone = ((MeasureFormat *) measure_format)->clone();
+       retv_if(*clone == NULL, I18N_ERROR_OUT_OF_MEMORY);
 
-    return I18N_ERROR_NONE;
+       return I18N_ERROR_NONE;
 }
 
-int i18n_measure_format_format(i18n_measure_format_h measure_format, i18n_formattable_h formattable, char **append_to, i18n_field_position_h field_position)
+int i18n_measure_format_format(i18n_measure_format_h measure_format,
+                                                          i18n_formattable_h formattable,
+                                                          char **append_to,
+                                                          i18n_field_position_h field_position)
 {
-    retv_if(measure_format == NULL, I18N_ERROR_INVALID_PARAMETER);
-    retv_if(formattable == NULL, I18N_ERROR_INVALID_PARAMETER);
-    retv_if(append_to == NULL, I18N_ERROR_INVALID_PARAMETER);
-    retv_if(field_position == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(measure_format == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(formattable == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(append_to == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(field_position == NULL, I18N_ERROR_INVALID_PARAMETER);
 
-    UErrorCode status = U_ZERO_ERROR;
+       UErrorCode status = U_ZERO_ERROR;
 
-    UnicodeString unicode_append_to(*append_to);
+       UnicodeString unicode_append_to(*append_to);
 
-    UnicodeString result = ((MeasureFormat *) measure_format)->format(*((Formattable *) formattable), unicode_append_to, *((FieldPosition *) field_position), status);
-    const UChar *uchar_result = result.getTerminatedBuffer();
+       UnicodeString &result =
+               ((MeasureFormat *) measure_format)->format(*((Formattable *) formattable),
+                                                                                                  unicode_append_to,
+                                                                                                  *((FieldPosition *) field_position),
+                                                                                                  status);
+       const UChar *uchar_result = result.getTerminatedBuffer();
 
-    retv_if(uchar_result == NULL, I18N_ERROR_INVALID_PARAMETER);
-    int32_t ulen = u_strlen(uchar_result);
+       retv_if(uchar_result == NULL, I18N_ERROR_INVALID_PARAMETER);
+       int32_t ulen = u_strlen(uchar_result);
 
-    retv_if(ulen <= 0, I18N_ERROR_INVALID_PARAMETER);
-    *append_to = (char *) malloc(ulen + 1);
+       retv_if(ulen <= 0, I18N_ERROR_INVALID_PARAMETER);
+       free(*append_to);
+       *append_to = (char *) malloc(ulen + 1);
 
-    retv_if(*append_to == NULL, I18N_ERROR_OUT_OF_MEMORY);
+       retv_if(*append_to == NULL, I18N_ERROR_OUT_OF_MEMORY);
 
-    u_austrcpy(*append_to, uchar_result);
+       u_austrcpy(*append_to, uchar_result);
 
-    return _i18n_error_mapping(status);
+       return _i18n_error_mapping(status);
 }
 
-int i18n_measure_format_parse_object(i18n_measure_format_h measure_format, const char *source, i18n_parse_position_h parse_position, i18n_formattable_h *result)
+int i18n_measure_format_parse_object(i18n_measure_format_h measure_format,
+                                                                        const char *source,
+                                                                        i18n_parse_position_h parse_position,
+                                                                        i18n_formattable_h *result)
 {
-    retv_if(measure_format == NULL, I18N_ERROR_INVALID_PARAMETER);
-    retv_if(source == NULL, I18N_ERROR_INVALID_PARAMETER);
-    retv_if(result == NULL, I18N_ERROR_INVALID_PARAMETER);
-    retv_if(parse_position == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(measure_format == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(source == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(result == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(parse_position == NULL, I18N_ERROR_INVALID_PARAMETER);
 
-    const UnicodeString unicode_source(source);
+       const UnicodeString unicode_source(source);
 
-    Formattable *f = new Formattable();
+       Formattable *f = new Formattable();
 
-    ((MeasureFormat *) measure_format)->parseObject(unicode_source, *f, *((ParsePosition *) parse_position));
+       ((MeasureFormat *) measure_format)->parseObject(unicode_source,
+                                                                                                       *f,
+                                                                                                       *((ParsePosition *) parse_position));
 
-    *result = (i18n_formattable_h) f;
-    retv_if(*result == NULL, I18N_ERROR_OUT_OF_MEMORY);
+       *result = (i18n_formattable_h) f;
+       retv_if(*result == NULL, I18N_ERROR_OUT_OF_MEMORY);
 
-    return I18N_ERROR_NONE;
+       return I18N_ERROR_NONE;
 }
 
-int i18n_measure_format_create_currency_format_from_locale(const char *language, const char *country, i18n_measure_format_h *measure_format)
+int i18n_measure_format_create_currency_format_from_locale(const char *language,
+                                                                                                                  const char *country,
+                                                                                                                  i18n_measure_format_h *measure_format)
 {
-    retv_if(measure_format == NULL, I18N_ERROR_INVALID_PARAMETER);
-    UErrorCode status = U_ZERO_ERROR;
-    Locale locale(language, country, 0, 0);
+       retv_if(measure_format == NULL, I18N_ERROR_INVALID_PARAMETER);
+       UErrorCode status = U_ZERO_ERROR;
+       Locale locale(language, country, 0, 0);
 
-    *measure_format = MeasureFormat::createCurrencyFormat(locale, status);
-    retv_if(*measure_format == NULL, I18N_ERROR_OUT_OF_MEMORY);
+       *measure_format = MeasureFormat::createCurrencyFormat(locale, status);
+       retv_if(*measure_format == NULL, I18N_ERROR_OUT_OF_MEMORY);
 
-    return _i18n_error_mapping(status);
+       return _i18n_error_mapping(status);
 }
 
 int i18n_measure_format_create_currency_format(i18n_measure_format_h *measure_format)
 {
-    retv_if(measure_format == NULL, I18N_ERROR_INVALID_PARAMETER);
-    UErrorCode status = U_ZERO_ERROR;
+       retv_if(measure_format == NULL, I18N_ERROR_INVALID_PARAMETER);
+       UErrorCode status = U_ZERO_ERROR;
 
-    *measure_format = MeasureFormat::createCurrencyFormat(status);
-    retv_if(*measure_format == NULL, I18N_ERROR_OUT_OF_MEMORY);
+       *measure_format = MeasureFormat::createCurrencyFormat(status);
+       retv_if(*measure_format == NULL, I18N_ERROR_OUT_OF_MEMORY);
 
-    return _i18n_error_mapping(status);
+       return _i18n_error_mapping(status);
 }
+
+int i18n_measure_format_format_buff(const i18n_measure_format_h measure_format,
+                                                                       const i18n_formattable_h formattable,
+                                                                       i18n_field_position_h field_position,
+                                                                       int32_t append_to_size,
+                                                                       i18n_uchar *append_to,
+                                                                       int32_t *output_length)
+{
+       retv_if(measure_format == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(formattable == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(field_position == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(output_length == NULL, I18N_ERROR_INVALID_PARAMETER);
+
+       UErrorCode status = U_ZERO_ERROR;
+       UnicodeString unicode_append_to;
+       if (append_to_size > 0) {
+               retv_if(append_to == NULL, I18N_ERROR_INVALID_PARAMETER);
+               unicode_append_to.append(append_to, 0, -1);
+       }
+
+       UnicodeString &result =
+               ((MeasureFormat *) measure_format)->format(*((Formattable *) formattable),
+                                                                                                  unicode_append_to,
+                                                                                                  *((FieldPosition *) field_position),
+                                                                                                  status);
+       const UChar *uchar_result = result.getTerminatedBuffer();
+       retv_if(uchar_result == NULL, I18N_ERROR_INVALID_PARAMETER);
+       *output_length = u_strlen(uchar_result);
+       retv_if(append_to_size < *output_length, I18N_ERROR_BUFFER_OVERFLOW);
+
+       if (*output_length > 0)
+               u_strncpy(append_to, uchar_result, append_to_size);
+
+       return _i18n_error_mapping(status);
+}
+
+int i18n_measure_format_format_measures(const i18n_measure_format_h measure_format,
+                                                                               const i18n_measure_h *measures,
+                                                                               int32_t measures_count,
+                                                                               i18n_field_position_h field_position,
+                                                                               int32_t append_to_size,
+                                                                               i18n_uchar *append_to,
+                                                                               int32_t *output_length)
+{
+       retv_if(measure_format == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(measures == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(field_position == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(measures_count <= 0, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(output_length == NULL, I18N_ERROR_INVALID_PARAMETER);
+       for (int i = 0; i < measures_count; i++) {
+               retv_if(measures[i] == NULL, I18N_ERROR_INVALID_PARAMETER);
+       }
+
+       UErrorCode status = U_ZERO_ERROR;
+       UnicodeString unicode_append_to;
+       if (append_to_size > 0) {
+               retv_if(append_to == NULL, I18N_ERROR_INVALID_PARAMETER);
+               unicode_append_to.append(append_to, 0, -1);
+       }
+
+       std::vector<Measure> measure_clones;
+       for (int i = 0; i < measures_count; i++) {
+               measure_clones.push_back(*((Measure *)measures[i]));
+       }
+       Measure *measure_array = &measure_clones[0];
+
+       UnicodeString &result =
+               ((MeasureFormat *) measure_format)->formatMeasures(measure_array,
+                                                                                                                  measures_count,
+                                                                                                                  unicode_append_to,
+                                                                                                                  *((FieldPosition *) field_position),
+                                                                                                                  status);
+
+       const UChar *uchar_result = result.getTerminatedBuffer();
+
+       retv_if(uchar_result == NULL, I18N_ERROR_INVALID_PARAMETER);
+       *output_length = u_strlen(uchar_result);
+       retv_if(append_to_size < *output_length, I18N_ERROR_BUFFER_OVERFLOW);
+
+       if (*output_length > 0)
+               u_strncpy(append_to, uchar_result, append_to_size);
+
+       return _i18n_error_mapping(status);
+}
+
+int i18n_measure_format_format_measure_per_unit(const i18n_measure_format_h measure_format,
+                                                                                               const i18n_measure_h measure,
+                                                                                               const i18n_measure_unit_h measure_unit,
+                                                                                               i18n_field_position_h field_position,
+                                                                                               int32_t append_to_size,
+                                                                                               i18n_uchar *append_to,
+                                                                                               int32_t *output_length)
+{
+       retv_if(measure_format == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(measure == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(measure_unit == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(field_position == NULL, I18N_ERROR_INVALID_PARAMETER);
+       retv_if(output_length == NULL, I18N_ERROR_INVALID_PARAMETER);
+
+       UErrorCode status = U_ZERO_ERROR;
+       UnicodeString unicode_append_to;
+       if (append_to_size > 0) {
+               retv_if(append_to == NULL, I18N_ERROR_INVALID_PARAMETER);
+               unicode_append_to.append(append_to, 0, -1);
+       }
+
+       UnicodeString &result =
+               ((MeasureFormat *) measure_format)->formatMeasurePerUnit(*((Measure *) measure),
+                                                                                                                                *((MeasureUnit *) measure_unit),
+                                                                                                                                unicode_append_to,
+                                                                                                                                *((FieldPosition *) field_position),
+                                                                                                                                status);
+
+       const UChar *uchar_result = result.getTerminatedBuffer();
+       retv_if(uchar_result == NULL, I18N_ERROR_INVALID_PARAMETER);
+       *output_length = u_strlen(uchar_result);
+       retv_if(append_to_size < *output_length, I18N_ERROR_BUFFER_OVERFLOW);
+
+       if (*output_length > 0)
+               u_strncpy(append_to, uchar_result, append_to_size);
+
+       return _i18n_error_mapping(status);
+}
+