diff options
Diffstat (limited to 'libs/fsScan/src')
-rw-r--r-- | libs/fsScan/src/AbstractMedia.cc | 78 | ||||
-rw-r--r-- | libs/fsScan/src/AbstractMultiFileMovie.cc | 89 | ||||
-rw-r--r-- | libs/fsScan/src/Audio.cc | 16 | ||||
-rw-r--r-- | libs/fsScan/src/DVDImage.cc | 87 | ||||
-rw-r--r-- | libs/fsScan/src/File.cc | 101 | ||||
-rw-r--r-- | libs/fsScan/src/FileRepresentation.cc | 81 | ||||
-rw-r--r-- | libs/fsScan/src/FileSystem.cc | 20 | ||||
-rw-r--r-- | libs/fsScan/src/FilesystemScanner.cc | 82 | ||||
-rw-r--r-- | libs/fsScan/src/LegacyVdrRecording.cc | 83 | ||||
-rw-r--r-- | libs/fsScan/src/MediaFactory.cc | 137 | ||||
-rw-r--r-- | libs/fsScan/src/Movie.cc | 16 | ||||
-rw-r--r-- | libs/fsScan/src/Picture.cc | 16 | ||||
-rw-r--r-- | libs/fsScan/src/VdrRecording.cc | 80 |
13 files changed, 476 insertions, 410 deletions
diff --git a/libs/fsScan/src/AbstractMedia.cc b/libs/fsScan/src/AbstractMedia.cc index 17cf86c..54a60d6 100644 --- a/libs/fsScan/src/AbstractMedia.cc +++ b/libs/fsScan/src/AbstractMedia.cc @@ -1,29 +1,32 @@ /** * ======================== legal notice ====================== - * + * * File: AbstractMedia.cc * Created: 2. Juli 2012, 14 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: libfsScan: mediatypes and filesystem scanning - * + * * 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 <AbstractMedia.h> #include <Logging.h> +#include <File.h> +#include <Url.h> +#include <Codec.h> #include <stddef.h> #include <stdlib.h> #include <string.h> @@ -32,24 +35,27 @@ #include <errno.h> #include <unistd.h> -cAbstractMedia::cAbstractMedia(cAbstractMedia::SupportedMediaType Type, const char *Name, const char *Logical, const char *Path, const char *Mime) +cAbstractMedia::cAbstractMedia(const cFile &File, const char *Mime, SupportedMediaType Type) : fd(-1) , mediaType(Type) - , logicalPath(Logical ? strdup(Logical) : NULL) - , realPath(Path ? strdup(Path) : NULL) - , name(Name ? strdup(Name) : NULL) , mimeType(Mime ? strdup(Mime) : NULL) - , lastModified(0) - , size(0) + , uri(NULL) + , keyPath(File) { + char *tmp = keyPath.toURI(); + uri = cUrl::Decoder()->Decode(tmp); + free(tmp); } cAbstractMedia::~cAbstractMedia() { - free(logicalPath); - free(realPath); - free(name); free(mimeType); + free(uri); +} + +const char *cAbstractMedia::Name(void) const +{ + return keyPath.Name(); } void cAbstractMedia::Refresh(void) @@ -59,25 +65,31 @@ void cAbstractMedia::Refresh(void) size_t cAbstractMedia::ReadChunk(char* Buf, size_t bufSize) { long rv = 0; + const char *path = AbsolutePath(); - if (fd < 1) { // fp stays open between various calls - fd = open(RealPath(), O_RDONLY | O_LARGEFILE); + if (fd < 1) { // fd stays open between various calls + fd = open(path, O_RDONLY | O_LARGEFILE); if (fd < 1) { - esyslog("could not open requested path %s - Error #%d", RealPath(), errno); + esyslog("could not open requested path %s - Error #%d", path, errno); return 0; } } - isyslog("have filehandle #%d (%s)", fd, RealPath()); + isyslog("have filehandle #%d (%s)", fd, path); if ((rv = read(fd, Buf, bufSize)) < 0) - esyslog("ERROR: failed to read from file %s #%d", RealPath(), errno); + esyslog("ERROR: failed to read from file %s #%d", path, errno); else - isyslog("read %u bytes from file", rv); + isyslog("read %u bytes from file %s", rv, path); if (rv < (long) bufSize) { // most probabely end of file close(fd); } return rv; } +size_t cAbstractMedia::Size(void) const +{ + return keyPath.Size(); +} + const char *cAbstractMedia::MediaType2Text(int Type) { switch(Type) { @@ -89,4 +101,26 @@ const char *cAbstractMedia::MediaType2Text(int Type) case Picture: return TO_STRING(Picture); default: return TO_STRING(Invalid); } -}
\ No newline at end of file +} + +const char *cAbstractMedia::AbsolutePath(void) const +{ + return keyPath.AbsolutePath(); +} + +ulong cAbstractMedia::LastModified(void) const +{ + return keyPath.LastModified(); +} + +const char *cAbstractMedia::URI(void) const +{ + return uri; +} + +void cAbstractMedia::SetMimeType(const char *MimeType) +{ + if (mimeType == MimeType) return; + free(mimeType); + mimeType = strdup(MimeType); +} diff --git a/libs/fsScan/src/AbstractMultiFileMovie.cc b/libs/fsScan/src/AbstractMultiFileMovie.cc index 823130e..a5de060 100644 --- a/libs/fsScan/src/AbstractMultiFileMovie.cc +++ b/libs/fsScan/src/AbstractMultiFileMovie.cc @@ -1,25 +1,25 @@ /** * ======================== legal notice ====================== - * + * * File: AbstractMultiFileMovie.cc * Created: 3. Juli 2012, 07 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: libfsScan: mediatypes and filesystem scanning - * + * * 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 <AbstractMultiFileMovie.h> @@ -29,45 +29,57 @@ #include <errno.h> #include <unistd.h> -cAbstractMultiFileMovie::cAbstractMultiFileMovie(const char *Name, const char *Logical, const char *Path, const char *Mime, SupportedMediaType Type) - : cMovie(Name, Logical, Path, Mime, Type) +cAbstractMultiFileMovie::cAbstractMultiFileMovie(const cFile &File, const char *Mime, SupportedMediaType Type) + : cMovie(File, Mime, Type) , movieFiles(0) , curFileNo(0) - , fileNameBuf(NULL) + , buf(NULL) , bufSize(0) + , name(NULL) { } cAbstractMultiFileMovie::~cAbstractMultiFileMovie() { - free(fileNameBuf); + free(name); + free(buf); +} + +bool cAbstractMultiFileMovie::checkBuffer() +{ + if (!buf && bufSize) { + buf = (char *) malloc(bufSize); + } + return buf != NULL; } size_t cAbstractMultiFileMovie::ReadChunk(char* Buf, size_t bufSize) { long rv = 0; + const char *path = NULL; if (fd < 1) { - fd = open(FirstFile(), O_RDONLY | O_LARGEFILE); + path = FirstFile(); + fd = open(path, O_RDONLY | O_LARGEFILE); if (fd < 1) { - esyslog("could not open requested path %s - Error #%d", FirstFile(), errno); + esyslog("could not open requested path %s - Error #%d", path, errno); return 0; } } - isyslog("have filehandle #%d (%s)", fd, FirstFile()); + isyslog("have filehandle #%d (%s)", fd, path); rv = read(fd, Buf, bufSize); if (rv < (long) bufSize) { - const char *nextFilename = NextFile(); + path = NextFile(); - if (nextFilename) { + if (path) { close(fd); - fd = open(nextFilename, O_RDONLY | O_LARGEFILE); + fd = open(path, O_RDONLY | O_LARGEFILE); if (fd < 1) { - esyslog("could not open requested path %s - Error #%d", nextFilename, errno); + esyslog("could not open requested path %s - Error #%d", path, errno); return 0; } - isyslog("have filehandle #%d (%s)", fd, nextFilename); + isyslog("have filehandle #%d (%s)", fd, path); rv = read(fd, Buf, bufSize); } if (rv < (long) bufSize) { @@ -78,34 +90,13 @@ size_t cAbstractMultiFileMovie::ReadChunk(char* Buf, size_t bufSize) return rv; } -//int cAbstractMultiFileMovie::ReadBlah(char* buf, size_t bufSize) -//{ -// size_t bytesRead = 0; -// -// if (!fp) { -// if (!(fp = f open(FirstFile(), "r"))) { -// //TODO: add some verbose error message? -// return 0; -// } -// } -// -// bytesRead = f read(buf, sizeof(char), bufSize, fp); -// -// if (bytesRead < bufSize) { -// const char *nextFilename = NextFile(); -// -// if (nextFilename) { -// f close(fp); -// if (!(fp = f open(nextFilename, "r"))) { -// //TODO: be verbose -// return 0; -// } -// bytesRead += f read(buf + bytesRead, sizeof(char), bufSize - bytesRead, fp); -// } -// if (bytesRead < bufSize) { -// f close(fp); -// fp = NULL; -// } -// } -// return bytesRead; -//} +void cAbstractMultiFileMovie::SetName(char* Name) +///< Name must have already been allocated from heap! +{ + name = Name; +} + +void cAbstractMultiFileMovie::SetSize(size_t Size) +{ + size = Size; +}
\ No newline at end of file diff --git a/libs/fsScan/src/Audio.cc b/libs/fsScan/src/Audio.cc index 6d92576..8933c36 100644 --- a/libs/fsScan/src/Audio.cc +++ b/libs/fsScan/src/Audio.cc @@ -1,25 +1,25 @@ /** * ======================== legal notice ====================== - * + * * File: Audio.cc * Created: 2. Juli 2012, 15 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: libfsScan: mediatypes and filesystem scanning - * + * * 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 <Audio.h> @@ -46,8 +46,8 @@ SupportedExtension cAudio::knownExtensions[] = { { NULL, NULL } }; -cAudio::cAudio(const char *Name, const char *Logical, const char *Path, const char *Mime) - : cAbstractMedia(Audio, Name, Logical, Path, Mime) +cAudio::cAudio(const cFile &File, const char *Mime) + : cAbstractMedia(File, Mime, Audio) { } diff --git a/libs/fsScan/src/DVDImage.cc b/libs/fsScan/src/DVDImage.cc index 6ce7d30..8c789b4 100644 --- a/libs/fsScan/src/DVDImage.cc +++ b/libs/fsScan/src/DVDImage.cc @@ -1,100 +1,117 @@ /** * ======================== legal notice ====================== - * + * * File: DVDImage.cc * Created: 3. Juli 2012, 08 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: libfsScan: mediatypes and filesystem scanning - * + * * 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 <DVDImage.h> #include <string.h> #include <stdlib.h> #include <stdio.h> + +#include "File.h" #define FILE_MASK "VIDEO_TS/VTS_%02d_%d.VOB" -cDVDImage::cDVDImage(const char *Name, const char *Logical, const char *Path) - : cAbstractMultiFileMovie(Name, Logical, Path, "video/mpeg", DVDImage) +cDVDImage::cDVDImage(const cFile &File) + : cAbstractMultiFileMovie(File, "video/mpeg", DVDImage) { + bufSize = 32; } cDVDImage::~cDVDImage() { } +const char *cDVDImage::Name(void) const +{ + return cAbstractMedia::Name(); +} + +size_t cDVDImage::Size(void) const +{ + return cAbstractMedia::Size(); +} + void cDVDImage::Refresh(void) { - struct stat stBuf; size_t maxSize = 0; size_t total = 0; - time_t lastMod = 0; + int numOfMovieFiles = 0; + cFile *tmp; - if (!fileNameBuf) { - if (!(fileNameBuf = (char *)malloc(strlen(RealPath()) + 10))) { - //TODO: some error message? - return; - } - strcpy(fileNameBuf, RealPath()); - } movieFiles = 0; mainMovie = 0; - + if (!checkBuffer()) return; for (int movie = 1; movie < 100; ++movie) { total = 0; for (int fileNo = 1;; ++fileNo) { - sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, movie, fileNo); - if (stat(fileNameBuf, &stBuf) < 0) { - movieFiles = fileNo - 1; + sprintf(buf, FILE_MASK, movie, fileNo); + tmp = new cFile(KeyPath(), buf); + + if (!tmp || !tmp->Exists()) { + numOfMovieFiles = fileNo - 1; break; } - total += stBuf.st_size; - if (stBuf.st_mtime > lastMod) lastMod = stBuf.st_mtime; + total += tmp->Size(); + delete tmp; } if (total > maxSize) { maxSize = total; mainMovie = movie; + movieFiles = numOfMovieFiles; } } SetSize(total); - SetLastModified(lastMod); } const char *cDVDImage::FirstFile(void) { - if (!fileNameBuf) { - if (!(fileNameBuf = (char *)malloc(strlen(RealPath()) + 10))) { - //TODO: some error message? - return NULL; - } - strcpy(fileNameBuf, RealPath()); - } + if (!checkBuffer()) return NULL; + curFileNo = 1; - sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, mainMovie, curFileNo); + sprintf(buf, FILE_MASK, mainMovie, curFileNo); + cFile *tmp = new cFile(KeyPath(), buf); + const char *rv = NULL; - return fileNameBuf; + if (tmp) { + rv = tmp->AbsolutePath(); + delete tmp; + } + return rv; } const char *cDVDImage::NextFile(void) { if (++curFileNo < movieFiles) { - sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, mainMovie, curFileNo); + if (!checkBuffer()) return NULL; + sprintf(buf, FILE_MASK, mainMovie, curFileNo); + cFile *tmp = new cFile(KeyPath(), buf); + const char *rv = NULL; - return fileNameBuf; + if (tmp) { + tmp->AbsolutePath(); + delete tmp; + + return rv; + } } return NULL; } diff --git a/libs/fsScan/src/File.cc b/libs/fsScan/src/File.cc index c88fd7c..477c5c8 100644 --- a/libs/fsScan/src/File.cc +++ b/libs/fsScan/src/File.cc @@ -1,25 +1,25 @@ /** * ======================== legal notice ====================== - * + * * File: File.cc - * Created: 21. Juli 2012, 12:41 + * Created: 21. Juli 2012, 12 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: libfsScan: mediatypes and filesystem scanning - * + * * 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 <File.h> @@ -39,7 +39,18 @@ cFile::cFile(const char *Path) : rep(NULL) { if (!fs) fs = new cFileSystem(); - rep = fs->representationOfFile(Path); + if (!Path) { + Path = getcwd(NULL, 0); + rep = fs->representationOfFile(Path); + free((char *) Path); + } + else rep = fs->representationOfFile(Path); +} + +cFile::cFile(const cFile &other) + : rep(other.rep) +{ + if (!fs) fs = new cFileSystem(); } cFile::cFile(const cFile& Parent, const char* RelativePath) @@ -59,88 +70,112 @@ cFile::~cFile() { } -char *cFile::AbsolutePath(void) const +cFile &cFile::operator =(const cFile &other) { - cStringBuilder *sb = rep->internalPath(); - char *rv = NULL; + rep = other.rep; + return *this; +} - if (sb) { - rv = sb->toString(); - delete sb; - } - return rv; +const char *cFile::AbsolutePath(void) const +{ + if (rep) return rep->Path(); + return NULL; } bool cFile::Exists(void) const { - return rep->exists; + if (rep) return rep->exists; + return false; } bool cFile::IsDirectory(void) const { - return (rep->mode & S_IFMT) == S_IFDIR; + if (rep) return (rep->mode & S_IFMT) == S_IFDIR; + return false; } bool cFile::IsFile(void) const { - return (rep->mode & S_IFMT) == S_IFREG; + if (rep) return (rep->mode & S_IFMT) == S_IFREG; + return false; } bool cFile::IsSymbolic(void) const { - return (rep->mode & S_IFMT) == S_IFLNK; + if (rep) return (rep->mode & S_IFMT) == S_IFLNK; + return false; } bool cFile::CanRead(void) const { - return rep->mode & ReadMask; + if (rep) return rep->mode & ReadMask; + return false; } bool cFile::CanWrite(void) const { - return rep->mode & WriteMask; + if (rep) return rep->mode & WriteMask; + return false; } bool cFile::CanExecute(void) const { - return rep->mode & ExecMask; + if (rep) return rep->mode & ExecMask; + return false; } off64_t cFile::Size(void) const { - return rep->size; + if (rep) return rep->size; + return 0; } ulong cFile::LastModified(void) const { - return rep->lastModified; + if (rep) return rep->lastModified; + return 0; } cFile *cFile::Parent(void) const { - return new cFile(rep->getParent()); + if (rep) return new cFile(rep->getParent()); + return NULL; } const char *cFile::Name(void) const { - return rep->name; + if (rep) return rep->name; + return NULL; } void cFile::Cleanup(void) { - if (fs) delete fs; + if (fs) { + delete fs; + fs = NULL; + } } -void cFile::VisitFiles(int (*cb)(cFile *, const char *)) +void cFile::VisitFiles(int (*cb)(void *, cFile *, const char *), void *opaque) { + if (!Exists() || !IsDirectory()) return; struct dirent entryBuffer, *pE; - char * path = AbsolutePath(); - DIR *dir = opendir(path); + DIR *dir = opendir(AbsolutePath()); while (!readdir_r(dir, &entryBuffer, &pE) && pE) { if (*(pE->d_name) == '.') continue; // don't bother with hidden stuff - cb(this, pE->d_name); + cb(opaque, this, pE->d_name); } closedir(dir); - free(path); +} + +char *cFile::toURI() const +{ + if (rep) return rep->toURI(); + return NULL; +} + +void cFile::SetVirtualRoot(bool isRoot) +{ + if (rep) ((cFileRepresentation *)rep)->SetVirtualRoot(isRoot); } diff --git a/libs/fsScan/src/FileRepresentation.cc b/libs/fsScan/src/FileRepresentation.cc index 8899e16..81599a3 100644 --- a/libs/fsScan/src/FileRepresentation.cc +++ b/libs/fsScan/src/FileRepresentation.cc @@ -1,30 +1,32 @@ /** * ======================== legal notice ====================== - * + * * File: FileRepresentation.cc - * Created: 21. Juli 2012, 12:41 + * Created: 21. Juli 2012, 12 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: libfsScan: mediatypes and filesystem scanning - * + * * 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 <FileRepresentation.h> #include <FileSystem.h> #include <StringBuilder.h> +#include <Url.h> +#include <Codec.h> #include <sys/types.h> #include <sys/stat.h> #include <string.h> @@ -32,19 +34,21 @@ #include <iostream> #include <stack> -cFileRepresentation::cFileRepresentation(const char *Path) +cFileRepresentation::cFileRepresentation(const char *Name) : exists(false) , isRoot(true) + , isVirtualRoot(true) , mode(0) , size(0) , lastModified(0) , name(NULL) + , path(NULL) , parent(NULL) { struct stat st; - if (!stat(Path, &st)) { - name = strdup(Path); + if (!stat(Name, &st)) { + name = strdup(Name); exists = true; mode = st.st_mode; size = st.st_size; @@ -52,58 +56,77 @@ cFileRepresentation::cFileRepresentation(const char *Path) } } -cFileRepresentation::cFileRepresentation(const cFileRepresentation *Parent, const char *Path) +cFileRepresentation::cFileRepresentation(const cFileRepresentation *Parent, const char *Name) : exists(false) , isRoot(false) + , isVirtualRoot(false) , mode(0) , size(0) , lastModified(0) - , name(NULL) + , name(strdup(Name)) + , path(NULL) , parent(Parent) { - name = strdup(Path); - cStringBuilder *sb = internalPath(); - char *tmp = sb->toString(); struct stat st; - std::cout << "real path is: " << tmp << std::endl; - if (!stat(tmp, &st)) { + if (!stat(Path(), &st)) { exists = true; mode = st.st_mode; size = st.st_size; lastModified = st.st_mtime; } - free(tmp); - delete sb; - std::cout << "should create file representation for " << Path << std::endl; } cFileRepresentation::~cFileRepresentation() { free(name); + free(path); +} + +const char *cFileRepresentation::Path() const +{ + if (!path) { + cStringBuilder sb; + + if (parent) sb.Append(parent->Path()); + sb.Append(cFileSystem::PathSeparator).Append(name); + path = sb.toString(); + } + return path; +} + +void cFileRepresentation::SetVirtualRoot(bool isRoot) +{ + isVirtualRoot = isRoot; } -cStringBuilder *cFileRepresentation::internalPath(void) const +char *cFileRepresentation::toURI() const { cStringBuilder *sb = new cStringBuilder(); const cFileRepresentation *f = this; std::stack<const cFileRepresentation *> rev; - char *chk; + cURLEncoder *enc = cUrl::Encoder(); + char *tmp, *chk, *rv; + size_t stackSize; - while (!f->isRoot) { + while (!f->isVirtualRoot) { rev.push(f); + stackSize = rev.size(); f = f->parent; } for (;;) { - sb->Append(f->name); - if (rev.empty()) break; - chk = f->name + strlen(f->name) - 1; - if (*chk != cFileSystem::PathSeparator) sb->Append(cFileSystem::PathSeparator); f = rev.top(); rev.pop(); + chk = f->name + strlen(f->name) - 1; + if (*chk != cFileSystem::PathSeparator) sb->Append(cFileSystem::PathSeparator); + tmp = enc->Encode(f->name); + sb->Append(tmp); + free(tmp); + if (rev.empty()) break; } + rv = sb->toString(); + delete sb; - return sb; + return rv; } - diff --git a/libs/fsScan/src/FileSystem.cc b/libs/fsScan/src/FileSystem.cc index 9d467c6..3891c97 100644 --- a/libs/fsScan/src/FileSystem.cc +++ b/libs/fsScan/src/FileSystem.cc @@ -1,25 +1,25 @@ /** * ======================== legal notice ====================== - * + * * File: FileSystem.cc - * Created: 21. Juli 2012, 12:44 + * Created: 21. Juli 2012, 12 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: libfsScan: mediatypes and filesystem scanning - * + * * 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 <FileSystem.h> @@ -49,6 +49,7 @@ cFileSystem::~cFileSystem() cFileRepresentation *cFileSystem::cacheEntry(const char* Path) { + if (fileCache.empty()) return NULL; std::tr1::unordered_map<std::string, cFileRepresentation *>::iterator it = fileCache.find(Path); if (it != fileCache.end()) return it->second; @@ -59,7 +60,7 @@ cFileRepresentation *cFileSystem::representationOfFile(const cFile &Parent, cons { cFileRepresentation *parentRep = (cFileRepresentation *) Parent.rep; cFileRepresentation *tmp = NULL; - cStringBuilder *sb = parentRep->internalPath(); + cStringBuilder *sb = new cStringBuilder(Parent.AbsolutePath()); char *scratch = strdup(Path); char *last = scratch + strlen(Path); char *start = *scratch == PathSeparator ? scratch + 1 : scratch; @@ -103,11 +104,10 @@ cFileRepresentation *cFileSystem::representationOfFile(const char* Path) if (!(rv = cacheEntry(RootPath))) { *p = 0; tmp = new cFileRepresentation(RootPath); - fileCache["/"] = tmp; + fileCache[RootPath] = tmp; break; } } - std::cout << "check path " << scratch << std::endl; if ((tmp = cacheEntry(scratch))) break; } diff --git a/libs/fsScan/src/FilesystemScanner.cc b/libs/fsScan/src/FilesystemScanner.cc index 2315ee1..23b5074 100644 --- a/libs/fsScan/src/FilesystemScanner.cc +++ b/libs/fsScan/src/FilesystemScanner.cc @@ -1,25 +1,25 @@ /** * ======================== legal notice ====================== - * + * * File: FilesystemScanner.cc * Created: 2. Juli 2012, 13 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: libfsScan: mediatypes and filesystem scanning - * + * * 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 <FilesystemScanner.h> @@ -41,9 +41,7 @@ void freeMediaCallback(void *elem) } cFilesystemScanner::cFilesystemScanner() - : baseDirectory(NULL) - , fileBufSize(512) - , dirEntryBuf(NULL) + : fileBufSize(512) , pool(freeMediaCallback) , mediaFactory(NULL) { @@ -51,28 +49,16 @@ cFilesystemScanner::cFilesystemScanner() cFilesystemScanner::~cFilesystemScanner() { - FREE(dirEntryBuf); - FREE(baseDirectory); pool.clear(); if (mediaFactory) delete mediaFactory; } -void cFilesystemScanner::SetBaseDirectory(const char* dir) -{ - FREE(baseDirectory); - baseDirectory = strdup(dir); - if (mediaFactory) mediaFactory->SetBaseDirectory(dir); -} - void cFilesystemScanner::SetMediaFactory(cMediaFactory* factory) { - if ((mediaFactory = factory)) { - FREE(baseDirectory); - baseDirectory = strdup(mediaFactory->BaseDirectory()); - } + mediaFactory = factory; } -// return true if a should be ordered before b +// return true if "a" should be ordered before "b" bool defaultMediaSortOrder(void *a, void *b) { if (a == b) return false; @@ -95,13 +81,8 @@ void cFilesystemScanner::Refresh() if (!mediaFactory) return; pool.clear(); categories.clear(); - dirEntryBuf = (struct dirent *)malloc(sizeof(struct dirent)); - if (!dirEntryBuf) { - esyslog("ERROR: out of memory!"); - return; - } - parseDir(baseDirectory, pool); - FREE(dirEntryBuf); + + mediaFactory->Scan4Media(pool); cAbstractMedia::SupportedMediaType ot = cAbstractMedia::Invalid; cAbstractMedia *m; @@ -115,51 +96,16 @@ void cFilesystemScanner::Refresh() } } -void cFilesystemScanner::parseDir(const char* dirName, cManagedVector &result) -{ - if (!mediaFactory) return; - DIR *dir = opendir(dirName); - cAbstractMedia *media; - char *pathBuf = (char *)malloc(fileBufSize); - struct dirent *dirEntry; - struct stat statBuf; - - if (!dir) return; - if (!pathBuf) { - closedir(dir); - return; - } - if (fileBufSize < strlen(dirName) + 128) { - fileBufSize += 256; - pathBuf = (char *)realloc(pathBuf, fileBufSize); - } - while (!readdir_r(dir, dirEntryBuf, &dirEntry) && dirEntry) { - if (*dirEntry->d_name == '.') continue; // don't bother with hidden stuff - strcpy(pathBuf, dirName); - strcat(pathBuf, "/"); - strcat(pathBuf, dirEntry->d_name); - if (stat(pathBuf, &statBuf) < 0) return; - if ((media = mediaFactory->CreateMedia(pathBuf, &statBuf))) { - result.push_back(media); - isyslog("found media %s - %s", media->MimeType(), media->LogicalPath()); - continue; - } - if ((statBuf.st_mode & S_IFMT) == S_IFDIR) parseDir(pathBuf, result); - } - closedir(dir); - FREE(pathBuf); -} - -cAbstractMedia *cFilesystemScanner::FindMedia(const char* LogicalPath) +cAbstractMedia *cFilesystemScanner::FindMedia(const char* URI) { cAbstractMedia *rv = NULL, *tmp; for (size_t i=0; i < pool.size(); ++i) { tmp = (cAbstractMedia *) pool[i]; - if (!strcmp(tmp->LogicalPath(), LogicalPath)) { + if (!strcmp(tmp->URI(), URI)) { rv = tmp; break; } } return rv; -}
\ No newline at end of file +} diff --git a/libs/fsScan/src/LegacyVdrRecording.cc b/libs/fsScan/src/LegacyVdrRecording.cc index 29bebe7..731d0f3 100644 --- a/libs/fsScan/src/LegacyVdrRecording.cc +++ b/libs/fsScan/src/LegacyVdrRecording.cc @@ -1,36 +1,47 @@ /** * ======================== legal notice ====================== - * + * * File: LegacyVdrRecording.cc * Created: 3. Juli 2012, 08 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: libfsScan: mediatypes and filesystem scanning - * + * * 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 <LegacyVdrRecording.h> +#include <StringBuilder.h> +#include <File.h> #include <string.h> #include <stdlib.h> #include <stdio.h> -#define FILE_MASK "/%03d.vdr" -cLegacyVdrRecording::cLegacyVdrRecording(const char *Name, const char *Logical, const char *Path) - : cAbstractMultiFileMovie(Name, Logical, Path, "video/mpeg", LegacyVdrRecording) +#define FILE_MASK "%03d.vdr" + +cLegacyVdrRecording::cLegacyVdrRecording(const cFile &File) + : cAbstractMultiFileMovie(File, "video/mpeg", LegacyVdrRecording) { + cStringBuilder sb; + cFile *parent = File.Parent(); + + sb.Append(parent->Name()); + sb.Append(" (").Append(File.Name()).Append(")"); + delete parent; + SetName(sb.toString()); + bufSize = 8; } cLegacyVdrRecording::~cLegacyVdrRecording() @@ -39,53 +50,55 @@ cLegacyVdrRecording::~cLegacyVdrRecording() void cLegacyVdrRecording::Refresh(void) { - struct stat stBuf; size_t total = 0; - time_t lastMod = 0; + cFile *tmp; - if (!fileNameBuf) { - if (!(fileNameBuf = (char *)malloc(strlen(RealPath()) + 10))) { - //TODO: some error message? - return; - } - strcpy(fileNameBuf, RealPath()); - } + if (!checkBuffer()) return; movieFiles = 0; - for (int fileNo = 1;; ++fileNo) { - sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, fileNo); - if (stat(fileNameBuf, &stBuf) < 0) { + sprintf(buf, FILE_MASK, fileNo); + tmp = new cFile(KeyPath(), buf); + + if (!tmp || !tmp->Exists()) { movieFiles = fileNo - 1; + delete tmp; break; } - total += stBuf.st_size; - if (stBuf.st_mtime > lastMod) lastMod = stBuf.st_mtime; + total += tmp->Size(); + delete tmp; } SetSize(total); - SetLastModified(lastMod); } const char *cLegacyVdrRecording::FirstFile(void) { - if (!fileNameBuf) { - if (!(fileNameBuf = (char *)malloc(strlen(RealPath()) + 10))) { - //TODO: some error message? - return NULL; - } - strcpy(fileNameBuf, RealPath()); - } + if (!checkBuffer()) return NULL; curFileNo = 1; - sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, curFileNo); + sprintf(buf, FILE_MASK, curFileNo); + cFile *tmp = new cFile(KeyPath(), buf); + const char *rv = NULL; - return fileNameBuf; + if (tmp) { + rv = tmp->AbsolutePath(); + delete tmp; + } + return rv; } const char *cLegacyVdrRecording::NextFile(void) { if (++curFileNo < movieFiles) { - sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, curFileNo); + if (!checkBuffer()) return NULL; + sprintf(buf, FILE_MASK, curFileNo); + cFile *tmp = new cFile(KeyPath(), buf); + const char *rv = NULL; - return fileNameBuf; + if (tmp) { + rv = tmp->AbsolutePath(); + delete tmp; + + return rv; + } } return NULL; } diff --git a/libs/fsScan/src/MediaFactory.cc b/libs/fsScan/src/MediaFactory.cc index dfb0142..22b9044 100644 --- a/libs/fsScan/src/MediaFactory.cc +++ b/libs/fsScan/src/MediaFactory.cc @@ -1,25 +1,25 @@ /** * ======================== legal notice ====================== - * + * * File: MediaFactory.cc * Created: 2. Juli 2012, 15 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: libfsScan: mediatypes and filesystem scanning - * + * * 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 <MediaFactory.h> @@ -29,109 +29,104 @@ #include <LegacyVdrRecording.h> #include <VdrRecording.h> #include <DVDImage.h> +#include <StringBuilder.h> +#include <Logging.h> +#include <File.h> #include <stddef.h> #include <stdlib.h> #include <string.h> - -cMediaFactory::cMediaFactory(const char *BaseDirectory) - : baseDirectory(BaseDirectory ? strdup(BaseDirectory) : NULL) +cMediaFactory::cMediaFactory(const cFile &BaseDirectory) + : baseDirectory(BaseDirectory) , scratch(NULL) , scratchSize(1024) { - if (baseDirectory && *(baseDirectory + strlen(baseDirectory) - 1) == '/') - *(baseDirectory + strlen(baseDirectory) - 1) = 0; scratch = (char *)malloc(scratchSize); } cMediaFactory::~cMediaFactory() { free(scratch); - free(baseDirectory); } -void cMediaFactory::SetBaseDirectory(const char* dir) +void cMediaFactory::SetBaseDirectory(const cFile &dir) { - if (baseDirectory == dir) return; - char *tmp = baseDirectory; - baseDirectory = NULL; - free(tmp); - if (dir) { - baseDirectory = strdup(dir); - if (*(baseDirectory + strlen(baseDirectory) - 1) == '/') - *(baseDirectory + strlen(baseDirectory) - 1) = 0; + if (!dir.IsDirectory()) { + esyslog("ERROR: attempt to set base directory to a file (%s)", dir.Name()); + return; } + baseDirectory = dir; } -cAbstractMedia *cMediaFactory::CreateMedia(const char* FileOrDirname, struct stat *st) +int cMediaFactory::createMedia(void *opaque, cFile *Parent, const char *Name) { - const char *name = rindex(FileOrDirname, '/') + 1; - const char *logical = FileOrDirname + strlen(baseDirectory); + if (!opaque) return -1; + cManagedVector *pool = (cManagedVector *) opaque; + cFile *curFile = new cFile(*Parent, Name); const char *mimeType = NULL; cAbstractMedia *rv = NULL; -// printf("CreateMedia(%s) ... name=[%s], logical=[%s]\n", FileOrDirname, name, logical); - if ((st->st_mode & S_IFMT) == S_IFDIR) { - static const char *addons[] = { "/001.vdr", "/00001.ts", "/VIDEO_TS/VIDEO_TS.IFO", "/video_ts/VIDEO_TS.IFO", "/video_ts/video_ts.ifo", NULL }; - struct stat stBuf; + 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; - if (scratchSize < (strlen(FileOrDirname) + 32)) { - scratchSize += 128; - scratch = (char *)realloc(scratch, scratchSize); - } - if (!scratch) return NULL; - - for (const char **pa = addons; pa && *pa; ++pa, ++n) { - strcpy(scratch, FileOrDirname); - strcat(scratch, *pa); + for (const char **kf = keyFiles; kf && *kf; ++kf, ++n) { + tmp = new cFile(*curFile, *kf); + check = tmp ? tmp->AbsolutePath() : NULL; - if (stat(scratch, &stBuf) < 0) continue; - - if ((stBuf.st_mode & S_IFMT) == S_IFREG) { - if (n < 2) { - char *tmp = rindex(scratch, '/'); // filename - char *p = tmp; - - *p = ')'; - *(p + 2) = 0; - tmp = rindex(scratch, '/'); // ts-directory - - for (; p > tmp; --p) *(p + 1) = *p; // shift it up one position - *(p + 1) = '('; // start of ts-directory - *tmp = ' '; // add separator - tmp = rindex(scratch, '/'); // name of vdr recording - if (tmp) name = tmp + 1; - } + if (tmp->Exists() && tmp->IsFile() && !tmp->IsDirectory()) { switch (n) { - case 0: rv = new cLegacyVdrRecording(name, logical, FileOrDirname); break; - case 1: rv = new cVdrRecording(name, logical, FileOrDirname); break; - default: rv = new cDVDImage(name, logical, FileOrDirname); break; + case 0: rv = new cLegacyVdrRecording(*curFile); break; + case 1: rv = new cVdrRecording(*curFile); break; + default: rv = new cDVDImage(*curFile); break; } - rv->SetLastModified(st->st_mtime); } + delete tmp; } + if (!rv) curFile->VisitFiles(createMedia, opaque); } - else if ((st->st_mode & S_IFMT) == S_IFREG) { - const char *extension = rindex(FileOrDirname, '.'); + else { + const char *extension = strrchr(Name, '.'); - if (!extension) return NULL; - ++extension; + if (!extension) { + delete curFile; + return -1; + } + ++extension; mimeType = cMovie::ContentType(extension); - if (mimeType) rv = new cMovie(name, logical, FileOrDirname, mimeType); + if (mimeType) rv = new cMovie(*curFile, mimeType); else { mimeType = cAudio::ContentType(extension); - if (mimeType) rv = new cAudio(name, logical, FileOrDirname, mimeType); + if (mimeType) rv = new cAudio(*curFile, mimeType); else { mimeType = cPicture::ContentType(extension); - if (mimeType) rv = new cPicture(name, logical, FileOrDirname, mimeType); + if (mimeType) rv = new cPicture(*curFile, mimeType); } } - if (rv) { - rv->SetLastModified(st->st_mtime); - rv->SetSize(st->st_size); - } } - return rv; -}
\ No newline at end of file + delete curFile; + if (rv) { + pool->push_back(rv); + return 0; + } + return -1; +} + +void cMediaFactory::Scan4Media(cManagedVector& pool) +{ + if (!baseDirectory.Exists() || !baseDirectory.IsDirectory()) return; + + baseDirectory.SetVirtualRoot(); + baseDirectory.VisitFiles(createMedia, &pool); +} diff --git a/libs/fsScan/src/Movie.cc b/libs/fsScan/src/Movie.cc index 878beb0..759ff3d 100644 --- a/libs/fsScan/src/Movie.cc +++ b/libs/fsScan/src/Movie.cc @@ -1,25 +1,25 @@ /** * ======================== legal notice ====================== - * + * * File: Movie.cc * Created: 2. Juli 2012, 15 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: libfsScan: mediatypes and filesystem scanning - * + * * 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 <Movie.h> @@ -42,8 +42,8 @@ SupportedExtension cMovie::knownExtensions[] = { { NULL, NULL } }; -cMovie::cMovie(const char *Name, const char *Logical, const char *Path, const char *Mime, SupportedMediaType Type) - : cAbstractMedia(Type, Name, Logical, Path, Mime) +cMovie::cMovie(const cFile &File, const char *Mime, SupportedMediaType Type) + : cAbstractMedia(File, Mime, Type) { } diff --git a/libs/fsScan/src/Picture.cc b/libs/fsScan/src/Picture.cc index f1e509c..566c44c 100644 --- a/libs/fsScan/src/Picture.cc +++ b/libs/fsScan/src/Picture.cc @@ -1,25 +1,25 @@ /** * ======================== legal notice ====================== - * + * * File: Picture.cc * Created: 2. Juli 2012, 15 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: libfsScan: mediatypes and filesystem scanning - * + * * 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 <Picture.h> @@ -50,8 +50,8 @@ SupportedExtension cPicture::knownExtensions[] = { { NULL, NULL } }; -cPicture::cPicture(const char *Name, const char *Logical, const char *Path, const char *Mime) -: cAbstractMedia(Picture, Name, Logical, Path, Mime) +cPicture::cPicture(const cFile &File, const char *Mime) +: cAbstractMedia(File, Mime, Picture) { } diff --git a/libs/fsScan/src/VdrRecording.cc b/libs/fsScan/src/VdrRecording.cc index cf192ba..4fb61fa 100644 --- a/libs/fsScan/src/VdrRecording.cc +++ b/libs/fsScan/src/VdrRecording.cc @@ -1,36 +1,46 @@ /** * ======================== legal notice ====================== - * + * * File: VdrRecording.cc * Created: 3. Juli 2012, 08 * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a> * Project: libfsScan: mediatypes and filesystem scanning - * + * * 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 <VdrRecording.h> +#include <StringBuilder.h> +#include <File.h> #include <string.h> #include <stdlib.h> #include <stdio.h> #define FILE_MASK "/%05d.ts" -cVdrRecording::cVdrRecording(const char *Name, const char *Logical, const char *Path) - : cAbstractMultiFileMovie(Name, Logical, Path, "video/mpeg", VdrRecording) +cVdrRecording::cVdrRecording(const cFile &File) + : cAbstractMultiFileMovie(File, "video/mpeg", VdrRecording) { + cStringBuilder sb; + cFile *parent = File.Parent(); + + sb.Append(parent->Name()); + sb.Append(" (").Append(File.Name()).Append(")"); + delete parent; + SetName(sb.toString()); + bufSize = 10; } cVdrRecording::~cVdrRecording() @@ -39,53 +49,55 @@ cVdrRecording::~cVdrRecording() void cVdrRecording::Refresh(void) { - struct stat stBuf; size_t total = 0; - time_t lastMod = 0; + cFile *tmp; - if (!fileNameBuf) { - if (!(fileNameBuf = (char *)malloc(strlen(RealPath()) + 10))) { - //TODO: some error message? - return; - } - strcpy(fileNameBuf, RealPath()); - } + if (!checkBuffer()) return; movieFiles = 0; - for (int fileNo = 1;; ++fileNo) { - sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, fileNo); - if (stat(fileNameBuf, &stBuf) < 0) { + sprintf(buf, FILE_MASK, fileNo); + tmp = new cFile(KeyPath(), buf); + + if (!tmp || !tmp->Exists()) { movieFiles = fileNo - 1; + delete tmp; break; } - total += stBuf.st_size; - if (stBuf.st_mtime > lastMod) lastMod = stBuf.st_mtime; + total += tmp->Size(); + delete tmp; } SetSize(total); - SetLastModified(lastMod); } const char *cVdrRecording::FirstFile(void) { - if (!fileNameBuf) { - if (!(fileNameBuf = (char *)malloc(strlen(RealPath()) + 16))) { - //TODO: some error message? - return NULL; - } - strcpy(fileNameBuf, RealPath()); - } + if (!checkBuffer()) return NULL; curFileNo = 1; - sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, curFileNo); + sprintf(buf, FILE_MASK, curFileNo); + cFile *tmp = new cFile(KeyPath(), buf); + const char *rv = NULL; - return fileNameBuf; + if (tmp) { + rv = tmp->AbsolutePath(); + delete tmp; + } + return rv; } const char *cVdrRecording::NextFile(void) { if (++curFileNo < movieFiles) { - sprintf(fileNameBuf + strlen(RealPath()), FILE_MASK, curFileNo); + if (!checkBuffer()) return NULL; + sprintf(buf, FILE_MASK, curFileNo); + cFile *tmp = new cFile(KeyPath(), buf); + const char *rv = NULL; - return fileNameBuf; + if (tmp) { + rv = tmp->AbsolutePath(); + delete tmp; + + return rv; + } } return NULL; } |