]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/rbt_data.cpp
ICU-64260.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / rbt_data.cpp
index 42fa1ab96bca0b65a0a5aca98ff3798d7124e5cb..4b596ac6c4a2b12e228704e45c5db42273d14196 100644 (file)
@@ -1,6 +1,8 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 **********************************************************************
-*   Copyright (C) 1999, International Business Machines
+*   Copyright (C) 1999-2014, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 **********************************************************************
 *   Date        Name        Description
@@ -9,6 +11,7 @@
 */
 
 #include "unicode/utypes.h"
+#include "umutex.h"
 
 #if !UCONFIG_NO_TRANSLITERATION
 
 U_NAMESPACE_BEGIN
 
 TransliterationRuleData::TransliterationRuleData(UErrorCode& status)
- : UMemory(), ruleSet(status),
-    variableNames(0), variables(0)
+ : UMemory(), ruleSet(status), variableNames(status),
+    variables(0), variablesAreOwned(TRUE)
 {
     if (U_FAILURE(status)) {
         return;
     }
-    variableNames = new Hashtable(status);
-    /* test for NULL */
-    if (variableNames == 0) {
-        status = U_MEMORY_ALLOCATION_ERROR;
-        return;
-    }
-    if (U_SUCCESS(status)) {
-        variableNames->setValueDeleter(uhash_deleteUnicodeString);
-    }
+    variableNames.setValueDeleter(uprv_deleteUObject);
     variables = 0;
     variablesLength = 0;
 }
 
 TransliterationRuleData::TransliterationRuleData(const TransliterationRuleData& other) :
     UMemory(other), ruleSet(other.ruleSet),
+    variablesAreOwned(TRUE),
     variablesBase(other.variablesBase),
     variablesLength(other.variablesLength)
 {
     UErrorCode status = U_ZERO_ERROR;
-    variableNames = new Hashtable(status);
-    if (U_SUCCESS(status)) {
-        variableNames->setValueDeleter(uhash_deleteUnicodeString);
-        int32_t pos = -1;
-        const UHashElement *e;
-        while ((e = other.variableNames->nextElement(pos)) != 0) {
-            UnicodeString* value =
-                new UnicodeString(*(const UnicodeString*)e->value.pointer);
-            variableNames->put(*(UnicodeString*)e->key.pointer, value, status);
+    int32_t i = 0;
+    variableNames.setValueDeleter(uprv_deleteUObject);
+    int32_t pos = UHASH_FIRST;
+    const UHashElement *e;
+    while ((e = other.variableNames.nextElement(pos)) != 0) {
+        UnicodeString* value =
+            new UnicodeString(*(const UnicodeString*)e->value.pointer);
+        // Exit out if value could not be created.
+        if (value == NULL) {
+               return;
         }
+        variableNames.put(*(UnicodeString*)e->key.pointer, value, status);
     }
 
     variables = 0;
@@ -66,23 +64,35 @@ TransliterationRuleData::TransliterationRuleData(const TransliterationRuleData&
             status = U_MEMORY_ALLOCATION_ERROR;
             return;
         }
-        for (int32_t i=0; i<variablesLength; ++i) {
+        for (i=0; i<variablesLength; ++i) {
             variables[i] = other.variables[i]->clone();
+            if (variables[i] == NULL) {
+                status = U_MEMORY_ALLOCATION_ERROR;
+                break;
+            }
+        }
+    }
+    // Remove the array and exit if memory allocation error occured.
+    if (U_FAILURE(status)) {
+        for (int32_t n = i-1; n >= 0; n--) {
+            delete variables[n];
         }
-    }    
+        uprv_free(variables);
+        variables = NULL;
+        return;
+    }
 
     // Do this last, _after_ setting up variables[].
     ruleSet.setData(this); // ruleSet must already be frozen
 }
 
 TransliterationRuleData::~TransliterationRuleData() {
-    delete variableNames;
-    if (variables != 0) {
+    if (variablesAreOwned && variables != 0) {
         for (int32_t i=0; i<variablesLength; ++i) {
             delete variables[i];
         }
-        uprv_free(variables);
     }
+    uprv_free(variables);
 }
 
 UnicodeFunctor*
@@ -103,6 +113,7 @@ TransliterationRuleData::lookupReplacer(UChar32 standIn) const {
     return (f != 0) ? f->toReplacer() : 0;
 }
 
+
 U_NAMESPACE_END
 
 #endif /* #if !UCONFIG_NO_TRANSLITERATION */