summaryrefslogtreecommitdiff
path: root/libs/IO/src
diff options
context:
space:
mode:
Diffstat (limited to 'libs/IO/src')
-rw-r--r--libs/IO/src/ConfigReader.cc64
-rw-r--r--libs/IO/src/File.cc185
-rw-r--r--libs/IO/src/FileReader.cc63
-rw-r--r--libs/IO/src/FileRepresentation.cc132
-rw-r--r--libs/IO/src/FileSystem.cc141
-rw-r--r--libs/IO/src/LineReader.cc100
6 files changed, 685 insertions, 0 deletions
diff --git a/libs/IO/src/ConfigReader.cc b/libs/IO/src/ConfigReader.cc
new file mode 100644
index 0000000..152c908
--- /dev/null
+++ b/libs/IO/src/ConfigReader.cc
@@ -0,0 +1,64 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: ConfigReader.cc
+ * Created: 28. Juli 2012, 18:41
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libIO: classes for files, filesystem and input/output
+ *
+ * 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 <ConfigReader.h>
+#include <LineReader.h>
+#include <stddef.h>
+#include <pcrecpp.h>
+
+cConfigReader::cConfigReader(cLineReader *LineReader)
+ : reader(LineReader)
+{
+}
+
+cConfigReader::~cConfigReader()
+{
+ Close();
+}
+
+void cConfigReader::Close(void)
+{
+ if (reader) {
+ delete reader;
+ reader = NULL;
+ }
+}
+
+cConfigReader::ConfigEntry *cConfigReader::ReadValue()
+{
+ if (!reader) return NULL;
+ const char *line = reader->ReadLine();
+ static pcrecpp::RE comment("^\\s*#.*$");
+ static pcrecpp::RE emptyLine("^\\s*$");
+ static pcrecpp::RE entry("^\\s*(\\S+)\\s*=\\s*(.+)$");
+ std::string name, value;
+ ConfigEntry *rv = NULL;
+
+ while (line && (comment.FullMatch(line) || emptyLine.FullMatch(line)))
+ line = reader->ReadLine();
+ if (line && entry.FullMatch(line, &name, &value)) {
+ rv = new ConfigEntry(name, value);
+ }
+ return rv;
+}
diff --git a/libs/IO/src/File.cc b/libs/IO/src/File.cc
new file mode 100644
index 0000000..6770ec8
--- /dev/null
+++ b/libs/IO/src/File.cc
@@ -0,0 +1,185 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: File.cc
+ * Created: 21. Juli 2012, 12
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libIO: classes for files, filesystem and input/output
+ *
+ * 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>
+#include <FileSystem.h>
+#include <FileRepresentation.h>
+#include <StringBuilder.h>
+#include <sys/stat.h>
+#include <sys/dir.h>
+
+cFileSystem *cFile::fs = NULL;
+static mode_t ReadMask = S_IRUSR | S_IRGRP | S_IROTH;
+static mode_t WriteMask = S_IWUSR | S_IWGRP | S_IWOTH;
+static mode_t ExecMask = S_IXUSR | S_IXGRP | S_IXOTH;
+
+
+cFile::cFile(const char *Path)
+ : rep(NULL)
+{
+ if (!fs) fs = new cFileSystem();
+ if (!Path || *Path != cFileSystem::PathSeparator) {
+ char *wd = getcwd(NULL, 0);
+ rep = fs->representationOfFile(wd);
+ free(wd);
+ if (Path) rep = fs->representationOfFile(rep, 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)
+ : rep(NULL)
+{
+ if (!fs) fs = new cFileSystem();
+ rep = fs->representationOfFile(Parent, RelativePath);
+}
+
+cFile::cFile(const cFileRepresentation *fr)
+ : rep(fr)
+{
+ if (!fs) fs = new cFileSystem();
+}
+
+cFile::~cFile()
+{
+}
+
+cFile &cFile::operator =(const cFile &other)
+{
+ rep = other.rep;
+ return *this;
+}
+
+const char *cFile::AbsolutePath(void) const
+{
+ if (rep) return rep->Path();
+ return NULL;
+}
+
+bool cFile::Exists(void) const
+{
+ if (rep) return rep->exists;
+ return false;
+}
+
+bool cFile::IsDirectory(void) const
+{
+ if (rep) return (rep->mode & S_IFMT) == S_IFDIR;
+ return false;
+}
+
+bool cFile::IsFile(void) const
+{
+ if (rep) return (rep->mode & S_IFMT) == S_IFREG;
+ return false;
+}
+
+bool cFile::IsSymbolic(void) const
+{
+ if (rep) return (rep->mode & S_IFMT) == S_IFLNK;
+ return false;
+}
+
+bool cFile::CanRead(void) const
+{
+ if (rep) return rep->mode & ReadMask;
+ return false;
+}
+
+bool cFile::CanWrite(void) const
+{
+ if (rep) return rep->mode & WriteMask;
+ return false;
+}
+
+bool cFile::CanExecute(void) const
+{
+ if (rep) return rep->mode & ExecMask;
+ return false;
+}
+
+off64_t cFile::Size(void) const
+{
+ if (rep) return rep->size;
+ return 0;
+}
+
+ulong cFile::LastModified(void) const
+{
+ if (rep) return rep->lastModified;
+ return 0;
+}
+
+cFile *cFile::Parent(void) const
+{
+ if (rep) return new cFile(rep->getParent());
+ return NULL;
+}
+
+const char *cFile::Name(void) const
+{
+ if (rep) return rep->name;
+ return NULL;
+}
+
+void cFile::Cleanup(void)
+{
+ if (fs) {
+ delete fs;
+ fs = NULL;
+ }
+}
+
+void cFile::VisitFiles(int (*cb)(void *, cFile *, const char *), void *opaque)
+{
+ if (!Exists() || !IsDirectory()) return;
+ const char *path = AbsolutePath();
+
+ if (!path) return;
+ struct dirent entryBuffer, *pE = NULL;
+ DIR *dir = opendir(path);
+
+ while (!readdir_r(dir, &entryBuffer, &pE) && pE) {
+ if (*(pE->d_name) == '.') continue; // don't bother with hidden stuff
+ cb(opaque, this, pE->d_name);
+ }
+ closedir(dir);
+}
+
+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/IO/src/FileReader.cc b/libs/IO/src/FileReader.cc
new file mode 100644
index 0000000..519c749
--- /dev/null
+++ b/libs/IO/src/FileReader.cc
@@ -0,0 +1,63 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: FileReader.cc
+ * Created: 28. Juli 2012, 15:00
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libIO: classes for files, filesystem and input/output
+ *
+ * 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 <FileReader.h>
+#include <File.h>
+#include <Logging.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+cFileReader::cFileReader(cFile *Input)
+ : fd(-1)
+ , file(Input)
+{
+ if (file && file->Exists() && file->CanRead()) {
+ fd = open(file->AbsolutePath(), O_RDONLY);
+ if (fd < 0) esyslog("ERROR: could not open %s", file->AbsolutePath());
+ }
+}
+
+cFileReader::~cFileReader()
+{
+ Close();
+}
+
+void cFileReader::Close()
+{
+ if (fd >= 0) {
+ close(fd);
+ fd = -1;
+ }
+ if (file) {
+ delete file;
+ file = NULL;
+ }
+}
+
+int cFileReader::Read(char* buf, int bufSize)
+{
+ if (fd >= 0) return read(fd, buf, bufSize);
+ esyslog("ERROR: not an open file! %s", file->AbsolutePath());
+ return 0;
+}
diff --git a/libs/IO/src/FileRepresentation.cc b/libs/IO/src/FileRepresentation.cc
new file mode 100644
index 0000000..f74d2c8
--- /dev/null
+++ b/libs/IO/src/FileRepresentation.cc
@@ -0,0 +1,132 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: FileRepresentation.cc
+ * Created: 21. Juli 2012, 12
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libIO: classes for files, filesystem and input/output
+ *
+ * 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>
+#include <stdlib.h>
+#include <iostream>
+#include <stack>
+
+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(Name, &st)) {
+ name = strdup(Name);
+ exists = true;
+ mode = st.st_mode;
+ size = st.st_size;
+ lastModified = st.st_mtime;
+ }
+}
+
+cFileRepresentation::cFileRepresentation(const cFileRepresentation *Parent, const char *Name)
+ : exists(false)
+ , isRoot(false)
+ , isVirtualRoot(false)
+ , mode(0)
+ , size(0)
+ , lastModified(0)
+ , name(strdup(Name))
+ , path(NULL)
+ , parent(Parent)
+{
+ struct stat st;
+
+ if (!stat(Path(), &st)) {
+ exists = true;
+ mode = st.st_mode;
+ size = st.st_size;
+ lastModified = st.st_mtime;
+ }
+}
+
+cFileRepresentation::~cFileRepresentation()
+{
+ free(name);
+ free(path);
+}
+
+const char *cFileRepresentation::Path() const
+{
+ if (!path) {
+ cStringBuilder sb;
+
+ if (parent) sb.Append(parent->Path());
+ if (strcmp(cFileSystem::RootPath, name)) sb.Append(cFileSystem::PathSeparator).Append(name);
+ path = sb.toString();
+ }
+ return path;
+}
+
+void cFileRepresentation::SetVirtualRoot(bool isRoot)
+{
+ isVirtualRoot = isRoot;
+}
+
+char *cFileRepresentation::toURI() const
+{
+ cStringBuilder *sb = new cStringBuilder();
+ const cFileRepresentation *f = this;
+ std::stack<const cFileRepresentation *> rev;
+ cURLEncoder *enc = cUrl::Encoder();
+ char *tmp, *chk, *rv;
+ size_t stackSize;
+
+ while (!f->isVirtualRoot) {
+ rev.push(f);
+ stackSize = rev.size();
+ f = f->parent;
+ }
+
+ for (;;) {
+ 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 rv;
+}
diff --git a/libs/IO/src/FileSystem.cc b/libs/IO/src/FileSystem.cc
new file mode 100644
index 0000000..049ca07
--- /dev/null
+++ b/libs/IO/src/FileSystem.cc
@@ -0,0 +1,141 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: FileSystem.cc
+ * Created: 21. Juli 2012, 12
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libIO: classes for files, filesystem and input/output
+ *
+ * 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>
+#include <FileRepresentation.h>
+#include <File.h>
+#include <StringBuilder.h>
+#include <iostream>
+#include <stdlib.h>
+#include <string.h>
+
+char cFileSystem::PathSeparator = '/';
+char cFileSystem::RootPath[4] = { PathSeparator, 0, 0, 0 };
+
+cFileSystem::cFileSystem()
+{
+}
+
+cFileSystem::~cFileSystem()
+{
+ std::tr1::unordered_map<std::string, cFileRepresentation *>::iterator it = fileCache.begin();
+
+ while (it != fileCache.end()) {
+ if (it->second) delete it->second;
+ ++it;
+ }
+}
+
+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;
+ return NULL;
+}
+
+cFileRepresentation *cFileSystem::representationOfFile(const cFile &Parent, const char* Path)
+{
+ cFileRepresentation *parentRep = (cFileRepresentation *) Parent.rep;
+
+ return representationOfFile(parentRep, Path);
+}
+
+cFileRepresentation *cFileSystem::representationOfFile(const cFileRepresentation *parentRep, const char* Path)
+{
+ cFileRepresentation *tmp = NULL;
+ cStringBuilder *sb = new cStringBuilder(parentRep->Path());
+ char *scratch = strdup(Path);
+ char *last = scratch + strlen(Path);
+ char *start = *scratch == PathSeparator ? scratch + 1 : scratch;
+ char *end = strchr(scratch, PathSeparator);
+ char *path;
+
+ while (start < last) {
+ end = strchr(start, PathSeparator);
+ if (!end) end = start + strlen(start);
+ *end = 0;
+ sb->Append(PathSeparator).Append(start);
+ path = sb->toString();
+ tmp = cacheEntry(path);
+ if (!tmp) {
+ tmp = new cFileRepresentation(parentRep, start);
+ fileCache[path] = tmp;
+ }
+ parentRep = tmp;
+ free(path);
+ start = end + 1;
+ }
+ free(scratch);
+ delete sb;
+
+ if (tmp) return tmp;
+ return NULL;
+}
+
+cFileRepresentation *cFileSystem::representationOfFile(const char* Path)
+{
+ cFileRepresentation *rv = cacheEntry(Path);
+
+ if (!rv) {
+ cFileRepresentation *tmp = NULL;
+ char *scratch = strdup(Path);
+ char *p, *last = scratch + strlen(Path);
+
+ for (p = strrchr(scratch, PathSeparator); !rv && p && p < last; p = strrchr(scratch, PathSeparator)) {
+ if (p > scratch) *p = 0;
+ else {
+ *p = 0;
+ if (!(rv = cacheEntry(RootPath))) {
+ tmp = new cFileRepresentation(RootPath);
+ fileCache[RootPath] = tmp;
+ break;
+ }
+ }
+ if ((tmp = cacheEntry(scratch))) break;
+ }
+ if (rv && strcmp(rv->Path(), Path)) {
+ tmp = rv;
+ rv = NULL;
+ }
+ if (tmp) {
+ cFileRepresentation *parent = tmp;
+ size_t poolSize = fileCache.size();
+ const char *last = scratch + strlen(Path);
+
+ for (p = scratch + strlen(scratch) + 1; p < last; p += strlen(p) + 1) {
+ if (!*(p - 1)) *(p - 1) = PathSeparator;
+ tmp = new cFileRepresentation(parent, p);
+ fileCache[scratch] = tmp;
+ poolSize = fileCache.size();
+ parent = tmp;
+ }
+ rv = parent;
+ }
+ free(scratch);
+ }
+ return rv;
+}
+
diff --git a/libs/IO/src/LineReader.cc b/libs/IO/src/LineReader.cc
new file mode 100644
index 0000000..bf4bcc2
--- /dev/null
+++ b/libs/IO/src/LineReader.cc
@@ -0,0 +1,100 @@
+/**
+ * ======================== legal notice ======================
+ *
+ * File: LineReader.cc
+ * Created: 28. Juli 2012, 06
+ * Author: <a href="mailto:geronimo013@gmx.de">Geronimo</a>
+ * Project: libIO: classes for files, filesystem and input/output
+ *
+ * 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 <LineReader.h>
+#include <FileReader.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <iostream>
+
+cLineReader::cLineReader(cFileReader *FileReader)
+ : reader(FileReader)
+ , bytesRead(0)
+ , off(0)
+ , bufSize(1024)
+ , buf(NULL)
+ , lastLine(NULL)
+{
+ buf = (char *) malloc(bufSize + 1);
+ if (buf) {
+ buf[bufSize] = 0;
+ *buf = 0;
+ }
+}
+
+cLineReader::~cLineReader()
+{
+ Close();
+}
+
+void cLineReader::Close()
+{
+ if (reader) {
+ delete reader;
+ reader = NULL;
+ }
+ free(buf);
+ buf = NULL;
+ off = NULL;
+}
+
+const char *cLineReader::ReadLine(void)
+{
+ const char *rv = NULL;
+ char *p;
+
+ if (lastLine) lastLine += strlen(lastLine) + 1;
+ else lastLine = buf;
+ if (bytesRead && lastLine - buf >= bytesRead) return NULL;
+ p = strchr(lastLine, '\n');
+
+ if (!p && strlen(lastLine)) {
+ memmove(buf, lastLine, strlen(lastLine));
+ buf[strlen(lastLine)] = 0;
+ lastLine = buf;
+ }
+
+ if (!p && (!bytesRead || bytesRead == bufSize)) {
+ bytesRead = strlen(buf);
+ int br = reader->Read(buf + bytesRead, bufSize - bytesRead);
+
+ if (br > 0) bytesRead += br;
+ if (bytesRead < bufSize) memset(buf + bytesRead, 0, bufSize - bytesRead);
+ }
+
+ if (!p) p = strchr(lastLine, '\n');
+
+ if (p) {
+ if (p - buf <= bytesRead) {
+ *p = 0;
+ rv = lastLine;
+ }
+ }
+ else {
+ if (strlen(lastLine)) rv = lastLine;
+ }
+ return rv;
+}