⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cache.c

📁 linux下的dvb收看解析软件代码; 带参考程序
💻 C
字号:
/*Copyright (C) 2006  Adam CharrettThis program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USAcache.cCaches service and PID information from the database for the current multiplex.*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "ts.h"#include "multiplexes.h"#include "services.h"#include "logging.h"#include "cache.h"#define SERVICES_MAX (256)enum CacheFlags{    CacheFlag_Clean         = 0x00,    CacheFlag_Dirty_PMTPID  = 0x01,    CacheFlag_Dirty_PIDs    = 0x02, /* Also means PMT Version needs to be updated */    CacheFlag_Dirty_Name    = 0x04,    CacheFlag_Dirty_Added   = 0x10,};static int cachedServicesMultiplexDirty = 0;static Multiplex_t *cachedServicesMultiplex = NULL;static int cachedServicesCount = 0;static int cachedDeletedServicesCount = 0;static enum CacheFlags cacheFlags[SERVICES_MAX];static Service_t*      cachedServices[SERVICES_MAX];static Service_t*      cachedDeletedServices[SERVICES_MAX];static int             cachedPIDsCount[SERVICES_MAX];static PID_t*          cachedPIDs[SERVICES_MAX];static void CacheServicesFree();static void CachePIDsFree();static int CachePIDsLoad(Service_t *service, int index);int CacheInit(){    /* Do nothing for the moment */    return 0;}void CacheDeInit(){    CacheWriteback();    CacheServicesFree();    CachePIDsFree();}int CacheLoad(Multiplex_t *multiplex){    int count = ServiceForMultiplexCount(multiplex->freq);    /* Free the services and PIDs from the previous multiplex */    CacheServicesFree();    CachePIDsFree();    printlog(LOG_DEBUG,"Loading %d services for %d\n", count, multiplex->freq);    if (count > 0)    {        int i;        ServiceEnumerator_t *enumerator;        enumerator = ServiceEnumeratorForMultiplex(multiplex->freq);        for (i=0; i < count; i++)        {            cachedServices[i] = ServiceGetNext(enumerator);            printlog(LOG_DEBUG,"Loaded 0x%04x %s\n", cachedServices[i]->id, cachedServices[i]->name);            CachePIDsLoad(cachedServices[i], i);            cacheFlags[i] = CacheFlag_Clean;        }        ServiceEnumeratorDestroy(enumerator);        cachedServicesCount = count;        cachedServicesMultiplex = multiplex;        cachedServicesMultiplexDirty = 0;        return 0;    }    return 1;}Service_t *CacheServiceFindId(int id){    Service_t *result = NULL;    int i;    if (cachedServices)    {        for (i = 0; i < cachedServicesCount; i ++)        {            if (cachedServices[i]->id == id)            {                result = cachedServices[i];                break;            }        }    }    return result;}Service_t *CacheServiceFindName(char *name, Multiplex_t **multiplex){    Service_t *result = NULL;    int i;    if (cachedServices)    {        printlog(LOG_DEBUGV,"Checking cached services\n");        for (i = 0; i < cachedServicesCount; i ++)        {            if (strcmp(cachedServices[i]->name, name) == 0)            {                result = cachedServices[i];                *multiplex = cachedServicesMultiplex;                printlog(LOG_DEBUGV,"Found in cached services!\n");                break;            }        }    }    if (result == NULL)    {        if (cachedServices)        {            printlog(LOG_DEBUGV,"Not found in cached services\n");        }        result = ServiceFindName(name);        if (result)        {            *multiplex = MultiplexFind(result->multiplexfreq);        }    }    return result;}Service_t **CacheServicesGet(int *count){    *count = cachedServicesCount;    return cachedServices;}static int CachePIDsLoad(Service_t *service, int index){    int count = ServicePIDCount(service);    if (count > 0)    {        cachedPIDs[index] = calloc(count, sizeof(PID_t));        if (!cachedPIDs[index])        {            return 1;        }        ServicePIDGet(service, cachedPIDs[index], &count);        cachedPIDsCount[index] = count;        return 0;    }    return 1;}PID_t *CachePIDsGet(Service_t *service, int *count){    PID_t *result = NULL;    int i;    *count = 0;    for (i = 0; i < cachedServicesCount; i ++)    {        if ((cachedServices[i]) && ServiceAreEqual(service, cachedServices[i]))        {            result = cachedPIDs[i];            *count = cachedPIDsCount[i];            break;        }    }    return result;}void CacheUpdateMultiplex(Multiplex_t *multiplex, int patversion, int tsid){    if (cachedServicesMultiplex && MultiplexAreEqual(multiplex, cachedServicesMultiplex))    {        cachedServicesMultiplex->patversion = patversion;        cachedServicesMultiplex->tsid = tsid;        cachedServicesMultiplexDirty = 1;    }}void CacheUpdateService(Service_t *service, int pmtpid){    int i;    for (i = 0; i < cachedServicesCount; i ++)    {        if ((cachedServices[i]) && ServiceAreEqual(service, cachedServices[i]))        {            cachedServices[i]->pmtpid = pmtpid;            cacheFlags[i] |= CacheFlag_Dirty_PMTPID;            break;        }    }}void CacheUpdateServiceName(Service_t *service, char *name){    int i;    for (i = 0; i < cachedServicesCount; i ++)    {        if ((cachedServices[i]) && ServiceAreEqual(service, cachedServices[i]))        {            free(cachedServices[i]->name);            cachedServices[i]->name = strdup(name);            cacheFlags[i] |= CacheFlag_Dirty_Name;            break;        }    }}void CacheUpdatePIDs(Service_t *service, PID_t *pids, int count, int pmtversion){    int i;    for (i = 0; i < cachedServicesCount; i ++)    {        if ((cachedServices[i]) && ServiceAreEqual(service, cachedServices[i]))        {            if (cachedPIDs[i])            {                free(cachedPIDs[i]);            }            cachedPIDs[i] = pids;            cachedPIDsCount[i] = count;            cachedServices[i]->pmtversion = pmtversion;            cacheFlags[i] |= CacheFlag_Dirty_PIDs;            break;        }    }}Service_t *CacheServiceAdd(int id){    Service_t *result = calloc(1, sizeof(Service_t));    if (result)    {        result->id = id;        result->pmtversion = -1;        result->pmtpid = 8192;        result->name = malloc(5);        sprintf(result->name, "%04x", id);        result->multiplexfreq = cachedServicesMultiplex->freq;        cachedServices[cachedServicesCount] = result;        cachedPIDs[cachedServicesCount] = NULL;        cachedPIDsCount[cachedServicesCount] = 0;        cacheFlags[cachedServicesCount]  = CacheFlag_Dirty_Added;        cachedServicesCount ++;    }    return result;}void CacheServiceDelete(Service_t *service){    int deletedIndex = -1;    int i;    for (i = 0; i < cachedServicesCount; i ++)    {        if ((cachedServices[i]) && ServiceAreEqual(service, cachedServices[i]))        {            deletedIndex = i;            break;        }    }    if (deletedIndex != -1)    {        /* Get rid of the pids as we don't need them any more! */        free(cachedPIDs[deletedIndex]);        /* Remove the deleted service from the list */        for (i = deletedIndex; i < cachedServicesCount; i ++)        {            cachedPIDs[i] = cachedPIDs[i + 1];            cachedServices[i] = cachedServices[i +1];            cacheFlags[i] = cacheFlags [i + 1];        }        cachedServicesCount --;        /* Add the deleted service to the list of deleted services for removal            when we writeback the cache.         */        cachedDeletedServices[cachedDeletedServicesCount] = service;        cachedDeletedServicesCount ++;    }}void CacheWriteback(){    int i;    printlog(LOG_DEBUG, "Writing changes to cache back to database\n");    if (cachedServicesMultiplexDirty)    {        int rc;        printlog(LOG_DEBUG, "Updating Multiplex PAT version\n");        rc =MultiplexPATVersionSet(cachedServicesMultiplex, cachedServicesMultiplex->patversion);        if (rc)        {            printlog(LOG_ERROR, "Failed to update Multiplex PAT version (0x%x)", rc);        }        rc = MultiplexTSIdSet(cachedServicesMultiplex, cachedServicesMultiplex->tsid);        if (rc)        {            printlog(LOG_ERROR, "Failed to update Multiplex TS ID (0x%x)", rc);        }        cachedServicesMultiplexDirty = 0;    }    for (i = 0; i < cachedServicesCount; i ++)    {        if (cacheFlags[i] & CacheFlag_Dirty_Added)        {            printlog(LOG_DEBUG, "Adding service %s (0x%04x)\n", cachedServices[i]->name, cachedServices[i]->id);            ServiceAdd(cachedServices[i]->multiplexfreq, cachedServices[i]->name, cachedServices[i]->id, cachedServices[i]->pmtversion, cachedServices[i]->pmtpid);            continue;        }        if (cacheFlags[i] & CacheFlag_Dirty_PMTPID)        {            printlog(LOG_DEBUG, "Updating PMT PID for %s\n", cachedServices[i]->name);            ServicePMTPIDSet(cachedServices[i], cachedServices[i]->pmtpid);        }        if (cacheFlags[i] & CacheFlag_Dirty_PIDs)        {            int p;            PID_t *pids = cachedPIDs[i];            printlog(LOG_DEBUG, "Updating PIDs for %s\n", cachedServices[i]->name);            ServicePIDRemove(cachedServices[i]);            for ( p = 0; p < cachedPIDsCount[i]; p ++)            {                ServicePIDAdd(cachedServices[i], pids[p].pid, pids[p].type, pids[p].subtype, cachedServices[i]->pmtversion);            }            ServicePMTVersionSet(cachedServices[i], cachedServices[i]->pmtversion);        }        if (cacheFlags[i] & CacheFlag_Dirty_Name)        {            printlog(LOG_DEBUG, "Updating name for 0x%04x new name %s\n", cachedServices[i]->id, cachedServices[i]->name);            ServiceNameSet(cachedServices[i], cachedServices[i]->name);        }    }    /* Delete deleted services from the database along with their PIDs*/    for (i = 0; i < cachedDeletedServicesCount; i ++)    {        printlog(LOG_DEBUG, "Deleting service %s (0x%04x)\n", cachedDeletedServices[i]->name, cachedDeletedServices[i]->id);        ServiceDelete(cachedDeletedServices[i]);        ServicePIDRemove(cachedDeletedServices[i]);        ServiceFree(cachedDeletedServices[i]);    }    cachedDeletedServicesCount = 0;}static void CacheServicesFree(){    if (cachedServices)    {        int i;        for (i = 0; i < cachedServicesCount; i ++)        {            if (cachedServices[i])            {                ServiceFree(cachedServices[i]);            }        }        cachedServicesCount = 0;        cachedServicesMultiplex = NULL;    }}static void CachePIDsFree(){    if (cachedPIDs)    {        int i;        for (i = 0; i < cachedServicesCount; i ++)        {            if (cachedPIDs[i])            {                free(cachedPIDs[i]);            }            cachedPIDsCount[i] = 0;        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -