File indexing completed on 2025-04-27 07:40:56
0001 /* 0002 SPDX-FileCopyrightText: 2006-2009 Sebastian Trueg <trueg@k3b.org> 0003 SPDX-FileCopyrightText: 1998-2009 Sebastian Trueg <trueg@k3b.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "k3bactivepipe.h" 0009 0010 #include <QDebug> 0011 #include <QIODevice> 0012 #include <QThread> 0013 0014 0015 class K3b::ActivePipe::Private : public QThread 0016 { 0017 public: 0018 Private( K3b::ActivePipe* pipe ) : 0019 m_pipe( pipe ), 0020 sourceIODevice(0), 0021 sinkIODevice(0), 0022 closeSinkIODevice( false ), 0023 closeSourceIODevice( false ) { 0024 } 0025 0026 void run() override { 0027 qDebug() << "(K3b::ActivePipe) writing from" << sourceIODevice << "to" << sinkIODevice; 0028 0029 bytesRead = bytesWritten = 0; 0030 buffer.resize( 10*2048 ); 0031 0032 bool fail = false; 0033 qint64 r = 0; 0034 while( !fail && ( r = m_pipe->readData( buffer.data(), buffer.size() ) ) > 0 ) { 0035 bytesRead += r; 0036 0037 ssize_t w = 0; 0038 ssize_t ww = 0; 0039 while( w < r ) { 0040 if( ( ww = m_pipe->write( buffer.data()+w, r-w ) ) > 0 ) { 0041 w += ww; 0042 bytesWritten += ww; 0043 } 0044 else { 0045 qDebug() << "write failed." << sinkIODevice->errorString(); 0046 fail = true; 0047 break; 0048 } 0049 } 0050 } 0051 0052 if ( r < 0 ) { 0053 qDebug() << "Read failed:" << sourceIODevice->errorString(); 0054 } 0055 0056 qDebug() << "Done:" 0057 << ( fail ? QLatin1String( "write failed" ) : QLatin1String( "write success" ) ) 0058 << ( r != 0 ? QLatin1String( "read failed" ) : QLatin1String( "read success" ) ) 0059 << "(total bytes read/written:" << bytesRead << "/" << bytesWritten << ")"; 0060 } 0061 0062 void _k3b_close() { 0063 qDebug(); 0064 if ( closeWhenDone ) 0065 m_pipe->close(); 0066 } 0067 0068 private: 0069 K3b::ActivePipe* m_pipe; 0070 0071 public: 0072 QIODevice* sourceIODevice; 0073 QIODevice* sinkIODevice; 0074 0075 bool closeWhenDone; 0076 bool closeSinkIODevice; 0077 bool closeSourceIODevice; 0078 0079 QByteArray buffer; 0080 0081 quint64 bytesRead; 0082 quint64 bytesWritten; 0083 }; 0084 0085 0086 K3b::ActivePipe::ActivePipe() 0087 { 0088 d = new Private( this ); 0089 connect( d, SIGNAL(finished()), this, SLOT(_k3b_close()) ); 0090 } 0091 0092 0093 K3b::ActivePipe::~ActivePipe() 0094 { 0095 delete d; 0096 } 0097 0098 0099 bool K3b::ActivePipe::open( OpenMode mode ) 0100 { 0101 return QIODevice::open( mode ); 0102 } 0103 0104 0105 bool K3b::ActivePipe::open( bool closeWhenDone ) 0106 { 0107 if( d->isRunning() ) 0108 return false; 0109 0110 QIODevice::open( ReadWrite|Unbuffered ); 0111 0112 d->closeWhenDone = closeWhenDone; 0113 0114 if( d->sourceIODevice && !d->sourceIODevice->isOpen() ) { 0115 qDebug() << "Need to open source device:" << d->sourceIODevice; 0116 if( !d->sourceIODevice->open( QIODevice::ReadOnly ) ) 0117 return false; 0118 } 0119 0120 if( d->sinkIODevice && !d->sinkIODevice->isOpen() ) { 0121 qDebug() << "Need to open sink device:" << d->sinkIODevice; 0122 if( !d->sinkIODevice->open( QIODevice::WriteOnly ) ) 0123 return false; 0124 } 0125 0126 qDebug() << "(K3b::ActivePipe) successfully opened pipe."; 0127 0128 // we only do active piping if both devices are set. 0129 // Otherwise we only work as a conduit 0130 if ( d->sourceIODevice && d->sinkIODevice ) { 0131 d->start(); 0132 } 0133 0134 return true; 0135 } 0136 0137 0138 void K3b::ActivePipe::close() 0139 { 0140 qDebug(); 0141 if( d->sourceIODevice && d->closeSourceIODevice ) 0142 d->sourceIODevice->close(); 0143 if( d->sinkIODevice && d->closeSinkIODevice ) 0144 d->sinkIODevice->close(); 0145 d->wait(); 0146 } 0147 0148 0149 void K3b::ActivePipe::readFrom( QIODevice* dev, bool close ) 0150 { 0151 d->sourceIODevice = dev; 0152 d->closeSourceIODevice = close; 0153 } 0154 0155 0156 void K3b::ActivePipe::writeTo( QIODevice* dev, bool close ) 0157 { 0158 d->sinkIODevice = dev; 0159 d->closeSinkIODevice = close; 0160 } 0161 0162 0163 qint64 K3b::ActivePipe::readData( char* data, qint64 max ) 0164 { 0165 if( d->sourceIODevice ) { 0166 return d->sourceIODevice->read( data, max ); 0167 } 0168 0169 return -1; 0170 } 0171 0172 0173 qint64 K3b::ActivePipe::writeData( const char* data, qint64 max ) 0174 { 0175 if( d->sinkIODevice ) { 0176 return d->sinkIODevice->write( data, max ); 0177 } 0178 else 0179 return -1; 0180 } 0181 0182 0183 quint64 K3b::ActivePipe::bytesRead() const 0184 { 0185 return d->bytesRead; 0186 } 0187 0188 0189 quint64 K3b::ActivePipe::bytesWritten() const 0190 { 0191 return d->bytesWritten; 0192 } 0193 0194 #include "moc_k3bactivepipe.cpp"