Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qbuffer.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qbuffer.h"
5#include <QtCore/qmetaobject.h>
6#include "private/qiodevice_p.h"
7
8#include <limits>
9
11
14{
15 Q_DECLARE_PUBLIC(QBuffer)
16
17public:
18 QBufferPrivate() = default;
19
20 QByteArray *buf = nullptr;
22
23 qint64 peek(char *data, qint64 maxSize) override;
24 QByteArray peek(qint64 maxSize) override;
25
26#ifndef QT_NO_QOBJECT
27 // private slots
28 void _q_emitSignals();
29
32 bool signalsEmitted = false;
33#endif
34};
35
36#ifndef QT_NO_QOBJECT
38{
39 Q_Q(QBuffer);
40 emit q->bytesWritten(writtenSinceLastEmit);
42 emit q->readyRead();
43 signalsEmitted = false;
44}
45#endif
46
48{
49 qint64 readBytes = qMin(maxSize, static_cast<qint64>(buf->size()) - pos);
50 memcpy(data, buf->constData() + pos, readBytes);
51 return readBytes;
52}
53
55{
56 qint64 readBytes = qMin(maxSize, static_cast<qint64>(buf->size()) - pos);
57 if (pos == 0 && maxSize >= buf->size())
58 return *buf;
59 return QByteArray(buf->constData() + pos, readBytes);
60}
61
111#ifdef QT_NO_QOBJECT
114{
115 Q_D(QBuffer);
116 d->buf = &d->defaultBuf;
117}
120{
121 Q_D(QBuffer);
122 d->buf = buf ? buf : &d->defaultBuf;
123 d->defaultBuf.clear();
124}
125#else
134 : QIODevice(*new QBufferPrivate, parent)
135{
136 Q_D(QBuffer);
137 d->buf = &d->defaultBuf;
138}
139
158 : QIODevice(*new QBufferPrivate, parent)
159{
160 Q_D(QBuffer);
161 d->buf = byteArray ? byteArray : &d->defaultBuf;
162 d->defaultBuf.clear();
163}
164#endif
165
173
197{
198 Q_D(QBuffer);
199 if (isOpen()) {
200 qWarning("QBuffer::setBuffer: Buffer is open");
201 return;
202 }
203 if (byteArray) {
204 d->buf = byteArray;
205 } else {
206 d->buf = &d->defaultBuf;
207 }
208 d->defaultBuf.clear();
209}
210
219{
220 Q_D(QBuffer);
221 return *d->buf;
222}
223
231{
232 Q_D(const QBuffer);
233 return *d->buf;
234}
235
236
246{
247 Q_D(const QBuffer);
248 return *d->buf;
249}
250
260{
261 Q_D(QBuffer);
262 if (isOpen()) {
263 qWarning("QBuffer::setData: Buffer is open");
264 return;
265 }
266 *d->buf = data;
267}
268
279{
280 Q_D(QBuffer);
281 if (isOpen()) {
282 qWarning("QBuffer::setData: Buffer is open");
283 return;
284 }
285 d->buf->assign(data, data + size);
286}
287
295bool QBuffer::open(OpenMode flags)
296{
297 Q_D(QBuffer);
298
299 if ((flags & (Append | Truncate)) != 0)
300 flags |= WriteOnly;
301 if ((flags & (ReadOnly | WriteOnly)) == 0) {
302 qWarning("QBuffer::open: Buffer access not specified");
303 return false;
304 }
305
306 if ((flags & Truncate) == Truncate)
307 d->buf->resize(0);
308
310}
311
316{
318}
319
324{
325 return QIODevice::pos();
326}
327
332{
333 Q_D(const QBuffer);
334 return qint64(d->buf->size());
335}
336
341{
342 Q_D(QBuffer);
343 const auto oldBufSize = d->buf->size();
344 constexpr qint64 MaxSeekPos = (std::numeric_limits<decltype(oldBufSize)>::max)();
345 if (pos <= MaxSeekPos && pos > oldBufSize && isWritable()) {
346 QT_TRY {
347 d->buf->resize(qsizetype(pos), '\0');
348 } QT_CATCH(const std::bad_alloc &) {} // swallow, failure case is handled below
349 if (d->buf->size() != pos) {
350 qWarning("QBuffer::seek: Unable to fill gap");
351 return false;
352 }
353 }
354 if (pos > d->buf->size() || pos < 0) {
355 qWarning("QBuffer::seek: Invalid pos: %lld", pos);
356 return false;
357 }
358 return QIODevice::seek(pos);
359}
360
364bool QBuffer::atEnd() const
365{
366 return QIODevice::atEnd();
367}
368
373{
374 Q_D(const QBuffer);
375 if (!isOpen())
376 return false;
377
378 return d->buf->indexOf('\n', int(pos())) != -1 || QIODevice::canReadLine();
379}
380
385{
386 Q_D(QBuffer);
387 if ((len = qMin(len, qint64(d->buf->size()) - pos())) <= 0)
388 return qint64(0);
389 memcpy(data, d->buf->constData() + pos(), len);
390 return len;
391}
392
397{
398 Q_D(QBuffer);
399 const quint64 required = quint64(pos()) + quint64(len); // cannot overflow (pos() ≥ 0, len ≥ 0)
400
401 if (required > quint64(d->buf->size())) { // capacity exceeded
402 // The following must hold, since qsizetype covers half the virtual address space:
403 Q_ASSERT(required <= quint64((std::numeric_limits<qsizetype>::max)()));
404 d->buf->resize(qsizetype(required));
405 if (quint64(d->buf->size()) != required) { // could not resize
406 qWarning("QBuffer::writeData: Memory allocation error");
407 return -1;
408 }
409 }
410
411 memcpy(d->buf->data() + pos(), data, size_t(len));
412
413#ifndef QT_NO_QOBJECT
414 d->writtenSinceLastEmit += len;
415 if (d->signalConnectionCount && !d->signalsEmitted && !signalsBlocked()) {
416 d->signalsEmitted = true;
417 QMetaObject::invokeMethod(this, "_q_emitSignals", Qt::QueuedConnection);
418 }
419#endif
420 return len;
421}
422
423#ifndef QT_NO_QOBJECT
425{
426 // dynamic initialization: minimize the number of guard variables:
427 static const struct {
430 } sigs;
431 return signal == sigs.readyReadSignal || signal == sigs.bytesWrittenSignal;
432}
438{
440 d_func()->signalConnectionCount++;
441}
442
448{
449 if (signal.isValid()) {
451 d_func()->signalConnectionCount--;
452 } else {
453 d_func()->signalConnectionCount = 0;
454 }
455}
456#endif
457
459
460#ifndef QT_NO_QOBJECT
461# include "moc_qbuffer.cpp"
462#endif
463
QBufferPrivate()=default
QByteArray defaultBuf
Definition qbuffer.cpp:21
void _q_emitSignals()
Definition qbuffer.cpp:37
int signalConnectionCount
Definition qbuffer.cpp:31
qint64 writtenSinceLastEmit
Definition qbuffer.cpp:30
qint64 peek(char *data, qint64 maxSize) override
Definition qbuffer.cpp:47
QByteArray * buf
Definition qbuffer.cpp:20
bool signalsEmitted
Definition qbuffer.cpp:32
\inmodule QtCore \reentrant
Definition qbuffer.h:16
qint64 writeData(const char *data, qint64 len) override
\reimp
Definition qbuffer.cpp:396
void disconnectNotify(const QMetaMethod &) override
\reimp
Definition qbuffer.cpp:447
~QBuffer()
Destroys the buffer.
Definition qbuffer.cpp:170
bool open(OpenMode openMode) override
\reimp
Definition qbuffer.cpp:295
void connectNotify(const QMetaMethod &) override
\reimp
Definition qbuffer.cpp:437
qint64 pos() const override
\reimp
Definition qbuffer.cpp:323
void setBuffer(QByteArray *a)
Makes QBuffer use the QByteArray pointed to by byteArray as its internal buffer.
Definition qbuffer.cpp:196
const QByteArray & data() const
Returns the data contained in the buffer.
Definition qbuffer.cpp:245
QBuffer(QObject *parent=nullptr)
Constructs an empty buffer with the given parent.
Definition qbuffer.cpp:133
void setData(const QByteArray &data)
Sets the contents of the internal buffer to be data.
Definition qbuffer.cpp:259
bool atEnd() const override
\reimp
Definition qbuffer.cpp:364
void close() override
\reimp
Definition qbuffer.cpp:315
qint64 readData(char *data, qint64 maxlen) override
\reimp
Definition qbuffer.cpp:384
qint64 size() const override
\reimp
Definition qbuffer.cpp:331
bool canReadLine() const override
\reimp
Definition qbuffer.cpp:372
bool seek(qint64 off) override
\reimp
Definition qbuffer.cpp:340
QByteArray & buffer()
Returns a reference to the QBuffer's internal buffer.
Definition qbuffer.cpp:218
\inmodule QtCore
Definition qbytearray.h:57
void clear()
Clears the contents of the byte array and makes it null.
\inmodule QtCore \reentrant
Definition qiodevice.h:34
virtual bool open(QIODeviceBase::OpenMode mode)
Opens the device and sets its OpenMode to mode.
void readyRead()
This signal is emitted once every time new data is available for reading from the device's current re...
virtual qint64 pos() const
For random-access devices, this function returns the position that data is written to or read from.
bool isOpen() const
Returns true if the device is open; otherwise returns false.
void bytesWritten(qint64 bytes)
This signal is emitted every time a payload of data has been written to the device's current write ch...
bool isWritable() const
Returns true if data can be written to the device; otherwise returns false.
virtual void close()
First emits aboutToClose(), then closes the device and sets its OpenMode to NotOpen.
virtual bool seek(qint64 pos)
For random-access devices, this function sets the current position to pos, returning true on success,...
virtual bool atEnd() const
Returns true if the current read and write position is at the end of the device (i....
virtual bool canReadLine() const
Returns true if a complete line of data can be read from the device; otherwise returns false.
\inmodule QtCore
Definition qmetaobject.h:19
static QMetaMethod fromSignal(PointerToMemberFunction signal)
\inmodule QtCore
Definition qobject.h:103
bool signalsBlocked() const noexcept
Returns true if signals are blocked; otherwise returns false.
Definition qobject.h:135
auto signal
Combined button and popup list for selecting options.
@ QueuedConnection
static bool is_tracked_signal(const QMetaMethod &signal)
Definition qbuffer.cpp:424
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
#define QT_CATCH(A)
#define QT_TRY
#define qWarning
Definition qlogging.h:166
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLuint GLenum GLsizei const GLchar * buf
GLbitfield flags
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLenum GLsizei len
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define emit
unsigned long long quint64
Definition qtypes.h:61
ptrdiff_t qsizetype
Definition qtypes.h:165
long long qint64
Definition qtypes.h:60
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(nullptr), QGenericArgument val1=QGenericArgument(), QGenericArgument val2=QGenericArgument(), QGenericArgument val3=QGenericArgument(), QGenericArgument val4=QGenericArgument(), QGenericArgument val5=QGenericArgument(), QGenericArgument val6=QGenericArgument(), QGenericArgument val7=QGenericArgument(), QGenericArgument val8=QGenericArgument(), QGenericArgument val9=QGenericArgument())
\threadsafe This is an overloaded member function, provided for convenience. It differs from the abov...