Qt 4.8
qnoncontiguousbytedevice.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
43 #include <qbuffer.h>
44 #include <qdebug.h>
45 #include <qfile.h>
46 
48 
162 {
163 }
164 
166 {
167 }
168 
170 {
171  resetDisabled = true;
172 }
173 
174 // FIXME we should scrap this whole implementation and instead change the ByteArrayImpl to be able to cope with sub-arrays?
176 {
177  buffer = b;
180  arrayImpl->setParent(this);
181  connect(arrayImpl, SIGNAL(readyRead()), SIGNAL(readyRead()));
183 }
184 
186 {
187 }
188 
190 {
191  return arrayImpl->readPointer(maximumLength, len);
192 }
193 
195 {
196  return arrayImpl->advanceReadPointer(amount);
197 }
198 
200 {
201  return arrayImpl->atEnd();
202 }
203 
205 {
206  if (resetDisabled)
207  return false;
208  return arrayImpl->reset();
209 }
210 
212 {
213  return arrayImpl->size();
214 }
215 
217 {
218  byteArray = ba;
219 }
220 
222 {
223 }
224 
226 {
227  if (atEnd()) {
228  len = -1;
229  return 0;
230  }
231 
232  if (maximumLength != -1)
233  len = qMin(maximumLength, size() - currentPosition);
234  else
235  len = size() - currentPosition;
236 
237  return byteArray->constData() + currentPosition;
238 }
239 
241 {
242  currentPosition += amount;
244  return true;
245 }
246 
248 {
249  return currentPosition >= size();
250 }
251 
253 {
254  if (resetDisabled)
255  return false;
256 
257  currentPosition = 0;
258  return true;
259 }
260 
262 {
263  return byteArray->size();
264 }
265 
268 {
269  ringBuffer = rb;
270 }
271 
273 {
274 }
275 
277 {
278  if (atEnd()) {
279  len = -1;
280  return 0;
281  }
282 
283  const char *returnValue = ringBuffer->readPointerAtPosition(currentPosition, len);
284 
285  if (maximumLength != -1)
286  len = qMin(len, maximumLength);
287 
288  return returnValue;
289 }
290 
292 {
293  currentPosition += amount;
295  return true;
296 }
297 
299 {
300  return currentPosition >= size();
301 }
302 
304 {
305  if (resetDisabled)
306  return false;
307 
308  currentPosition = 0;
309  return true;
310 }
311 
313 {
314  return ringBuffer->size();
315 }
316 
319  currentReadBuffer(0), currentReadBufferSize(16*1024),
320  currentReadBufferAmount(0), currentReadBufferPosition(0), totalAdvancements(0),
321  eof(false)
322 {
323  device = d;
324  initialPosition = d->pos();
326  connect(device, SIGNAL(readChannelFinished()), this, SIGNAL(readyRead()), Qt::QueuedConnection);
327 }
328 
330 {
331  delete currentReadBuffer;
332 }
333 
335 {
336  if (eof == true) {
337  len = -1;
338  return 0;
339  }
340 
341  if (currentReadBuffer == 0)
342  currentReadBuffer = new QByteArray(currentReadBufferSize, '\0'); // lazy alloc
343 
344  if (maximumLength == -1)
345  maximumLength = currentReadBufferSize;
346 
350  }
351 
352  qint64 haveRead = device->read(currentReadBuffer->data(), qMin(maximumLength, currentReadBufferSize));
353 
354  if ((haveRead == -1) || (haveRead == 0 && device->atEnd() && !device->isSequential())) {
355  eof = true;
356  len = -1;
357  // size was unknown before, emit a readProgress with the final size
358  if (size() == -1)
360  return 0;
361  }
362 
363  currentReadBufferAmount = haveRead;
365 
366  len = haveRead;
367  return currentReadBuffer->data();
368 }
369 
371 {
372  totalAdvancements += amount;
373 
374  // normal advancement
375  currentReadBufferPosition += amount;
376 
377  if (size() == -1)
379  else
381 
382  // advancing over that what has actually been read before
385  while (i > 0) {
386  if (device->getChar(0) == false) {
388  return false; // ### FIXME handle eof
389  }
390  i--;
391  }
392 
394  currentReadBufferAmount = 0;
395  }
396 
397 
398  return true;
399 }
400 
402 {
403  return eof == true;
404 }
405 
407 {
408  if (resetDisabled)
409  return false;
411  if (reset) {
412  eof = false; // assume eof is false, it will be true after a read has been attempted
413  totalAdvancements = 0; //reset the progress counter
414  if (currentReadBuffer) {
415  delete currentReadBuffer;
416  currentReadBuffer = 0;
417  }
420  return true;
421  }
422 
423  return false;
424 }
425 
427 {
428  // note that this is different from the size() implementation of QIODevice!
429 
430  if (device->isSequential())
431  return -1;
432 
433  return device->size() - initialPosition;
434 }
435 
437 {
438  byteDevice = bd;
440 
441  open(ReadOnly);
442 }
443 
445 {
446 
447 }
448 
450 {
451  return (byteDevice->size() == -1);
452 }
453 
455 {
456  return byteDevice->atEnd();
457 }
458 
460 {
461  return byteDevice->reset();
462 }
463 
465 {
466  if (isSequential())
467  return 0;
468 
469  return byteDevice->size();
470 }
471 
472 
474 {
475  qint64 len;
476  const char *readPointer = byteDevice->readPointer(maxSize, len);
477  if (len == -1)
478  return -1;
479 
480  memcpy(data, readPointer, len);
482  return len;
483 }
484 
486 {
487  Q_UNUSED(data);
488  Q_UNUSED(maxSize);
489  return -1;
490 }
491 
518 {
519  // shortcut if it is a QBuffer
520  if (QBuffer* buffer = qobject_cast<QBuffer*>(device)) {
521  return new QNonContiguousByteDeviceBufferImpl(buffer);
522  }
523 
524  // ### FIXME special case if device is a QFile that supports map()
525  // then we can actually deal with the file without using read/peek
526 
527  // generic QIODevice
528  return new QNonContiguousByteDeviceIoDeviceImpl(device); // FIXME
529 }
530 
537 {
538  return new QNonContiguousByteDeviceRingBufferImpl(ringBuffer);
539 }
540 
549 {
550  return new QNonContiguousByteDeviceByteArrayImpl(byteArray);
551 }
552 
561 {
562  // ### FIXME if it already has been based on QIoDevice, we could that one out again
563  // and save some calling
564 
565  // needed for FTP backend
566 
567  return new QByteDeviceWrappingIoDevice(byteDevice);
568 }
569 
571 
double d
Definition: qnumeric_p.h:62
virtual bool reset()=0
Moves the internal read pointer back to the beginning.
virtual qint64 size() const
For open random-access devices, this function returns the size of the device.
Definition: qiodevice.cpp:642
qint64 size()
Returns the size of the complete device or -1 if unknown.
void readyRead()
Emitted when there is data available.
Q_DECL_CONSTEXPR const T & qMin(const T &a, const T &b)
Definition: qglobal.h:1215
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
char * data()
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:429
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.e.
bool advanceReadPointer(qint64 amount)
The old readPointer is invalid after this call.
bool reset()
Moves the internal read pointer back to the beginning.
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
virtual qint64 pos() const
For random-access devices, this function returns the position that data is written to or read from...
Definition: qiodevice.cpp:624
QNonContiguousByteDevice * byteDevice
bool getChar(char *c)
Reads one character from the device and stores it in c.
Definition: qiodevice.cpp:1536
qint64 pos() const
Reimplemented Function
Definition: qbuffer.cpp:367
qint64 size() const
Reimplemented Function
Definition: qbuffer.cpp:375
The QBuffer class provides a QIODevice interface for a QByteArray.
Definition: qbuffer.h:57
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
virtual bool atEnd() const
Returns true if the current read and write position is at the end of the device (i.e.
Definition: qiodevice.cpp:711
QByteDeviceWrappingIoDevice(QNonContiguousByteDevice *bd)
virtual const char * readPointer(qint64 maximumLength, qint64 &len)=0
Return a byte pointer for at most maximumLength bytes of that device.
qint64 size()
Returns the size of the complete device or -1 if unknown.
qint64 read(char *data, qint64 maxlen)
Reads at most maxSize bytes from the device into data, and returns the number of bytes read...
Definition: qiodevice.cpp:791
bool atEnd()
Returns true if everything has been read and the read pointer cannot be advanced anymore.
#define SIGNAL(a)
Definition: qobjectdefs.h:227
void disableReset()
Disable the reset() call, e.
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
bool reset()
Moves the internal read pointer back to the beginning.
static bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
Creates a connection of the given type from the signal in the sender object to the method in the rece...
Definition: qobject.cpp:2580
QByteArray & buffer()
Returns a reference to the QBuffer&#39;s internal buffer.
Definition: qbuffer.cpp:271
#define emit
Definition: qobjectdefs.h:76
static QByteArray fromRawData(const char *, int size)
Constructs a QByteArray that uses the first size bytes of the data array.
bool advanceReadPointer(qint64 amount)
The old readPointer is invalid after this call.
static const char * data(const QByteArray &arr)
__int64 qint64
Definition: qglobal.h:942
bool atEnd()
Returns true if everything has been read and the read pointer cannot be advanced anymore.
const char * readPointer(qint64 maximumLength, qint64 &len)
Return a byte pointer for at most maximumLength bytes of that device.
virtual bool isSequential() const
Returns true if this device is sequential; otherwise returns false.
Definition: qiodevice.cpp:454
qint64 size()
Returns the size of the complete device or -1 if unknown.
void readProgress(qint64 current, qint64 total)
Emitted when data has been "read" by advancing the read pointer.
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
const char * readPointer(qint64 maximumLength, qint64 &len)
Return a byte pointer for at most maximumLength bytes of that device.
bool reset()
Moves the internal read pointer back to the beginning.
const char * readPointer(qint64 maximumLength, qint64 &len)
Return a byte pointer for at most maximumLength bytes of that device.
bool advanceReadPointer(qint64 amount)
The old readPointer is invalid after this call.
QNonContiguousByteDeviceByteArrayImpl * arrayImpl
virtual bool advanceReadPointer(qint64 amount)=0
The old readPointer is invalid after this call.
const char * readPointerAtPosition(qint64 pos, qint64 &length) const
Definition: qringbuffer_p.h:80
bool atEnd()
Returns true if everything has been read and the read pointer cannot be advanced anymore.
virtual bool isSequential() const
Returns true if this device is sequential; otherwise returns false.
virtual bool reset()
Seeks to the start of input for random-access devices.
Definition: qiodevice.cpp:732
virtual qint64 readData(char *data, qint64 maxSize)
Reads up to maxSize bytes from the device into data, and returns the number of bytes read or -1 if an...
static QIODevice * wrap(QNonContiguousByteDevice *byteDevice)
Wrap the byteDevice (possibly again) into a QIODevice.
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
static QNonContiguousByteDevice * create(QIODevice *device)
Create a QNonContiguousByteDevice out of a QIODevice.
virtual bool open(OpenMode mode)
Opens the device and sets its OpenMode to mode.
Definition: qiodevice.cpp:570
bool atEnd()
Returns true if everything has been read and the read pointer cannot be advanced anymore.
A QNonContiguousByteDevice is a representation of a file, array or buffer that allows access with a r...
bool reset()
Moves the internal read pointer back to the beginning.
QNonContiguousByteDeviceRingBufferImpl(QSharedPointer< QRingBuffer > rb)
virtual bool atEnd()=0
Returns true if everything has been read and the read pointer cannot be advanced anymore.
virtual qint64 size()=0
Returns the size of the complete device or -1 if unknown.
void readyRead()
This signal is emitted once every time new data is available for reading from the device...
The QIODevice class is the base interface class of all I/O devices in Qt.
Definition: qiodevice.h:66
virtual qint64 writeData(const char *data, qint64 maxSize)
Writes up to maxSize bytes from data to the device.
const char * readPointer(qint64 maximumLength, qint64 &len)
Return a byte pointer for at most maximumLength bytes of that device.
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
virtual bool seek(qint64 pos)
For random-access devices, this function sets the current position to pos, returning true on success...
Definition: qiodevice.cpp:659
qint64 size()
Returns the size of the complete device or -1 if unknown.
virtual qint64 size() const
For open random-access devices, this function returns the size of the device.
int size() const
bool advanceReadPointer(qint64 amount)
The old readPointer is invalid after this call.