Qt 4.8
qlocale_blackberry.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 "qlocale_blackberry.h"
43 #include "qlocale_p.h"
44 
45 #include "qdatetime.h"
46 
47 #include "qcoreapplication.h"
48 #include "private/qcore_unix_p.h"
49 
50 #include <errno.h>
51 #include <sys/pps.h>
52 #include <unistd.h>
53 
55 
56 #ifndef QT_NO_SYSTEMLOCALE
57 
58 static const char ppsUomPath[] = "/pps/services/locale/uom";
59 static const char ppsRegionLocalePath[] = "/pps/services/locale/settings";
60 static const char ppsLanguageLocalePath[] = "/pps/services/confstr/_CS_LOCALE";
61 static const char ppsHourFormatPath[] = "/pps/system/settings";
62 
63 static const int MAX_PPS_SIZE = 16000;
64 
66  : languageNotifier(0)
67  , regionNotifier(0)
68  , measurementNotifier(0)
69  , hourNotifier(0)
70 {
71  // Do not use qWarning to log warnings if qt_safe_open fails to open the pps file
72  // since the user code may install a message handler that invokes QLocale API again
73  // (i.e QDate, QDateTime, ...) which will cause an infinite loop.
75  fprintf(stderr, "Failed to open uom pps, errno=%d\n", errno);
76 
78  fprintf(stderr, "Failed to open region pps, errno=%d\n", errno);
79 
81  fprintf(stderr, "Failed to open language pps, errno=%d\n", errno);
82 
84  fprintf(stderr, "Failed to open hour format pps, errno=%d\n", errno);
85 
86  // we cannot call this directly, because by the time this constructor is
87  // called, the event dispatcher has not yet been created, causing the
88  // subsequent call to QSocketNotifier constructor to fail.
89  QMetaObject::invokeMethod(this, "installSocketNotifiers", Qt::QueuedConnection);
90 
95 }
96 
98 {
99  if (measurementFd != -1)
101 
102  if (languageFd != -1)
104 
105  if (regionFd != -1)
107 
108  if (hourFd != -1)
110 }
111 
113 {
114  return m_measurementSystem;
115 }
116 
118 {
119  return getCorrectFormat(regionLocale().timeFormat(formatType), formatType);
120 }
121 
123 {
124  return getCorrectFormat(regionLocale().dateTimeFormat(formatType), formatType);
125 }
126 
128 {
129  if (!lc_langage.isEmpty())
131 
132  return QLocale::c();
133 }
134 
136 {
137  if (!lc_region.isEmpty())
139 
140  return QLocale::c();
141 }
142 
144 {
147 
149  QObject::connect(languageNotifier, SIGNAL(activated(int)), this, SLOT(readLangageLocale()));
150 
152  QObject::connect(regionNotifier, SIGNAL(activated(int)), this, SLOT(readRegionLocale()));
153 
156 
158  QObject::connect(hourNotifier, SIGNAL(activated(int)), this, SLOT(readHourFormat()));
159 }
160 
162 {
163  lc_langage = readPpsValue("_CS_LOCALE", languageFd);
164 }
165 
167 {
168  lc_region = readPpsValue("region", regionFd);
169 }
170 
172 {
173  QByteArray measurement = readPpsValue("uom", measurementFd);
174  m_measurementSystem = (qstrcmp(measurement, "imperial") == 0) ? QLocale::ImperialSystem : QLocale::MetricSystem;
175 }
176 
178 {
179  QByteArray hourFormat = readPpsValue("hourFormat", hourFd);
180  is24HourFormat = (qstrcmp(hourFormat, "24") == 0);
181 }
182 
183 QByteArray QBBSystemLocaleData::readPpsValue(const char *ppsObject, int ppsFd)
184 {
185  QByteArray result;
186  if (!ppsObject || ppsFd == -1)
187  return result;
188 
189 
190  // PPS objects are of unknown size, but must be read all at once.
191  // Relying on the file size may not be a good idea since the size may change before reading.
192  // Let's try with an initial size (512), and if the buffer is too small try with bigger one,
193  // until we succeed or until other non buffer-size-related error occurs.
194  // Using QVarLengthArray means the first try (of size == 512) uses a buffer on the stack - no allocation necessary.
195  // Hopefully that covers most use cases.
196  int bytes;
198  for (;;) {
199  errno = 0;
200  bytes = qt_safe_read(ppsFd, buffer.data(), buffer.capacity() - 1);
201  const bool bufferIsTooSmall = (bytes == -1 && errno == EMSGSIZE && buffer.capacity() < MAX_PPS_SIZE);
202  if (!bufferIsTooSmall)
203  break;
204 
205  buffer.resize(qMin(buffer.capacity()*2, MAX_PPS_SIZE));
206  }
207 
208  // This method is called in the ctor(), so do not use qWarning to log warnings
209  // if qt_safe_read fails to read the pps file
210  // since the user code may install a message handler that invokes QLocale API again
211  // (i.e QDate, QDateTime, ...) which will cause a infinite loop.
212  if (bytes == -1) {
213  fprintf(stderr, "Failed to read pps object:%s, errno=%d\n", ppsObject, errno);
214  return result;
215  }
216  // ensure data is null terminated
217  buffer[bytes] = '\0';
218 
219  pps_decoder_t ppsDecoder;
220  pps_decoder_initialize(&ppsDecoder, 0);
221  if (pps_decoder_parse_pps_str(&ppsDecoder, buffer.data()) == PPS_DECODER_OK) {
222  pps_decoder_push(&ppsDecoder, 0);
223  const char *ppsBuff;
224  if (pps_decoder_get_string(&ppsDecoder, ppsObject, &ppsBuff) == PPS_DECODER_OK) {
225  result = ppsBuff;
226  } else {
227  int val;
228  if (pps_decoder_get_int(&ppsDecoder, ppsObject, &val) == PPS_DECODER_OK)
229  result = QByteArray::number(val);
230  }
231  }
232 
233  pps_decoder_cleanup(&ppsDecoder);
234 
235  return result;
236 }
237 
239 {
240  QString format = baseFormat;
241  if (is24HourFormat) {
242  if (format.contains(QLatin1String("AP"), Qt::CaseInsensitive)) {
245  }
246 
247  } else {
248 
249  if (!format.contains(QLatin1String("AP"), Qt::CaseInsensitive)) {
250  format.contains(QLatin1String("HH"), Qt::CaseSensitive) ?
251  format.replace(QLatin1String("HH"), QLatin1String("hh"), Qt::CaseSensitive) :
253 
254  formatType == QLocale::LongFormat ? format.append(QLatin1String(" AP t")) : format.append(QLatin1String(" AP"));
255  }
256  }
257 
258  return format;
259 }
260 
261 Q_GLOBAL_STATIC(QBBSystemLocaleData, bbSysLocaleData)
262 
263 QLocale QSystemLocale::fallbackLocale() const
264 {
265  return bbSysLocaleData()->languageLocale();
266 }
267 
269 {
270  QBBSystemLocaleData *d = bbSysLocaleData();
271 
272  QReadLocker locker(&d->lock);
273 
274  const QLocale &lc_language = d->languageLocale();
275  const QLocale &lc_region = d->regionLocale();
276 
277  switch (type) {
278  case DecimalPoint:
279  return lc_region.decimalPoint();
280  case GroupSeparator:
281  return lc_region.groupSeparator();
282  case NegativeSign:
283  return lc_region.negativeSign();
284  case PositiveSign:
285  return lc_region.positiveSign();
286  case DateFormatLong:
287  return lc_region.dateFormat(QLocale::LongFormat);
288  case DateFormatShort:
289  return lc_region.dateFormat(QLocale::ShortFormat);
290  case TimeFormatLong:
291  return d->timeFormat(QLocale::LongFormat);
292  case TimeFormatShort:
293  return d->timeFormat(QLocale::ShortFormat);
294  case DateTimeFormatLong:
296  case DateTimeFormatShort:
298  case DayNameLong:
299  return lc_language.dayName(in.toInt(), QLocale::LongFormat);
300  case DayNameShort:
301  return lc_language.dayName(in.toInt(), QLocale::ShortFormat);
302  case MonthNameLong:
303  return lc_language.monthName(in.toInt(), QLocale::LongFormat);
304  case MonthNameShort:
305  return lc_language.monthName(in.toInt(), QLocale::ShortFormat);
306  case StandaloneMonthNameLong:
307  return lc_language.standaloneMonthName(in.toInt(), QLocale::LongFormat);
308  case StandaloneMonthNameShort:
309  return lc_language.standaloneMonthName(in.toInt(), QLocale::ShortFormat);
310  case DateToStringLong:
311  return lc_region.toString(in.toDate(), QLocale::LongFormat);
312  case DateToStringShort:
313  return lc_region.toString(in.toDate(), QLocale::ShortFormat);
314  case TimeToStringLong:
315  return lc_region.toString(in.toTime(), d->timeFormat(QLocale::LongFormat).toString());
316  case TimeToStringShort:
317  return lc_region.toString(in.toTime(), d->timeFormat(QLocale::ShortFormat).toString());
318  case DateTimeToStringShort:
319  return lc_region.toString(in.toDateTime(), d->dateTimeFormat(QLocale::ShortFormat).toString());
320  case DateTimeToStringLong:
321  return lc_region.toString(in.toDateTime(), d->dateTimeFormat(QLocale::LongFormat).toString());
322  case MeasurementSystem:
323  return d->measurementSystem();
324  case ZeroDigit:
325  return lc_region.zeroDigit();
326  case CountryId:
327  return lc_region.country();
328  case LanguageId:
329  return lc_language.language();
330  case AMText:
331  return lc_language.amText();
332  case PMText:
333  return lc_language.pmText();
334  default:
335  break;
336  }
337  return QVariant();
338 }
339 
340 #endif
341 
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
QBool contains(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.h:904
void resize(int size)
double d
Definition: qnumeric_p.h:62
QSocketNotifier * languageNotifier
QChar positiveSign() const
Returns the positive sign character of this locale.
Definition: qlocale.cpp:1830
static const char ppsHourFormatPath[]
int type
Definition: qmetatype.cpp:239
Language language() const
Returns the language of this locale.
Definition: qlocale.cpp:920
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QString monthName(int, FormatType format=LongFormat) const
Returns the localized name of month, in the format specified by type.
Definition: qlocale.cpp:2007
QString & replace(int i, int len, QChar after)
Definition: qstring.cpp:2005
QString formatType(const NamePool::Ptr &np, const T &type)
Formats ItemType and SequenceType.
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
#define SLOT(a)
Definition: qobjectdefs.h:226
#define O_RDONLY
QSocketNotifier * measurementNotifier
FormatType
Definition: qlocale.h:659
QString toString() const
Returns the variant as a QString if the variant has type() String , Bool , ByteArray ...
Definition: qvariant.cpp:2270
QDateTime toDateTime() const
Returns the variant as a QDateTime if the variant has type() DateTime , Date , or String ; otherwise ...
Definition: qvariant.cpp:2349
QChar zeroDigit() const
Returns the zero digit character of this locale.
Definition: qlocale.cpp:1804
QByteArray readPpsValue(const char *ppsObject, int ppsFd)
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
static int qt_safe_close(int fd)
Definition: qcore_unix_p.h:297
The QString class provides a Unicode character string.
Definition: qstring.h:83
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
QString toString(qlonglong i) const
Returns a localized string representation of i.
Definition: qlocale.cpp:1295
The QSocketNotifier class provides support for monitoring activity on a file descriptor.
int toInt(bool *ok=0) const
Returns the variant as an int if the variant has type() Int , Bool , ByteArray , Char ...
Definition: qvariant.cpp:2625
#define SIGNAL(a)
Definition: qobjectdefs.h:227
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
static int qt_safe_open(const char *pathname, int flags, mode_t mode=0777)
Definition: qcore_unix_p.h:171
QChar decimalPoint() const
Returns the decimal point character of this locale.
Definition: qlocale.cpp:1765
static const int MAX_PPS_SIZE
QChar groupSeparator() const
Returns the group separator character of this locale.
Definition: qlocale.cpp:1778
QString pmText() const
Returns the localized name of the "PM" suffix for times specified using the conventions of the 12-hou...
Definition: qlocale.cpp:2376
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
Definition: qglobal.h:1968
static const char ppsUomPath[]
QSocketNotifier * hourNotifier
unsigned int uint
Definition: qglobal.h:996
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
int capacity() const
The QReadLocker class is a convenience class that simplifies locking and unlocking read-write locks f...
QChar negativeSign() const
Returns the negative sign character of this locale.
Definition: qlocale.cpp:1817
QString amText() const
Returns the localized name of the "AM" suffix for times specified using the conventions of the 12-hou...
Definition: qlocale.cpp:2353
QDate toDate() const
Returns the variant as a QDate if the variant has type() Date , DateTime , or String ; otherwise retu...
Definition: qvariant.cpp:2311
static QLocale c()
Returns a QLocale object initialized to the "C" locale.
Definition: qlocale.h:773
QString & append(QChar c)
Definition: qstring.cpp:1777
QVariant timeFormat(QLocale::FormatType)
static QCoreApplication * instance()
Returns a pointer to the application&#39;s QCoreApplication (or QApplication) instance.
QString standaloneMonthName(int, FormatType format=LongFormat) const
Returns the localized name of month that is used as a standalone text, in the format specified by typ...
Definition: qlocale.cpp:2056
QString getCorrectFormat(const QString &baseFormat, QLocale::FormatType typeFormat)
virtual QVariant query(QueryType type, QVariant in) const
QVariant dateTimeFormat(QLocale::FormatType)
static const char ppsRegionLocalePath[]
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
Invokes the member (a signal or a slot name) on the object obj.
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
QString dayName(int, FormatType format=LongFormat) const
Returns the localized name of the day (where 1 represents Monday, 2 represents Tuesday and so on)...
Definition: qlocale.cpp:2106
int qstrcmp(const QByteArray &str1, const char *str2)
Definition: qbytearray.cpp:336
QTime toTime() const
Returns the variant as a QTime if the variant has type() Time , DateTime , or String ; otherwise retu...
Definition: qvariant.cpp:2330
Country country() const
Returns the country of this locale.
Definition: qlocale.cpp:945
QString dateFormat(FormatType format=LongFormat) const
Returns the date format used for the current locale.
Definition: qlocale.cpp:1495
static const char ppsLanguageLocalePath[]
static QByteArray number(int, int base=10)
Returns a byte array containing the string equivalent of the number n to base base (10 by default)...
QSocketNotifier * regionNotifier
static qint64 qt_safe_read(int fd, void *data, qint64 maxlen)
Definition: qcore_unix_p.h:273
int errno