1 /****************************************************************************
3 ** Copyright (C) Qxt Foundation. Some rights reserved.
5 ** This file is part of the QxtCore module of the Qt eXTension library
7 ** This library is free software; you can redistribute it and/or modify it
8 ** under the terms of th Common Public License, version 1.0, as published by
11 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
12 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
13 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
14 ** FITNESS FOR A PARTICULAR PURPOSE.
16 ** You should have received a copy of the CPL along with this file.
17 ** See the LICENSE file and the cpl1.0.txt file included with the source
18 ** distribution for more information. If you did not receive a copy of the
19 ** license, contact the Qxt Foundation.
21 ** <http://libqxt.sourceforge.net> <foundation@libqxt.org>
23 ****************************************************************************/
28 #include <QMutableListIterator>
31 * \class QxtPipe QxtPipe
33 * \brief a pipeable QIODevice
35 * pipes can be connected to other pipes, to exchange data \n
36 * The default implementation uses a buffer. \n
37 * Reimplement to make your custom class able to be connected into a pipe chain. \n
44 * p1.write("hello world");
45 * qDebug()<<p2.readAll();
53 QIODevice::OpenMode mode;
54 Qt::ConnectionType connectionType;
57 class QxtPipePrivate:public QxtPrivate<QxtPipe>
61 QList<Connection> connections;
65 * Contructs a new QxtPipe.
67 QxtPipe::QxtPipe(QObject * parent):QIODevice(parent)
69 setOpenMode (QIODevice::ReadWrite);
73 /** reimplemented from QIODevice*/
74 bool QxtPipe::isSequential () const
79 /** reimplemented from QIODevice*/
80 qint64 QxtPipe::bytesAvailable () const
82 return qxt_d().q.count();
86 * pipes the output of this instance to the \p other QxtPipe using the given mode and connectiontype \n
87 * connection pipes with this function can be considered thread safe \n
93 p1.connect(&p2,QIODevice::ReadOnly);
95 ///this data will go nowhere. p2 is connected to p1, but not p2 to p1.
98 ///while this data will end up in p1
101 qDebug()<<p1.readAll();
106 bool QxtPipe::connect (QxtPipe * other ,QIODevice::OpenMode mode,Qt::ConnectionType connectionType)
109 ///tell the other pipe to write into this
110 if(mode & QIODevice::ReadOnly)
112 other->connect(this,QIODevice::WriteOnly,connectionType);
119 c.connectionType=connectionType;
120 qxt_d().connections.append(c);
126 * cuts the pipe to the \p other QxtPipe
128 bool QxtPipe::disconnect (QxtPipe * other )
132 QMutableListIterator<Connection> i(qxt_d().connections);
136 if(i.value().pipe==other)
140 other->disconnect(this);
148 * convinence function for QxtPipe::connect.
149 * pipes the output of this instance to the \p other QxtPipe in readwrite mode with autoconnection
151 QxtPipe & QxtPipe::operator | ( QxtPipe & target)
157 /** reimplemented from QIODevice*/
158 qint64 QxtPipe::readData ( char * data, qint64 maxSize )
160 QQueue<char> * q=&qxt_d().q;
167 (*data++)=q->dequeue();
172 /** reimplemented from QIODevice*/
173 qint64 QxtPipe::writeData ( const char * data, qint64 maxSize )
175 foreach(Connection c,qxt_d().connections)
178 if(!(c.mode & QIODevice::WriteOnly))
181 //we want thread safety, so we use a QByteArray instead of the raw data. that migth be slow
182 QMetaObject::invokeMethod(c.pipe, "receiveData",c.connectionType,
183 Q_ARG(QByteArray, data),Q_ARG(QxtPipe *,this));
191 receiveData is called from any connected pipe to input data into this instance.
193 qint64 QxtPipe::receiveData (QByteArray datab ,QxtPipe * sender)
195 QQueue<char> * q=&qxt_d().q;
197 const char * data =datab.constData();
198 qint64 maxSize =datab.size();
205 foreach(Connection c,qxt_d().connections)
208 //don't write back to sender
212 if(!(c.mode & QIODevice::WriteOnly))
216 QMetaObject::invokeMethod(c.pipe, "receiveData",c.connectionType,
217 Q_ARG(QByteArray, datab),Q_ARG(QxtPipe *,this));