trunk 20080912
[gitenigma.git] / lib / dvb / servicefile.cpp
blob9fdcdd48c2665bfe5f1607f7cd4061326d74a20a
1 #include <lib/dvb/servicefile.h>
2 #include <lib/dvb/servicestructure.h>
3 #include <lib/system/init.h>
4 #include <lib/system/init_num.h>
5 #include <dirent.h>
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 #include <unistd.h>
11 eServiceFileHandler is some kind of a "multplexer", it gives
12 you a filesystem structure (with ref.path = path), and calls
13 "addFile" with every file. various file handlers can hook into
14 this handler and parse files and return a eServiceReference.
16 services itself are addRef'd first through the real handler (e.g.
17 the mp3 handler), then reflected back into serviceFileHandler,
18 then parsed by the cache (different file handlers to not need
19 to have their own), calls to createService will be forwared to
20 the module handlers.
23 eServiceFileHandler *eServiceFileHandler::instance;
25 static const int dirflags=eServiceReference::isDirectory|eServiceReference::canDescent|eServiceReference::mustDescent|eServiceReference::shouldSort|eServiceReference::sort1;
27 eServiceFileHandler::eServiceFileHandler(): eServiceHandler(eServiceReference::idFile), cache(*this)
29 if (eServiceInterface::getInstance()->registerHandler(id, this)<0)
30 eFatal("couldn't register serviceHandler %d", id);
31 instance=this;
32 cache.addPersistentService(eServiceReference(eServiceReference::idFile, dirflags, "/"), new eService("root"));
33 cache.addPersistentService(eServiceReference(eServiceReference::idFile, dirflags, "/hdd/"), new eService("harddisk"));
37 eServiceFileHandler::~eServiceFileHandler()
39 eServiceInterface::getInstance()->unregisterHandler(id);
42 void eServiceFileHandler::loadNode(eServiceCache<eServiceFileHandler>::eNode &node, const eServiceReference &ref)
44 switch (ref.type)
46 case eServiceReference::idStructure:
47 switch (ref.data[0])
49 case eServiceStructureHandler::modeRoot:
50 case eServiceStructureHandler::modeFile:
52 cache.addToNode(node, eServiceReference(eServiceReference::idFile, dirflags, "/"));
53 cache.addToNode(node, eServiceReference(eServiceReference::idFile, dirflags, "/hdd/"));
54 // Add all links present in $CONFIGDIR/enigma/root/ to root-menu
55 DIR *d=opendir(CONFIGDIR "/enigma/root/");
56 if (d)
58 while (struct dirent64 *e=readdir64(d))
60 if (!(strcmp(e->d_name, ".") && strcmp(e->d_name, "..")))
61 continue;
62 eString filename;
63 filename.sprintf("%s/enigma/root/%s", CONFIGDIR,e->d_name);
64 struct stat64 s;
65 if (stat64(filename.c_str(), &s)<0)
66 continue;
67 if (S_ISDIR(s.st_mode))
69 filename+="/";
70 eServiceReference service(eServiceReference::idFile, dirflags, filename);
71 service.data[0]=!!S_ISDIR(s.st_mode);
72 cache.addToNode(node, service);
75 closedir(d);
77 break;
80 break;
81 case eServiceReference::idFile:
83 DIR *d=opendir(ref.path.c_str());
84 if (!d)
85 return;
86 while (struct dirent64 *e=readdir64(d))
88 if (!(strcmp(e->d_name, ".") && strcmp(e->d_name, "..")))
89 continue;
90 eString filename;
92 filename=ref.path;
93 filename+=e->d_name;
95 struct stat64 s;
96 if (stat64(filename.c_str(), &s)<0)
97 continue;
99 if (S_ISDIR(s.st_mode))
100 filename+="/";
102 if (S_ISDIR(s.st_mode))
104 /* we allow a servicehandler to be registered to a directory */
105 directoryHandlers((void*)&node, filename);
106 eServiceReference service(eServiceReference::idFile, dirflags, filename);
107 service.data[0]=!!S_ISDIR(s.st_mode);
108 cache.addToNode(node, service);
109 } else
110 fileHandlers((void*)&node, filename);
112 closedir(d);
113 break;
115 default:
116 break;
120 void eServiceFileHandler::addReference(void *node, const eServiceReference &ref)
122 if (!node)
123 result=ref; // super unthreadsafe und nichtmal reentrant.
124 else
125 cache.addToNode(*(eServiceCache<eServiceFileHandler>::eNode*)node, ref);
128 eService *eServiceFileHandler::createService(const eServiceReference &node)
130 if (node.type == id)
132 int n=node.path.size()-2;
133 if (n<0)
134 n=0;
135 eString path=node.path.mid(node.path.rfind("/", n)+1);
136 if (!isUTF8(path))
137 path=convertLatin1UTF8(path);
138 return new eService(path.c_str());
140 eServiceHandler *handler=eServiceInterface::getInstance()->getServiceHandler(node.type);
141 if (!handler)
142 return 0;
143 return handler->createService(node);
146 void eServiceFileHandler::enterDirectory(const eServiceReference &dir, Signal1<void,const eServiceReference&> &callback)
148 cache.enterDirectory(dir, callback);
151 void eServiceFileHandler::leaveDirectory(const eServiceReference &dir)
153 cache.leaveDirectory(dir);
156 eService *eServiceFileHandler::addRef(const eServiceReference &service)
158 return cache.addRef(service);
161 void eServiceFileHandler::removeRef(const eServiceReference &service)
163 return cache.removeRef(service);
166 int eServiceFileHandler::lookupService(eServiceReference &ref, const char *filename)
168 result=eServiceReference();
169 fileHandlers(0, filename);
170 if (result)
172 ref=result;
173 return 1;
175 return 0;
178 eAutoInitP0<eServiceFileHandler> i_eServiceFileHandler(eAutoInitNumbers::service+1, "eServiceFileHandler");