QCborStreamReader: move the readStringChunk code to the Private

And add a currently-unused QByteArray pointer parameter. This function
will resize the array as necessary as data comes in.

Change-Id: I7b9b97ae9b32412abdc6fffd16451f5c6b280f3b
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
(cherry picked from c16ad16bd0a1d51d559eed8a4f2f10ac1518f6aa)
This commit is contained in:
Thiago Macieira 2020-11-06 20:28:44 -08:00 committed by Volker Hilsheimer
parent f77caf4c60
commit f5dd248de5

View File

@ -668,6 +668,7 @@ public:
} }
bool ensureStringIteration(); bool ensureStringIteration();
QCborStreamReader::StringResult<qsizetype> readStringChunk(char *ptr, qsizetype maxlen);
}; };
void qt_cbor_stream_set_error(QCborStreamReaderPrivate *d, QCborError error) void qt_cbor_stream_set_error(QCborStreamReaderPrivate *d, QCborError error)
@ -1460,29 +1461,38 @@ qsizetype QCborStreamReader::_currentStringChunkSize() const
*/ */
QCborStreamReader::StringResult<qsizetype> QCborStreamReader::StringResult<qsizetype>
QCborStreamReader::readStringChunk(char *ptr, qsizetype maxlen) QCborStreamReader::readStringChunk(char *ptr, qsizetype maxlen)
{
auto r = d->readStringChunk(ptr, maxlen);
if (r.status == EndOfString && lastError() == QCborError::NoError)
preparse();
return r;
}
QCborStreamReader::StringResult<qsizetype>
QCborStreamReaderPrivate::readStringChunk(char *ptr, qsizetype maxlen)
{ {
CborError err; CborError err;
size_t len; size_t len;
const void *content = nullptr; const void *content = nullptr;
QCborStreamReader::StringResult<qsizetype> result; QCborStreamReader::StringResult<qsizetype> result;
result.data = 0; result.data = 0;
result.status = Error; result.status = QCborStreamReader::Error;
d->lastError = {}; lastError = {};
if (!d->ensureStringIteration()) if (!ensureStringIteration())
return result; return result;
#if 1 #if 1
// Using internal TinyCBOR API! // Using internal TinyCBOR API!
err = _cbor_value_get_string_chunk(&d->currentElement, &content, &len, &d->currentElement); err = _cbor_value_get_string_chunk(&currentElement, &content, &len, &currentElement);
#else #else
// the above is effectively the same as: // the above is effectively the same as:
if (cbor_value_is_byte_string(&currentElement)) if (cbor_value_is_byte_string(&currentElement))
err = cbor_value_get_byte_string_chunk(&d->currentElement, reinterpret_cast<const uint8_t **>(&content), err = cbor_value_get_byte_string_chunk(&currentElement, reinterpret_cast<const uint8_t **>(&content),
&len, &d->currentElement); &len, &currentElement);
else else
err = cbor_value_get_text_string_chunk(&d->currentElement, reinterpret_cast<const char **>(&content), err = cbor_value_get_text_string_chunk(&currentElement, reinterpret_cast<const char **>(&content),
&len, &d->currentElement); &len, &currentElement);
#endif #endif
// Range check: using implementation-defined behavior in converting an // Range check: using implementation-defined behavior in converting an
@ -1494,14 +1504,13 @@ QCborStreamReader::readStringChunk(char *ptr, qsizetype maxlen)
if (err) { if (err) {
if (err == CborErrorNoMoreStringChunks) { if (err == CborErrorNoMoreStringChunks) {
d->preread(); preread();
err = cbor_value_finish_string_iteration(&d->currentElement); err = cbor_value_finish_string_iteration(&currentElement);
result.status = EndOfString; result.status = QCborStreamReader::EndOfString;
} }
if (err) if (err)
d->handleError(err); handleError(err);
else // caller musts call preparse()
preparse();
return result; return result;
} }
@ -1515,34 +1524,34 @@ QCborStreamReader::readStringChunk(char *ptr, qsizetype maxlen)
else else
toRead = maxlen; // buffer smaller than string toRead = maxlen; // buffer smaller than string
if (d->device) { if (device) {
// This first skip can't fail because we've already read this many bytes. // This first skip can't fail because we've already read this many bytes.
d->device->skip(d->bufferStart + qptrdiff(content)); device->skip(bufferStart + qptrdiff(content));
actuallyRead = d->device->read(ptr, toRead); actuallyRead = device->read(ptr, toRead);
if (actuallyRead != toRead) { if (actuallyRead != toRead) {
actuallyRead = -1; actuallyRead = -1;
} else if (left) { } else if (left) {
qint64 skipped = d->device->skip(left); qint64 skipped = device->skip(left);
if (skipped != left) if (skipped != left)
actuallyRead = -1; actuallyRead = -1;
} }
if (actuallyRead < 0) { if (actuallyRead < 0) {
d->handleError(CborErrorIO); handleError(CborErrorIO);
return result; return result;
} }
d->updateBufferAfterString(offset, len); updateBufferAfterString(offset, len);
} else { } else {
actuallyRead = toRead; actuallyRead = toRead;
memcpy(ptr, d->buffer.constData() + d->bufferStart + offset, toRead); memcpy(ptr, buffer.constData() + bufferStart + offset, toRead);
d->bufferStart += QByteArray::size_type(offset + len); bufferStart += QByteArray::size_type(offset + len);
} }
d->preread(); preread();
result.data = actuallyRead; result.data = actuallyRead;
result.status = Ok; result.status = QCborStreamReader::Ok;
return result; return result;
} }