1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qglobal.h"
5#include "qdebug.h"
6#include "qlocale_p.h"
7#include "qmutex.h"
8
9#include "unicode/uloc.h"
10#include "unicode/ustring.h"
11
12QT_BEGIN_NAMESPACE
13
14typedef int32_t (*Ptr_u_strToCase)(UChar *dest, int32_t destCapacity, const UChar *src, int32_t srcLength, const char *locale, UErrorCode *pErrorCode);
15
16// caseFunc can either be u_strToUpper or u_strToLower
17static bool qt_u_strToCase(const QString &str, QString *out, const char *localeID, Ptr_u_strToCase caseFunc)
18{
19 Q_ASSERT(out);
20
21 int32_t size = str.size();
22 size += size >> 2; // add 25% for possible expansions
23 QString result(size, Qt::Uninitialized);
24
25 UErrorCode status = U_ZERO_ERROR;
26
27 size = caseFunc(reinterpret_cast<UChar *>(result.data()), result.size(),
28 reinterpret_cast<const UChar *>(str.constData()), str.size(),
29 localeID, &status);
30
31 if (U_FAILURE(code: status) && status != U_BUFFER_OVERFLOW_ERROR)
32 return false;
33
34 if (size < result.size()) {
35 result.resize(size);
36 } else if (size > result.size()) {
37 // the resulting string is larger than our source string
38 result.resize(size);
39
40 status = U_ZERO_ERROR;
41 size = caseFunc(reinterpret_cast<UChar *>(result.data()), result.size(),
42 reinterpret_cast<const UChar *>(str.constData()), str.size(),
43 localeID, &status);
44
45 if (U_FAILURE(code: status))
46 return false;
47
48 // if the sizes don't match now, we give up.
49 if (size != result.size())
50 return false;
51 }
52
53 *out = result;
54 return true;
55}
56
57QString QIcu::toUpper(const QByteArray &localeID, const QString &str, bool *ok)
58{
59 QString out;
60 bool err = qt_u_strToCase(str, out: &out, localeID, u_strToUpper);
61 if (ok)
62 *ok = err;
63 return out;
64}
65
66QString QIcu::toLower(const QByteArray &localeID, const QString &str, bool *ok)
67{
68 QString out;
69 bool err = qt_u_strToCase(str, out: &out, localeID, u_strToLower);
70 if (ok)
71 *ok = err;
72 return out;
73}
74
75QT_END_NAMESPACE
76

source code of qtbase/src/corelib/text/qlocale_icu.cpp