vdr  1.7.27
filter.c
Go to the documentation of this file.
00001 /*
00002  * filter.c: Section filter
00003  *
00004  * See the main source file 'vdr.c' for copyright information and
00005  * how to reach the author.
00006  *
00007  * $Id: filter.c 2.0 2004/01/11 13:31:34 kls Exp $
00008  */
00009 
00010 #include "filter.h"
00011 #include "sections.h"
00012 
00013 // --- cSectionSyncer --------------------------------------------------------
00014 
00015 cSectionSyncer::cSectionSyncer(void)
00016 {
00017   Reset();
00018 }
00019 
00020 void cSectionSyncer::Reset(void)
00021 {
00022   lastVersion = 0xFF;
00023   synced = false;
00024 }
00025 
00026 bool cSectionSyncer::Sync(uchar Version, int Number, int LastNumber)
00027 {
00028   if (Version == lastVersion)
00029      return false;
00030   if (!synced) {
00031      if (Number != 0)
00032         return false; // sync on first section
00033      synced = true;
00034      }
00035   if (Number == LastNumber)
00036      lastVersion = Version;
00037   return synced;
00038 }
00039 
00040 // --- cFilterData -----------------------------------------------------------
00041 
00042 cFilterData::cFilterData(void)
00043 {
00044   pid = 0;
00045   tid = 0;
00046   mask = 0;
00047   sticky = false;
00048 }
00049 
00050 cFilterData::cFilterData(u_short Pid, u_char Tid, u_char Mask, bool Sticky)
00051 {
00052   pid = Pid;
00053   tid = Tid;
00054   mask = Mask;
00055   sticky = Sticky;
00056 }
00057 
00058 bool cFilterData::Is(u_short Pid, u_char Tid, u_char Mask)
00059 {
00060   return pid == Pid && tid == Tid && mask == Mask;
00061 }
00062 
00063 bool cFilterData::Matches(u_short Pid, u_char Tid)
00064 {
00065   return pid == Pid && tid == (Tid & mask);
00066 }
00067 
00068 // --- cFilter ---------------------------------------------------------------
00069 
00070 cFilter::cFilter(void)
00071 {
00072   sectionHandler = NULL;
00073   on = false;
00074 }
00075 
00076 cFilter::cFilter(u_short Pid, u_char Tid, u_char Mask)
00077 {
00078   sectionHandler = NULL;
00079   on = false;
00080   Set(Pid, Tid, Mask);
00081 }
00082 
00083 cFilter::~cFilter()
00084 {
00085   if (sectionHandler)
00086      sectionHandler->Detach(this);
00087 }
00088 
00089 int cFilter::Source(void)
00090 {
00091   return sectionHandler ? sectionHandler->Source() : 0;
00092 }
00093 
00094 int cFilter::Transponder(void)
00095 {
00096   return sectionHandler ? sectionHandler->Transponder() : 0;
00097 }
00098 
00099 const cChannel *cFilter::Channel(void)
00100 {
00101   return sectionHandler ? sectionHandler->Channel() : NULL;
00102 }
00103 
00104 void cFilter::SetStatus(bool On)
00105 {
00106   if (sectionHandler && on != On) {
00107      cFilterData *fd = data.First();
00108      while (fd) {
00109            if (On)
00110               sectionHandler->Add(fd);
00111            else {
00112               sectionHandler->Del(fd);
00113               if (!fd->sticky) {
00114                  cFilterData *next = data.Next(fd);
00115                  data.Del(fd);
00116                  fd = next;
00117                  continue;
00118                  }
00119               }
00120            fd = data.Next(fd);
00121            }
00122      on = On;
00123      }
00124 }
00125 
00126 bool cFilter::Matches(u_short Pid, u_char Tid)
00127 {
00128   if (on) {
00129      for (cFilterData *fd = data.First(); fd; fd = data.Next(fd)) {
00130          if (fd->Matches(Pid, Tid))
00131             return true;
00132          }
00133      }
00134   return false;
00135 }
00136 
00137 void cFilter::Set(u_short Pid, u_char Tid, u_char Mask)
00138 {
00139   Add(Pid, Tid, Mask, true);
00140 }
00141 
00142 void cFilter::Add(u_short Pid, u_char Tid, u_char Mask, bool Sticky)
00143 {
00144   cFilterData *fd = new cFilterData(Pid, Tid, Mask, Sticky);
00145   data.Add(fd);
00146   if (sectionHandler && on)
00147      sectionHandler->Add(fd);
00148 }
00149 
00150 void cFilter::Del(u_short Pid, u_char Tid, u_char Mask)
00151 {
00152   for (cFilterData *fd = data.First(); fd; fd = data.Next(fd)) {
00153       if (fd->Is(Pid, Tid, Mask)) {
00154          if (sectionHandler && on)
00155             sectionHandler->Del(fd);
00156          data.Del(fd);
00157          return;
00158          }
00159       }
00160 }