File indexing completed on 2025-02-23 04:27:37

0001 /****************************************************************************************
0002  * Copyright (c) 2006 Ian Monroe <ian@monroe.nu>                                        *
0003  *                                                                                      *
0004  * This program is free software; you can redistribute it and/or modify it under        *
0005  * the terms of the GNU General Public License as published by the Free Software        *
0006  * Foundation; either version 2 of the License, or (at your option) version 3 or        *
0007  * any later version accepted by the membership of KDE e.V. (or its successor approved  *
0008  * by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of  *
0009  * version 3 of the license.                                                            *
0010  *                                                                                      *
0011  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0012  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0013  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0014  *                                                                                      *
0015  * You should have received a copy of the GNU General Public License along with         *
0016  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0017  ****************************************************************************************/
0018 
0019 #ifndef DAAPREADER_H
0020 #define DAAPREADER_H
0021 
0022 #include <core-impl/collections/support/MemoryCollection.h>
0023 
0024 #include <QObject>
0025 
0026 #include <QUrl>
0027 #include <ThreadWeaver/Job>
0028 
0029 class QString;
0030 
0031 namespace Collections {
0032     class DaapCollection;
0033 }
0034 
0035 
0036 namespace Daap
0037 {
0038     typedef QMap<QString, QVariant>    Map;
0039 
0040     enum ContentTypes { INVALID = 0, CHAR = 1, SHORT = 3, LONG = 5, LONGLONG = 7,
0041                         STRING = 9, DATE = 10, DVERSION = 11, CONTAINER = 12 };
0042 
0043     struct Code
0044     {
0045         Code() : type(INVALID) { }
0046         Code( const QString& nName, ContentTypes nType ) : name( nName ), type( nType ) { }
0047         ~Code() { }
0048         QString name;
0049         ContentTypes type;
0050     };
0051 
0052 
0053 
0054     /**
0055         The nucleus of the DAAP client; composes queries and parses responses.
0056         @author Ian Monroe <ian@monroe.nu>
0057     */
0058     class Reader : public QObject
0059     {
0060         Q_OBJECT
0061 
0062         public:
0063             Reader( Collections::DaapCollection *mc, const QString& host, quint16 port, const QString& password, QObject* parent, const char* name );
0064            ~Reader() override;
0065 
0066             //QPtrList<MetaBundle> getSongList();
0067             enum Options { SESSION_ID = 1, SERVER_VERSION = 2  };
0068             void loginRequest();
0069             void logoutRequest();
0070 
0071             int sessionId() const { return m_sessionId; }
0072             QString host() const { return m_host; }
0073             quint16 port() const { return m_port; }
0074 
0075             bool parseSongList( const QByteArray &data, bool set_collection = false);
0076         public Q_SLOTS:
0077             void logoutRequestFinished();
0078             void contentCodesReceived();
0079             void loginHeaderReceived();
0080             void loginFinished();
0081             void updateFinished();
0082             void databaseIdFinished();
0083             void songListFinished();
0084             void fetchingError( const QString& error );
0085 
0086         Q_SIGNALS:
0087             //void daapBundles( const QString& host, Daap::SongList bundles );
0088             void httpError( const QString& );
0089             void passwordRequired();
0090 
0091         private:
0092             /**
0093             * Make a map-vector tree out of the DAAP binary result
0094             * @param raw stream of DAAP reply
0095             */
0096             Map parse( QDataStream &raw);
0097             static void addElement( Map &parentMap, char* tag, const QVariant &element ); //!< supporter function for parse
0098             static quint32 getTagAndLength( QDataStream &raw, char tag[5] );
0099             QVariant readTagData(QDataStream &, char[5], quint32);
0100             void addTrack( const QString& itemId, const QString& title, const QString& artist, const QString& composer,
0101                            const QString& comment, const QString& album, const QString& genre, int year,
0102                            const QString& format, qint32 trackNumber, qint32 songTime );
0103 
0104             QMap<QString, Code> m_codes;
0105 
0106             Collections::DaapCollection *m_memColl;
0107             QString m_host;
0108             quint16 m_port;
0109             QString m_loginString;
0110             QString m_databaseId;
0111             int m_sessionId;
0112             QString m_password;
0113             TrackMap m_trackMap;
0114             ArtistMap m_artistMap;
0115             AlbumMap m_albumMap;
0116             GenreMap m_genreMap;
0117             ComposerMap m_composerMap;
0118             YearMap m_yearMap;
0119     };
0120 
0121     class WorkerThread : public QObject, public ThreadWeaver::Job
0122     {
0123         Q_OBJECT
0124         public:
0125             WorkerThread( const QByteArray &data, Reader* reader, Collections::DaapCollection *coll );
0126             ~WorkerThread() override;
0127 
0128             bool success() const override;
0129 
0130         protected:
0131             void defaultBegin(const ThreadWeaver::JobPointer& job, ThreadWeaver::Thread *thread) override;
0132             void defaultEnd(const ThreadWeaver::JobPointer& job, ThreadWeaver::Thread *thread) override;
0133             void run(ThreadWeaver::JobPointer self=QSharedPointer<WorkerThread>(), ThreadWeaver::Thread *thread = nullptr) override;
0134 
0135         Q_SIGNALS:
0136             /** This signal is emitted when this job is being processed by a thread. */
0137             void started(ThreadWeaver::JobPointer);
0138             /** This signal is emitted when the job has been finished (no matter if it succeeded or not). */
0139             void done(ThreadWeaver::JobPointer);
0140             /** This job has failed.
0141              * This signal is emitted when success() returns false after the job is executed. */
0142             void failed(ThreadWeaver::JobPointer);
0143 
0144         private:
0145             bool m_success;
0146             QByteArray m_data;
0147             Reader *m_reader;
0148     };
0149 
0150 }
0151 
0152 #endif