From 56e40b4b0f436dc7d9214fd3a96a621c15bd9f10 Mon Sep 17 00:00:00 2001 From: Andreas Monzner Date: Thu, 11 May 2006 21:14:28 +0000 Subject: [PATCH 1/1] implement and re-enable default ac3 option --- data/setup.xml | 2 +- lib/base/Makefile.am | 3 +- lib/base/nconfig.cpp | 1039 +------------------------------------ lib/base/nconfig.h | 398 +------------- lib/python/Components/AVSwitch.py | 2 +- lib/python/Components/config.py | 12 + lib/python/enigma_python.i | 2 + lib/service/servicedvb.cpp | 17 +- mytest.py | 2 + 9 files changed, 68 insertions(+), 1409 deletions(-) diff --git a/data/setup.xml b/data/setup.xml index 49a43b4..f4fea25 100644 --- a/data/setup.xml +++ b/data/setup.xml @@ -12,7 +12,7 @@ config.av.aspectratio config.av.tvsystem config.av.wss - + config.av.defaultac3 config.av.vcrswitch diff --git a/lib/base/Makefile.am b/lib/base/Makefile.am index 3741df6..cd1a157 100644 --- a/lib/base/Makefile.am +++ b/lib/base/Makefile.am @@ -7,5 +7,6 @@ libenigma_base_a_SOURCES = \ buffer.cpp ebase.cpp eerror.cpp elock.cpp \ init.cpp message.cpp thread.cpp \ smartptr.cpp estring.cpp connection.cpp \ - filepush.cpp encoding.cpp console.cpp rawfile.cpp + filepush.cpp encoding.cpp console.cpp rawfile.cpp \ + nconfig.cpp diff --git a/lib/base/nconfig.cpp b/lib/base/nconfig.cpp index a0e4a31..562b350 100644 --- a/lib/base/nconfig.cpp +++ b/lib/base/nconfig.cpp @@ -1,1027 +1,34 @@ -// this is nconfig 0.92, a bit modified -#define NO_MAP_SHARED -#include -#include -#include #include +#include -#include -#include -#include -#include -#include -#include +PyObject *ePythonConfigQuery::m_queryFunc; -#include - -#include - -#ifndef PAGESIZE -#ifdef PAGE_SIZE -#define PAGESIZE PAGE_SIZE -#else -#define PAGESIZE 4096 -#endif -#endif - -#define SB ((struct nc_sb_s *) data) -#define CM(x) ((struct nc_chunk_s *) (data+(x))) -#define DE(x) ((struct nc_de_s *) (data+(x))) -#define IDE(x, y) (DE(((unsigned *) (data+(x)->offset))[(y)])) -#define CS(x) (((unsigned *) (data+(x)))[-1]) - -inline unsigned NConfig::crc(const char *d, unsigned len) -{ - unsigned ret = 0; - unsigned l = len / sizeof(unsigned); - - while (l) { - ret += *(const unsigned *)d; - ret = (ret << 3) & (ret >> 29); - l--; - d += sizeof(unsigned); - } - return ret; -} - -NConfig::NConfig(int protect) -{ - fd = -1; - cname = fname = data = NULL; - sb = NULL; - cdir = NULL; - chunks = NULL; - revision = update = lsize = omode = 0; - olck = 0; - lock = NC_L_NONE; - careful = protect; -} - -NConfig::~NConfig() -{ - close(); - free(fname); -} - -void NConfig::close() -{ - free(cname); - cname = NULL; - if (fd > -1) { -#ifdef NO_MAP_SHARED - if (data) { - int size=sb->size; - char *buffer=new char[size]; - memcpy(buffer, data, size); - munmap(data, size); - data = NULL; - ::lseek(fd, 0, SEEK_SET); - ::write(fd, buffer, size); - delete[] buffer; - } -#endif - ::close(fd); - fd = -1; - } - if (data) { - munmap(data, sb->size); - data = NULL; - } -} - -void NConfig::flush() -{ - close(); - open(omode); -} - -int NConfig::setName(const char *name) -{ - if (!name) - return NC_ERR_NVAL; - if (fd > -1) - return NC_ERR_PERM; - free(fname); - fname = strdup(name); - return NC_ERR_OK; -} - -int NConfig::createNew(unsigned resize, unsigned dirent, unsigned mchunks) -{ - if (fd > -1) - return NC_ERR_NVAL; - if (!access(fname, F_OK)) - return NC_ERR_PERM; - - int ff; - if ((ff = ::open(fname, O_WRONLY | O_CREAT, 0600)) == -1) - return NC_ERR_NFILE; - struct nc_sb_s bsb = {NC_SB_MAGIC, resize*PAGESIZE, - dirent, mchunks, resize, mchunks, - sizeof(struct nc_sb_s)+sizeof(struct nc_de_s)+2*sizeof(unsigned), - sizeof(struct nc_sb_s), 0}; - struct nc_de_s bde = {sizeof(struct nc_sb_s)+sizeof(struct nc_de_s), - NC_DIR, sizeof(struct nc_sb_s), 0, 0, 0}; - struct nc_chunk_s bcm; - - write(ff, &bsb, sizeof(bsb)); - write(ff, &bde, sizeof(bde)); - write(ff, "/", 2); - - lseek(ff, sizeof(unsigned)-2, SEEK_CUR); - unsigned cl = sizeof(nc_chunk_s)*mchunks+sizeof(unsigned); - write(ff, &cl, sizeof(unsigned)); - - bcm.offset = bsb.chunk + sizeof(struct nc_chunk_s)*mchunks; - bcm.size = bsb.size - bcm.offset; - - write(ff, &bcm, sizeof(bcm)); - - lseek(ff, bsb.size-1, SEEK_SET); - write(ff, "", 1); - ::close(ff); - return NC_ERR_OK; -} - - -int NConfig::open(int how) -{ - if (!fname) - return NC_ERR_NFILE; - if (how != NC_O_RO && how != NC_O_RW) - return NC_ERR_TYPE; - if (fd > -1) - close(); - - int ff; - if ((ff = ::open(fname, how)) == -1) - return NC_ERR_PERM; - - struct stat sbuf; - fstat(ff, &sbuf); - - if (!sbuf.st_size) - return NC_ERR_CORRUPT; - -#ifdef NO_MAP_SHARED - if ((data = (char *) mmap(NULL, sbuf.st_size, how == NC_O_RO ? PROT_READ : (PROT_READ|PROT_WRITE), MAP_PRIVATE, ff, 0)) == MAP_FAILED) { -#else - if ((data = (char *) mmap(NULL, sbuf.st_size, how == NC_O_RO ? PROT_READ : (PROT_READ|PROT_WRITE), MAP_SHARED, ff, 0)) == MAP_FAILED) { -#endif - ::close(ff); - return NC_ERR_NMEM; - } - if (memcmp(((struct nc_sb_s *) data)->magic, NC_SB_MAGIC, 4)) { - munmap(data, sbuf.st_size); - ::close(ff); - return NC_ERR_CORRUPT; - } - fd = ff; - omode = how; - sb = SB; - lsize = 0; - cname = strdup("/"); - - lockFile(NC_L_RO, TRUE); - rdir = DE(sb->root); - unLockFile(); - return NC_ERR_OK; -} - -void NConfig::expand(unsigned toadd) -{ - unsigned nsize = sb->size + toadd; - lseek(fd, nsize-1, SEEK_SET); - write(fd, "", 1); - _remap(sb->size, nsize); - sb->size = nsize; - cdir = getDirEnt(cname); - chunks = CM(sb->chunk); -#ifdef NC_DEBUG_ALLOC - fprintf(stderr, "Expanded from %u to %u\n", nsize-toadd, nsize); -#endif -} - -unsigned NConfig::getChunk(unsigned s) -{ - int lst = -1; - - // Make sure we get aligned data - s = alignSize(s) + sizeof(unsigned); - -#ifdef NC_DEBUG_ALLOC - fprintf(stderr, "Taking %u (total %u)\n", s, sb->chunk_ttl); -#endif - - do { - int left = 0, right = sb->chunk_ttl - 1, c; - while (left <= right) { - int diff = chunks[c = (left + right) / 2].size - s; - if (diff < 0 || diff == sizeof(unsigned)) { -#ifdef NC_DEBUG_ALLOC - if (diff > 0) - fprintf(stderr, "Rejected chunk %d (%u:%u)\n", c, chunks[c].offset, chunks[c].size); -#endif - right = c - 1; - continue; - } - lst = c; - if (!diff) - break; - left = c + 1; - } - if (lst < 0) { - unsigned ll = (s / (sb->size_inc*PAGESIZE) + 1) * PAGESIZE * sb->size_inc; - // we don't have a suitable chunk - expand(ll); - // insert new chunk into list (always succeeds) - *(unsigned *)(data+sb->size-ll) = ll; - fast_free(sb->size-ll+sizeof(unsigned)); - } - } while (lst < 0); - -#ifdef NC_DEBUG_ALLOC - fprintf(stderr, "haluz 7: off = %u size = %u\n", chunks[7].offset, chunks[7].size); - fprintf(stderr, "Got %u chunk (pos %d), taking %u\n", chunks[lst].size, lst, s); - fprintf(stderr, "chunk (%u:%u)\n", chunks[lst].offset, chunks[lst].size); -#endif - - unsigned best = chunks[lst].offset+sizeof(unsigned); - memset(data+best, 0, s-sizeof(unsigned)); - chunks[lst].size -= s; - chunks[lst].offset += s; - CS(best) = s; - - while (lst < ((signed)sb->chunk_ttl - 1) && chunks[lst].size < chunks[lst+1].size) { - unsigned b = chunks[lst].size; - unsigned i = lst + 1; - chunks[lst].size = chunks[i].size; - chunks[i].size = b; - b = chunks[lst].offset; - chunks[lst].offset = chunks[i].offset; - chunks[i].offset = b; - lst = i; - } - -#ifdef NC_DEBUG_ALLOC - fprintf(stderr, "Returned %u:%u\n", best, CS(best)); -#endif - return best; -} - -void NConfig::freeChunk(unsigned where) -{ -#ifdef NC_DEBUG_ALLOC - fprintf(stderr, "Free chunk: %u\n", CS(where)); -#endif - if (chunks[sb->chunk_ttl-2].size) { -#ifdef NC_DEBUG_ALLOC - fprintf(stderr, "Last slot available.\n"); -#endif - unsigned n = getChunk((sb->chunk_ttl+sb->chunk_inc)*sizeof(struct nc_chunk_s)); - unsigned f = sb->chunk; - memcpy(data+n, chunks, (sb->chunk_ttl-1)*sizeof(struct nc_chunk_s)); - chunks = CM(sb->chunk = n); - sb->chunk_ttl += sb->chunk_inc; - fast_free(f); - } - fast_free(where); -} - -inline unsigned NConfig::alignSize(unsigned s) -{ - unsigned of = s % sizeof(unsigned); - return of ? s + sizeof(unsigned) - of : s; -} - -void NConfig::delKey(const char *name) -{ - _delKey(name, NULL, TRUE); -} - -void NConfig::_delKey(const char *name, struct nc_de_s *p, int tosort) -{ - if (fd < 0) - return; - lockFile(NC_L_RW); - struct nc_de_s *nd = getDirEnt(name, p); - if (nd && nd != rdir && nd != cdir) { - unsigned ndo = ((char *)nd) - data; - if (nd->type == NC_DIR) - for (unsigned i=0; ipages; i++) { - struct nc_de_s *dd = IDE(nd, i); - if (dd->type) - _delKey(data+dd->name, nd, FALSE); - nd = DE(ndo); - } - sb->modtime++; - freeChunk(nd->offset); - freeChunk(DE(ndo)->name); - nd = DE(ndo); - struct nc_de_s *parent = DE(nd->parent); - memset(nd, 0, sizeof(struct nc_de_s)); - // keep parent directory sorted - if (tosort) { - unsigned i = 0; - while (i < parent->pages && IDE(parent, i) != nd) - i++; - memmove(((unsigned *)(data+parent->offset))+i, - ((unsigned *)(data+parent->offset))+i+1, - sizeof(unsigned)*(parent->pages-i-1)); - ((unsigned *)(data+parent->offset))[parent->pages-1] = ndo; - } - } - unLockFile(); -} - -int NConfig::_setKey(const char *name, const unsigned t, const char *value, const unsigned len) -{ - if (fd < 0) - return NC_ERR_NFILE; - if (omode != NC_O_RW) - return NC_ERR_RDONLY; - lockFile(NC_L_RW); - struct nc_de_s *nd = getDirEnt(name); -#ifdef NC_DEBUG_INSERT - fprintf(stderr, "Found DE %p\n", nd); -#endif - if (!nd) { - struct nc_de_s *sd = *name == '/' ? rdir : cdir; - char *parse = canonize(name), *p = parse; - - while ((nd = getDirEnt(p, sd))) - if (nd->type == NC_DIR) { - sd = nd; - p += strlen(p)+1; - } else { - free(parse); - unLockFile(); - return NC_ERR_PERM; - } - - size_t pl = 0; - struct nc_de_s ds; - unsigned sdo = ((char *)sd) - data; - while (*(p+(pl = strlen(p)+1))) { - ds.pages = ds.offset = 0; - ds.name = getChunk(pl); - memcpy(data+ds.name, p, pl); - ds.type = NC_DIR; -#ifdef NC_DEBUG_INSERT - fprintf(stderr, "Insertion parent 2: %p\n", DE(sdo)); -#endif - // FIXME: crc calculation - sdo = ((char *)insert(sdo, &ds)) - data; - p += pl; - } - ds.type = t; - memcpy(data+(ds.name = getChunk(pl)), p, pl); - ds.pages = ds.offset = 0; -#ifdef NC_DEBUG_INSERT - fprintf(stderr, "Insertion parent 1: %p\n", DE(sdo)); -#endif - nd = insert(sdo, &ds); - sb->modtime++; - free(parse); - } else - if (nd->type != t) { - unLockFile(); - return NC_ERR_TYPE; - } - unsigned ndo = ((char *)nd) - data; - if (t != NC_DIR) { - if (value) { - if (nd->offset && CS(nd->offset)-sizeof(unsigned) < len) { - freeChunk(nd->offset); - nd = DE(ndo); - nd->offset = 0; - } - if (nd->offset) { - if (CS(nd->offset)-sizeof(unsigned) > alignSize(len)+sizeof(unsigned)) { - unsigned trim = CS(nd->offset) - alignSize(len) - sizeof(unsigned); - unsigned off = nd->offset + alignSize(len) + sizeof(unsigned); - CS(off) = trim; - CS(nd->offset) -= trim; - freeChunk(off); - nd = DE(ndo); - } - } else { - unsigned off = getChunk(len); - nd = DE(ndo); - nd->offset = off; - } - memcpy(data+nd->offset, value, len); - nd->pages = len; - } else - if (nd->offset) { - freeChunk(nd->offset); - DE(ndo)->offset = 0; - } - } else - // Preallocate pages for directory - if (len > nd->pages) { - unsigned off = getChunk(sizeof(unsigned)*len); - if (DE(ndo)->offset) { - memcpy(data+off, data+DE(ndo)->offset, sizeof(unsigned)*(DE(ndo)->pages)); - freeChunk(DE(ndo)->offset); - } - DE(ndo)->offset = off; - for (unsigned al = len - DE(ndo)->pages; al; al--) { - off = getChunk(sizeof(struct nc_de_s)); - ((unsigned *)(data+DE(ndo)->offset))[DE(ndo)->pages++] = off; - } - } - unLockFile(); -#ifdef NC_DEBUG_INSERT - fprintf(stderr, "%p\n", cdir); -#endif - return NC_ERR_OK; -} - -char *NConfig::getName(const struct nc_de_s *w) -{ - if (w == rdir) - return strdup("/"); - char *parent = getName(DE(w->parent)); - unsigned l1 = strlen(parent); - unsigned l2 = strlen(data+w->name)+1; - - parent = (char *) realloc(parent, l1 + l2 + (l1 == 1 ? 0 : 1)); - if (l1 != 1) { - memcpy(parent+l1, "/", 2); - l1++; - } - memcpy(parent+l1, data+w->name, l2); - return parent; -} - -int NConfig::chDir(const char *name) -{ - if (fd < 0) - return NC_ERR_NFILE; - lockFile(NC_L_RO); - - int ret = NC_ERR_OK; - struct nc_de_s *nd = getDirEnt(name); - if (nd) { - if (nd->type == NC_DIR) { - cdir = nd; - free(cname); - cname = getName(cdir); - } else - ret = NC_ERR_NDIR; - } else - ret = NC_ERR_NEXIST; - unLockFile(); - return ret; -} - -const char *NConfig::pwDir() -{ - if (fd < 0) - return NULL; - lockFile(NC_L_RO); - struct nc_de_s *l = cdir; - char * ret = strdup(data+l->name); - while (DE(l->parent) != l) { - unsigned len = CS(l->name); - char *r = (char *) malloc(strlen(ret) + len + 2); - memcpy(r, data+l->name, len); - if (*ret != '/' && DE(l->parent) != rdir) - strcat(r, "/"); - strcat(r, ret); - free(ret); - ret = r; - l = DE(l->parent); - } - unLockFile(); - return ret; -} - -struct nc_de_s *NConfig::getDirEnt(const char *name, struct nc_de_s *cc) -{ - struct nc_de_s *ret = cc ? cc : ((*name == '/') ? rdir : cdir); - char *c = canonize(name), *can; - - if (!(can = c)) - return ret; - while (*c) { - if (!strcmp(c, "..")) - ret = DE(ret->parent); - else - if (strcmp(c, ".")) { - struct nc_de_s *re = ret; - int left = 0, right = ret->pages-1, p, r; - - ret = NULL; - while (left <= right) { - p = (left + right) / 2; - r = strcmp(c, data+IDE(re, p)->name); - if (r < 0) { - left = p + 1; - continue; - } - if (!r) { - ret = IDE(re, p); - break; - } - right = p - 1; - } - } - c += strlen(c)+1; - if (!ret || (*c && ret->type != NC_DIR)) { - ret = NULL; - break; - } - } - free(can); - return ret; -} - -char *NConfig::canonize(const char *name) -{ - if (*name == '/') - name++; - size_t i = strlen(name); - char *ret = (char *)calloc(1, i+3); - memcpy(ret, name, i); - for (size_t j=0; jname, what->type); -#endif - struct nc_de_s *w = DE(where); - if (!DE(where)->offset || IDE(w, w->pages-1)->type) { - unsigned a = getChunk((w->pages+sb->ent_inc)*sizeof(unsigned)); - w = DE(where); - if (w->offset) { - memcpy(data+a, data+w->offset, w->pages*sizeof(unsigned)); - freeChunk(w->offset); - w = DE(where); - } - w->offset = a; - for (unsigned ha = 0; haent_inc; ha++) { - unsigned off = getChunk(sizeof(struct nc_de_s)); - w = DE(where); - ((unsigned *)(data+w->offset))[w->pages] = off; - w->pages++; - } - } - int i = 0, l = 0, r = w->pages - 1, c; - while (l <= r) { - c = (l + r) / 2; - if (!IDE(w, c)->type || strcmp(data+what->name, data+IDE(w, c)->name) > 0) { - i = c; - r = c - 1; - } else - l = c + 1; - } - -#ifdef NC_DEBUG_INSERT - fprintf(stderr, "Insertion to slot %u (%s)\n", i, data+what->name); -#endif - what->parent = where; - unsigned to = ((unsigned *)(data+w->offset))[w->pages-1]; - memmove(((unsigned *)(data+w->offset))+i+1, ((unsigned *)(data+w->offset))+i, sizeof(unsigned)*(w->pages-i-1)); - ((unsigned *)(data+w->offset))[i] = to; - void *ret = memcpy(DE(to), what, sizeof(struct nc_de_s)); - sb->modtime++; - return (struct nc_de_s *)ret; -} - -void NConfig::status() -{ - if (fd < 0) - return; - lockFile(NC_L_RO); - fprintf(stderr, "Size:\t%u\n", sb->size); - unsigned low=0, hi=chunks[0].size, cnt=0, ttl=0; - for (unsigned i=0; ichunk_ttl; i++) - if (chunks[i].size > 0) { - if (!low || low > chunks[i].size) - low = chunks[i].size; - ttl += chunks[i].size; - cnt++; - } - unLockFile(); - fprintf(stderr, "Free:\t%u in %u chunk%s\n", ttl, cnt, cnt > 1 ? "s" : ""); - if (cnt > 0) - fprintf(stderr, "Min:\t%u\nAvg:\t%u\nMax:\t%u\n", low, ttl / cnt, hi); -} - -struct nc_ls_s *NConfig::ls(const char *name) -{ - if (fd < 0) - return NULL; - lockFile(NC_L_RO); - - struct nc_ls_s *rt = NULL; - unsigned count = 0; - struct nc_de_s *de = NULL; - struct nc_de_s *ds = name ? getDirEnt(name) : cdir; - - if (ds && ds->type == NC_DIR) { - for (unsigned i=0; ipages; i++) { - de = IDE(ds, i); - if (de->type && de->name) { - rt = (struct nc_ls_s *) realloc(rt, (count+2)*sizeof(nc_ls_s)); - rt[count].type = de->type; - rt[count].name = strdup(data+de->name); - rt[++count].type = 0; - rt[count].name = NULL; - } - } - } - unLockFile(); - return rt; -} - -void NConfig::fast_free(unsigned offset) -{ - unsigned s = CS(offset), i = 0; - offset -= sizeof(unsigned); - - while (1) { - if (!chunks[i].size) { -#ifdef NC_DEBUG_ALLOC - fprintf(stderr, "Inserting %u:%u to %u\n", offset, s, i); -#endif - chunks[i].offset = offset; - chunks[i].size = s; - break; - } - if (chunks[i].offset == offset + s) { -#ifdef NC_DEBUG_ALLOC - fprintf(stderr, "Prepending %u:%u to %u (%u:%u)\n", offset, s, i, chunks[i].offset, chunks[i].size); -#endif - chunks[i].offset -= s; - chunks[i].size += s; - break; - } - if (offset == chunks[i].offset + chunks[i].size) { -#ifdef NC_DEBUG_ALLOC - fprintf(stderr, "Appending %u:%u to %u (%u:%u)\n", offset, s, i, chunks[i].offset, chunks[i].size); -#endif - chunks[i].size += s; - break; - } - i++; - } - - // Keep the array sorted - while (i && chunks[i].size > chunks[i-1].size) { - unsigned b = chunks[i].size; - unsigned j = i - 1; - chunks[i].size = chunks[j].size; - chunks[j].size = b; - b = chunks[i].offset; - chunks[i].offset = chunks[j].offset; - chunks[j].offset = b; - i = j; - } -} - -int NConfig::renameKey(const char *oldname, const char *newname) -{ - if (fd < 0) - return NC_ERR_NFILE; - if (omode != NC_O_RW) - return NC_ERR_RDONLY; - lockFile(NC_L_RW); - int ret = NC_ERR_OK; - struct nc_de_s *parent, *nd = getDirEnt(newname); - if (nd) { - if ((nd = getDirEnt(oldname))) { - size_t len = strlen(newname)+1; - int inc = strcmp(oldname, newname); - unsigned i, off, pos, ndo = ((char *)nd) - data; - if (alignSize(len) != CS(nd->name)) { - freeChunk(nd->name); - off = getChunk(len); - DE(ndo)->name = off; - nd = DE(ndo); - } - memcpy(data+nd->name, newname, len); - parent = DE(nd->parent); - for (pos = 0; pos < parent->pages && IDE(parent, pos) != nd; pos++) - ; - for (i = pos; i>=0 && ipages; i += inc) - if (strcmp(data+IDE(parent, i)->name, newname) != inc) - break; - if (inc == -1) - memmove(((unsigned *)(data+parent->offset))+i+1, - ((unsigned *)(data+parent->offset))+i, - sizeof(unsigned)*(pos - i)); - else - memmove(((unsigned *)(data+parent->offset))+pos, - ((unsigned *)(data+parent->offset))+pos+1, - sizeof(unsigned)*(i-pos)); - ((unsigned *)(data+parent->offset))[i] = ndo; - sb->modtime++; - } else - ret = NC_ERR_NEXIST; - } else - ret = NC_ERR_PERM; - unLockFile(); - return NC_ERR_OK; -} - -int NConfig::createDir(const char *name, unsigned entries) -{ - return _setKey(name, NC_DIR, NULL, entries); -} - -int NConfig::setKey(const char *name, const unsigned long long value) -{ - return _setKey(name, NC_UINT, (const char *)&value, sizeof(value)); -} - -int NConfig::setKey(const char *name, const unsigned value) -{ - unsigned long long b = value; - return _setKey(name, NC_UINT, (const char *)&b, sizeof(b)); -} - -int NConfig::setKey(const char *name, const signed long long value) -{ - return _setKey(name, NC_INT, (const char *)&value, sizeof(value)); -} - -int NConfig::setKey(const char *name, const int value) -{ - signed long long b = value; - return _setKey(name, NC_INT, (const char *)&b, sizeof(b)); -} - -int NConfig::setKey(const char *name, const char *value) -{ - return _setKey(name, NC_STRING, value, strlen(value)+1); -} - -int NConfig::setKey(const char *name, const long double value) +void ePythonConfigQuery::setQueryFunc(PyObject *queryFunc) { - return _setKey(name, NC_DOUBLE, (const char *)&value, sizeof(value)); + if (m_queryFunc) + Py_DECREF(m_queryFunc); + m_queryFunc = queryFunc; + if (m_queryFunc) + Py_INCREF(m_queryFunc); } -int NConfig::setKey(const char *name, const double value) +RESULT ePythonConfigQuery::getConfigValue(const char *key, std::string &value) { - long double b = value; - return _setKey(name, NC_DOUBLE, (const char *)&b, sizeof(b)); -} - -int NConfig::setKey(const char *name, const char *value, const unsigned len) -{ - if (!value && len) - return NC_ERR_NVAL; - if (!len) - return _setKey(name, NC_RAW, NULL, 0); - return _setKey(name, NC_RAW, value, len); -} - -int NConfig::getKey(const char *name, unsigned long long &value) -{ - if (fd < 0) - return NC_ERR_NFILE; - lockFile(NC_L_RO); - int ret = NC_ERR_OK; - struct nc_de_s *k = getDirEnt(name); - if (k) { - if (k->type == NC_UINT) { - memcpy(&value, data+k->offset, sizeof(value)); - } else - ret = NC_ERR_TYPE; - } else - ret = NC_ERR_NEXIST; - unLockFile(); - return ret; -} - -int NConfig::getKey(const char *name, unsigned &value) -{ - if (fd < 0) - return NC_ERR_NFILE; - lockFile(NC_L_RO); - int ret = NC_ERR_OK; - struct nc_de_s *k = getDirEnt(name); - if (k) { - if (k->type == NC_UINT) { - unsigned long long b; - memcpy(&b, data+k->offset, sizeof(b)); - value = b; - } else - ret = NC_ERR_TYPE; - } else - ret = NC_ERR_NEXIST; - unLockFile(); - return ret; -} - -int NConfig::getKey(const char *name, long double &value) -{ - if (fd < 0) - return NC_ERR_NFILE; - lockFile(NC_L_RO); - int ret = NC_ERR_OK; - struct nc_de_s *k = getDirEnt(name); - if (k) { - if (k->type == NC_DOUBLE) { - memcpy(&value, data+k->offset, sizeof(value)); - } else - ret = NC_ERR_TYPE; - } else - ret = NC_ERR_NEXIST; - unLockFile(); - return ret; -} - -int NConfig::getKey(const char *name, double &value) -{ - if (fd < 0) - return NC_ERR_NFILE; - lockFile(NC_L_RO); - int ret = NC_ERR_OK; - struct nc_de_s *k = getDirEnt(name); - if (k) { - if (k->type == NC_DOUBLE) { - long double b; - memcpy(&b, data+k->offset, sizeof(b)); - value = b; - } else - ret = NC_ERR_TYPE; - } else - ret = NC_ERR_NEXIST; - unLockFile(); - return ret; -} - -int NConfig::getKey(const char *name, signed long long &value) -{ - if (fd < 0) - return NC_ERR_NFILE; - lockFile(NC_L_RO); - int ret = NC_ERR_OK; - struct nc_de_s *k = getDirEnt(name); - if (k) { - if (k->type == NC_INT) { - memcpy(&value, data+k->offset, sizeof(value)); - } else - ret = NC_ERR_TYPE; - } else - ret = NC_ERR_NEXIST; - unLockFile(); - return ret; -} - -int NConfig::getKey(const char *name, int &value) -{ - if (fd < 0) - return NC_ERR_NFILE; - lockFile(NC_L_RO); - int ret = NC_ERR_OK; - struct nc_de_s *k = getDirEnt(name); - if (k) { - if (k->type == NC_INT) { - signed long long b; - memcpy(&b, data+k->offset, sizeof(b)); - value = b; - } else - ret = NC_ERR_TYPE; - } else - ret = NC_ERR_NEXIST; - unLockFile(); - return ret; -} - -int NConfig::getKey(const char *name, char *&value) -{ - if (fd < 0) - return NC_ERR_NFILE; - lockFile(NC_L_RO); - int ret = NC_ERR_OK; - struct nc_de_s *k = getDirEnt(name); - if (k) { - if (k->type == NC_STRING) { - if (k->offset) { - if (!(value = strdup(data+k->offset))) - ret = NC_ERR_NMEM; - } else - value = NULL; - } else - ret = NC_ERR_TYPE; - } else - ret = NC_ERR_NEXIST; - unLockFile(); - return ret; -} - -int NConfig::getKey(const char *name, char *&value, unsigned &len) -{ - if (fd < 0) - return NC_ERR_NFILE; - lockFile(NC_L_RO); - int ret = NC_ERR_OK; - struct nc_de_s *k = getDirEnt(name); - if (k) { - if (k->type == NC_RAW) { - if (k->offset) { - len = k->pages; - value = (char *)malloc(len); - memcpy(value, data+k->offset, len); - } else { - len = 0; - value = NULL; + if (key && PyCallable_Check(m_queryFunc)) + { + PyObject *pArgs = PyTuple_New(1); + PyTuple_SET_ITEM(pArgs, 0, PyString_FromString(key)); + PyObject *pRet = PyObject_CallObject(m_queryFunc, pArgs); + Py_DECREF(pArgs); + if (pRet) + { + if (PyString_Check(pRet)) + { + value.assign(PyString_AS_STRING(pRet)); + return 0; } - } else - ret = NC_ERR_TYPE; - } else - ret = NC_ERR_NEXIST; - unLockFile(); - return ret; -} - -void NConfig::lockFile(int type, int force) -{ -#ifdef NC_DEBUG_LOCK - fprintf(stderr, "Lock called type=%d force=%d lock=%d olck=%u\n", type, force, lock, olck); -#endif - if (lock == NC_L_RO && type == NC_L_RW) { - fprintf(stderr, "Lock promotion is not possible.\n"); - abort(); - } - if (lock != NC_L_NONE) { - olck++; - return; - } - - struct flock flc = { type == NC_L_RW ? F_WRLCK : F_RDLCK, SEEK_SET, 0, 0, 0 }; - while (fcntl(fd, F_SETLKW, &flc)) { - sched_yield(); - flc.l_type = type == NC_L_RW ? F_WRLCK : F_RDLCK; - flc.l_whence = SEEK_SET; - flc.l_len = flc.l_start = 0; - } - -#ifdef NC_DEBUG_LOCK - fprintf(stderr, "Locked %u %u %s\n", sb->modtime, update, force ? "forced." : ""); -#endif - if (careful && type == NC_L_RW) - mprotect(data, sb->size, PROT_READ | PROT_WRITE); - lock = type; - olck = 0; - if (sb->modtime != update || force) { - // refresh memory mapping - if (lsize != sb->size) { - _remap(lsize, sb->size); - lsize = sb->size; - chunks = CM(sb->chunk); + Py_DECREF(pRet); } - cdir = getDirEnt(cname); - update = sb->modtime; } + return -1; } - -void NConfig::unLockFile() -{ -#ifdef NC_DEBUG_LOCK - fprintf(stderr, "UnLock called lock=%u olck=%u\n", lock, olck); -#endif - if (olck) { - olck--; - return; - } - if (lock == NC_L_NONE) - return; - struct flock flc = {F_UNLCK, SEEK_SET, 0, 0, 0 }; - update = sb->modtime; -#ifdef NC_DEBUG_LOCK - fprintf(stderr, "Unlock %u\n", update); -#endif - if (careful) - mprotect(data, sb->size, PROT_READ); - fcntl(fd, F_SETLK, &flc); - lock = NC_L_NONE; - olck = 0; -} - -void NConfig::_remap(const size_t osize, const size_t nsize) -{ - data = (char *) mremap(data, osize, nsize, 1); - if (data == MAP_FAILED) { - perror("mremap"); - abort(); - } - sb = SB; - rdir = DE(sb->root); -} - -char * NConfig::version() -{ - return strdup("EliteDVB registry"); -} - diff --git a/lib/base/nconfig.h b/lib/base/nconfig.h index 12a3c6c..2c87491 100644 --- a/lib/base/nconfig.h +++ b/lib/base/nconfig.h @@ -1,392 +1,18 @@ -#ifndef NC_NCONFIG_H -#define NC_NCONFIG_H 1 +#ifndef __lib_base_nconfig_h_ +#define __lib_base_nconfig_h_ -#include -#include +#include -/* - * Superblock definitions - */ -#define NC_SB_MAGIC ("\0\11\22") // Superblock identifier - -/* - * Key type definitions - */ -#define NC_DIR 0x01 // The key is a directory -#define NC_STRING 0x02 // The key contains a string -#define NC_INT 0x03 // The key contains a signed integer -#define NC_UINT 0x04 // The key contains an unsigned integer -#define NC_RAW 0x05 // The key contains raw data -#define NC_DOUBLE 0x06 // The key contains a double -#define NC_LINK 0x07 // The key points somewhere else - -/* - * File access definitions - */ -#define NC_O_RO 0x01 // Open file in read-only mode -#define NC_O_RW 0x02 // Open file in read-write mode - -/* - * Lock types - */ -#define NC_L_NONE 0x00 // No lock -#define NC_L_RO 0x01 // Read-only lock -#define NC_L_RW 0x02 // Read-write lock - -/* - * Error codes - */ -#define NC_ERR_OK 0 // Everything is OK -#define NC_ERR_TYPE -1 // Type mismatch -#define NC_ERR_NDIR -2 // Key is not a directory -#define NC_ERR_PERM -3 // Operation is not allowed -#define NC_ERR_NMEM -4 // Not enough memory to complete operation -#define NC_ERR_NEXIST -5 // Key does not exist -#define NC_ERR_NFILE -6 // No file is assigned/open -#define NC_ERR_CORRUPT -7 // File is corrupted -#define NC_ERR_NVAL -8 // Invalid value -#define NC_ERR_RDONLY -9 // File is open in read-only mode -#define NC_ERR_NOSUPPORT -10 // Support is not compiled-in - -/* - * Truth value definitions - */ -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -/* - * Header of the config file. - */ -struct nc_sb_s { - char magic[4]; // superblock magic - unsigned size; // Current file size - unsigned ent_inc; // directory increment - unsigned chunk_inc; // Memory chunks increment - unsigned size_inc; // file size increment - unsigned chunk_ttl; // size of chunkmap - unsigned chunk; // pointer to chunkmap - unsigned root; // pointer to root direntry - unsigned modtime; // file version -}; - -/* - * Free chunk descriptor - */ -struct nc_chunk_s { - unsigned offset; - unsigned size; -}; - -/* - * In-file directory entry - */ -struct nc_de_s { - unsigned name; - unsigned type; - unsigned parent; - unsigned offset; - unsigned pages; - unsigned crc; -}; - -/* - * Ls reporting - */ -struct nc_ls_s { - const char *name; - unsigned type; -}; - -class NConfig +class ePythonConfigQuery { + static PyObject *m_queryFunc; + ePythonConfigQuery() {} + ~ePythonConfigQuery() {} public: - /* - * Class constructor - * pass TRUE as parameter to enable - * write protection when leaving library - */ - NConfig(int protect = FALSE); - virtual ~NConfig(); - - /* - * Set file name (prior to open) - * Errors: - * NC_ERR_PERM file is already open - * NC_ERR_NVAL no file name is given - */ - int setName(const char *name); - - /* - * Open the configuration file, re-open it - * Errors: - * NC_ERR_NFILE no file name is assigned - * NC_ERR_TYPE file open mode is invalid - * NC_ERR_PERM file cannot be opened/created - * NC_ERR_NMEM unable to mmap the file - * NC_ERR_CORRUPT superblock magic mismatch - */ - int open(const int how = NC_O_RW); - - /* - * Close the configuration file - * No errors defined - */ - void close(); - - void flush(); // flush file if not mmap'ed - - /* - * Create a new file - * resize is filesize increment is system pages - * dirent is directory increment - * mchunks is memory block increment - * Errors: - * NC_ERR_PERM file already exists - * NC_ERR_NFILE cannot create new file - * NC_ERR_NVAL file is already open - */ - int createNew(unsigned resize = 4, unsigned dirent = 32, unsigned mchunks = 32); - - /* - * Get an unsigned integer - * Errors: - * NC_ERR_NFILE no file is open - * NC_ERR_NEXIST the key does not exist - * NC_ERR_TYPE the key exists, but is of different type - */ - int getKey(const char *name, unsigned &value); - int getKey(const char *name, unsigned long long &value); - - /* - * Get a signed integer - * Errors: - * NC_ERR_NFILE no file is open - * NC_ERR_NEXIST the key does not exist - * NC_ERR_TYPE the key exists, but is of different type - */ - int getKey(const char *name, int &value); - int getKey(const char *name, signed long long &value); - - /* - * Get a string - * Errors: - * NC_ERR_NFILE no file is open - * NC_ERR_NEXIST the key does not exist - * NC_ERR_TYPE the key exists, but is of different type - */ - int getKey(const char *name, char *&value); - - /* - * Get a long double - * Errors: - * NC_ERR_NFILE no file is open - * NC_ERR_NEXIST the key does not exist - * NC_ERR_TYPE the key exists, but is of different type - */ - int getKey(const char *name, double &value); - int getKey(const char *name, long double &value); - - /* - * Get raw data - * Errors: - * NC_ERR_NFILE no file is open - * NC_ERR_NEXIST the key does not exist - * NC_ERR_TYPE the key exists, but is of different type - */ - int getKey(const char *name, char *&value, unsigned &len); - - /* - * Insert an unsigned integer - * NC_ERR_NFILE no file is open - * NC_ERR_RDONLY file is open in read-only mode - * NC_ERR_PERM intermediate key is not a directory - * NC_ERR_TYPE key already exists, but is not an usigned integer - * NC_ERR_NEXIST key does not exist (should NEVER happen) - */ - int setKey(const char *name, const unsigned value); - int setKey(const char *name, const unsigned long long value); - - /* - * Insert an integer - * NC_ERR_NFILE no file is open - * NC_ERR_RDONLY file is open in read-only mode - * NC_ERR_PERM intermediate key is not a directory - * NC_ERR_TYPE key already exists, but is not a signed integer - * NC_ERR_NEXIST key does not exist (should NEVER happen) - */ - int setKey(const char *name, const int value); - int setKey(const char *name, const signed long long value); - - /* - * Insert a string - * NC_ERR_NFILE no file is open - * NC_ERR_RDONLY file is open in read-only mode - * NC_ERR_PERM intermediate key is not a directory - * NC_ERR_TYPE key already exists, but is not a string - * NC_ERR_NEXIST key does not exist (should NEVER happen) - */ - int setKey(const char *name, const char *value); - - /* - * Insert raw data - * NC_ERR_NFILE no file is open - * NC_ERR_RDONLY file is open in read-only mode - * NC_ERR_PERM intermediate key is not a directory - * NC_ERR_TYPE key already exists, but is not raw data - * NC_ERR_NEXIST key does not exist (should NEVER happen) - */ - int setKey(const char *name, const char *value, const unsigned len); - - /* - * Insert a double - * NC_ERR_NFILE no file is open - * NC_ERR_RDONLY file is open in read-only mode - * NC_ERR_PERM intermediate key is not a directory - * NC_ERR_TYPE key already exists, but is not raw data - * NC_ERR_NEXIST key does not exist (should NEVER happen) - */ - int setKey(const char *name, const double value); - int setKey(const char *name, const long double value); - - /* - * Rename a key - * Errors: - * NC_ERR_NFILE no file is open - * NC_ERR_RDONLY file is open read-only - * NC_ERR_NEXIST the key does not exist - * NC_ERR_PERM key with specified name already exists - */ - int renameKey(const char *oldname, const char *newname); - - /* - * Delete a key - * No errors defined - */ - void delKey(const char *name); - - /* - * Create a directory - * entries parameter specifies number of direntries to preallocate - * Errors: - * NC_ERR_NFILE no file is open - * NC_ERR_RDONLY file is open in read-only mode - * NC_ERR_PERM intermediate key is not a directory - * NC_ERR_TYPE key already exists, but is not a directory - * NC_ERR_NEXIST key does not exist (should NEVER happen) - */ - int createDir(const char *name, unsigned entries = 0); - - /* - * Change working directory - * Errors: - * NC_ERR_NFILE no file is open - * NC_ERR_NDIR target key is not a directory - * NC_ERR_NEXIST target key direcotry does not exist - */ - int chDir(const char *name); - - /* - * Print working directory - * Errors: - * Returns NULL on error - */ - const char *pwDir(); - - /* - * List all keys in current/specified directory - * Result is a NULL-terminated array of nc_ls_s - * structures. - * Errors: - * Returns NULL on error - * Note: - * You need to free the returned pointer, - * as well as all the names in it. - */ - struct nc_ls_s *ls(const char *dir = NULL); - - /* - * Lock file - * This will block until lock becomes available - * type is either: - * NC_L_RO for read-only lock - * NC_L_RW for read-write lock - * No errors defined - * - * NOTE: lock may get promoted - */ - void lockFile(int type, int force = FALSE); - - /* - * Unlock file - * No errors defined - */ - void unLockFile(); - - /* - * Print out (to stderr) information about current file - * No errors defined - */ - void status(); - - /* - * Return version string - */ - static char *version(); - - /* - * Dump current file to XML - * Errors: - * NC_ERR_NFILE no file is open - * NC_ERR_PERM could not write XML output - */ - int toXML(const char *filename); - - /* - * Load XML to current file - * a file has to be open - * force can be - * TRUE - existing keys will be deleted - * FALSE - import will ignore a key if existing key type conflicts - * Errors: - * NC_ERR_NFILE no file is open - * NC_ERR_PERM file is open read-only - */ - int fromXML(const char *filename, int force = TRUE); - -protected: - int fd, omode, lock, careful; - char *fname, *data, *cname; - unsigned lsize, update; - unsigned revision, olck; - struct nc_sb_s *sb; - struct nc_de_s *rdir, *cdir; - struct nc_chunk_s *chunks; - - int _setKey(const char *, const unsigned, const char *, const unsigned); - void _delKey(const char *, struct nc_de_s *, int); - void expand(unsigned); - - void fast_free(unsigned); - - unsigned getChunk(unsigned); - void freeChunk(unsigned); - static inline unsigned alignSize(unsigned); - - struct nc_de_s *getDirEnt(const char *, struct nc_de_s * = NULL); - struct nc_de_s *insert(unsigned, struct nc_de_s *); - char *canonize(const char *); - char *getName(const struct nc_de_s *); - - void _remap(const size_t, const size_t); - - inline unsigned crc(const char *, unsigned); - void store(nc_de_s *, FILE *); - void restore(void *, int); + static void setQueryFunc(PyObject *func); +#ifndef SWIG + static RESULT getConfigValue(const char *key, std::string &value); +#endif }; -#endif /* NC_NCONFIG_H */ - +#endif // __lib_base_nconfig_h_ diff --git a/lib/python/Components/AVSwitch.py b/lib/python/Components/AVSwitch.py index 525ecb9..19fccf5 100644 --- a/lib/python/Components/AVSwitch.py +++ b/lib/python/Components/AVSwitch.py @@ -84,7 +84,7 @@ def InitAVSwitch(): #config.av.tvsystem = configElement("config.av.tvsystem", configSelection, 0, ("PAL", "PAL + PAL60", "Multi", "NTSC") ) config.av.tvsystem = configElement("config.av.tvsystem", configSelection, 0, (("pal", _("PAL")), ("ntsc", _("NTSC"))) ) config.av.wss = configElement("config.av.wss", configSelection, 0, (("off", _("Off")), ("on", _("On"))) ) -# config.av.defaultac3 = configElement("config.av.defaultac3", configSelection, 1, (("enable", _("Enable")), ("disable", _("Disable")))) + config.av.defaultac3 = configElement("config.av.defaultac3", configSelection, 1, (("enable", _("Enable")), ("disable", _("Disable")))) config.av.vcrswitch = configElement("config.av.vcrswitch", configSelection, 1, (("enable", _("Enable")), ("disable", _("Disable")))) iAVSwitch = AVSwitch() diff --git a/lib/python/Components/config.py b/lib/python/Components/config.py index 7c7acc3..4217202 100644 --- a/lib/python/Components/config.py +++ b/lib/python/Components/config.py @@ -38,6 +38,18 @@ class configFile: else: self.configElements[key] = value + def getResolvedKey(self, key): + str = self.configElements[key] + if len(str): + pos = str.find('*') + if pos != -1: + str = str[pos+1:] + pos = str.find('*') + if pos != -1: + return str[:pos] + return str + return None + def save(self): if self.changed == 0: #no changes, so no write to disk needed return diff --git a/lib/python/enigma_python.i b/lib/python/enigma_python.i index eee5ef0..0ca55bb 100644 --- a/lib/python/enigma_python.i +++ b/lib/python/enigma_python.i @@ -40,6 +40,7 @@ is usually caused by not marking PSignals as immutable. #include #include #include +#include #include #include #include @@ -154,6 +155,7 @@ typedef long time_t; %immutable eListbox::selectionChanged; %include +%include %include %include %include diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index a36b300..d1b9906 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -5,7 +5,7 @@ #include #include #include - +#include // access to python config #include #include #include @@ -1560,6 +1560,12 @@ void eDVBServicePlay::updateDecoder() int vpid = -1, apid = -1, apidtype = -1, pcrpid = -1, tpid = -1; eDVBServicePMTHandler &h = m_timeshift_active ? m_service_handler_timeshift : m_service_handler; + bool defaultac3=false; + std::string default_ac3; + + if (!ePythonConfigQuery::getConfigValue("config.av.defaultac3", default_ac3)) + defaultac3 = default_ac3 == "enable"; + eDVBServicePMTHandler::program program; if (h.getProgramInfo(program)) eDebug("getting program info failed."); @@ -1589,10 +1595,13 @@ void eDVBServicePlay::updateDecoder() i(program.audioStreams.begin()); i != program.audioStreams.end(); ++i) { - if (apid == -1) + if (apid == -1 || (apidtype == eDVBAudio::aMPEG && defaultac3)) { - apid = i->pid; - apidtype = i->type; + if ( apid == -1 || (i->type != eDVBAudio::aMPEG) ) + { + apid = i->pid; + apidtype = i->type; + } } if (i != program.audioStreams.begin()) eDebugNoNewLine(", "); diff --git a/mytest.py b/mytest.py index 8b3ad49..5f574ad 100644 --- a/mytest.py +++ b/mytest.py @@ -415,6 +415,8 @@ def runScreenTest(): screensToRun.append(Screens.InfoBar.InfoBar) + ePythonConfigQuery.setQueryFunc(configfile.getResolvedKey) + def runNextScreen(session, screensToRun, *result): if result: quitMainloop(*result) -- 2.7.4