vdr
1.7.27
|
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 }