1// Copyright (C) 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
33U_NAMESPACE_BEGIN
34
35CollationTailoring::CollationTailoring(const CollationSettings *baseSettings)
36        : data(NULL), settings(baseSettings),
37          actualLocale(""),
38          ownedData(NULL),
39          builder(NULL), memory(NULL), bundle(NULL),
40          trie(NULL), unsafeBackwardSet(NULL),
41          maxExpansions(NULL) {
42    if(baseSettings != NULL) {
43        U_ASSERT(baseSettings->reorderCodesLength == 0);
44        U_ASSERT(baseSettings->reorderTable == NULL);
45        U_ASSERT(baseSettings->minHighNoReorder == 0);
46    } else {
47        settings = new CollationSettings();
48    }
49    if(settings != NULL) {
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
57CollationTailoring::~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
69UBool
70CollationTailoring::ensureOwnedData(UErrorCode &errorCode) {
71    if(U_FAILURE(errorCode)) { return FALSE; }
72    if(ownedData == NULL) {
73        const Normalizer2Impl *nfcImpl = Normalizer2Factory::getNFCImpl(errorCode);
74        if(U_FAILURE(errorCode)) { return FALSE; }
75        ownedData = new CollationData(*nfcImpl);
76        if(ownedData == NULL) {
77            errorCode = U_MEMORY_ALLOCATION_ERROR;
78            return FALSE;
79        }
80    }
81    data = ownedData;
82    return TRUE;
83}
84
85void
86CollationTailoring::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
93void
94CollationTailoring::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
102int32_t
103CollationTailoring::getUCAVersion() const {
104    return ((int32_t)version[1] << 4) | (version[2] >> 6);
105}
106
107CollationCacheEntry::~CollationCacheEntry() {
108    SharedObject::clearPtr(tailoring);
109}
110
111U_NAMESPACE_END
112
113#endif  // !UCONFIG_NO_COLLATION
114