QByteArray QBBSystemLocaleData::readPpsValue(const char *ppsObject, int ppsFd) { QByteArray result; if (!ppsObject || ppsFd == -1) return result; // 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 // (i.e QDate, QDateTime, ...) which will cause a infinite loop. if (bytes == -1) { fprintf(stderr, "Failed to read pps object:%s, errno=%d\n", ppsObject, errno); return result; } // ensure data is null terminated buffer[bytes] = '\0'; pps_decoder_t ppsDecoder; pps_decoder_initialize(&ppsDecoder, 0); 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) { result = ppsBuff; } else { int val; if (pps_decoder_get_int(&ppsDecoder, ppsObject, &val) == PPS_DECODER_OK) result = QByteArray::number(val); } } pps_decoder_cleanup(&ppsDecoder); return result; }
void tst_QVarLengthArray::squeeze() { QVarLengthArray<int> list; int sizeOnStack = list.capacity(); int sizeOnHeap = sizeOnStack * 2; list.resize(0); QCOMPARE(list.capacity(), sizeOnStack); list.resize(sizeOnHeap); QCOMPARE(list.capacity(), sizeOnHeap); list.resize(sizeOnStack); QCOMPARE(list.capacity(), sizeOnHeap); list.resize(0); QCOMPARE(list.capacity(), sizeOnHeap); list.squeeze(); QCOMPARE(list.capacity(), sizeOnStack); list.resize(sizeOnStack); list.squeeze(); QCOMPARE(list.capacity(), sizeOnStack); list.resize(sizeOnHeap); list.squeeze(); QCOMPARE(list.capacity(), sizeOnHeap); }
void tst_QVarLengthArray::oldTests() { { QVarLengthArray<int, 256> sa(128); QVERIFY(sa.data() == &sa[0]); sa[0] = 0xfee; sa[10] = 0xff; QVERIFY(sa[0] == 0xfee); QVERIFY(sa[10] == 0xff); sa.resize(512); QVERIFY(sa.data() == &sa[0]); QVERIFY(sa[0] == 0xfee); QVERIFY(sa[10] == 0xff); QVERIFY(sa.at(0) == 0xfee); QVERIFY(sa.at(10) == 0xff); QVERIFY(sa.value(0) == 0xfee); QVERIFY(sa.value(10) == 0xff); QVERIFY(sa.value(1000) == 0); QVERIFY(sa.value(1000, 12) == 12); QVERIFY(sa.size() == 512); sa.reserve(1024); QVERIFY(sa.capacity() == 1024); QVERIFY(sa.size() == 512); } { QVarLengthArray<QString> sa(10); sa[0] = "Hello"; sa[9] = "World"; QVERIFY(*sa.data() == "Hello"); QVERIFY(sa[9] == "World"); sa.reserve(512); QVERIFY(*sa.data() == "Hello"); QVERIFY(sa[9] == "World"); sa.resize(512); QVERIFY(*sa.data() == "Hello"); QVERIFY(sa[9] == "World"); } { int arr[2] = {1, 2}; QVarLengthArray<int> sa(10); QCOMPARE(sa.size(), 10); sa.append(arr, 2); QCOMPARE(sa.size(), 12); QCOMPARE(sa[10], 1); QCOMPARE(sa[11], 2); } { QString arr[2] = { QString("hello"), QString("world") }; QVarLengthArray<QString> sa(10); QCOMPARE(sa.size(), 10); sa.append(arr, 2); QCOMPARE(sa.size(), 12); QCOMPARE(sa[10], QString("hello")); QCOMPARE(sa[11], QString("world")); QCOMPARE(sa.at(10), QString("hello")); QCOMPARE(sa.at(11), QString("world")); QCOMPARE(sa.value(10), QString("hello")); QCOMPARE(sa.value(11), QString("world")); QCOMPARE(sa.value(10000), QString()); QCOMPARE(sa.value(1212112, QString("none")), QString("none")); QCOMPARE(sa.value(-12, QString("neg")), QString("neg")); sa.append(arr, 1); QCOMPARE(sa.size(), 13); QCOMPARE(sa[12], QString("hello")); sa.append(arr, 0); QCOMPARE(sa.size(), 13); } { // assignment operator and copy constructor QVarLengthArray<int> sa(10); sa[5] = 5; QVarLengthArray<int> sa2(10); sa2[5] = 6; sa2 = sa; QCOMPARE(sa2[5], 5); QVarLengthArray<int> sa3(sa); QCOMPARE(sa3[5], 5); } QSKIP("This test causes the machine to crash when allocating too much memory.", SkipSingle); { QVarLengthArray<Foo> a; const int N = 0x7fffffff / sizeof(Foo); const int Prealloc = a.capacity(); const Foo *data0 = a.constData(); a.resize(N); if (a.size() == N) { QVERIFY(a.capacity() >= N); QCOMPARE(fooCtor, N); QCOMPARE(fooDtor, 0); for (int i = 0; i < N; i += 35000) a[i] = Foo(); } else { // this is the case we're actually testing QCOMPARE(a.size(), 0); QCOMPARE(a.capacity(), Prealloc); QCOMPARE(a.constData(), data0); QCOMPARE(fooCtor, 0); QCOMPARE(fooDtor, 0); a.resize(5); QCOMPARE(a.size(), 5); QCOMPARE(a.capacity(), Prealloc); QCOMPARE(a.constData(), data0); QCOMPARE(fooCtor, 5); QCOMPARE(fooDtor, 0); a.resize(Prealloc + 1); QCOMPARE(a.size(), Prealloc + 1); QVERIFY(a.capacity() >= Prealloc + 1); QVERIFY(a.constData() != data0); QCOMPARE(fooCtor, Prealloc + 6); QCOMPARE(fooDtor, 5); const Foo *data1 = a.constData(); a.resize(0x10000000); QCOMPARE(a.size(), 0); QVERIFY(a.capacity() >= Prealloc + 1); QVERIFY(a.constData() == data1); QCOMPARE(fooCtor, Prealloc + 6); QCOMPARE(fooDtor, Prealloc + 6); } } }
Kst::Object::UpdateType AsciiSource::internalDataSourceUpdate() { if (!_haveHeader) { _haveHeader = initRowIndex(); if (!_haveHeader) { return NoChange; } // Re-update the field list since we have one now _fieldList = fieldListFor(_filename, &_config); _fieldListComplete = _fieldList.count() > 1; // Re-update the scalar list since we have one now _scalarList = scalarListFor(_filename, &_config); _stringList = stringListFor(_filename, &_config); } QFile file(_filename); if (!openValidFile(file)) { // Qt: If the device is closed, the size returned will not reflect the actual size of the device. return NoChange; } bool forceUpdate; if (_byteLength == file.size()) { forceUpdate = false; } else { forceUpdate = true; _byteLength = file.size(); } int bufread; bool new_data = false; //bool first_read = (_numFrames == 0); QByteArray delbytes = _config._delimiters.value().toLatin1(); const char *del = delbytes.constData(); do { // Read the tmpbuffer, starting at row_index[_numFrames] QVarLengthArray<char, MAXBUFREADLEN + 1> varBuffer; varBuffer.resize(varBuffer.capacity()); int bufstart = _rowIndex[_numFrames]; bufread = readFromFile(file, varBuffer, bufstart, _byteLength - bufstart, MAXBUFREADLEN); #ifdef KST_DONT_CHECK_INDEX_IN_DEBUG const char* buffer = varBuffer.constData(); const char* bufferData = buffer; #else QVarLengthArray<char, MAXBUFREADLEN + 1>& buffer = varBuffer; const char* bufferData = buffer.data(); #endif bool is_comment = false, has_dat = false; char *comment = strpbrk(const_cast<char*>(bufferData), del); for (int i = 0; i < bufread; i++) { if (comment == &(buffer[i])) { is_comment = true; } else if (buffer[i] == '\n' || buffer[i] == '\r') { if (has_dat) { ++_numFrames; if (_numFrames >= _rowIndex.size()) { _rowIndex.resize(_rowIndex.size() + 32768); if (_numFrames >= _rowIndex.size()) { // TODO where could we report an error; return NoChange; } } new_data = true; } _rowIndex[_numFrames] = bufstart + i + 1; has_dat = is_comment = false; if (comment && comment < &(buffer[i])) { comment = strpbrk(const_cast<char*>(&(buffer[i])), del); } } else if (!is_comment && !isspace((unsigned char)buffer[i])) { // FIXME: this breaks custom delimiters has_dat = true; } } } while ((bufread == MAXBUFREADLEN)); // && (!first_read)); return (forceUpdate ? Updated : (new_data ? Updated : NoChange)); }