File indexing completed on 2024-04-28 04:49:50
0001 /* 0002 SPDX-FileCopyrightText: 1998-2008 Sebastian Trueg <trueg@k3b.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 0008 #include "k3bdevicehandler.h" 0009 #include "k3bprogressinfoevent.h" 0010 #include "k3bthread.h" 0011 #include "k3bdevice.h" 0012 #include "k3bcdtext.h" 0013 #include "k3bcore.h" 0014 #include "k3bmediacache.h" 0015 0016 0017 class K3b::Device::DeviceHandler::Private 0018 { 0019 public: 0020 Private( bool _selfDelete ) 0021 : selfDelete( _selfDelete ) { 0022 } 0023 0024 bool selfDelete; 0025 0026 bool success; 0027 Commands command; 0028 DiskInfo diskInfo; 0029 Toc toc; 0030 CdText cdText; 0031 QByteArray cdTextRaw; 0032 long long bufferCapacity; 0033 long long availableBufferCapacity; 0034 Device* dev; 0035 K3b::Msf nextWritableAddress; 0036 }; 0037 0038 0039 K3b::Device::DeviceHandler::DeviceHandler( Device* dev, QObject* parent ) 0040 : K3b::ThreadJob( 0, parent ), 0041 d( new Private( false ) ) 0042 { 0043 d->dev = dev; 0044 } 0045 0046 0047 K3b::Device::DeviceHandler::DeviceHandler( QObject* parent ) 0048 : K3b::ThreadJob( 0, parent ), 0049 d( new Private( false ) ) 0050 { 0051 } 0052 0053 0054 K3b::Device::DeviceHandler::DeviceHandler( Commands command, Device* dev ) 0055 : K3b::ThreadJob( 0, 0 ), 0056 d( new Private( false ) ) 0057 { 0058 d->dev = dev; 0059 sendCommand(command); 0060 } 0061 0062 K3b::Device::DeviceHandler::~DeviceHandler() 0063 { 0064 delete d; 0065 } 0066 0067 0068 bool K3b::Device::DeviceHandler::success() const 0069 { 0070 return d->success; 0071 } 0072 0073 0074 K3b::Device::DiskInfo K3b::Device::DeviceHandler::diskInfo() const 0075 { 0076 return d->diskInfo; 0077 } 0078 0079 0080 K3b::Device::Toc K3b::Device::DeviceHandler::toc() const 0081 { 0082 return d->toc; 0083 } 0084 0085 K3b::Device::CdText K3b::Device::DeviceHandler::cdText() const 0086 { 0087 return d->cdText; 0088 } 0089 0090 0091 QByteArray K3b::Device::DeviceHandler::cdTextRaw() const 0092 { 0093 return d->cdTextRaw; 0094 } 0095 0096 0097 K3b::Msf K3b::Device::DeviceHandler::diskSize() const 0098 { 0099 return d->diskInfo.capacity(); 0100 } 0101 0102 K3b::Msf K3b::Device::DeviceHandler::remainingSize() const 0103 { 0104 return d->diskInfo.remainingSize(); 0105 } 0106 0107 int K3b::Device::DeviceHandler::tocType() const 0108 { 0109 return d->toc.contentType(); 0110 } 0111 0112 int K3b::Device::DeviceHandler::numSessions() const 0113 { 0114 return d->diskInfo.numSessions(); 0115 } 0116 0117 long long K3b::Device::DeviceHandler::bufferCapacity() const 0118 { 0119 return d->bufferCapacity; 0120 } 0121 0122 long long K3b::Device::DeviceHandler::availableBufferCapacity() const 0123 { 0124 return d->availableBufferCapacity; 0125 } 0126 0127 K3b::Msf K3b::Device::DeviceHandler::nextWritableAddress() const 0128 { 0129 return d->nextWritableAddress; 0130 } 0131 0132 void K3b::Device::DeviceHandler::setDevice( Device* dev ) 0133 { 0134 d->dev = dev; 0135 } 0136 0137 0138 void K3b::Device::DeviceHandler::sendCommand( DeviceHandler::Commands command ) 0139 { 0140 if( active() ) { 0141 qDebug() << "thread already running. canceling thread..."; 0142 cancel(); 0143 wait(); 0144 } 0145 0146 d->command = command; 0147 start(); 0148 } 0149 0150 void K3b::Device::DeviceHandler::getToc() 0151 { 0152 sendCommand(DeviceHandler::CommandToc); 0153 } 0154 0155 void K3b::Device::DeviceHandler::getDiskInfo() 0156 { 0157 sendCommand(DeviceHandler::CommandDiskInfo); 0158 } 0159 0160 void K3b::Device::DeviceHandler::getDiskSize() 0161 { 0162 sendCommand(DeviceHandler::CommandDiskSize); 0163 } 0164 0165 void K3b::Device::DeviceHandler::getRemainingSize() 0166 { 0167 sendCommand(DeviceHandler::CommandRemainingSize); 0168 } 0169 0170 void K3b::Device::DeviceHandler::getTocType() 0171 { 0172 sendCommand(DeviceHandler::CommandTocType); 0173 } 0174 0175 void K3b::Device::DeviceHandler::getNumSessions() 0176 { 0177 sendCommand(DeviceHandler::CommandNumSessions); 0178 } 0179 0180 0181 void K3b::Device::DeviceHandler::block( bool b ) 0182 { 0183 sendCommand(b ? DeviceHandler::CommandBlock : DeviceHandler::CommandUnblock); 0184 } 0185 0186 void K3b::Device::DeviceHandler::eject() 0187 { 0188 sendCommand(DeviceHandler::CommandEject); 0189 } 0190 0191 K3b::Device::DeviceHandler* K3b::Device::sendCommand( DeviceHandler::Commands command, Device* dev ) 0192 { 0193 return new DeviceHandler( command, dev ); 0194 } 0195 0196 void K3b::Device::DeviceHandler::jobFinished( bool success ) 0197 { 0198 K3b::ThreadJob::jobFinished( success ); 0199 0200 emit finished( this ); 0201 0202 if( d->selfDelete ) { 0203 deleteLater(); 0204 } 0205 } 0206 0207 0208 bool K3b::Device::DeviceHandler::run() 0209 { 0210 qDebug() << "starting command: " << d->command; 0211 0212 d->success = false; 0213 0214 // clear data 0215 d->toc.clear(); 0216 d->diskInfo = DiskInfo(); 0217 d->cdText.clear(); 0218 d->cdTextRaw.clear(); 0219 0220 if( d->dev ) { 0221 d->success = d->dev->open(); 0222 if( !canceled() && d->command & CommandBlock ) 0223 d->success = (d->success && d->dev->block( true )); 0224 0225 if( !canceled() && d->command & CommandUnblock ) 0226 d->success = (d->success && d->dev->block( false )); 0227 0228 // 0229 // It is important that eject is performed before load 0230 // since the CommandReload command is a combination of both 0231 // 0232 0233 if( !canceled() && d->command & CommandEject ) { 0234 d->success = (d->success && d->dev->eject()); 0235 0236 // to be on the safe side, especially with respect to the EmptyDiscWaiter 0237 // we reset the device in the cache. 0238 k3bcore->mediaCache()->resetDevice( d->dev ); 0239 } 0240 0241 if( !canceled() && d->command & CommandLoad ) 0242 d->success = (d->success && d->dev->load()); 0243 0244 if( !canceled() && d->command & (CommandDiskInfo| 0245 CommandDiskSize| 0246 CommandRemainingSize| 0247 CommandNumSessions) ) { 0248 d->diskInfo = d->dev->diskInfo(); 0249 } 0250 0251 if( !canceled() && d->command & (CommandToc|CommandTocType) ) { 0252 d->toc = d->dev->readToc(); 0253 } 0254 0255 if( !canceled() && 0256 d->command & CommandCdText && 0257 !( d->command & CommandToc && 0258 d->toc.contentType() == DATA ) 0259 ) { 0260 d->cdText = d->dev->readCdText(); 0261 if ( d->command != CommandMediaInfo ) 0262 d->success = (d->success && !d->cdText.isEmpty()); 0263 } 0264 0265 if( !canceled() && d->command & CommandCdTextRaw ) { 0266 bool cdTextSuccess = true; 0267 d->cdTextRaw = d->dev->readRawCdText( &cdTextSuccess ); 0268 d->success = d->success && cdTextSuccess; 0269 } 0270 0271 if( !canceled() && d->command & CommandBufferCapacity ) 0272 d->success = d->dev->readBufferCapacity( d->bufferCapacity, d->availableBufferCapacity ); 0273 0274 if ( !canceled() && d->command & CommandNextWritableAddress ) { 0275 int nwa = d->dev->nextWritableAddress(); 0276 d->nextWritableAddress = nwa; 0277 d->success = ( d->success && ( nwa > 0 ) ); 0278 } 0279 0280 d->dev->close(); 0281 } 0282 0283 qDebug() << "finished command: " << d->command; 0284 0285 return d->success; 0286 } 0287 0288 0289 QDebug operator<<( QDebug dbg, K3b::Device::DeviceHandler::Commands commands ) 0290 { 0291 QStringList commandStrings; 0292 if ( commands & K3b::Device::DeviceHandler::CommandDiskInfo ) 0293 commandStrings << QLatin1String( "CommandDiskInfo" ); 0294 if ( commands & K3b::Device::DeviceHandler::CommandToc ) 0295 commandStrings << QLatin1String( "CommandToc" ); 0296 if ( commands & K3b::Device::DeviceHandler::CommandCdText ) 0297 commandStrings << QLatin1String( "CommandCdText" ); 0298 if ( commands & K3b::Device::DeviceHandler::CommandCdTextRaw ) 0299 commandStrings << QLatin1String( "CommandCdTextRaw" ); 0300 if ( commands & K3b::Device::DeviceHandler::CommandDiskSize ) 0301 commandStrings << QLatin1String( "CommandDiskSize" ); 0302 if ( commands & K3b::Device::DeviceHandler::CommandRemainingSize ) 0303 commandStrings << QLatin1String( "CommandRemainingSize" ); 0304 if ( commands & K3b::Device::DeviceHandler::CommandTocType ) 0305 commandStrings << QLatin1String( "CommandTocType" ); 0306 if ( commands & K3b::Device::DeviceHandler::CommandNumSessions ) 0307 commandStrings << QLatin1String( "CommandNumSessions" ); 0308 if ( commands & K3b::Device::DeviceHandler::CommandBlock ) 0309 commandStrings << QLatin1String( "CommandBlock" ); 0310 if ( commands & K3b::Device::DeviceHandler::CommandUnblock ) 0311 commandStrings << QLatin1String( "CommandUnblock" ); 0312 if ( commands & K3b::Device::DeviceHandler::CommandEject ) 0313 commandStrings << QLatin1String( "CommandEject" ); 0314 if ( commands & K3b::Device::DeviceHandler::CommandLoad ) 0315 commandStrings << QLatin1String( "CommandLoad" ); 0316 if ( commands & K3b::Device::DeviceHandler::CommandBufferCapacity ) 0317 commandStrings << QLatin1String( "CommandBufferCapacity" ); 0318 if ( commands & K3b::Device::DeviceHandler::CommandNextWritableAddress ) 0319 commandStrings << QLatin1String( "CommandNextWritableAddress" ); 0320 dbg.nospace() << '(' + commandStrings.join( "|" ) + ')'; 0321 return dbg.space(); 0322 } 0323 0324 #include "moc_k3bdevicehandler.cpp"