forked from rofafor/vdr-plugin-iptv
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprotocolfile.cpp
134 lines (102 loc) · 3.26 KB
/
protocolfile.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
* protocolfile.c: IPTV plugin for the Video Disk Recorder
*
* See the README file for copyright information and how to reach the author.
*
*/
#include <vdr/device.h>
#include "common.h"
#include "config.h"
#include "log.h"
#include "protocolfile.h"
cIptvProtocolFile::cIptvProtocolFile()
: fileLocationM(strdup("")),
fileDelayM(0),
fileStreamM(nullptr),
isActiveM(false) {
debug1("%s", __PRETTY_FUNCTION__);
}
cIptvProtocolFile::~cIptvProtocolFile() {
debug1("%s", __PRETTY_FUNCTION__);
// Drop open handles
cIptvProtocolFile::Close();
// Free allocated memory
free(fileLocationM);
}
bool cIptvProtocolFile::OpenFile() {
debug1("%s", __PRETTY_FUNCTION__);
// Check that stream address is valid
if (!isActiveM && !isempty(fileLocationM)) {
fileStreamM = fopen(fileLocationM, "rb");
ERROR_IF_RET(!fileStreamM || ferror(fileStreamM), "fopen()", return false);
// Update active flag
isActiveM = true;
}
return true;
}
void cIptvProtocolFile::CloseFile() {
debug1("%s", __PRETTY_FUNCTION__);
// Check that file stream is valid
if (isActiveM && !isempty(fileLocationM)) {
fclose(fileStreamM);
// Update active flag
isActiveM = false;
}
}
int cIptvProtocolFile::Read(unsigned char *bufferAddrP, unsigned int bufferLenP) {
debug16("%s (, %u)", __PRETTY_FUNCTION__, bufferLenP);
// Check errors
if (!fileStreamM || ferror(fileStreamM)) {
debug1("%s (, %d) Stream error", __PRETTY_FUNCTION__, bufferLenP);
return -1;
}
// Rewind if EOF
if (feof(fileStreamM)) {
rewind(fileStreamM);
}
// Sleep before reading the file stream to prevent aggressive busy looping
// and prevent transfer ringbuffer overflows
if (fileDelayM) {
cCondWait::SleepMs(fileDelayM);
}
// This check is to prevent a race condition where file may be switched off
// during the sleep and buffers are disposed. Check here that the plugin is
// still active before accessing the buffers
if (isActiveM) {
return (int) fread(bufferAddrP, sizeof(unsigned char), bufferLenP, fileStreamM);
}
return -1;
}
bool cIptvProtocolFile::Open() {
debug1("%s", __PRETTY_FUNCTION__);
// Open the file stream
OpenFile();
return true;
}
bool cIptvProtocolFile::Close() {
debug1("%s", __PRETTY_FUNCTION__);
// Close the file stream
CloseFile();
return true;
}
bool cIptvProtocolFile::SetSource(SourceParameter parameter) {
debug1("%s (%s, %d, %d)", __PRETTY_FUNCTION__, parameter.locationP, parameter.parameterP, parameter.indexP);
if (!isempty(parameter.locationP)) {
// Close the file stream
CloseFile();
// Update stream address and port
fileLocationM = strcpyrealloc(fileLocationM, parameter.locationP);
fileDelayM = parameter.parameterP;
// Open the file for input
OpenFile();
}
return true;
}
bool cIptvProtocolFile::SetPid(int pidP, int typeP, bool onP) {
debug16("%s (%d, %d, %d)", __PRETTY_FUNCTION__, pidP, typeP, onP);
return true;
}
cString cIptvProtocolFile::GetInformation() {
debug16("%s", __PRETTY_FUNCTION__);
return cString::sprintf("file://%s:%d", fileLocationM, fileDelayM);
}