/**
* ======================== legal notice ======================
*
* File: FileSystemTest.cc
* Created: 21.07.2012, 12
* Author: Geronimo
* Project: cmps - the backend (server) part of compound media player
*
* CMP - compound media player
*
* is a client/server mediaplayer intended to play any media from any workstation
* without the need to export or mount shares. cmps is an easy to use backend
* with a (ready to use) HTML-interface. Additionally the backend supports
* authentication via HTTP-digest authorization.
* cmpc is a client with vdr-like osd-menues.
*
* Copyright (c) 2012 Reinhard Mantey, some rights reserved!
* published under Creative Commons by-sa
* For details see http://creativecommons.org/licenses/by-sa/3.0/
*
* The cmp project's homepage is at http://projects.vdr-developer.org/projects/cmp
*
* --------------------------------------------------------------
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
int visitor(void *opaque, cFile *Parent, const char *Name)
{
cFile *child = new cFile(*Parent, Name);
std::cout << Parent->Name() << " - has child-entry: " << Name << std::endl;
if (child->IsDirectory()) {
child->VisitFiles(visitor, opaque);
}
char *uri = child->toURI();
const char *path = child->AbsolutePath();
std::cout << "child does ";
if (!child->Exists()) std::cout << "NOT ";
std::cout << "exists ..." << std::endl;
std::cout << path << " - has URI: " << uri << std::endl << std::endl;
free(uri);
delete child;
return 0;
}
void test1()
{
std::cout << "FileSystemTest test 1" << std::endl;
cFile *f = new cFile("/media/xchange/");
const char *path = f->AbsolutePath();
std::cout << "got file: " << path << std::endl;
cFile *other = f->Parent();
other->SetVirtualRoot(true);
path = other->AbsolutePath();
std::cout << "parent is file: " << path << std::endl;
cFile *newOne = new cFile(*other, "/video/test/blah");
path = newOne->AbsolutePath();
std::cout << "assembled file: " << path << std::endl;
cFile *again = new cFile("/media/audio/Collection/Rock/Idol, Billy");
path = again->AbsolutePath();
std::cout << "re-assembled file: " << path << std::endl;
std::cout << path << " does ";
if (!again->Exists()) std::cout << "NOT ";
std::cout << "exists" << std::endl;
again->VisitFiles(visitor, NULL);
delete newOne;
delete other;
delete f;
delete again;
cFile::Cleanup();
}
int check4Media(void *opaque, cFile *Parent, const char *Name)
{
if (!opaque) return -1;
std::vector *pool = (std::vector *) opaque;
cFile *curFile = new cFile(*Parent, Name);
const char *mimeType = NULL;
cAbstractMedia *rv = NULL;
if (!curFile) {
esyslog("ERROR: out of memory!");
return -1;
}
if (!curFile->Exists()) {
delete curFile;
return -1;
}
if (curFile->IsDirectory()) {
static const char *keyFiles[] = { "001.vdr", "00001.ts", "VIDEO_TS/VIDEO_TS.IFO", NULL };
cFile *tmp;
const char *check;
int n=0;
for (const char **kf = keyFiles; kf && *kf; ++kf, ++n) {
tmp = new cFile(*curFile, *kf);
check = tmp ? tmp->AbsolutePath() : NULL;
if (tmp->Exists() && tmp->IsFile() && !tmp->IsDirectory()) {
switch (n) {
case 0: rv = new cLegacyVdrRecording(*curFile); break;
case 1: rv = new cVdrRecording(*curFile); break;
default: rv = new cDVDImage(*curFile); break;
}
}
delete tmp;
}
if (!rv) curFile->VisitFiles(check4Media, opaque);
}
else {
const char *extension = strrchr(Name, '.');
if (!extension) {
delete curFile;
return -1;
}
++extension;
mimeType = cMovie::ContentType(extension);
if (mimeType) rv = new cMovie(*curFile, mimeType);
else {
mimeType = cAudio::ContentType(extension);
if (mimeType) rv = new cAudio(*curFile, mimeType);
else {
mimeType = cPicture::ContentType(extension);
if (mimeType) rv = new cPicture(*curFile, mimeType);
}
}
}
delete curFile;
if (rv) {
pool->push_back(rv);
return 0;
}
else return -1;
}
void test2()
{
std::cout << "FileSystemTest test 2" << std::endl;
cFile mediaRoot("/media");
cFile &startScan = mediaRoot; //("/media/images");
if (!mediaRoot.Exists() || !mediaRoot.IsDirectory())
std::cout << "%TEST_FAILED% time=0 testname=test2 (FileSystemTest) message=error message sample" << std::endl;
if (!startScan.Exists() || !startScan.IsDirectory())
std::cout << "%TEST_FAILED% time=0 testname=test2 (FileSystemTest) message=error message sample" << std::endl;
mediaRoot.SetVirtualRoot();
std::vector mediaPool;
uint64_t start = cTimeMs::Now();
startScan.VisitFiles(check4Media, &mediaPool);
uint64_t end = cTimeMs::Now();
for (size_t i=0; i < mediaPool.size(); ++i) {
std::cout << "pool entry: " << mediaPool[i]->Name() << std::endl;
}
//19: got 9998 media in 8081ms. (with valgrind)
// ==9779== total heap usage: 637,920 allocs, 637,918 frees, 172,023,271 bytes allocated
//19: got 9998 media in 3750ms. (with valgrind)
//19: got 9998 media in 122ms. (without valgrind)
// ==30004== total heap usage: 348,984 allocs, 348,982 frees, 103,182,434 bytes allocated
//01: got 5739 media in 88165ms. (with valgrind)
// ==2605== total heap usage: 924,253 allocs, 924,247 frees, 259,567,759 bytes allocated
//01: got 5739 media in 71959ms. (with valgrind)
//01: got 5739 media in 54619ms. (without valgrind - fresh reboot)
//01: got 5739 media in 205ms (without valgrind - repeated run)
// ==2465== total heap usage: 469,151 allocs, 469,145 frees, 155,163,997 bytes allocated
std::cout << "got " << mediaPool.size() << " media in " << (end - start) << "ms." << std::endl;
for (size_t i=0; i < mediaPool.size(); ++i) {
delete mediaPool[i];
}
cFile::Cleanup();
}
int main(int argc, char** argv)
{
uint64_t t0 = cTimeMs::Now();
std::cout << "%SUITE_STARTING% FileSystemTest" << std::endl;
std::cout << "%SUITE_STARTED%" << std::endl;
std::cout << "%TEST_STARTED% test1 (FileSystemTest)" << std::endl;
uint64_t start = cTimeMs::Now();
test1();
uint64_t end = cTimeMs::Now();
std::cout << "%TEST_FINISHED% time=" << (double)(end - start) / 1000 << " test1 (FileSystemTest)" << std::endl;
std::cout << "%TEST_STARTED% test2 (FileSystemTest)\n" << std::endl;
start = cTimeMs::Now();
test2();
end = cTimeMs::Now();
std::cout << "%TEST_FINISHED% time=" << (double)(end - start) / 1000 << " test2 (FileSystemTest)" << std::endl;
std::cout << "%SUITE_FINISHED% time=" << (double)(cTimeMs::Now() - t0) / 1000 << std::endl;
return (EXIT_SUCCESS);
}