Qt 4.8
qlocale_icu.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qglobal.h"
43 #include "qlibrary.h"
44 #include "qdebug.h"
45 
46 #include "unicode/uversion.h"
47 #include "unicode/ucol.h"
48 
50 
51 typedef UCollator *(*Ptr_ucol_open)(const char *loc, UErrorCode *status);
52 typedef void (*Ptr_ucol_close)(UCollator *coll);
53 typedef UCollationResult (*Ptr_ucol_strcoll)(const UCollator *coll, const UChar *source, int32_t sourceLength, const UChar *target, int32_t targetLength);
54 typedef int32_t (*Ptr_u_strToCase)(UChar *dest, int32_t destCapacity, const UChar *src, int32_t srcLength, const char *locale, UErrorCode *pErrorCode);
55 
61 
63 {
65  NotLoaded = 0,
66  Loaded = 1
67 };
68 
70 
71 static UCollator *icuCollator = 0;
72 
73 #define STRINGIFY2(x) #x
74 #define STRINGIFY(x) STRINGIFY2(x)
75 
76 bool qt_initIcu(const QString &localeString)
77 {
78  if (status == ErrorLoading)
79  return false;
80 
81  if (status == NotLoaded) {
82 
83  // resolve libicui18n
84  QLibrary lib(QLatin1String("icui18n"), QLatin1String(U_ICU_VERSION_SHORT));
86  if (!lib.load()) {
87  qWarning() << "Unable to load library icui18n" << lib.errorString();
89  return false;
90  }
91 
92  ptr_ucol_open = (Ptr_ucol_open)lib.resolve("ucol_open");
93  ptr_ucol_close = (Ptr_ucol_close)lib.resolve("ucol_close");
94  ptr_ucol_strcoll = (Ptr_ucol_strcoll)lib.resolve("ucol_strcoll");
95 
97  // try again with decorated symbol names
98  ptr_ucol_open = (Ptr_ucol_open)lib.resolve("ucol_open" STRINGIFY(U_ICU_VERSION_SUFFIX));
99  ptr_ucol_close = (Ptr_ucol_close)lib.resolve("ucol_close" STRINGIFY(U_ICU_VERSION_SUFFIX));
100  ptr_ucol_strcoll = (Ptr_ucol_strcoll)lib.resolve("ucol_strcoll" STRINGIFY(U_ICU_VERSION_SUFFIX));
101  }
102 
104  ptr_ucol_open = 0;
105  ptr_ucol_close = 0;
106  ptr_ucol_strcoll = 0;
107 
108  qWarning("Unable to find symbols in icui18n");
110  return false;
111  }
112 
113  // resolve libicuuc
114  QLibrary ucLib(QLatin1String("icuuc"), QLatin1String(U_ICU_VERSION_SHORT));
116  if (!ucLib.load()) {
117  qWarning() << "Unable to load library icuuc" << ucLib.errorString();
119  return false;
120  }
121 
122  ptr_u_strToUpper = (Ptr_u_strToCase)ucLib.resolve("u_strToUpper");
123  ptr_u_strToLower = (Ptr_u_strToCase)ucLib.resolve("u_strToLower");
124 
126  ptr_u_strToUpper = (Ptr_u_strToCase)ucLib.resolve("u_strToUpper" STRINGIFY(U_ICU_VERSION_SUFFIX));
127  ptr_u_strToLower = (Ptr_u_strToCase)ucLib.resolve("u_strToLower" STRINGIFY(U_ICU_VERSION_SUFFIX));
128  }
129 
131  ptr_u_strToUpper = 0;
132  ptr_u_strToLower = 0;
133 
134  qWarning("Unable to find symbols in icuuc");
136  return false;
137  }
138 
139  // success :)
140  status = Loaded;
141  }
142 
143  if (icuCollator) {
145  icuCollator = 0;
146  }
147 
148  UErrorCode icuStatus = U_ZERO_ERROR;
149  icuCollator = ptr_ucol_open(localeString.toLatin1().constData(), &icuStatus);
150 
151  if (!icuCollator) {
152  qWarning("Unable to open locale %s in ICU, error code %d", qPrintable(localeString), icuStatus);
153  return false;
154  }
155 
156  return true;
157 }
158 
159 bool qt_ucol_strcoll(const QChar *source, int sourceLength, const QChar *target, int targetLength, int *result)
160 {
161  Q_ASSERT(result);
162  Q_ASSERT(source);
163  Q_ASSERT(target);
164 
165  if (!icuCollator)
166  return false;
167 
168  *result = ptr_ucol_strcoll(icuCollator, reinterpret_cast<const UChar *>(source), int32_t(sourceLength),
169  reinterpret_cast<const UChar *>(target), int32_t(targetLength));
170 
171  return true;
172 }
173 
174 // caseFunc can either be u_strToUpper or u_strToLower
175 static bool qt_u_strToCase(const QString &str, QString *out, const QLocale &locale, Ptr_u_strToCase caseFunc)
176 {
177  Q_ASSERT(out);
178 
179  if (!icuCollator)
180  return false;
181 
182  QString result(str.size(), Qt::Uninitialized);
183 
184  UErrorCode status = U_ZERO_ERROR;
185 
186  int32_t size = caseFunc(reinterpret_cast<UChar *>(result.data()), result.size(),
187  reinterpret_cast<const UChar *>(str.constData()), str.size(),
188  locale.bcp47Name().toLatin1().constData(), &status);
189 
190  if (U_FAILURE(status))
191  return false;
192 
193  if (size < result.size()) {
194  result.resize(size);
195  } else if (size > result.size()) {
196  // the resulting string is larger than our source string
197  result.resize(size);
198 
199  status = U_ZERO_ERROR;
200  size = caseFunc(reinterpret_cast<UChar *>(result.data()), result.size(),
201  reinterpret_cast<const UChar *>(str.constData()), str.size(),
202  locale.bcp47Name().toLatin1().constData(), &status);
203 
204  if (U_FAILURE(status))
205  return false;
206 
207  // if the sizes don't match now, we give up.
208  if (size != result.size())
209  return false;
210  }
211 
212  *out = result;
213  return true;
214 }
215 
216 bool qt_u_strToUpper(const QString &str, QString *out, const QLocale &locale)
217 {
218  return qt_u_strToCase(str, out, locale, ptr_u_strToUpper);
219 }
220 
221 bool qt_u_strToLower(const QString &str, QString *out, const QLocale &locale)
222 {
223  return qt_u_strToCase(str, out, locale, ptr_u_strToLower);
224 }
225 
bool qt_u_strToLower(const QString &str, QString *out, const QLocale &locale)
static Ptr_ucol_open ptr_ucol_open
Definition: qlocale_icu.cpp:56
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
static Ptr_u_strToCase ptr_u_strToLower
Definition: qlocale_icu.cpp:60
static UCollator * icuCollator
Definition: qlocale_icu.cpp:71
static Ptr_ucol_close ptr_ucol_close
Definition: qlocale_icu.cpp:58
static LibLoadStatus status
Definition: qlocale_icu.cpp:69
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
void * resolve(const char *symbol)
Returns the address of the exported symbol symbol.
Definition: qlibrary.cpp:1155
The QString class provides a Unicode character string.
Definition: qstring.h:83
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
static bool qt_u_strToCase(const QString &str, QString *out, const QLocale &locale, Ptr_u_strToCase caseFunc)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
int size() const
Returns the number of characters in this string.
Definition: qstring.h:102
bool qt_ucol_strcoll(const QChar *source, int sourceLength, const QChar *target, int targetLength, int *result)
Q_CORE_EXPORT void qWarning(const char *,...)
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
bool qt_initIcu(const QString &localeString)
Definition: qlocale_icu.cpp:76
#define STRINGIFY(x)
Definition: qlocale_icu.cpp:74
UCollator *(* Ptr_ucol_open)(const char *loc, UErrorCode *status)
Definition: qlocale_icu.cpp:51
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
void(* Ptr_ucol_close)(UCollator *coll)
Definition: qlocale_icu.cpp:52
UCollationResult(* Ptr_ucol_strcoll)(const UCollator *coll, const UChar *source, int32_t sourceLength, const UChar *target, int32_t targetLength)
Definition: qlocale_icu.cpp:53
bool load()
Loads the library and returns true if the library was loaded successfully; otherwise returns false...
Definition: qlibrary.cpp:909
static Ptr_ucol_strcoll ptr_ucol_strcoll
Definition: qlocale_icu.cpp:57
int32_t(* Ptr_u_strToCase)(UChar *dest, int32_t destCapacity, const UChar *src, int32_t srcLength, const char *locale, UErrorCode *pErrorCode)
Definition: qlocale_icu.cpp:54
void setLoadHints(LoadHints hints)
Definition: qlibrary.cpp:1304
bool qt_u_strToUpper(const QString &str, QString *out, const QLocale &locale)
#define qPrintable(string)
Definition: qglobal.h:1750
LibLoadStatus
Definition: qlocale_icu.cpp:62
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition: qstring.h:712
static Ptr_u_strToCase ptr_u_strToUpper
Definition: qlocale_icu.cpp:59
QString errorString() const
Returns a text string with the description of the last error that occurred.
Definition: qlibrary.cpp:1267
QString bcp47Name() const
Returns the dash-separated language, script and country (and possibly other BCP47 fields) of this loc...
Definition: qlocale.cpp:1012
The QLibrary class loads shared libraries at runtime.
Definition: qlibrary.h:62