Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qiopipe.cpp
Go to the documentation of this file.
1// Copyright (C) 2019 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 "qiopipe_p.h"
5#include <QtCore/qmetaobject.h>
6#include <QDebug>
7
9
10/*
11 proxying means do *not* emit readyRead, and instead pump data
12 into child pipes directly in a zero-copy fashion.
13*/
15 : m_proxying(proxying), source(iodevice)
16{
17}
18
22
24{
25 const QIOPipe *parentPipe = qobject_cast<QIOPipe *>(source);
26 if (parentPipe && parentPipe->d_func()->m_proxying) // with proxying parent,
27 return; // don't do anything
28
29 // read available data, does not emit.
31 // connect readyRead to onReadyRead
32 QObjectPrivate::connect(source, &QIODevice::readyRead, this, &QIOPipePrivate::_q_onReadyRead);
33}
34
36 if (!source)
37 return false;
38 QByteArray ba = source->readAll();
39 if (ba.isEmpty())
40 return false;
41
42 pumpData(ba);
43 return true;
44}
45
46void QIOPipePrivate::pumpData(const QByteArray &ba)
47{
48 if (m_proxying) {
49 auto isNull = [](const auto &cp) { return cp == nullptr; };
50 childPipes.removeIf(isNull);
51 for (const auto &cp : std::as_const(childPipes))
52 cp->d_func()->pushData(ba);
53 } else {
54 for (auto &buffer : readBuffers)
55 buffer.append(ba);
56 }
57}
58
59void QIOPipePrivate::pushData(const QByteArray &ba)
60{
61 Q_Q(QIOPipe);
62 if (ba.isEmpty())
63 return;
64
65 pumpData(ba);
66 if (!m_proxying)
67 emit q->readyRead();
68}
69
71{
72 Q_Q(QIOPipe);
74 emit q->readyRead();
75}
76
77void QIOPipePrivate::addChildPipe(QIOPipe *childPipe)
78{
79 if (childPipes.contains(childPipe))
80 return;
81 childPipes.append(childPipe);
82}
83
84void QIOPipePrivate::removeChildPipe(QIOPipe *childPipe)
85{
86 childPipes.removeOne(childPipe);
87}
88
89QIOPipe::QIOPipe(QIODevice *parent, Mode mode)
91{
92 this->d_func()->initialize();
93 if (!parent->isOpen() && !parent->open(QIODevice::ReadOnly)) {
94 qWarning() << "QIOPipe: Failed to open " << parent;
95 return;
96 }
97 open(ReadOnly);
98}
99
101{
102
103}
104
105bool QIOPipe::open(QIODevice::OpenMode mode)
106{
107 if (isOpen())
108 return true;
109
110 static const OpenMode supportedOpenMode = ReadOnly; // Currently limit it to read only
111 if (!(mode & supportedOpenMode)) {
112 qFatal("Unsupported open mode");
113 return false;
114 }
115
116 return QIODevice::open(mode);
117}
118
120{
121 return true;
122}
123
125{
126 Q_D(QIOPipe);
127 d->setReadChannelCount(qMax(count, 1));
128}
129
130void QIOPipe::addChildPipe(QIOPipe *childPipe)
131{
132 Q_D(QIOPipe);
133 d->addChildPipe(childPipe);
134}
135
136/*!
137 \reimp
138
139 \omit
140 This function does not really read anything, as we use QIODevicePrivate's
141 buffer. The buffer will be read inside of QIODevice before this
142 method will be called.
143 See QIODevicePrivate::read, buffer.read(data, maxSize).
144 \endomit
145*/
146qint64 QIOPipe::readData(char *data, qint64 maxlen)
147{
148 Q_UNUSED(data);
149 Q_UNUSED(maxlen);
150
151 // return 0 indicating there may be more data in the future
152 // Returning -1 means no more data in the future (end of stream).
153 return qint64(0);
154}
155
156qint64 QIOPipe::writeData(const char * /*data*/, qint64 /*len*/)
157{
158 qFatal("QIOPipe is a read-only device");
159 return qint64(0);
160}
161
162QT_END_NAMESPACE
163
164#include "moc_qiopipe_p.cpp"
\inmodule QtCore \reentrant
Definition qiodevice.h:38
void _q_onReadyRead()
Definition qiopipe.cpp:70
~QIOPipePrivate() override
Definition qiopipe.cpp:19
void pumpData(const QByteArray &ba)
Definition qiopipe.cpp:46
void pushData(const QByteArray &ba)
Definition qiopipe.cpp:59
bool readAvailableData()
Definition qiopipe.cpp:35
void initialize()
Definition qiopipe.cpp:23
QIOPipe(QIODevice *parent, Mode mode=EndPipe)
Definition qiopipe.cpp:89
qint64 readData(char *data, qint64 maxlen) override
\reimp
Definition qiopipe.cpp:146
~QIOPipe() override
Definition qiopipe.cpp:100
bool isSequential() const override
Returns true if this device is sequential; otherwise returns false.
Definition qiopipe.cpp:119
void setReadChannelCount(int count)
Definition qiopipe.cpp:124
bool open(OpenMode openMode) override
Definition qiopipe.cpp:105
void addChildPipe(QIOPipe *childPipe)
Definition qiopipe.cpp:130
qint64 writeData(const char *data, qint64 len) override
Writes up to maxSize bytes from data to the device.
Definition qiopipe.cpp:156