]> granicus.if.org Git - icu/commitdiff
ICU-21455 Add new API ubrk_clone() and deprecate ubrk_safeClone()
authorVictor Chang <vichang@google.com>
Mon, 1 Feb 2021 22:20:48 +0000 (22:20 +0000)
committerAndy Heninger <andy.heninger@gmail.com>
Tue, 9 Feb 2021 16:49:55 +0000 (08:49 -0800)
icu4c/source/common/ubrk.cpp
icu4c/source/common/unicode/ubrk.h
icu4c/source/test/cintltst/cbiapts.c

index f8bdf5a6b6582270bc97e5472cd29a1cbab81a17..bb5bdd1b5012fbbde236a2e2472255adce303841 100644 (file)
@@ -174,6 +174,18 @@ ubrk_safeClone(
     return (UBreakIterator *)newBI;
 }
 
+U_CAPI UBreakIterator * U_EXPORT2
+ubrk_clone(const UBreakIterator *bi, UErrorCode *status) {
+    if (U_FAILURE(*status)) {
+        return nullptr;
+    }
+    BreakIterator *newBI = ((BreakIterator *)bi)->clone();
+    if (newBI == nullptr) {
+        *status = U_MEMORY_ALLOCATION_ERROR;
+        return nullptr;
+    }
+    return (UBreakIterator *)newBI;
+}
 
 
 U_CAPI void U_EXPORT2
index 37189a85984b680c1ababad3f410cc39882dbdc5..1249b0b160d3625aeb97bfedebfd14dd69351021 100644 (file)
@@ -296,6 +296,8 @@ ubrk_openBinaryRules(const uint8_t *binaryRules, int32_t rulesLength,
                      const UChar *  text, int32_t textLength,
                      UErrorCode *   status);
 
