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.

Change-Id: I48f80389161bfbce3342e53ceec0b13bb7df0e4c
Reviewed-by: Tony Van Eerd <tvaneerd@blackberry.com>
Reviewed-by: Rafael Roquetto <rafael.roquetto@kdab.com>
This commit is contained in:
El Mehdi Fekari 2013-11-18 18:23:26 +01:00 committed by The Qt Project
parent 17333720e0
commit edf29a9aa9

View File

@ -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,24 @@ QByteArray QBBSystemLocaleData::readPpsValue(const char *ppsObject, int ppsFd)
if (!ppsObject || ppsFd == -1)
return result;
char buffer[ppsBufferSize];
// 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));
}
int bytes = qt_safe_read(ppsFd, buffer, ppsBufferSize - 1);
// 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 +217,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) {