예제 #1
0
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);
        }
    }
}
예제 #4
0
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));
}