+#ifndef U_HIDE_DEPRECATED_API
+
 /**
  * Thread safe cloning operation
  * @param bi iterator to be cloned
@@ -312,7 +314,7 @@ ubrk_openBinaryRules(const uint8_t *binaryRules, int32_t rulesLength,
  * @param status to indicate whether the operation went on smoothly or there were errors
  *  An informational status value, U_SAFECLONE_ALLOCATED_ERROR, is used if any allocations were necessary.
  * @return pointer to the new clone
- * @stable ICU 2.0
+ * @deprecated ICU 69 Use ubrk_clone() instead.
  */
 U_CAPI UBreakIterator * U_EXPORT2
 ubrk_safeClone(
@@ -321,6 +323,23 @@ ubrk_safeClone(
           int32_t *pBufferSize,
           UErrorCode *status);
 
+#endif /* U_HIDE_DEPRECATED_API */
+
+#ifndef U_HIDE_DRAFT_API
+
+/**
+ * Thread safe cloning operation.
+ * @param bi iterator to be cloned
+ * @param status to indicate whether the operation went on smoothly or there were errors
+ * @return pointer to the new clone
+ * @draft ICU 69
+ */
+U_CAPI UBreakIterator * U_EXPORT2
+ubrk_clone(const UBreakIterator *bi,
+           UErrorCode *status);
+
+#endif  // U_HIDE_DRAFT_API
+
 #ifndef U_HIDE_DEPRECATED_API
 
 /**
index c72de75bcd31f192ab90b7bcc579a0ae1fe99a87..40272c8ff73fc0305131274abb0cff0aed21a9ae 100644 (file)
@@ -49,6 +49,7 @@
 
 #if !UCONFIG_NO_FILE_IO
 static void TestBreakIteratorSafeClone(void);
+static void TestBreakIteratorClone(void);
 #endif
 static void TestBreakIteratorRules(void);
 static void TestBreakIteratorRuleError(void);
@@ -66,6 +67,7 @@ void addBrkIterAPITest(TestNode** root)
 #if !UCONFIG_NO_FILE_IO
     addTest(root, &TestBreakIteratorCAPI, "tstxtbd/cbiapts/TestBreakIteratorCAPI");
     addTest(root, &TestBreakIteratorSafeClone, "tstxtbd/cbiapts/TestBreakIteratorSafeClone");
+    addTest(root, &TestBreakIteratorClone, "tstxtbd/cbiapts/TestBreakIteratorClone");
     addTest(root, &TestBreakIteratorUText, "tstxtbd/cbiapts/TestBreakIteratorUText");
 #endif
     addTest(root, &TestBreakIteratorRules, "tstxtbd/cbiapts/TestBreakIteratorRules");
@@ -515,6 +517,88 @@ static void TestBreakIteratorSafeClone(void)
         ubrk_close(someIterators[i]);
     }
 }
+
+static void TestBreakIteratorClone(void)
+{
+    const UChar text[] = u"He's from Africa. Mr. Livingston, I presume? Yeah";
+    UBreakIterator * someIterators [CLONETEST_ITERATOR_COUNT];
+
+    UBreakIterator * brk;
+    UErrorCode status = U_ZERO_ERROR;
+    int32_t start,pos;
+    int32_t i;
+
+    /*Testing ubrk_clone */
+
+    /* US & Thai - rule-based & dictionary based */
+    someIterators[0] = ubrk_open(UBRK_WORD, "en_US", text, u_strlen(text), &status);
+    if(!someIterators[0] || U_FAILURE(status)) {
+      log_data_err("Couldn't open en_US word break iterator - %s\n", u_errorName(status));
+      return;
+    }
+
+    someIterators[1] = ubrk_open(UBRK_WORD, "th_TH", text, u_strlen(text), &status);
+    if(!someIterators[1] || U_FAILURE(status)) {
+      log_data_err("Couldn't open th_TH word break iterator - %s\n", u_errorName(status));
+      return;
+    }
+
+    /* test each type of iterator */
+    for (i = 0; i < CLONETEST_ITERATOR_COUNT; i++)
+    {
+        /* error status - should return 0 & keep error the same */
+        status = U_MEMORY_ALLOCATION_ERROR;
+        if (NULL != ubrk_clone(someIterators[i], &status) || status != U_MEMORY_ALLOCATION_ERROR)
+        {
+            log_err("FAIL: Cloned Iterator failed to deal correctly with incoming error status\n");
+        }
+
+        status = U_ZERO_ERROR;
+
+        /* Do these cloned Iterators work at all - make a first & next call */
+        brk = ubrk_clone(someIterators[i], &status);
+
+        start = ubrk_first(brk);
+        if(start!=0)
+            log_err("error ubrk_start(clone) did not return 0, but %i\n", start);
+        pos=ubrk_next(brk);
+        if(pos!=4)
+            log_err("error ubrk_next(clone) did not return 4, but %i\n", pos);
+
+        ubrk_close(brk);
+
+        pos = ubrk_next(someIterators[i]);
+        if (pos != 4) {
+            log_err("error ubrk_next(iter) did not return 4, but %i\n", pos);
+        }
+
+        brk = ubrk_clone(someIterators[i], &status);
+        // The text position should be kept in the new clone.
+        start = ubrk_current(brk);
+        if (start != 4) {
+            log_err("error ubrk_current(clone) did not return 4, but %i\n", start);
+        }
+
+        pos = ubrk_next(brk);
+        if (pos != 5) {
+            log_err("error ubrk_next(clone) did not return 5, but %i\n", pos);
+        }
+        start = ubrk_current(brk);
+        if (start != 5) {
+            log_err("error ubrk_current(clone) did not return 5, but %i\n", start);
+        }
+
+        start = ubrk_current(someIterators[i]);
+        if (start != 4) {
+            log_err("error ubrk_current(iter) did not keep the same position of 4,"
+                    " but %i after advancing the position in its clone.\n", start);
+        }
+
+        ubrk_close(brk);
+
+        ubrk_close(someIterators[i]);
+    }
+}
 #endif