diff options
author | El Mehdi Fekari <mfekari@blackberry.com> | 2013-12-04 15:58:25 (GMT) |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-12-05 01:50:15 (GMT) |
commit | 085f851bd8431a30bc84ee20bdb5c5aa51949f4e (patch) | |
tree | 65237dd260db62af9b16e21b4bfe41bcad21f5da | |
parent | 0f6438baf5188c69c7c64cca524e2e229b786dab (diff) | |
download | Qt-085f851bd8431a30bc84ee20bdb5c5aa51949f4e.zip Qt-085f851bd8431a30bc84ee20bdb5c5aa51949f4e.tar.gz Qt-085f851bd8431a30bc84ee20bdb5c5aa51949f4e.tar.bz2 |
QBBSystemLocale: Do not set fixed buffer size when reading pps objects
Set dynamically the buffer size when reading pps objects since a pps file
size is not always fix.
Cherry-picked: qtbase/edf29a9aa93660ac8e4927db7fef2b5d925e9b59
Change-Id: Id55df6a474b6b79d96e3459e807f0bbfeacbf0cb
Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com>
-rw-r--r-- | src/corelib/tools/qlocale_blackberry.cpp | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/src/corelib/tools/qlocale_blackberry.cpp b/src/corelib/tools/qlocale_blackberry.cpp index 44bf133..56bffbc 100644 --- a/src/corelib/tools/qlocale_blackberry.cpp +++ b/src/corelib/tools/qlocale_blackberry.cpp @@ -60,7 +60,7 @@ static const char ppsRegionLocalePath[] = "/pps/services/locale/settings"; static const char ppsLanguageLocalePath[] = "/pps/services/confstr/_CS_LOCALE"; static const char ppsHourFormatPath[] = "/pps/system/settings"; -static const size_t ppsBufferSize = 256; +static const int MAX_PPS_SIZE = 16000; QBBSystemLocaleData::QBBSystemLocaleData() : languageNotifier(0) @@ -186,9 +186,25 @@ QByteArray QBBSystemLocaleData::readPpsValue(const char *ppsObject, int ppsFd) if (!ppsObject || ppsFd == -1) return result; - char buffer[ppsBufferSize]; - int bytes = qt_safe_read(ppsFd, buffer, ppsBufferSize - 1); + // PPS objects are of unknown size, but must be read all at once. + // Relying on the file size may not be a good idea since the size may change before reading. + // Let's try with an initial size (512), and if the buffer is too small try with bigger one, + // until we succeed or until other non buffer-size-related error occurs. + // Using QVarLengthArray means the first try (of size == 512) uses a buffer on the stack - no allocation necessary. + // Hopefully that covers most use cases. + int bytes; + QVarLengthArray<char, 512> buffer; + for (;;) { + errno = 0; + bytes = qt_safe_read(ppsFd, buffer.data(), buffer.capacity() - 1); + const bool bufferIsTooSmall = (bytes == -1 && errno == EMSGSIZE && buffer.capacity() < MAX_PPS_SIZE); + if (!bufferIsTooSmall) + break; + + buffer.resize(qMin(buffer.capacity()*2, MAX_PPS_SIZE)); + } + // This method is called in the ctor(), so do not use qWarning to log warnings // if qt_safe_read fails to read the pps file // since the user code may install a message handler that invokes QLocale API again @@ -202,7 +218,7 @@ QByteArray QBBSystemLocaleData::readPpsValue(const char *ppsObject, int ppsFd) pps_decoder_t ppsDecoder; pps_decoder_initialize(&ppsDecoder, 0); - if (pps_decoder_parse_pps_str(&ppsDecoder, buffer) == PPS_DECODER_OK) { + if (pps_decoder_parse_pps_str(&ppsDecoder, buffer.data()) == PPS_DECODER_OK) { pps_decoder_push(&ppsDecoder, 0); const char *ppsBuff; if (pps_decoder_get_string(&ppsDecoder, ppsObject, &ppsBuff) == PPS_DECODER_OK) { |