| OLD | NEW | 
|---|
| (Empty) |  | 
|  | 1 /* | 
|  | 2 ******************************************************************************* | 
|  | 3 * Copyright (C) 2013-2014, International Business Machines | 
|  | 4 * Corporation and others.  All Rights Reserved. | 
|  | 5 ******************************************************************************* | 
|  | 6 * collationsettings.cpp | 
|  | 7 * | 
|  | 8 * created on: 2013feb07 | 
|  | 9 * created by: Markus W. Scherer | 
|  | 10 */ | 
|  | 11 | 
|  | 12 #include "unicode/utypes.h" | 
|  | 13 | 
|  | 14 #if !UCONFIG_NO_COLLATION | 
|  | 15 | 
|  | 16 #include "unicode/ucol.h" | 
|  | 17 #include "cmemory.h" | 
|  | 18 #include "collation.h" | 
|  | 19 #include "collationsettings.h" | 
|  | 20 #include "sharedobject.h" | 
|  | 21 #include "uassert.h" | 
|  | 22 #include "umutex.h" | 
|  | 23 | 
|  | 24 U_NAMESPACE_BEGIN | 
|  | 25 | 
|  | 26 CollationSettings::CollationSettings(const CollationSettings &other) | 
|  | 27         : SharedObject(other), | 
|  | 28           options(other.options), variableTop(other.variableTop), | 
|  | 29           reorderTable(NULL), | 
|  | 30           reorderCodes(NULL), reorderCodesLength(0), reorderCodesCapacity(0), | 
|  | 31           fastLatinOptions(other.fastLatinOptions) { | 
|  | 32     int32_t length = other.reorderCodesLength; | 
|  | 33     if(length == 0) { | 
|  | 34         U_ASSERT(other.reorderTable == NULL); | 
|  | 35     } else { | 
|  | 36         U_ASSERT(other.reorderTable != NULL); | 
|  | 37         if(other.reorderCodesCapacity == 0) { | 
|  | 38             aliasReordering(other.reorderCodes, length, other.reorderTable); | 
|  | 39         } else { | 
|  | 40             setReordering(other.reorderCodes, length, other.reorderTable); | 
|  | 41         } | 
|  | 42     } | 
|  | 43     if(fastLatinOptions >= 0) { | 
|  | 44         uprv_memcpy(fastLatinPrimaries, other.fastLatinPrimaries, sizeof(fastLat
     inPrimaries)); | 
|  | 45     } | 
|  | 46 } | 
|  | 47 | 
|  | 48 CollationSettings::~CollationSettings() { | 
|  | 49     if(reorderCodesCapacity != 0) { | 
|  | 50         uprv_free(const_cast<int32_t *>(reorderCodes)); | 
|  | 51     } | 
|  | 52 } | 
|  | 53 | 
|  | 54 UBool | 
|  | 55 CollationSettings::operator==(const CollationSettings &other) const { | 
|  | 56     if(options != other.options) { return FALSE; } | 
|  | 57     if((options & ALTERNATE_MASK) != 0 && variableTop != other.variableTop) { re
     turn FALSE; } | 
|  | 58     if(reorderCodesLength != other.reorderCodesLength) { return FALSE; } | 
|  | 59     for(int32_t i = 0; i < reorderCodesLength; ++i) { | 
|  | 60         if(reorderCodes[i] != other.reorderCodes[i]) { return FALSE; } | 
|  | 61     } | 
|  | 62     return TRUE; | 
|  | 63 } | 
|  | 64 | 
|  | 65 int32_t | 
|  | 66 CollationSettings::hashCode() const { | 
|  | 67     int32_t h = options << 8; | 
|  | 68     if((options & ALTERNATE_MASK) != 0) { h ^= variableTop; } | 
|  | 69     h ^= reorderCodesLength; | 
|  | 70     for(int32_t i = 0; i < reorderCodesLength; ++i) { | 
|  | 71         h ^= (reorderCodes[i] << i); | 
|  | 72     } | 
|  | 73     return h; | 
|  | 74 } | 
|  | 75 | 
|  | 76 void | 
|  | 77 CollationSettings::resetReordering() { | 
|  | 78     // When we turn off reordering, we want to set a NULL permutation | 
|  | 79     // rather than a no-op permutation. | 
|  | 80     // Keep the memory via reorderCodes and its capacity. | 
|  | 81     reorderTable = NULL; | 
|  | 82     reorderCodesLength = 0; | 
|  | 83 } | 
|  | 84 | 
|  | 85 void | 
|  | 86 CollationSettings::aliasReordering(const int32_t *codes, int32_t length, const u
     int8_t *table) { | 
|  | 87     if(length == 0) { | 
|  | 88         resetReordering(); | 
|  | 89     } else { | 
|  | 90         // We need to release the memory before setting the alias pointer. | 
|  | 91         if(reorderCodesCapacity != 0) { | 
|  | 92             uprv_free(const_cast<int32_t *>(reorderCodes)); | 
|  | 93             reorderCodesCapacity = 0; | 
|  | 94         } | 
|  | 95         reorderTable = table; | 
|  | 96         reorderCodes = codes; | 
|  | 97         reorderCodesLength = length; | 
|  | 98     } | 
|  | 99 } | 
|  | 100 | 
|  | 101 UBool | 
|  | 102 CollationSettings::setReordering(const int32_t *codes, int32_t length, const uin
     t8_t table[256]) { | 
|  | 103     if(length == 0) { | 
|  | 104         resetReordering(); | 
|  | 105     } else { | 
|  | 106         uint8_t *ownedTable; | 
|  | 107         int32_t *ownedCodes; | 
|  | 108         if(length <= reorderCodesCapacity) { | 
|  | 109             ownedTable = const_cast<uint8_t *>(reorderTable); | 
|  | 110             ownedCodes = const_cast<int32_t *>(reorderCodes); | 
|  | 111         } else { | 
|  | 112             // Allocate one memory block for the codes and the 16-aligned table. | 
|  | 113             int32_t capacity = (length + 3) & ~3;  // round up to a multiple of 
     4 ints | 
|  | 114             uint8_t *bytes = (uint8_t *)uprv_malloc(256 + capacity * 4); | 
|  | 115             if(bytes == NULL) { return FALSE; } | 
|  | 116             if(reorderCodesCapacity != 0) { | 
|  | 117                 uprv_free(const_cast<int32_t *>(reorderCodes)); | 
|  | 118             } | 
|  | 119             reorderTable = ownedTable = bytes + capacity * 4; | 
|  | 120             reorderCodes = ownedCodes = (int32_t *)bytes; | 
|  | 121             reorderCodesCapacity = capacity; | 
|  | 122         } | 
|  | 123         uprv_memcpy(ownedTable, table, 256); | 
|  | 124         uprv_memcpy(ownedCodes, codes, length * 4); | 
|  | 125         reorderCodesLength = length; | 
|  | 126     } | 
|  | 127     return TRUE; | 
|  | 128 } | 
|  | 129 | 
|  | 130 void | 
|  | 131 CollationSettings::setStrength(int32_t value, int32_t defaultOptions, UErrorCode
      &errorCode) { | 
|  | 132     if(U_FAILURE(errorCode)) { return; } | 
|  | 133     int32_t noStrength = options & ~STRENGTH_MASK; | 
|  | 134     switch(value) { | 
|  | 135     case UCOL_PRIMARY: | 
|  | 136     case UCOL_SECONDARY: | 
|  | 137     case UCOL_TERTIARY: | 
|  | 138     case UCOL_QUATERNARY: | 
|  | 139     case UCOL_IDENTICAL: | 
|  | 140         options = noStrength | (value << STRENGTH_SHIFT); | 
|  | 141         break; | 
|  | 142     case UCOL_DEFAULT: | 
|  | 143         options = noStrength | (defaultOptions & STRENGTH_MASK); | 
|  | 144         break; | 
|  | 145     default: | 
|  | 146         errorCode = U_ILLEGAL_ARGUMENT_ERROR; | 
|  | 147         break; | 
|  | 148     } | 
|  | 149 } | 
|  | 150 | 
|  | 151 void | 
|  | 152 CollationSettings::setFlag(int32_t bit, UColAttributeValue value, | 
|  | 153                            int32_t defaultOptions, UErrorCode &errorCode) { | 
|  | 154     if(U_FAILURE(errorCode)) { return; } | 
|  | 155     switch(value) { | 
|  | 156     case UCOL_ON: | 
|  | 157         options |= bit; | 
|  | 158         break; | 
|  | 159     case UCOL_OFF: | 
|  | 160         options &= ~bit; | 
|  | 161         break; | 
|  | 162     case UCOL_DEFAULT: | 
|  | 163         options = (options & ~bit) | (defaultOptions & bit); | 
|  | 164         break; | 
|  | 165     default: | 
|  | 166         errorCode = U_ILLEGAL_ARGUMENT_ERROR; | 
|  | 167         break; | 
|  | 168     } | 
|  | 169 } | 
|  | 170 | 
|  | 171 void | 
|  | 172 CollationSettings::setCaseFirst(UColAttributeValue value, | 
|  | 173                                 int32_t defaultOptions, UErrorCode &errorCode) { | 
|  | 174     if(U_FAILURE(errorCode)) { return; } | 
|  | 175     int32_t noCaseFirst = options & ~CASE_FIRST_AND_UPPER_MASK; | 
|  | 176     switch(value) { | 
|  | 177     case UCOL_OFF: | 
|  | 178         options = noCaseFirst; | 
|  | 179         break; | 
|  | 180     case UCOL_LOWER_FIRST: | 
|  | 181         options = noCaseFirst | CASE_FIRST; | 
|  | 182         break; | 
|  | 183     case UCOL_UPPER_FIRST: | 
|  | 184         options = noCaseFirst | CASE_FIRST_AND_UPPER_MASK; | 
|  | 185         break; | 
|  | 186     case UCOL_DEFAULT: | 
|  | 187         options = noCaseFirst | (defaultOptions & CASE_FIRST_AND_UPPER_MASK); | 
|  | 188         break; | 
|  | 189     default: | 
|  | 190         errorCode = U_ILLEGAL_ARGUMENT_ERROR; | 
|  | 191         break; | 
|  | 192     } | 
|  | 193 } | 
|  | 194 | 
|  | 195 void | 
|  | 196 CollationSettings::setAlternateHandling(UColAttributeValue value, | 
|  | 197                                         int32_t defaultOptions, UErrorCode &erro
     rCode) { | 
|  | 198     if(U_FAILURE(errorCode)) { return; } | 
|  | 199     int32_t noAlternate = options & ~ALTERNATE_MASK; | 
|  | 200     switch(value) { | 
|  | 201     case UCOL_NON_IGNORABLE: | 
|  | 202         options = noAlternate; | 
|  | 203         break; | 
|  | 204     case UCOL_SHIFTED: | 
|  | 205         options = noAlternate | SHIFTED; | 
|  | 206         break; | 
|  | 207     case UCOL_DEFAULT: | 
|  | 208         options = noAlternate | (defaultOptions & ALTERNATE_MASK); | 
|  | 209         break; | 
|  | 210     default: | 
|  | 211         errorCode = U_ILLEGAL_ARGUMENT_ERROR; | 
|  | 212         break; | 
|  | 213     } | 
|  | 214 } | 
|  | 215 | 
|  | 216 void | 
|  | 217 CollationSettings::setMaxVariable(int32_t value, int32_t defaultOptions, UErrorC
     ode &errorCode) { | 
|  | 218     if(U_FAILURE(errorCode)) { return; } | 
|  | 219     int32_t noMax = options & ~MAX_VARIABLE_MASK; | 
|  | 220     switch(value) { | 
|  | 221     case MAX_VAR_SPACE: | 
|  | 222     case MAX_VAR_PUNCT: | 
|  | 223     case MAX_VAR_SYMBOL: | 
|  | 224     case MAX_VAR_CURRENCY: | 
|  | 225         options = noMax | (value << MAX_VARIABLE_SHIFT); | 
|  | 226         break; | 
|  | 227     case UCOL_DEFAULT: | 
|  | 228         options = noMax | (defaultOptions & MAX_VARIABLE_MASK); | 
|  | 229         break; | 
|  | 230     default: | 
|  | 231         errorCode = U_ILLEGAL_ARGUMENT_ERROR; | 
|  | 232         break; | 
|  | 233     } | 
|  | 234 } | 
|  | 235 | 
|  | 236 U_NAMESPACE_END | 
|  | 237 | 
|  | 238 #endif  // !UCONFIG_NO_COLLATION | 
| OLD | NEW | 
|---|