/** * ======================== legal notice ====================== * * File: FileSystem.cc * Created: 21. Juli 2012, 12 * Author: Geronimo * 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 #include #include #include #include #include #include char cFileSystem::PathSeparator = '/'; char cFileSystem::RootPath[4] = { PathSeparator, 0, 0, 0 }; cFileSystem::cFileSystem() { } cFileSystem::~cFileSystem() { std::tr1::unordered_map::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::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; }