1*da17e06bSIngo Weinhold /* 2*da17e06bSIngo Weinhold * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. 3*da17e06bSIngo Weinhold * Distributed under the terms of the MIT License. 4*da17e06bSIngo Weinhold */ 5*da17e06bSIngo Weinhold #ifndef _ENTRY_FILTER_H 6*da17e06bSIngo Weinhold #define _ENTRY_FILTER_H 7*da17e06bSIngo Weinhold 8*da17e06bSIngo Weinhold #include <stddef.h> 9*da17e06bSIngo Weinhold #include <stdlib.h> 10*da17e06bSIngo Weinhold #include <string.h> 11*da17e06bSIngo Weinhold 12*da17e06bSIngo Weinhold #include <new> 13*da17e06bSIngo Weinhold 14*da17e06bSIngo Weinhold #if defined(__BEOS__) && !defined(__HAIKU__) 15*da17e06bSIngo Weinhold // BeOS doesn't have <fnmatch.h>, but libroot.so features fnmatch() anyway 16*da17e06bSIngo Weinhold extern "C" int fnmatch(const char *pattern, const char *string, int flags); 17*da17e06bSIngo Weinhold #else 18*da17e06bSIngo Weinhold # include <fnmatch.h> 19*da17e06bSIngo Weinhold #endif 20*da17e06bSIngo Weinhold 21*da17e06bSIngo Weinhold namespace BPrivate { 22*da17e06bSIngo Weinhold 23*da17e06bSIngo Weinhold 24*da17e06bSIngo Weinhold class BasicEntryFilter { 25*da17e06bSIngo Weinhold public: BasicEntryFilter()26*da17e06bSIngo Weinhold BasicEntryFilter() 27*da17e06bSIngo Weinhold : fPattern(NULL), 28*da17e06bSIngo Weinhold fIsFileName(false) 29*da17e06bSIngo Weinhold { 30*da17e06bSIngo Weinhold } 31*da17e06bSIngo Weinhold ~BasicEntryFilter()32*da17e06bSIngo Weinhold ~BasicEntryFilter() 33*da17e06bSIngo Weinhold { 34*da17e06bSIngo Weinhold free(fPattern); 35*da17e06bSIngo Weinhold } 36*da17e06bSIngo Weinhold SetTo(const char * pattern,bool isFileName)37*da17e06bSIngo Weinhold bool SetTo(const char* pattern, bool isFileName) 38*da17e06bSIngo Weinhold { 39*da17e06bSIngo Weinhold free(fPattern); 40*da17e06bSIngo Weinhold 41*da17e06bSIngo Weinhold fPattern = strdup(pattern); 42*da17e06bSIngo Weinhold if (fPattern == NULL) 43*da17e06bSIngo Weinhold return false; 44*da17e06bSIngo Weinhold 45*da17e06bSIngo Weinhold fIsFileName = isFileName; 46*da17e06bSIngo Weinhold 47*da17e06bSIngo Weinhold return true; 48*da17e06bSIngo Weinhold } 49*da17e06bSIngo Weinhold Filter(const char * path,const char * name)50*da17e06bSIngo Weinhold bool Filter(const char* path, const char* name) const 51*da17e06bSIngo Weinhold { 52*da17e06bSIngo Weinhold if (fPattern != NULL) { 53*da17e06bSIngo Weinhold if (fnmatch(fPattern, (fIsFileName ? name : path), 0) == 0) 54*da17e06bSIngo Weinhold return true; 55*da17e06bSIngo Weinhold } 56*da17e06bSIngo Weinhold 57*da17e06bSIngo Weinhold return false; 58*da17e06bSIngo Weinhold } 59*da17e06bSIngo Weinhold SetNextFilter(BasicEntryFilter * next)60*da17e06bSIngo Weinhold void SetNextFilter(BasicEntryFilter* next) 61*da17e06bSIngo Weinhold { 62*da17e06bSIngo Weinhold fNextFilter = next; 63*da17e06bSIngo Weinhold } 64*da17e06bSIngo Weinhold NextFilter()65*da17e06bSIngo Weinhold BasicEntryFilter* NextFilter() const 66*da17e06bSIngo Weinhold { 67*da17e06bSIngo Weinhold return fNextFilter; 68*da17e06bSIngo Weinhold } 69*da17e06bSIngo Weinhold 70*da17e06bSIngo Weinhold private: 71*da17e06bSIngo Weinhold char* fPattern; 72*da17e06bSIngo Weinhold bool fIsFileName; 73*da17e06bSIngo Weinhold BasicEntryFilter* fNextFilter; 74*da17e06bSIngo Weinhold }; 75*da17e06bSIngo Weinhold 76*da17e06bSIngo Weinhold 77*da17e06bSIngo Weinhold class EntryFilter { 78*da17e06bSIngo Weinhold public: EntryFilter()79*da17e06bSIngo Weinhold EntryFilter() 80*da17e06bSIngo Weinhold : fIncludeFilters(NULL), 81*da17e06bSIngo Weinhold fExcludeFilters(NULL) 82*da17e06bSIngo Weinhold { 83*da17e06bSIngo Weinhold } 84*da17e06bSIngo Weinhold ~EntryFilter()85*da17e06bSIngo Weinhold ~EntryFilter() 86*da17e06bSIngo Weinhold { 87*da17e06bSIngo Weinhold while (BasicEntryFilter* filter = fIncludeFilters) { 88*da17e06bSIngo Weinhold fIncludeFilters = filter->NextFilter(); 89*da17e06bSIngo Weinhold delete filter; 90*da17e06bSIngo Weinhold } 91*da17e06bSIngo Weinhold 92*da17e06bSIngo Weinhold while (BasicEntryFilter* filter = fExcludeFilters) { 93*da17e06bSIngo Weinhold fExcludeFilters = filter->NextFilter(); 94*da17e06bSIngo Weinhold delete filter; 95*da17e06bSIngo Weinhold } 96*da17e06bSIngo Weinhold } 97*da17e06bSIngo Weinhold AddIncludeFilter(BasicEntryFilter * filter)98*da17e06bSIngo Weinhold void AddIncludeFilter(BasicEntryFilter* filter) 99*da17e06bSIngo Weinhold { 100*da17e06bSIngo Weinhold _AddFilter(fIncludeFilters, filter); 101*da17e06bSIngo Weinhold } 102*da17e06bSIngo Weinhold AddIncludeFilter(const char * pattern,bool isFilePattern)103*da17e06bSIngo Weinhold bool AddIncludeFilter(const char* pattern, bool isFilePattern) 104*da17e06bSIngo Weinhold { 105*da17e06bSIngo Weinhold return _AddFilter(fIncludeFilters, pattern, isFilePattern); 106*da17e06bSIngo Weinhold } 107*da17e06bSIngo Weinhold AddExcludeFilter(BasicEntryFilter * filter)108*da17e06bSIngo Weinhold void AddExcludeFilter(BasicEntryFilter* filter) 109*da17e06bSIngo Weinhold { 110*da17e06bSIngo Weinhold _AddFilter(fExcludeFilters, filter); 111*da17e06bSIngo Weinhold } 112*da17e06bSIngo Weinhold AddExcludeFilter(const char * pattern,bool isFilePattern)113*da17e06bSIngo Weinhold bool AddExcludeFilter(const char* pattern, bool isFilePattern) 114*da17e06bSIngo Weinhold { 115*da17e06bSIngo Weinhold return _AddFilter(fExcludeFilters, pattern, isFilePattern); 116*da17e06bSIngo Weinhold } 117*da17e06bSIngo Weinhold Filter(const char * path)118*da17e06bSIngo Weinhold bool Filter(const char* path) const 119*da17e06bSIngo Weinhold { 120*da17e06bSIngo Weinhold if (fExcludeFilters == NULL && fIncludeFilters) 121*da17e06bSIngo Weinhold return true; 122*da17e06bSIngo Weinhold 123*da17e06bSIngo Weinhold // get leaf name 124*da17e06bSIngo Weinhold const char* name = strrchr(path, '/'); 125*da17e06bSIngo Weinhold name = (name != NULL ? name + 1 : path); 126*da17e06bSIngo Weinhold 127*da17e06bSIngo Weinhold // exclude filters 128*da17e06bSIngo Weinhold if (_Filter(fExcludeFilters, path, name)) 129*da17e06bSIngo Weinhold return false; 130*da17e06bSIngo Weinhold 131*da17e06bSIngo Weinhold // include filters -- if none are given, everything matches 132*da17e06bSIngo Weinhold return fIncludeFilters == NULL || _Filter(fIncludeFilters, path, name); 133*da17e06bSIngo Weinhold } 134*da17e06bSIngo Weinhold 135*da17e06bSIngo Weinhold private: _AddFilter(BasicEntryFilter * & filterList,BasicEntryFilter * filter)136*da17e06bSIngo Weinhold static void _AddFilter(BasicEntryFilter*& filterList, 137*da17e06bSIngo Weinhold BasicEntryFilter* filter) 138*da17e06bSIngo Weinhold { 139*da17e06bSIngo Weinhold filter->SetNextFilter(filterList); 140*da17e06bSIngo Weinhold filterList = filter; 141*da17e06bSIngo Weinhold } 142*da17e06bSIngo Weinhold _AddFilter(BasicEntryFilter * & filterList,const char * pattern,bool isFilePattern)143*da17e06bSIngo Weinhold static bool _AddFilter(BasicEntryFilter*& filterList, const char* pattern, 144*da17e06bSIngo Weinhold bool isFilePattern) 145*da17e06bSIngo Weinhold { 146*da17e06bSIngo Weinhold BasicEntryFilter* filter = new(std::nothrow) BasicEntryFilter; 147*da17e06bSIngo Weinhold if (filter == NULL) 148*da17e06bSIngo Weinhold return false; 149*da17e06bSIngo Weinhold 150*da17e06bSIngo Weinhold if (!filter->SetTo(pattern, isFilePattern)) { 151*da17e06bSIngo Weinhold delete filter; 152*da17e06bSIngo Weinhold return false; 153*da17e06bSIngo Weinhold } 154*da17e06bSIngo Weinhold 155*da17e06bSIngo Weinhold _AddFilter(filterList, filter); 156*da17e06bSIngo Weinhold 157*da17e06bSIngo Weinhold return true; 158*da17e06bSIngo Weinhold } 159*da17e06bSIngo Weinhold _Filter(const BasicEntryFilter * const & filterList,const char * path,const char * name)160*da17e06bSIngo Weinhold static bool _Filter(const BasicEntryFilter* const& filterList, 161*da17e06bSIngo Weinhold const char* path, const char* name) 162*da17e06bSIngo Weinhold { 163*da17e06bSIngo Weinhold const BasicEntryFilter* filter = filterList; 164*da17e06bSIngo Weinhold while (filter) { 165*da17e06bSIngo Weinhold if (filter->Filter(path, name)) 166*da17e06bSIngo Weinhold return true; 167*da17e06bSIngo Weinhold filter = filter->NextFilter(); 168*da17e06bSIngo Weinhold } 169*da17e06bSIngo Weinhold 170*da17e06bSIngo Weinhold return false; 171*da17e06bSIngo Weinhold } 172*da17e06bSIngo Weinhold 173*da17e06bSIngo Weinhold private: 174*da17e06bSIngo Weinhold BasicEntryFilter* fIncludeFilters; 175*da17e06bSIngo Weinhold BasicEntryFilter* fExcludeFilters; 176*da17e06bSIngo Weinhold }; 177*da17e06bSIngo Weinhold 178*da17e06bSIngo Weinhold } // namespace BPrivate 179*da17e06bSIngo Weinhold 180*da17e06bSIngo Weinhold 181*da17e06bSIngo Weinhold #endif // _ENTRY_FILTER_H 182