MythTV master
netstream.h
Go to the documentation of this file.
1/* Network stream
2 * Copyright 2011 Lawrence Rust <lvr at softsystem dot co dot uk>
3 */
4#ifndef NETSTREAM_H
5#define NETSTREAM_H
6
7#include <QList>
8#include <QString>
9#include <QByteArray>
10#include <QObject>
11#include <QMutex>
12#include <QSemaphore>
13#include <QThread>
14#include <QNetworkRequest>
15#include <QNetworkReply>
16#include <QRecursiveMutex>
17#include <QSslError>
18#include <QWaitCondition>
19#include <QQueue>
20#include <QDateTime>
21
22class QUrl;
23class QNetworkAccessManager;
25class NetStreamAbort;
26
27
31class NetStream : public QObject
32{
33 Q_OBJECT
34
35public:
36 enum EMode : std::uint8_t { kNeverCache, kPreferCache, kAlwaysCache };
37 explicit NetStream(const QUrl &url, EMode mode = kPreferCache,
38 QByteArray cert = QByteArray());
39 ~NetStream() override;
40
41public:
42 // RingBuffer interface
43 static bool IsSupported(const QUrl &url);
44 bool IsOpen() const;
45 void Abort();
46 int safe_read(void *data, unsigned sz, unsigned millisecs = 0);
47 qlonglong Seek(qlonglong pos);
48 qlonglong GetReadPosition() const;
49 qlonglong GetSize() const;
50
51 // Properties
52 const QUrl &Url() const { return m_url; }
53
54 // Synchronous interface
55 bool WaitTillReady(std::chrono::milliseconds timeout);
56 bool WaitTillFinished(std::chrono::milliseconds timeout);
57 QNetworkReply::NetworkError GetError() const;
58 QString GetErrorString() const;
59 qlonglong BytesAvailable() const;
60 QByteArray ReadAll();
61
62 // Async interface
63 bool isStarted() const;
64 bool isReady() const;
65 bool isFinished() const;
66
67signals:
68 void ReadyRead(QObject*);
69 void Finished(QObject*);
70
71public:
72 // Time when a URI was last written to cache or invalid if not cached.
73 static QDateTime GetLastModified(const QUrl &url);
74 // Is the network accessible
75 static bool isAvailable();
76
77 // Implementation
78private slots:
79 // NAMThread signals
80 void slotRequestStarted(int id, QNetworkReply *reply);
81 // QNetworkReply signals
82 void slotFinished();
83#ifndef QT_NO_OPENSSL
84 void slotSslErrors(const QList<QSslError> & errors);
85#endif
86 // QIODevice signals
87 void slotReadyRead();
88
89private:
90 Q_DISABLE_COPY(NetStream)
91
92 bool Request(const QUrl &url);
93
94 const int m_id; // Unique request ID
95 const QUrl m_url;
96
97 mutable QMutex m_mutex; // Protects r/w access to the following data
98 QNetworkRequest m_request;
99 enum : std::uint8_t
102 QNetworkReply* m_reply {nullptr};
104 qlonglong m_size {-1};
105 qlonglong m_pos {0};
106 QByteArray m_cert;
107 QWaitCondition m_ready;
108 QWaitCondition m_finished;
109};
110
111
115class NAMThread : public QThread
116{
117 Q_OBJECT
118
119 // Use manager() to create
120 NAMThread();
121
122public:
123 static NAMThread & manager(); // Singleton
124 ~NAMThread() override;
125
126 static void PostEvent(QEvent *e) { manager().Post(e); }
127 void Post(QEvent *event);
128
129 static QRecursiveMutex* GetMutex() { return &manager().m_mutexNAM; }
130
131 static bool isAvailable(); // is network usable
132 static QDateTime GetLastModified(const QUrl &url);
133
134signals:
135 void requestStarted(int, QNetworkReply *);
136
137 // Implementation
138protected:
139 void run() override; // QThread
140 bool NewRequest(QEvent *event);
142 static bool AbortRequest(NetStreamAbort *p);
143
144private slots:
145 void quit();
146
147private:
148 Q_DISABLE_COPY(NAMThread)
149
150 volatile bool m_bQuit {false};
151 QSemaphore m_running;
152 mutable QRecursiveMutex m_mutexNAM; // Provides recursive access to m_nam
153 QNetworkAccessManager *m_nam {nullptr};
154 mutable QMutex m_mutex; // Protects r/w access to the following data
155 QQueue< QEvent * > m_workQ;
156 QWaitCondition m_work;
157};
158
159#endif /* ndef NETSTREAM_H */
Thread to process NetStream requests.
Definition: netstream.h:116
static bool isAvailable()
Definition: netstream.cpp:925
QWaitCondition m_work
Definition: netstream.h:156
static void PostEvent(QEvent *e)
Definition: netstream.h:126
QRecursiveMutex m_mutexNAM
Definition: netstream.h:152
QNetworkAccessManager * m_nam
Definition: netstream.h:153
bool StartRequest(NetStreamRequest *p)
Definition: netstream.cpp:886
static QRecursiveMutex * GetMutex()
Definition: netstream.h:129
QSemaphore m_running
Definition: netstream.h:151
void Post(QEvent *event)
Definition: netstream.cpp:863
volatile bool m_bQuit
Definition: netstream.h:150
QQueue< QEvent * > m_workQ
Definition: netstream.h:155
bool NewRequest(QEvent *event)
Definition: netstream.cpp:869
static bool AbortRequest(NetStreamAbort *p)
Definition: netstream.cpp:908
~NAMThread() override
Definition: netstream.cpp:767
static NAMThread & manager()
NetworkAccessManager event loop thread.
Definition: netstream.cpp:745
void requestStarted(int, QNetworkReply *)
static QDateTime GetLastModified(const QUrl &url)
Definition: netstream.cpp:940
void quit()
Definition: netstream.cpp:857
QMutex m_mutex
Definition: netstream.h:154
void run() override
Definition: netstream.cpp:774
Stream content from a URI.
Definition: netstream.h:32
qlonglong BytesAvailable() const
Definition: netstream.cpp:685
qlonglong GetSize() const
Definition: netstream.cpp:628
void slotRequestStarted(int id, QNetworkReply *reply)
Definition: netstream.cpp:279
~NetStream() override
Definition: netstream.cpp:124
qlonglong Seek(qlonglong pos)
Definition: netstream.cpp:600
QNetworkReply * m_reply
Definition: netstream.h:102
void slotReadyRead()
Definition: netstream.cpp:367
bool isReady() const
Definition: netstream.cpp:712
static bool isAvailable()
Public helpers.
Definition: netstream.cpp:728
int safe_read(void *data, unsigned sz, unsigned millisecs=0)
Definition: netstream.cpp:568
NetStreamRequest * m_pending
Definition: netstream.h:101
bool IsOpen() const
Definition: netstream.cpp:537
@ kNeverCache
Definition: netstream.h:36
@ kPreferCache
Definition: netstream.h:36
@ kAlwaysCache
Definition: netstream.h:36
QByteArray ReadAll()
Definition: netstream.cpp:691
QNetworkReply::NetworkError GetError() const
Definition: netstream.cpp:673
static QDateTime GetLastModified(const QUrl &url)
Definition: netstream.cpp:735
QByteArray m_cert
Definition: netstream.h:106
enum NetStream::@17 kClosed
qlonglong m_pos
Definition: netstream.h:105
int m_nRedirections
Definition: netstream.h:103
void slotSslErrors(const QList< QSslError > &errors)
Definition: netstream.cpp:487
void Finished(QObject *)
bool WaitTillReady(std::chrono::milliseconds timeout)
Synchronous interface.
Definition: netstream.cpp:639
bool isStarted() const
Asynchronous interface.
Definition: netstream.cpp:706
static bool IsSupported(const QUrl &url)
RingBuffer interface.
Definition: netstream.cpp:529
NetStream(const QUrl &url, EMode mode=kPreferCache, QByteArray cert=QByteArray())
Network streaming request.
Definition: netstream.cpp:96
qlonglong m_size
Definition: netstream.h:104
bool Request(const QUrl &url)
Definition: netstream.cpp:159
void ReadyRead(QObject *)
qlonglong GetReadPosition() const
Definition: netstream.cpp:621
QNetworkRequest m_request
Definition: netstream.h:98
const int m_id
Definition: netstream.h:94
void Abort()
Definition: netstream.cpp:543
const QUrl & Url() const
Definition: netstream.h:52
const QUrl m_url
Definition: netstream.h:95
void slotFinished()
Definition: netstream.cpp:418
bool isFinished() const
Definition: netstream.cpp:718
QWaitCondition m_ready
Definition: netstream.h:107
QWaitCondition m_finished
Definition: netstream.h:108
QMutex m_mutex
Definition: netstream.h:97
QString GetErrorString() const
Definition: netstream.cpp:679
bool WaitTillFinished(std::chrono::milliseconds timeout)
Definition: netstream.cpp:656