• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
TransliterationRuleData(UErrorCode & status)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 
TransliterationRuleData(const TransliterationRuleData & other)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 
~TransliterationRuleData()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*
lookup(UChar32 standIn) const99 TransliterationRuleData::lookup(UChar32 standIn) const {
100     int32_t i = standIn - variablesBase;
101     return (i >= 0 && i < variablesLength) ? variables[i] : 0;
102 }
103 
104 UnicodeMatcher*
lookupMatcher(UChar32 standIn) const105 TransliterationRuleData::lookupMatcher(UChar32 standIn) const {
106     UnicodeFunctor *f = lookup(standIn);
107     return (f != 0) ? f->toMatcher() : 0;
108 }
109 
110 UnicodeReplacer*
lookupReplacer(UChar32 standIn) const111 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