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>
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
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
);
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
)
46 case eServiceReference::idStructure
:
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/");
58 while (struct dirent64
*e
=readdir64(d
))
60 if (!(strcmp(e
->d_name
, ".") && strcmp(e
->d_name
, "..")))
63 filename
.sprintf("%s/enigma/root/%s", CONFIGDIR
,e
->d_name
);
65 if (stat64(filename
.c_str(), &s
)<0)
67 if (S_ISDIR(s
.st_mode
))
70 eServiceReference
service(eServiceReference::idFile
, dirflags
, filename
);
71 service
.data
[0]=!!S_ISDIR(s
.st_mode
);
72 cache
.addToNode(node
, service
);
81 case eServiceReference::idFile
:
83 DIR *d
=opendir(ref
.path
.c_str());
86 while (struct dirent64
*e
=readdir64(d
))
88 if (!(strcmp(e
->d_name
, ".") && strcmp(e
->d_name
, "..")))
96 if (stat64(filename
.c_str(), &s
)<0)
99 if (S_ISDIR(s
.st_mode
))
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
);
110 fileHandlers((void*)&node
, filename
);
120 void eServiceFileHandler::addReference(void *node
, const eServiceReference
&ref
)
123 result
=ref
; // super unthreadsafe und nichtmal reentrant.
125 cache
.addToNode(*(eServiceCache
<eServiceFileHandler
>::eNode
*)node
, ref
);
128 eService
*eServiceFileHandler::createService(const eServiceReference
&node
)
132 int n
=node
.path
.size()-2;
135 eString path
=node
.path
.mid(node
.path
.rfind("/", n
)+1);
137 path
=convertLatin1UTF8(path
);
138 return new eService(path
.c_str());
140 eServiceHandler
*handler
=eServiceInterface::getInstance()->getServiceHandler(node
.type
);
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
);
178 eAutoInitP0
<eServiceFileHandler
> i_eServiceFileHandler(eAutoInitNumbers::service
+1, "eServiceFileHandler");