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 #if QT_VERSION >= QT_VERSION_CHECK(5,14,0)
17 #include <QRecursiveMutex>
18 #endif
19 #include <QSslError>
20 #include <QWaitCondition>
21 #include <QQueue>
22 #include <QDateTime>
23 
24 class QUrl;
25 class QNetworkAccessManager;
26 class NetStreamRequest;
27 class NetStreamAbort;
28 
29 
33 class NetStream : public QObject
34 {
35  Q_OBJECT
36 
37 public:
39  explicit NetStream(const QUrl &url, EMode mode = kPreferCache,
40  QByteArray cert = QByteArray());
41  ~NetStream() override;
42 
43 public:
44  // RingBuffer interface
45  static bool IsSupported(const QUrl &url);
46  bool IsOpen() const;
47  void Abort();
48  int safe_read(void *data, unsigned sz, unsigned millisecs = 0);
49  qlonglong Seek(qlonglong pos);
50  qlonglong GetReadPosition() const;
51  qlonglong GetSize() const;
52 
53  // Properties
54  const QUrl &Url() const { return m_url; }
55 
56  // Synchronous interface
57  bool WaitTillReady(std::chrono::milliseconds timeout);
58  bool WaitTillFinished(std::chrono::milliseconds timeout);
59  QNetworkReply::NetworkError GetError() const;
60  QString GetErrorString() const;
61  qlonglong BytesAvailable() const;
62  QByteArray ReadAll();
63 
64  // Async interface
65  bool isStarted() const;
66  bool isReady() const;
67  bool isFinished() const;
68 
69 signals:
70  void ReadyRead(QObject*);
71  void Finished(QObject*);
72 
73 public:
74  // Time when a URI was last written to cache or invalid if not cached.
75  static QDateTime GetLastModified(const QUrl &url);
76  // Is the network accessible
77  static bool isAvailable();
78 
79  // Implementation
80 private slots:
81  // NAMThread signals
82  void slotRequestStarted(int id, QNetworkReply *reply);
83  // QNetworkReply signals
84  void slotFinished();
85 #ifndef QT_NO_OPENSSL
86  void slotSslErrors(const QList<QSslError> & errors);
87 #endif
88  // QIODevice signals
89  void slotReadyRead();
90 
91 private:
92  Q_DISABLE_COPY(NetStream)
93 
94  bool Request(const QUrl &url);
95 
96  const int m_id; // Unique request ID
97  const QUrl m_url;
98 
99  mutable QMutex m_mutex; // Protects r/w access to the following data
100  QNetworkRequest m_request;
103  QNetworkReply* m_reply {nullptr};
105  qlonglong m_size {-1};
106  qlonglong m_pos {0};
107  QByteArray m_cert;
108  QWaitCondition m_ready;
109  QWaitCondition m_finished;
110 };
111 
112 
116 class NAMThread : public QThread
117 {
118  Q_OBJECT
119 
120  // Use manager() to create
121  NAMThread();
122 
123 public:
124  static NAMThread & manager(); // Singleton
125  ~NAMThread() override;
126 
127  static inline void PostEvent(QEvent *e) { manager().Post(e); }
128  void Post(QEvent *event);
129 
130 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
131  static inline QMutex* GetMutex() { return &manager().m_mutexNAM; }
132 #else
133  static inline QRecursiveMutex* GetMutex() { return &manager().m_mutexNAM; }
134 #endif
135 
136  static bool isAvailable(); // is network usable
137  static QDateTime GetLastModified(const QUrl &url);
138 
139 signals:
140  void requestStarted(int, QNetworkReply *);
141 
142  // Implementation
143 protected:
144  void run() override; // QThread
145  bool NewRequest(QEvent *event);
147  static bool AbortRequest(NetStreamAbort *p);
148 
149 private slots:
150  void quit();
151 
152 private:
153  Q_DISABLE_COPY(NAMThread)
154 
155  volatile bool m_bQuit {false};
156  QSemaphore m_running;
157 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
158  mutable QMutex m_mutexNAM {QMutex::Recursive}; // Provides recursive access to m_nam
159 #else
160  mutable QRecursiveMutex m_mutexNAM; // Provides recursive access to m_nam
161 #endif
162  QNetworkAccessManager *m_nam {nullptr};
163  mutable QMutex m_mutex; // Protects r/w access to the following data
164  QQueue< QEvent * > m_workQ;
165  QWaitCondition m_work;
166 };
167 
168 #endif /* ndef NETSTREAM_H */
NetStream::ReadAll
QByteArray ReadAll()
Definition: netstream.cpp:685
NetStream::slotSslErrors
void slotSslErrors(const QList< QSslError > &errors)
Definition: netstream.cpp:483
NAMThread::m_bQuit
volatile bool m_bQuit
Definition: netstream.h:155
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
NetStream::m_ready
QWaitCondition m_ready
Definition: netstream.h:108
NAMThread::m_nam
QNetworkAccessManager * m_nam
Definition: netstream.h:162
NAMThread::StartRequest
bool StartRequest(NetStreamRequest *p)
Definition: netstream.cpp:876
NetStream::Request
bool Request(const QUrl &url)
Definition: netstream.cpp:164
NetStream::isStarted
bool isStarted() const
Asynchronous interface.
Definition: netstream.cpp:700
NetStream::GetLastModified
static QDateTime GetLastModified(const QUrl &url)
Definition: netstream.cpp:729
NAMThread::m_mutexNAM
QRecursiveMutex m_mutexNAM
Definition: netstream.h:160
NetStream::isFinished
bool isFinished() const
Definition: netstream.cpp:712
NAMThread::m_running
QSemaphore m_running
Definition: netstream.h:156
NAMThread::NewRequest
bool NewRequest(QEvent *event)
Definition: netstream.cpp:859
NetStream::m_pending
NetStreamRequest * m_pending
Definition: netstream.h:102
NetStream::m_finished
QWaitCondition m_finished
Definition: netstream.h:109
NetStream::EMode
EMode
Definition: netstream.h:38
NAMThread::quit
void quit()
Definition: netstream.cpp:847
NAMThread::Post
void Post(QEvent *event)
Definition: netstream.cpp:853
NetStream::Url
const QUrl & Url() const
Definition: netstream.h:54
NetStream::m_request
QNetworkRequest m_request
Definition: netstream.h:100
NetStream::m_reply
QNetworkReply * m_reply
Definition: netstream.h:103
NetStream::m_nRedirections
int m_nRedirections
Definition: netstream.h:104
NAMThread::m_workQ
QQueue< QEvent * > m_workQ
Definition: netstream.h:164
NetStream::WaitTillFinished
bool WaitTillFinished(std::chrono::milliseconds timeout)
Definition: netstream.cpp:650
NetStream::m_id
const int m_id
Definition: netstream.h:96
NetStream::kClosed
enum NetStream::@18 kClosed
NAMThread::PostEvent
static void PostEvent(QEvent *e)
Definition: netstream.h:127
NetStream::slotFinished
void slotFinished()
Definition: netstream.cpp:420
NAMThread::GetLastModified
static QDateTime GetLastModified(const QUrl &url)
Definition: netstream.cpp:928
NAMThread::~NAMThread
~NAMThread() override
Definition: netstream.cpp:761
NetStreamAbort
Definition: netstream.cpp:85
NetStream::WaitTillReady
bool WaitTillReady(std::chrono::milliseconds timeout)
Synchronous interface.
Definition: netstream.cpp:633
NAMThread::isAvailable
static bool isAvailable()
Definition: netstream.cpp:913
NAMThread::NAMThread
NAMThread()
Definition: netstream.cpp:749
NetStream::IsSupported
static bool IsSupported(const QUrl &url)
RingBuffer interface.
Definition: netstream.cpp:523
hardwareprofile.config.p
p
Definition: config.py:33
NetStream::BytesAvailable
qlonglong BytesAvailable() const
Definition: netstream.cpp:679
NAMThread::run
void run() override
Definition: netstream.cpp:768
NetStream::GetSize
qlonglong GetSize() const
Definition: netstream.cpp:622
NetStream::NetStream
NetStream(const QUrl &url, EMode mode=kPreferCache, QByteArray cert=QByteArray())
Network streaming request.
Definition: netstream.cpp:104
NetStream::GetReadPosition
qlonglong GetReadPosition() const
Definition: netstream.cpp:615
NetStream::Finished
void Finished(QObject *)
NAMThread::requestStarted
void requestStarted(int, QNetworkReply *)
NetStream::safe_read
int safe_read(void *data, unsigned sz, unsigned millisecs=0)
Definition: netstream.cpp:562
NetStream
Stream content from a URI.
Definition: netstream.h:33
NetStream::slotReadyRead
void slotReadyRead()
Definition: netstream.cpp:370
NetStream::kPending
@ kPending
Definition: netstream.h:101
NetStream::GetError
QNetworkReply::NetworkError GetError() const
Definition: netstream.cpp:667
NetStream::isAvailable
static bool isAvailable()
Public helpers.
Definition: netstream.cpp:722
NAMThread::m_mutex
QMutex m_mutex
Definition: netstream.h:163
NAMThread
Thread to process NetStream requests.
Definition: netstream.h:116
NetStream::IsOpen
bool IsOpen() const
Definition: netstream.cpp:531
NetStream::Seek
qlonglong Seek(qlonglong pos)
Definition: netstream.cpp:594
NAMThread::AbortRequest
static bool AbortRequest(NetStreamAbort *p)
Definition: netstream.cpp:896
NAMThread::m_work
QWaitCondition m_work
Definition: netstream.h:165
NetStream::ReadyRead
void ReadyRead(QObject *)
NetStreamRequest
Definition: netstream.cpp:68
NetStream::kPreferCache
@ kPreferCache
Definition: netstream.h:38
NetStream::kFinished
@ kFinished
Definition: netstream.h:101
NetStream::isReady
bool isReady() const
Definition: netstream.cpp:706
NetStream::kStarted
@ kStarted
Definition: netstream.h:101
NetStream::m_cert
QByteArray m_cert
Definition: netstream.h:107
NAMThread::manager
static NAMThread & manager()
NetworkAccessManager event loop thread.
Definition: netstream.cpp:739
NetStream::m_pos
qlonglong m_pos
Definition: netstream.h:106
NetStream::~NetStream
~NetStream() override
Definition: netstream.cpp:129
NetStream::slotRequestStarted
void slotRequestStarted(int id, QNetworkReply *reply)
Definition: netstream.cpp:284
NetStream::kNeverCache
@ kNeverCache
Definition: netstream.h:38
NetStream::m_mutex
QMutex m_mutex
Definition: netstream.h:99
NetStream::m_url
const QUrl m_url
Definition: netstream.h:97
NAMThread::GetMutex
static QRecursiveMutex * GetMutex()
Definition: netstream.h:133
NetStream::GetErrorString
QString GetErrorString() const
Definition: netstream.cpp:673
NetStream::Abort
void Abort()
Definition: netstream.cpp:537
NetStream::kAlwaysCache
@ kAlwaysCache
Definition: netstream.h:38
NetStream::kReady
@ kReady
Definition: netstream.h:101
NetStream::m_size
qlonglong m_size
Definition: netstream.h:105