/* * filter.c: Section filter * * See the main source file 'vdr.c' for copyright information and * how to reach the author. * * $Id: filter.c 1.4 2004/01/11 13:31:34 kls Exp $ */ #include "filter.h" #include "sections.h" // --- cSectionSyncer -------------------------------------------------------- cSectionSyncer::cSectionSyncer(void) { Reset(); } void cSectionSyncer::Reset(void) { lastVersion = 0xFF; synced = false; } bool cSectionSyncer::Sync(uchar Version, int Number, int LastNumber) { if (Version == lastVersion) return false; if (!synced) { if (Number != 0) return false; // sync on first section synced = true; } if (Number == LastNumber) lastVersion = Version; return synced; } // --- cFilterData ----------------------------------------------------------- cFilterData::cFilterData(void) { pid = 0; tid = 0; mask = 0; sticky = false; } cFilterData::cFilterData(u_short Pid, u_char Tid, u_char Mask, bool Sticky) { pid = Pid; tid = Tid; mask = Mask; sticky = Sticky; } bool cFilterData::Is(u_short Pid, u_char Tid, u_char Mask) { return pid == Pid && tid == Tid && mask == Mask; } bool cFilterData::Matches(u_short Pid, u_char Tid) { return pid == Pid && tid == (Tid & mask); } // --- cFilter --------------------------------------------------------------- cFilter::cFilter(void) { sectionHandler = NULL; on = false; } cFilter::cFilter(u_short Pid, u_char Tid, u_char Mask) { sectionHandler = NULL; on = false; Set(Pid, Tid, Mask); } cFilter::~cFilter() { if (sectionHandler) sectionHandler->Detach(this); } int cFilter::Source(void) { return sectionHandler ? sectionHandler->Source() : 0; } int cFilter::Transponder(void) { return sectionHandler ? sectionHandler->Transponder() : 0; } const cChannel *cFilter::Channel(void) { return sectionHandler ? sectionHandler->Channel() : NULL; } void cFilter::SetStatus(bool On) { if (sectionHandler && on != On) { cFilterData *fd = data.First(); while (fd) { if (On) sectionHandler->Add(fd); else { sectionHandler->Del(fd); if (!fd->sticky) { cFilterData *next = data.Next(fd); data.Del(fd); fd = next; continue; } } fd = data.Next(fd); } on = On; } } bool cFilter::Matches(u_short Pid, u_char Tid) { if (on) { for (cFilterData *fd = data.First(); fd; fd = data.Next(fd)) { if (fd->Matches(Pid, Tid)) return true; } } return false; } void cFilter::Set(u_short Pid, u_char Tid, u_char Mask) { Add(Pid, Tid, Mask, true); } void cFilter::Add(u_short Pid, u_char Tid, u_char Mask, bool Sticky) { cFilterData *fd = new cFilterData(Pid, Tid, Mask, Sticky); data.Add(fd); if (sectionHandler && on) sectionHandler->Add(fd); } void cFilter::Del(u_short Pid, u_char Tid, u_char Mask) { for (cFilterData *fd = data.First(); fd; fd = data.Next(fd)) { if (fd->Is(Pid, Tid, Mask)) { if (sectionHandler && on) sectionHandler->Del(fd); data.Del(fd); return; } } }