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 <QSslError>
17 #include <QWaitCondition>
18 #include <QQueue>
19 #include <QDateTime>
20 
21 class QUrl;
22 class QNetworkAccessManager;
23 class NetStreamRequest;
24 class NetStreamAbort;
25 
26 
30 class NetStream : public QObject
31 {
32  Q_OBJECT
33 
34 public:
36  explicit NetStream(const QUrl &url, EMode mode = kPreferCache,
37  QByteArray cert = QByteArray());
38  ~NetStream() override;
39 
40 public:
41  // RingBuffer interface
42  static bool IsSupported(const QUrl &url);
43  bool IsOpen() const;
44  void Abort();
45  int safe_read(void *data, unsigned sz, unsigned millisecs = 0);
46  qlonglong Seek(qlonglong pos);
47  qlonglong GetReadPosition() const;
48  qlonglong GetSize() const;
49 
50  // Properties
51  const QUrl &Url() const { return m_url; }
52 
53  // Synchronous interface
54  bool WaitTillReady(unsigned long milliseconds);
55  bool WaitTillFinished(unsigned long milliseconds);
56  QNetworkReply::NetworkError GetError() const;
57  QString GetErrorString() const;
58  qlonglong BytesAvailable() const;
59  QByteArray ReadAll();
60 
61  // Async interface
62  bool isStarted() const;
63  bool isReady() const;
64  bool isFinished() const;
65 
66 signals:
67  void ReadyRead(QObject*);
68  void Finished(QObject*);
69 
70 public:
71  // Time when a URI was last written to cache or invalid if not cached.
72  static QDateTime GetLastModified(const QUrl &url);
73  // Is the network accessible
74  static bool isAvailable();
75 
76  // Implementation
77 private slots:
78  // NAMThread signals
79  void slotRequestStarted(int id, QNetworkReply *reply);
80  // QNetworkReply signals
81  void slotFinished();
82 #ifndef QT_NO_OPENSSL
83  void slotSslErrors(const QList<QSslError> & errors);
84 #endif
85  // QIODevice signals
86  void slotReadyRead();
87 
88 private:
89  Q_DISABLE_COPY(NetStream)
90 
91  bool Request(const QUrl &url);
92 
93  const int m_id; // Unique request ID
94  const QUrl m_url;
95 
96  mutable QMutex m_mutex; // Protects r/w access to the following data
97  QNetworkRequest m_request;
98  enum { kClosed, kPending, kStarted, kReady, kFinished } m_state {kClosed};
100  QNetworkReply* m_reply {nullptr};
102  qlonglong m_size {-1};
103  qlonglong m_pos {0};
104  QByteArray m_cert;
105  QWaitCondition m_ready;
106  QWaitCondition m_finished;
107 };
108 
109 
113 class NAMThread : public QThread
114 {
115  Q_OBJECT
116 
117  // Use manager() to create
118  NAMThread();
119 
120 public:
121  static NAMThread & manager(); // Singleton
122  ~NAMThread() override;
123 
124  static inline void PostEvent(QEvent *e) { manager().Post(e); }
125  void Post(QEvent *event);
126 
127  static inline QMutex* GetMutex() { return &manager().m_mutexNAM; }
128 
129  static bool isAvailable(); // is network usable
130  static QDateTime GetLastModified(const QUrl &url);
131 
132 signals:
133  void requestStarted(int, QNetworkReply *);
134 
135  // Implementation
136 protected:
137  void run() override; // QThread
138  bool NewRequest(QEvent *event);
140  static bool AbortRequest(NetStreamAbort *p);
141 
142 private slots:
143  void quit();
144 
145 private:
146  Q_DISABLE_COPY(NAMThread)
147 
148  volatile bool m_bQuit {false};
149  QSemaphore m_running;
150  mutable QMutex m_mutexNAM {QMutex::Recursive}; // Provides recursive access to m_nam
151  QNetworkAccessManager *m_nam {nullptr};
152  mutable QMutex m_mutex; // Protects r/w access to the following data
153  QQueue< QEvent * > m_workQ;
154  QWaitCondition m_work;
155 };
156 
157 #endif /* ndef NETSTREAM_H */
static bool AbortRequest(NetStreamAbort *p)
Definition: netstream.cpp:887
QNetworkAccessManager * m_nam
Definition: netstream.h:151
bool isFinished() const
Definition: netstream.cpp:704
void Finished(QObject *)
~NAMThread() override
Definition: netstream.cpp:753
bool isStarted() const
Asynchronous interface.
Definition: netstream.cpp:692
QWaitCondition m_ready
Definition: netstream.h:105
qlonglong GetSize() const
Definition: netstream.cpp:614
QString GetErrorString() const
Definition: netstream.cpp:665
NetStream(const QUrl &url, EMode mode=kPreferCache, QByteArray cert=QByteArray())
Network streaming request.
Definition: netstream.cpp:97
void quit()
Definition: netstream.cpp:838
QMutex m_mutex
Definition: netstream.h:152
const int m_id
Definition: netstream.h:93
unsigned int slots[4]
Definition: element.cpp:38
void slotFinished()
Definition: netstream.cpp:412
void slotSslErrors(const QList< QSslError > &errors)
Definition: netstream.cpp:475
void requestStarted(int, QNetworkReply *)
static void PostEvent(QEvent *e)
Definition: netstream.h:124
bool isReady() const
Definition: netstream.cpp:698
QWaitCondition m_work
Definition: netstream.h:154
void ReadyRead(QObject *)
const QUrl & Url() const
Definition: netstream.h:51
qlonglong GetReadPosition() const
Definition: netstream.cpp:607
void Abort()
Definition: netstream.cpp:529
static bool IsSupported(const QUrl &url)
RingBuffer interface.
Definition: netstream.cpp:515
QNetworkReply * m_reply
Definition: netstream.h:100
static QMutex * GetMutex()
Definition: netstream.h:127
qlonglong Seek(qlonglong pos)
Definition: netstream.cpp:586
QByteArray ReadAll()
Definition: netstream.cpp:677
static QDateTime GetLastModified(const QUrl &url)
Definition: netstream.cpp:721
int m_nRedirections
Definition: netstream.h:101
QByteArray m_cert
Definition: netstream.h:104
bool IsOpen() const
Definition: netstream.cpp:523
int safe_read(void *data, unsigned sz, unsigned millisecs=0)
Definition: netstream.cpp:554
void slotRequestStarted(int id, QNetworkReply *reply)
Definition: netstream.cpp:277
void run() override
Definition: netstream.cpp:760
volatile bool m_bQuit
Definition: netstream.h:148
QMutex m_mutex
Definition: netstream.h:96
static QDateTime GetLastModified(const QUrl &url)
Definition: netstream.cpp:929
bool StartRequest(NetStreamRequest *p)
Definition: netstream.cpp:867
bool WaitTillFinished(unsigned long milliseconds)
Definition: netstream.cpp:642
static bool isAvailable()
Definition: netstream.cpp:904
static bool isAvailable()
Public helpers.
Definition: netstream.cpp:714
QWaitCondition m_finished
Definition: netstream.h:106
const QUrl m_url
Definition: netstream.h:94
qlonglong BytesAvailable() const
Definition: netstream.cpp:671
bool Request(const QUrl &url)
Definition: netstream.cpp:157
void Post(QEvent *event)
Definition: netstream.cpp:844
QMutex m_mutexNAM
Definition: netstream.h:150
QNetworkRequest m_request
Definition: netstream.h:97
Stream content from a URI.
Definition: netstream.h:30
bool WaitTillReady(unsigned long milliseconds)
Synchronous interface.
Definition: netstream.cpp:625
bool NewRequest(QEvent *event)
Definition: netstream.cpp:850
static NAMThread & manager()
NetworkAccessManager event loop thread.
Definition: netstream.cpp:731
~NetStream() override
Definition: netstream.cpp:122
QSemaphore m_running
Definition: netstream.h:149
Thread to process NetStream requests.
Definition: netstream.h:113
qlonglong m_pos
Definition: netstream.h:103
QQueue< QEvent * > m_workQ
Definition: netstream.h:153
void slotReadyRead()
Definition: netstream.cpp:362
qlonglong m_size
Definition: netstream.h:102
enum NetStream::@19 kClosed
QNetworkReply::NetworkError GetError() const
Definition: netstream.cpp:659
NetStreamRequest * m_pending
Definition: netstream.h:99