Qt 4.8
qbuffer.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 
42 #include "qbuffer.h"
43 #include "private/qiodevice_p.h"
44 
46 
49 {
51 
52 public:
54  : buf(0)
55 #ifndef QT_NO_QOBJECT
57 #endif
58  { }
60 
63  int ioIndex;
64 
65  virtual qint64 peek(char *data, qint64 maxSize);
66  virtual QByteArray peek(qint64 maxSize);
67 
68 #ifndef QT_NO_QOBJECT
69  // private slots
70  void _q_emitSignals();
71 
75 #endif
76 };
77 
78 #ifndef QT_NO_QOBJECT
80 {
81  Q_Q(QBuffer);
82  emit q->bytesWritten(writtenSinceLastEmit);
84  emit q->readyRead();
85  signalsEmitted = false;
86 }
87 #endif
88 
90 {
91  qint64 readBytes = qMin(maxSize, static_cast<qint64>(buf->size()) - pos);
92  memcpy(data, buf->constData() + pos, readBytes);
93  return readBytes;
94 }
95 
97 {
98  qint64 readBytes = qMin(maxSize, static_cast<qint64>(buf->size()) - pos);
99  if (pos == 0 && maxSize >= buf->size())
100  return *buf;
101  return QByteArray(buf->constData() + pos, readBytes);
102 }
103 
159 #ifdef QT_NO_QOBJECT
161  : QIODevice(*new QBufferPrivate)
162 {
163  Q_D(QBuffer);
164  d->buf = &d->defaultBuf;
165  d->ioIndex = 0;
166 }
168  : QIODevice(*new QBufferPrivate)
169 {
170  Q_D(QBuffer);
171  d->buf = buf ? buf : &d->defaultBuf;
172  d->ioIndex = 0;
173  d->defaultBuf.clear();
174 }
175 #else
176 
184  : QIODevice(*new QBufferPrivate, parent)
185 {
186  Q_D(QBuffer);
187  d->buf = &d->defaultBuf;
188  d->ioIndex = 0;
189 }
190 
209  : QIODevice(*new QBufferPrivate, parent)
210 {
211  Q_D(QBuffer);
212  d->buf = byteArray ? byteArray : &d->defaultBuf;
213  d->defaultBuf.clear();
214  d->ioIndex = 0;
215 }
216 #endif
217 
223 {
224 }
225 
249 {
250  Q_D(QBuffer);
251  if (isOpen()) {
252  qWarning("QBuffer::setBuffer: Buffer is open");
253  return;
254  }
255  if (byteArray) {
256  d->buf = byteArray;
257  } else {
258  d->buf = &d->defaultBuf;
259  }
260  d->defaultBuf.clear();
261  d->ioIndex = 0;
262 }
263 
272 {
273  Q_D(QBuffer);
274  return *d->buf;
275 }
276 
287 {
288  Q_D(const QBuffer);
289  return *d->buf;
290 }
291 
292 
301 const QByteArray &QBuffer::data() const
302 {
303  Q_D(const QBuffer);
304  return *d->buf;
305 }
306 
316 {
317  Q_D(QBuffer);
318  if (isOpen()) {
319  qWarning("QBuffer::setData: Buffer is open");
320  return;
321  }
322  *d->buf = data;
323  d->ioIndex = 0;
324 }
325 
338 bool QBuffer::open(OpenMode flags)
339 {
340  Q_D(QBuffer);
341 
342  if ((flags & (Append | Truncate)) != 0)
343  flags |= WriteOnly;
344  if ((flags & (ReadOnly | WriteOnly)) == 0) {
345  qWarning("QBuffer::open: Buffer access not specified");
346  return false;
347  }
348 
349  if ((flags & Truncate) == Truncate)
350  d->buf->resize(0);
351  d->ioIndex = (flags & Append) == Append ? d->buf->size() : 0;
352 
353  return QIODevice::open(flags);
354 }
355 
360 {
362 }
363 
368 {
369  return QIODevice::pos();
370 }
371 
376 {
377  Q_D(const QBuffer);
378  return qint64(d->buf->size());
379 }
380 
385 {
386  Q_D(QBuffer);
387  if (pos > d->buf->size() && isWritable()) {
388  if (seek(d->buf->size())) {
389  const qint64 gapSize = pos - d->buf->size();
390  if (write(QByteArray(gapSize, 0)) != gapSize) {
391  qWarning("QBuffer::seek: Unable to fill gap");
392  return false;
393  }
394  } else {
395  return false;
396  }
397  } else if (pos > d->buf->size() || pos < 0) {
398  qWarning("QBuffer::seek: Invalid pos: %d", int(pos));
399  return false;
400  }
401  d->ioIndex = int(pos);
402  return QIODevice::seek(pos);
403 }
404 
408 bool QBuffer::atEnd() const
409 {
410  return QIODevice::atEnd();
411 }
412 
417 {
418  Q_D(const QBuffer);
419  if (!isOpen())
420  return false;
421 
422  return d->buf->indexOf('\n', int(pos())) != -1 || QIODevice::canReadLine();
423 }
424 
429 {
430  Q_D(QBuffer);
431  if ((len = qMin(len, qint64(d->buf->size()) - d->ioIndex)) <= 0)
432  return qint64(0);
433  memcpy(data, d->buf->constData() + d->ioIndex, len);
434  d->ioIndex += int(len);
435  return len;
436 }
437 
442 {
443  Q_D(QBuffer);
444  int extraBytes = d->ioIndex + len - d->buf->size();
445  if (extraBytes > 0) { // overflow
446  int newSize = d->buf->size() + extraBytes;
447  d->buf->resize(newSize);
448  if (d->buf->size() != newSize) { // could not resize
449  qWarning("QBuffer::writeData: Memory allocation error");
450  return -1;
451  }
452  }
453 
454  memcpy(d->buf->data() + d->ioIndex, (uchar *)data, int(len));
455  d->ioIndex += int(len);
456 
457 #ifndef QT_NO_QOBJECT
458  d->writtenSinceLastEmit += len;
459  if (d->signalConnectionCount && !d->signalsEmitted && !signalsBlocked()) {
460  d->signalsEmitted = true;
461  QMetaObject::invokeMethod(this, "_q_emitSignals", Qt::QueuedConnection);
462  }
463 #endif
464  return len;
465 }
466 
467 #ifndef QT_NO_QOBJECT
468 
472 void QBuffer::connectNotify(const char *signal)
473 {
474  if (strcmp(signal + 1, "readyRead()") == 0 || strcmp(signal + 1, "bytesWritten(qint64)") == 0)
475  d_func()->signalConnectionCount++;
476 }
477 
482 void QBuffer::disconnectNotify(const char *signal)
483 {
484  if (!signal || strcmp(signal + 1, "readyRead()") == 0 || strcmp(signal + 1, "bytesWritten(qint64)") == 0)
485  d_func()->signalConnectionCount--;
486 }
487 #endif
488 
490 
491 #ifndef QT_NO_QOBJECT
492 # include "moc_qbuffer.cpp"
493 #endif
494 
double d
Definition: qnumeric_p.h:62
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
const QByteArray & data() const
Returns the data contained in the buffer.
Definition: qbuffer.cpp:301
bool isWritable() const
Returns true if data can be written to the device; otherwise returns false.
Definition: qiodevice.cpp:558
void _q_emitSignals()
Definition: qbuffer.cpp:79
virtual void close()
First emits aboutToClose(), then closes the device and sets its OpenMode to NotOpen.
Definition: qiodevice.cpp:590
void setData(const QByteArray &data)
Sets the contents of the internal buffer to be data.
Definition: qbuffer.cpp:315
bool open(OpenMode openMode)
Reimplemented Function
Definition: qbuffer.cpp:338
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
void close()
Reimplemented Function
Definition: qbuffer.cpp:359
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
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
void setBuffer(QByteArray *a)
Makes QBuffer uses the QByteArray pointed to by byteArray as its internal buffer. ...
Definition: qbuffer.cpp:248
#define Q_D(Class)
Definition: qglobal.h:2482
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
bool canReadLine() const
Reimplemented Function
Definition: qbuffer.cpp:416
bool seek(qint64 off)
Reimplemented Function
Definition: qbuffer.cpp:384
#define Q_Q(Class)
Definition: qglobal.h:2483
virtual qint64 peek(char *data, qint64 maxSize)
Definition: qbuffer.cpp:89
unsigned char uchar
Definition: qglobal.h:994
QBuffer(QObject *parent=0)
Constructs an empty buffer with the given parent.
Definition: qbuffer.cpp:183
bool atEnd() const
Reimplemented Function
Definition: qbuffer.cpp:408
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
bool isOpen() const
Returns true if the device is open; otherwise returns false.
Definition: qiodevice.cpp:530
QByteArray & buffer()
Returns a reference to the QBuffer&#39;s internal buffer.
Definition: qbuffer.cpp:271
#define emit
Definition: qobjectdefs.h:76
QByteArray defaultBuf
Definition: qbuffer.cpp:62
Q_CORE_EXPORT void qWarning(const char *,...)
static const char * data(const QByteArray &arr)
__int64 qint64
Definition: qglobal.h:942
~QBuffer()
Destroys the buffer.
Definition: qbuffer.cpp:222
qint64 readData(char *data, qint64 maxlen)
Reimplemented Function
Definition: qbuffer.cpp:428
QByteArray * buf
Definition: qbuffer.cpp:61
void connectNotify(const char *)
Reimplemented Function
Definition: qbuffer.cpp:472
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
#define Q_DECLARE_PUBLIC(Class)
Definition: qglobal.h:2477
int signalConnectionCount
Definition: qbuffer.cpp:73
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
qint64 writtenSinceLastEmit
Definition: qbuffer.cpp:72
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
virtual bool open(OpenMode mode)
Opens the device and sets its OpenMode to mode.
Definition: qiodevice.cpp:570
QObject * parent
Definition: qobject.h:92
static bool invokeMethod(QObject *obj, const char *member, Qt::ConnectionType, QGenericReturnArgument ret, QGenericArgument val0=QGenericArgument(0), 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())
Invokes the member (a signal or a slot name) on the object obj.
void disconnectNotify(const char *)
Reimplemented Function
Definition: qbuffer.cpp:482
virtual bool canReadLine() const
Returns true if a complete line of data can be read from the device; otherwise returns false...
Definition: qiodevice.cpp:1330
bool signalsEmitted
Definition: qbuffer.cpp:74
bool signalsBlocked() const
Returns true if signals are blocked; otherwise returns false.
Definition: qobject.h:148
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
Definition: qiodevice.cpp:1342
The QIODevice class is the base interface class of all I/O devices in Qt.
Definition: qiodevice.h:66
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 writeData(const char *data, qint64 len)
Reimplemented Function
Definition: qbuffer.cpp:441