Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qnoncontiguousbytedevice.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
5#include <qbuffer.h>
6#include <qdebug.h>
7#include <qfile.h>
8
10
95{
96}
97
99{
100}
101
102// FIXME we should scrap this whole implementation and instead change the ByteArrayImpl to be able to cope with sub-arrays?
104{
105 buffer = b;
106 byteArray = QByteArray::fromRawData(buffer->buffer().constData() + buffer->pos(), buffer->size() - buffer->pos());
108 arrayImpl->setParent(this);
111}
112
114{
115}
116
118{
119 return arrayImpl->readPointer(maximumLength, len);
120}
121
123{
124 return arrayImpl->advanceReadPointer(amount);
125}
126
128{
129 return arrayImpl->atEnd();
130}
131
133{
134 return arrayImpl->reset();
135}
136
138{
139 return arrayImpl->size();
140}
141
143{
144 byteArray = ba;
145}
146
148{
149}
150
152{
153 if (atEnd()) {
154 len = -1;
155 return nullptr;
156 }
157
158 if (maximumLength != -1)
159 len = qMin(maximumLength, size() - currentPosition);
160 else
162
164}
165
167{
168 currentPosition += amount;
170 return true;
171}
172
174{
175 return currentPosition >= size();
176}
177
179{
180 currentPosition = 0;
181 return true;
182}
183
185{
186 return byteArray->size();
187}
188
190{
191 return currentPosition;
192}
193
195 : QNonContiguousByteDevice(), ringBuffer(std::move(rb))
196{
197}
198
200{
201}
202
204{
205 if (atEnd()) {
206 len = -1;
207 return nullptr;
208 }
209
210 const char *returnValue = ringBuffer->readPointerAtPosition(currentPosition, len);
211
212 if (maximumLength != -1)
213 len = qMin(len, maximumLength);
214
215 return returnValue;
216}
217
219{
220 currentPosition += amount;
222 return true;
223}
224
226{
227 return currentPosition >= size();
228}
229
231{
232 return currentPosition;
233}
234
236{
237 currentPosition = 0;
238 return true;
239}
240
242{
243 return ringBuffer->size();
244}
245
248 currentReadBuffer(nullptr), currentReadBufferSize(16*1024),
249 currentReadBufferAmount(0), currentReadBufferPosition(0), totalAdvancements(0),
250 eof(false)
251{
252 device = d;
253 initialPosition = d->pos();
255 connect(device, SIGNAL(readChannelFinished()), this, SIGNAL(readyRead()), Qt::QueuedConnection);
256}
257
259{
260 delete currentReadBuffer;
261}
262
264{
265 if (eof == true) {
266 len = -1;
267 return nullptr;
268 }
269
270 if (currentReadBuffer == nullptr)
271 currentReadBuffer = new QByteArray(currentReadBufferSize, '\0'); // lazy alloc
272
273 if (maximumLength == -1)
274 maximumLength = currentReadBufferSize;
275
279 }
280
281 qint64 haveRead = device->read(currentReadBuffer->data(), qMin(maximumLength, currentReadBufferSize));
282
283 if ((haveRead == -1) || (haveRead == 0 && device->atEnd() && !device->isSequential())) {
284 eof = true;
285 len = -1;
286 // size was unknown before, emit a readProgress with the final size
287 if (size() == -1)
289 return nullptr;
290 }
291
292 currentReadBufferAmount = haveRead;
294
295 len = haveRead;
296 return currentReadBuffer->data();
297}
298
300{
301 totalAdvancements += amount;
302
303 // normal advancement
305
306 if (size() == -1)
308 else
310
311 // advancing over that what has actually been read before
314 while (i > 0) {
315 if (device->getChar(nullptr) == false) {
317 return false; // ### FIXME handle eof
318 }
319 i--;
320 }
321
324 }
325
326 return true;
327}
328
330{
331 return eof == true;
332}
333
335{
337 if (reset) {
338 eof = false; // assume eof is false, it will be true after a read has been attempted
339 totalAdvancements = 0; // reset the progress counter
340 if (currentReadBuffer) {
341 delete currentReadBuffer;
342 currentReadBuffer = nullptr;
343 }
346 return true;
347 }
348
349 return false;
350}
351
353{
354 // note that this is different from the size() implementation of QIODevice!
355
356 if (device->isSequential())
357 return -1;
358
359 return device->size() - initialPosition;
360}
361
363{
364 if (device->isSequential())
365 return -1;
366
367 return device->pos();
368}
369
371{
372 byteDevice = bd;
374
375 open(ReadOnly);
376}
377
379{
380
381}
382
384{
385 return (byteDevice->size() == -1);
386}
387
389{
390 return byteDevice->atEnd();
391}
392
394{
395 return byteDevice->reset();
396}
397
399{
400 if (isSequential())
401 return 0;
402
403 return byteDevice->size();
404}
405
407{
408 qint64 len;
409 const char *readPointer = byteDevice->readPointer(maxSize, len);
410 if (len == -1)
411 return -1;
412
413 memcpy(data, readPointer, len);
415 return len;
416}
417
419{
420 Q_UNUSED(data);
421 Q_UNUSED(maxSize);
422 return -1;
423}
424
447{
448 // shortcut if it is a QBuffer
449 if (QBuffer *buffer = qobject_cast<QBuffer *>(device)) {
451 }
452
453 // ### FIXME special case if device is a QFile that supports map()
454 // then we can actually deal with the file without using read/peek
455
456 // generic QIODevice
457 return new QNonContiguousByteDeviceIoDeviceImpl(device); // FIXME
458}
459
466std::shared_ptr<QNonContiguousByteDevice> QNonContiguousByteDeviceFactory::createShared(QIODevice *device)
467{
468 // shortcut if it is a QBuffer
469 if (QBuffer *buffer = qobject_cast<QBuffer*>(device))
470 return std::make_shared<QNonContiguousByteDeviceBufferImpl>(buffer);
471
472 // ### FIXME special case if device is a QFile that supports map()
473 // then we can actually deal with the file without using read/peek
474
475 // generic QIODevice
476 return std::make_shared<QNonContiguousByteDeviceIoDeviceImpl>(device); // FIXME
477}
478
487{
488 return new QNonContiguousByteDeviceRingBufferImpl(ringBuffer);
489}
490
496std::shared_ptr<QNonContiguousByteDevice> QNonContiguousByteDeviceFactory::createShared(std::shared_ptr<QRingBuffer> ringBuffer)
497{
498 return std::make_shared<QNonContiguousByteDeviceRingBufferImpl>(std::move(ringBuffer));
499}
500
509{
510 return new QNonContiguousByteDeviceByteArrayImpl(byteArray);
511}
512
518std::shared_ptr<QNonContiguousByteDevice> QNonContiguousByteDeviceFactory::createShared(QByteArray *byteArray)
519{
520 return std::make_shared<QNonContiguousByteDeviceByteArrayImpl>(byteArray);
521}
522
531{
532 // ### FIXME if it already has been based on QIoDevice, we could that one out again
533 // and save some calling
534
535 // needed for FTP backend
536
537 return new QByteDeviceWrappingIoDevice(byteDevice);
538}
539
541
542#include "moc_qnoncontiguousbytedevice_p.cpp"
IOBluetoothDevice * device
\inmodule QtCore \reentrant
Definition qbuffer.h:16
\inmodule QtCore
Definition qbytearray.h:57
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
Definition qbytearray.h:534
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
Definition qbytearray.h:474
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:122
static QByteArray fromRawData(const char *data, qsizetype size)
Constructs a QByteArray that uses the first size bytes of the data array.
Definition qbytearray.h:394
QNonContiguousByteDevice * byteDevice
qint64 readData(char *data, qint64 maxSize) override
Reads up to maxSize bytes from the device into data, and returns the number of bytes read or -1 if an...
qint64 size() const override
For open random-access devices, this function returns the size of the device.
QByteDeviceWrappingIoDevice(QNonContiguousByteDevice *bd)
bool isSequential() const override
Returns true if this device is sequential; otherwise returns false.
bool atEnd() const override
Returns true if the current read and write position is at the end of the device (i....
bool reset() override
Seeks to the start of input for random-access devices.
qint64 writeData(const char *data, qint64 maxSize) override
Writes up to maxSize bytes from data to the device.
\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 size() const
For open random-access devices, this function returns the size of the device.
virtual qint64 pos() const
For random-access devices, this function returns the position that data is written to or read from.
virtual bool isSequential() const
Returns true if this device is sequential; otherwise returns false.
bool getChar(char *c)
Reads one character from the device and stores it in c.
virtual bool seek(qint64 pos)
For random-access devices, this function sets the current position to pos, returning true on success,...
virtual bool reset()
Seeks to the start of input for random-access devices.
virtual bool atEnd() const
Returns true if the current read and write position is at the end of the device (i....
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read.
QNonContiguousByteDeviceByteArrayImpl * arrayImpl
bool advanceReadPointer(qint64 amount) override
will advance the internal read pointer by amount bytes.
bool reset() override
Moves the internal read pointer back to the beginning.
const char * readPointer(qint64 maximumLength, qint64 &len) override
Return a byte pointer for at most maximumLength bytes of that device.
bool atEnd() const override
Returns true if everything has been read and the read pointer cannot be advanced anymore.
qint64 size() const override
Returns the size of the complete device or -1 if unknown.
bool reset() override
Moves the internal read pointer back to the beginning.
qint64 size() const override
Returns the size of the complete device or -1 if unknown.
bool advanceReadPointer(qint64 amount) override
will advance the internal read pointer by amount bytes.
const char * readPointer(qint64 maximumLength, qint64 &len) override
Return a byte pointer for at most maximumLength bytes of that device.
bool atEnd() const override
Returns true if everything has been read and the read pointer cannot be advanced anymore.
static QNonContiguousByteDevice * create(QIODevice *device)
Create a QNonContiguousByteDevice out of a QIODevice.
static std::shared_ptr< QNonContiguousByteDevice > createShared(QIODevice *device)
Create a QNonContiguousByteDevice out of a QIODevice, return it in a std::shared_ptr.
static QIODevice * wrap(QNonContiguousByteDevice *byteDevice)
Wrap the byteDevice (possibly again) into a QIODevice.
bool atEnd() const override
Returns true if everything has been read and the read pointer cannot be advanced anymore.
qint64 size() const override
Returns the size of the complete device or -1 if unknown.
bool advanceReadPointer(qint64 amount) override
will advance the internal read pointer by amount bytes.
bool reset() override
Moves the internal read pointer back to the beginning.
const char * readPointer(qint64 maximumLength, qint64 &len) override
Return a byte pointer for at most maximumLength bytes of that device.
qint64 size() const override
Returns the size of the complete device or -1 if unknown.
bool atEnd() const override
Returns true if everything has been read and the read pointer cannot be advanced anymore.
bool advanceReadPointer(qint64 amount) override
will advance the internal read pointer by amount bytes.
bool reset() override
Moves the internal read pointer back to the beginning.
const char * readPointer(qint64 maximumLength, qint64 &len) override
Return a byte pointer for at most maximumLength bytes of that device.
QNonContiguousByteDeviceRingBufferImpl(std::shared_ptr< QRingBuffer > rb)
virtual const char * readPointer(qint64 maximumLength, qint64 &len)=0
Return a byte pointer for at most maximumLength bytes of that device.
virtual qint64 size() const =0
Returns the size of the complete device or -1 if unknown.
virtual bool advanceReadPointer(qint64 amount)=0
will advance the internal read pointer by amount bytes.
virtual bool reset()=0
Moves the internal read pointer back to the beginning.
void readyRead()
Emitted when there is data available.
void readProgress(qint64 current, qint64 total)
Emitted when data has been "read" by advancing the read pointer.
virtual bool atEnd() const =0
Returns true if everything has been read and the read pointer cannot be advanced anymore.
\inmodule QtCore
Definition qobject.h:90
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
void setParent(QObject *parent)
Makes the object a child of parent.
Definition qobject.cpp:2142
Combined button and popup list for selecting options.
@ QueuedConnection
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
#define SIGNAL(a)
Definition qobjectdefs.h:52
GLboolean GLboolean GLboolean b
GLenum GLuint buffer
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLboolean reset
GLenum GLsizei len
#define emit
#define Q_UNUSED(x)
long long qint64
Definition qtypes.h:55
QByteArray ba
[0]
QObject::connect nullptr