1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 *******************************************************************************
5 * Copyright (C) 2013-2015, International Business Machines
6 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
8 * collationtailoring.cpp
9 *
10 * created on: 2013mar12
11 * created by: Markus W. Scherer
12 */
13
14 #include "unicode/utypes.h"
15
16 #if !UCONFIG_NO_COLLATION
17
18 #include "unicode/udata.h"
19 #include "unicode/unistr.h"
20 #include "unicode/ures.h"
21 #include "unicode/uversion.h"
22 #include "unicode/uvernum.h"
23 #include "cmemory.h"
24 #include "collationdata.h"
25 #include "collationsettings.h"
26 #include "collationtailoring.h"
27 #include "normalizer2impl.h"
28 #include "uassert.h"
29 #include "uhash.h"
30 #include "umutex.h"
31 #include "utrie2.h"
32
33 U_NAMESPACE_BEGIN
34
CollationTailoring(const CollationSettings * baseSettings)35 CollationTailoring::CollationTailoring(const CollationSettings *baseSettings)
36 : data(nullptr), settings(baseSettings),
37 actualLocale(""),
38 ownedData(nullptr),
39 builder(nullptr), memory(nullptr), bundle(nullptr),
40 trie(nullptr), unsafeBackwardSet(nullptr),
41 maxExpansions(nullptr) {
42 if(baseSettings != nullptr) {
43 U_ASSERT(baseSettings->reorderCodesLength == 0);
44 U_ASSERT(baseSettings->reorderTable == nullptr);
45 U_ASSERT(baseSettings->minHighNoReorder == 0);
46 } else {
47 settings = new CollationSettings();
48 }
49 if(settings != nullptr) {
50 settings->addRef();
51 }
52 rules.getTerminatedBuffer(); // ensure NUL-termination
53 version[0] = version[1] = version[2] = version[3] = 0;
54 maxExpansionsInitOnce.reset();
55 }
56
~CollationTailoring()57 CollationTailoring::~CollationTailoring() {
58 SharedObject::clearPtr(settings);
59 delete ownedData;
60 delete builder;
61 udata_close(memory);
62 ures_close(bundle);
63 utrie2_close(trie);
64 delete unsafeBackwardSet;
65 uhash_close(maxExpansions);
66 maxExpansionsInitOnce.reset();
67 }
68
69 UBool
ensureOwnedData(UErrorCode & errorCode)70 CollationTailoring::ensureOwnedData(UErrorCode &errorCode) {
71 if(U_FAILURE(errorCode)) { return false; }
72 if(ownedData == nullptr) {
73 const Normalizer2Impl *nfcImpl = Normalizer2Factory::getNFCImpl(errorCode);
74 if(U_FAILURE(errorCode)) { return false; }
75 ownedData = new CollationData(*nfcImpl);
76 if(ownedData == nullptr) {
77 errorCode = U_MEMORY_ALLOCATION_ERROR;
78 return false;
79 }
80 }
81 data = ownedData;
82 return true;
83 }
84
85 void
makeBaseVersion(const UVersionInfo ucaVersion,UVersionInfo version)86 CollationTailoring::makeBaseVersion(const UVersionInfo ucaVersion, UVersionInfo version) {
87 version[0] = UCOL_BUILDER_VERSION;
88 version[1] = (ucaVersion[0] << 3) + ucaVersion[1];
89 version[2] = ucaVersion[2] << 6;
90 version[3] = 0;
91 }
92
93 void
setVersion(const UVersionInfo baseVersion,const UVersionInfo rulesVersion)94 CollationTailoring::setVersion(const UVersionInfo baseVersion, const UVersionInfo rulesVersion) {
95 version[0] = UCOL_BUILDER_VERSION;
96 version[1] = baseVersion[1];
97 version[2] = (baseVersion[2] & 0xc0) + ((rulesVersion[0] + (rulesVersion[0] >> 6)) & 0x3f);
98 version[3] = (rulesVersion[1] << 3) + (rulesVersion[1] >> 5) + rulesVersion[2] +
99 (rulesVersion[3] << 4) + (rulesVersion[3] >> 4);
100 }
101
102 int32_t
getUCAVersion() const103 CollationTailoring::getUCAVersion() const {
104 return ((int32_t)version[1] << 4) | (version[2] >> 6);
105 }
106
~CollationCacheEntry()107 CollationCacheEntry::~CollationCacheEntry() {
108 SharedObject::clearPtr(tailoring);
109 }
110
111 U_NAMESPACE_END
112
113 #endif // !UCONFIG_NO_COLLATION
114