Qt 6.x
The Qt SDK
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
135{
136 Q_D(QBuffer);
137 d->buf = &d->defaultBuf;
138}
139
159{
160 Q_D(QBuffer);
161 d->buf = byteArray ? byteArray : &d->defaultBuf;
162 d->defaultBuf.clear();
163}
164#endif
165
171{
172}
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->replace(qsizetype(0), d->buf->size(), // ### QByteArray lacks assign(ptr, n)
286 data, size);
287}
288
296bool QBuffer::open(OpenMode flags)
297{
298 Q_D(QBuffer);
299
300 if ((flags & (Append | Truncate)) != 0)
301 flags |= WriteOnly;
302 if ((flags & (ReadOnly | WriteOnly)) == 0) {
303 qWarning("QBuffer::open: Buffer access not specified");
304 return false;
305 }
306
307 if ((flags & Truncate) == Truncate)
308 d->buf->resize(0);
309
311}
312
317{
319}
320
325{
326 return QIODevice::pos();
327}
328
333{
334 Q_D(const QBuffer);
335 return qint64(d->buf->size());
336}
337
342{
343 Q_D(QBuffer);
344 const auto oldBufSize = d->buf->size();
345 constexpr qint64 MaxSeekPos = (std::numeric_limits<decltype(oldBufSize)>::max)();
346 if (pos <= MaxSeekPos && pos > oldBufSize && isWritable()) {
347 QT_TRY {
348 d->buf->resize(qsizetype(pos), '\0');
349 } QT_CATCH(const std::bad_alloc &) {} // swallow, failure case is handled below
350 if (d->buf->size() != pos) {
351 qWarning("QBuffer::seek: Unable to fill gap");
352 return false;
353 }
354 }
355 if (pos > d->buf->size() || pos < 0) {
356 qWarning("QBuffer::seek: Invalid pos: %lld", pos);
357 return false;
358 }
359 return QIODevice::seek(pos);
360}
361
365bool QBuffer::atEnd() const
366{
367 return QIODevice::atEnd();
368}
369
374{
375 Q_D(const QBuffer);
376 if (!isOpen())
377 return false;
378
379 return d->buf->indexOf('\n', int(pos())) != -1 || QIODevice::canReadLine();
380}
381
386{
387 Q_D(QBuffer);
388 if ((len = qMin(len, qint64(d->buf->size()) - pos())) <= 0)
389 return qint64(0);
390 memcpy(data, d->buf->constData() + pos(), len);
391 return len;
392}
393
398{
399 Q_D(QBuffer);
400 const quint64 required = quint64(pos()) + quint64(len); // cannot overflow (pos() ≥ 0, len ≥ 0)
401
402 if (required > quint64(d->buf->size())) { // capacity exceeded
403 // The following must hold, since qsizetype covers half the virtual address space:
404 Q_ASSUME(required <= quint64((std::numeric_limits<qsizetype>::max)()));
405 d->buf->resize(qsizetype(required));
406 if (quint64(d->buf->size()) != required) { // could not resize
407 qWarning("QBuffer::writeData: Memory allocation error");
408 return -1;
409 }
410 }
411
412 memcpy(d->buf->data() + pos(), data, size_t(len));
413
414#ifndef QT_NO_QOBJECT
415 d->writtenSinceLastEmit += len;
416 if (d->signalConnectionCount && !d->signalsEmitted && !signalsBlocked()) {
417 d->signalsEmitted = true;
418 QMetaObject::invokeMethod(this, "_q_emitSignals", Qt::QueuedConnection);
419 }
420#endif
421 return len;
422}
423
424#ifndef QT_NO_QOBJECT
426{
427 // dynamic initialization: minimize the number of guard variables:
428 static const struct {
431 } sigs;
432 return signal == sigs.readyReadSignal || signal == sigs.bytesWrittenSignal;
433}
439{
441 d_func()->signalConnectionCount++;
442}
443
449{
450 if (signal.isValid()) {
452 d_func()->signalConnectionCount--;
453 } else {
454 d_func()->signalConnectionCount = 0;
455 }
456}
457#endif
458
460
461#ifndef QT_NO_QOBJECT
462# include "moc_qbuffer.cpp"
463#endif
464
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:397
void disconnectNotify(const QMetaMethod &) override
\reimp
Definition qbuffer.cpp:448
~QBuffer()
Destroys the buffer.
Definition qbuffer.cpp:170
bool open(OpenMode openMode) override
\reimp
Definition qbuffer.cpp:296
void connectNotify(const QMetaMethod &) override
\reimp
Definition qbuffer.cpp:438
qint64 pos() const override
\reimp
Definition qbuffer.cpp:324
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:365
void close() override
\reimp
Definition qbuffer.cpp:316
qint64 readData(char *data, qint64 maxlen) override
\reimp
Definition qbuffer.cpp:385
qint64 size() const override
\reimp
Definition qbuffer.cpp:332
bool canReadLine() const override
\reimp
Definition qbuffer.cpp:373
bool seek(qint64 off) override
\reimp
Definition qbuffer.cpp:341
QByteArray & buffer()
Returns a reference to the QBuffer's internal buffer.
Definition qbuffer.cpp:218
\inmodule QtCore
Definition qbytearray.h:57
\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:18
static QMetaMethod fromSignal(PointerToMemberFunction signal)
\inmodule QtCore
Definition qobject.h:90
bool signalsBlocked() const noexcept
Returns true if signals are blocked; otherwise returns false.
Definition qobject.h:122
auto signal
Combined button and popup list for selecting options.
@ QueuedConnection
static bool is_tracked_signal(const QMetaMethod &signal)
Definition qbuffer.cpp:425
#define QT_CATCH(A)
#define QT_TRY
#define qWarning
Definition qlogging.h:162
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei const GLchar * buf
GLbitfield flags
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum GLsizei len
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
#define emit
unsigned long long quint64
Definition qtypes.h:56
ptrdiff_t qsizetype
Definition qtypes.h:70
long long qint64
Definition qtypes.h:55
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...
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent