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