Home | History | Annotate | Download | only in i18n
      1 //  2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 **********************************************************************
      5 *   Copyright (C) 1999-2014, International Business Machines
      6 *   Corporation and others.  All Rights Reserved.
      7 **********************************************************************
      8 *   Date        Name        Description
      9 *   11/17/99    aliu        Creation.
     10 **********************************************************************
     11 */
     12 
     13 #include "unicode/utypes.h"
     14 #include "umutex.h"
     15 
     16 #if !UCONFIG_NO_TRANSLITERATION
     17 
     18 #include "unicode/unistr.h"
     19 #include "unicode/uniset.h"
     20 #include "rbt_data.h"
     21 #include "hash.h"
     22 #include "cmemory.h"
     23 
     24 U_NAMESPACE_BEGIN
     25 
     26 TransliterationRuleData::TransliterationRuleData(UErrorCode& status)
     27  : UMemory(), ruleSet(status), variableNames(status),
     28     variables(0), variablesAreOwned(TRUE)
     29 {
     30     if (U_FAILURE(status)) {
     31         return;
     32     }
     33     variableNames.setValueDeleter(uprv_deleteUObject);
     34     variables = 0;
     35     variablesLength = 0;
     36 }
     37 
     38 TransliterationRuleData::TransliterationRuleData(const TransliterationRuleData& other) :
     39     UMemory(other), ruleSet(other.ruleSet),
     40     variablesAreOwned(TRUE),
     41     variablesBase(other.variablesBase),
     42     variablesLength(other.variablesLength)
     43 {
     44     UErrorCode status = U_ZERO_ERROR;
     45     int32_t i = 0;
     46     variableNames.setValueDeleter(uprv_deleteUObject);
     47     int32_t pos = UHASH_FIRST;
     48     const UHashElement *e;
     49     while ((e = other.variableNames.nextElement(pos)) != 0) {
     50         UnicodeString* value =
     51             new UnicodeString(*(const UnicodeString*)e->value.pointer);
     52         // Exit out if value could not be created.
     53         if (value == NULL) {
     54         	return;
     55         }
     56         variableNames.put(*(UnicodeString*)e->key.pointer, value, status);
     57     }
     58 
     59     variables = 0;
     60     if (other.variables != 0) {
     61         variables = (UnicodeFunctor **)uprv_malloc(variablesLength * sizeof(UnicodeFunctor *));
     62         /* test for NULL */
     63         if (variables == 0) {
     64             status = U_MEMORY_ALLOCATION_ERROR;
     65             return;
     66         }
     67         for (i=0; i<variablesLength; ++i) {
     68             variables[i] = other.variables[i]->clone();
     69             if (variables[i] == NULL) {
     70                 status = U_MEMORY_ALLOCATION_ERROR;
     71                 break;
     72             }
     73         }
     74     }
     75     // Remove the array and exit if memory allocation error occured.
     76     if (U_FAILURE(status)) {
     77         for (int32_t n = i-1; n >= 0; n--) {
     78             delete variables[n];
     79         }
     80         uprv_free(variables);
     81         variables = NULL;
     82         return;
     83     }
     84 
     85     // Do this last, _after_ setting up variables[].
     86     ruleSet.setData(this); // ruleSet must already be frozen
     87 }
     88 
     89 TransliterationRuleData::~TransliterationRuleData() {
     90     if (variablesAreOwned && variables != 0) {
     91         for (int32_t i=0; i<variablesLength; ++i) {
     92             delete variables[i];
     93         }
     94     }
     95     uprv_free(variables);
     96 }
     97 
     98 UnicodeFunctor*
     99 TransliterationRuleData::lookup(UChar32 standIn) const {
    100     int32_t i = standIn - variablesBase;
    101     return (i >= 0 && i < variablesLength) ? variables[i] : 0;
    102 }
    103 
    104 UnicodeMatcher*
    105 TransliterationRuleData::lookupMatcher(UChar32 standIn) const {
    106     UnicodeFunctor *f = lookup(standIn);
    107     return (f != 0) ? f->toMatcher() : 0;
    108 }
    109 
    110 UnicodeReplacer*
    111 TransliterationRuleData::lookupReplacer(UChar32 standIn) const {
    112     UnicodeFunctor *f = lookup(standIn);
    113     return (f != 0) ? f->toReplacer() : 0;
    114 }
    115 
    116 
    117 U_NAMESPACE_END
    118 
    119 #endif /* #if !UCONFIG_NO_TRANSLITERATION */
    120