1 /* 2 SPDX-FileCopyrightText: 2002 Rik Hemsley (rikkus) <rik@kde.org> 3 SPDX-FileCopyrightText: 2002 Benjamin Meyer <ben-devel@meyerhome.net> 4 SPDX-FileCopyrightText: 2005 Richard Lärkäng <nouseforaname@home.se> 5 6 SPDX-License-Identifier: LGPL-2.0-or-later 7 */ 8 9 #include "synccddbplookup.h" 10 #include "logging.h" 11 12 #include <QStringList> 13 14 namespace KCDDB 15 { SyncCDDBPLookup()16 SyncCDDBPLookup::SyncCDDBPLookup() 17 : CDDBPLookup() 18 { 19 } 20 ~SyncCDDBPLookup()21 SyncCDDBPLookup::~SyncCDDBPLookup() 22 { 23 // Empty. 24 } 25 26 Result lookup(const QString & hostName,uint port,const TrackOffsetList & trackOffsetList)27 SyncCDDBPLookup::lookup 28 ( 29 const QString & hostName, 30 uint port, 31 const TrackOffsetList & trackOffsetList 32 ) 33 { 34 trackOffsetList_ = trackOffsetList; 35 36 socket_ = new QTcpSocket; 37 socket_->connectToHost(hostName, port); 38 39 if ( !socket_->waitForConnected(30000) ) 40 { 41 qCDebug(LIBKCDDB) << "Couldn't connect to " << socket_->peerName() << ":" << socket_->peerPort(); 42 qCDebug(LIBKCDDB) << "Socket error: " << socket_->errorString(); 43 const auto socketError = socket_->error(); 44 if ( socketError == QAbstractSocket::HostNotFoundError ) 45 return HostNotFound; 46 else if ( socketError == QAbstractSocket::SocketTimeoutError ) 47 return NoResponse; 48 else 49 return UnknownError; 50 } 51 52 Result result; 53 54 // Try a handshake. 55 result = shakeHands(); 56 if ( Success != result ) 57 return result; 58 59 // Run a query. 60 result = runQuery(); 61 if ( Success != result ) 62 return result; 63 64 if (matchList_.isEmpty()) 65 return NoRecordFound; 66 67 qCDebug(LIBKCDDB) << matchList_.count() << " matches found."; 68 69 // For each match, read the cd info from the server and save it to 70 // cdInfoList. 71 CDDBMatchList::ConstIterator matchIt = matchList_.constBegin(); 72 73 while ( matchIt != matchList_.constEnd() ) 74 { 75 CDDBMatch match( *matchIt ); 76 result = matchToCDInfo( match ); 77 ++matchIt; 78 } 79 80 sendQuit(); 81 82 close(); 83 84 return Success; 85 } 86 87 Result shakeHands()88 SyncCDDBPLookup::shakeHands() 89 { 90 QString line = readLine(); 91 92 if ( !parseGreeting( line ) ) 93 return ServerError; 94 95 sendHandshake(); 96 97 line = readLine(); 98 99 if ( !parseHandshake( line ) ) 100 return ServerError; 101 102 sendProto(); 103 104 // Ignore the response for now 105 readLine(); 106 107 return Success; 108 } 109 110 Result runQuery()111 SyncCDDBPLookup::runQuery() 112 { 113 Result result; 114 115 sendQuery(); 116 117 QString line = readLine(); 118 result = parseQuery( line ); 119 120 if ( ServerError == result ) 121 return ServerError; 122 123 if ( MultipleRecordFound == result ) 124 { 125 // We have multiple matches 126 line = readLine(); 127 128 while (!line.startsWith(QLatin1String( "." )) && !line.isNull() ) 129 { 130 parseExtraMatch( line ); 131 line = readLine(); 132 } 133 } 134 135 return Success; 136 } 137 138 Result matchToCDInfo(const CDDBMatch & match)139 SyncCDDBPLookup::matchToCDInfo( const CDDBMatch & match ) 140 { 141 sendRead( match ); 142 143 QString line = readLine(); 144 145 Result result = parseRead( line ); 146 if ( Success != result ) 147 return result; 148 149 QStringList lineList; 150 line = readLine(); 151 152 while ( !line.startsWith(QLatin1String( "." )) && !line.isNull() ) 153 { 154 lineList.append( line ); 155 line = readLine(); 156 } 157 158 CDInfo info; 159 160 if ( info.load( lineList ) ) 161 { 162 info.set( QLatin1String( "category" ), category_ ); 163 info.set( QLatin1String( "discid" ), discid_ ); 164 info.set( QLatin1String( "source" ), QLatin1String( "freedb" ) ); 165 cdInfoList_.append( info ); 166 } 167 168 return Success; 169 } 170 171 QString readLine()172 SyncCDDBPLookup::readLine() 173 { 174 if ( !isConnected() ) 175 { 176 qCDebug(LIBKCDDB) << "socket status: " << socket_->state(); 177 return QString(); 178 } 179 180 if (!socket_->canReadLine()) 181 { 182 if (!socket_->waitForReadyRead(-1)) 183 return QString(); 184 } 185 186 return QString::fromUtf8(socket_->readLine()); 187 } 188 } 189 190 // vim:tabstop=2:shiftwidth=2:expandtab:cinoptions=(s,U1,m1 191