fix redraw problem when adding a timer
[enigma2.git] / lib / service / servicefs.cpp
1 #include <lib/base/eerror.h>
2 #include <lib/base/object.h>
3 #include <string>
4 #include <errno.h>
5 #include <lib/service/servicefs.h>
6 #include <lib/service/service.h>
7 #include <lib/service/servicedvb.h>
8 #include <lib/base/init_num.h>
9 #include <lib/base/init.h>
10 #include <dirent.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <unistd.h>
14
15 class eStaticServiceFSInformation: public iStaticServiceInformation
16 {
17         DECLARE_REF(eStaticServiceFSInformation);
18 public:
19         RESULT getName(const eServiceReference &ref, std::string &name);
20         int getLength(const eServiceReference &ref) { return -1; }
21 };
22
23 DEFINE_REF(eStaticServiceFSInformation);
24
25 RESULT eStaticServiceFSInformation::getName(const eServiceReference &ref, std::string &name)
26 {
27         name = ref.path;
28 }
29
30 // eServiceFactoryFS
31
32 eServiceFactoryFS::eServiceFactoryFS()
33 {
34         ePtr<eServiceCenter> sc;
35         
36         eServiceCenter::getPrivInstance(sc);
37         if (sc)
38                 sc->addServiceFactory(eServiceFactoryFS::id, this);
39         
40         m_service_information = new eStaticServiceFSInformation();
41 }
42
43 eServiceFactoryFS::~eServiceFactoryFS()
44 {
45         ePtr<eServiceCenter> sc;
46         
47         eServiceCenter::getPrivInstance(sc);
48         if (sc)
49                 sc->removeServiceFactory(eServiceFactoryFS::id);
50 }
51
52 DEFINE_REF(eServiceFactoryFS)
53
54         // iServiceHandler
55 RESULT eServiceFactoryFS::play(const eServiceReference &ref, ePtr<iPlayableService> &ptr)
56 {
57         ptr=0;
58         return -1;
59 }
60
61 RESULT eServiceFactoryFS::record(const eServiceReference &ref, ePtr<iRecordableService> &ptr)
62 {
63         ptr=0;
64         return -1;
65 }
66
67 RESULT eServiceFactoryFS::list(const eServiceReference &ref, ePtr<iListableService> &ptr)
68 {
69         ptr = new eServiceFS(ref.path.c_str());
70         return 0;
71 }
72
73 RESULT eServiceFactoryFS::info(const eServiceReference &ref, ePtr<iStaticServiceInformation> &ptr)
74 {
75         ptr = m_service_information;
76         return 0;
77 }
78
79 RESULT eServiceFactoryFS::offlineOperations(const eServiceReference &, ePtr<iServiceOfflineOperations> &ptr)
80 {
81         ptr = 0;
82         return -1;
83 }
84
85 // eServiceFS
86
87 DEFINE_REF(eServiceFS);
88
89 eServiceFS::eServiceFS(const char *path): path(path)
90 {
91         m_list_valid = 0;
92 }
93
94 eServiceFS::~eServiceFS()
95 {
96 }
97
98 RESULT eServiceFS::getContent(std::list<eServiceReference> &list)
99 {
100         DIR *d=opendir(path.c_str());
101         if (!d)
102                 return -errno;
103         while (dirent *e=readdir(d))
104         {
105                 if (!(strcmp(e->d_name, ".") && strcmp(e->d_name, "..")))
106                         continue;
107                 
108                 std::string filename;
109                 
110                 filename = path;
111                 filename += e->d_name;
112                 
113                 struct stat s;
114                 if (::stat(filename.c_str(), &s) < 0)
115                         continue;
116                 
117                 if (S_ISDIR(s.st_mode))
118                         filename += "/";
119                 
120                 if (S_ISDIR(s.st_mode))
121                 {
122                         eServiceReference service(eServiceFactoryFS::id, 
123                                 eServiceReference::isDirectory|
124                                 eServiceReference::canDescent|eServiceReference::mustDescent|
125                                 eServiceReference::shouldSort|eServiceReference::sort1,
126                                 filename);
127                         service.data[0] = 1;
128                         list.push_back(service);
129                 } else
130                 {
131                                 /* FIIIIIX ME */
132                         if (filename.substr(filename.size()-3) == ".ts")
133                         {
134                                 eServiceReference service(eServiceFactoryDVB::id,
135                                         0,
136                                         filename);
137                                 service.data[0] = 0;
138                                 list.push_back(service);
139                         }
140                 }
141         }
142         closedir(d);
143         return 0;
144 }
145
146 RESULT eServiceFS::getNext(eServiceReference &ptr)
147 {
148         if (!m_list_valid)
149         {
150                 m_list_valid = 1;
151                 int res = getContent(m_list);
152                 if (res)
153                         return res;
154         }
155         
156         if (!m_list.size())
157         {
158                 ptr = eServiceReference();
159                 return -ERANGE;
160         }
161         
162         ptr = m_list.front();
163         m_list.pop_front();
164         return 0;
165 }
166
167 int eServiceFS::compareLessEqual(const eServiceReference &a, const eServiceReference &b)
168 {
169                 /* directories first */
170         if ((a.flags & ~b.flags) & eServiceReference::isDirectory)
171                 return 1;
172         else if ((~a.flags & b.flags) & eServiceReference::isDirectory)
173                 return 0;
174                 /* sort by filename */
175         else
176                 return a.path < b.path;
177 }
178
179 eAutoInitPtr<eServiceFactoryFS> init_eServiceFactoryFS(eAutoInitNumbers::service+1, "eServiceFactoryFS");