From da17e06b929909c456176b8645e90498edeb7f0c Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Wed, 26 Mar 2008 04:03:44 +0000 Subject: [PATCH] Small helper class for filtering file/path names. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24583 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/shared/EntryFilter.h | 181 +++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 headers/private/shared/EntryFilter.h diff --git a/headers/private/shared/EntryFilter.h b/headers/private/shared/EntryFilter.h new file mode 100644 index 0000000000..b7511765ce --- /dev/null +++ b/headers/private/shared/EntryFilter.h @@ -0,0 +1,181 @@ +/* + * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ +#ifndef _ENTRY_FILTER_H +#define _ENTRY_FILTER_H + +#include +#include +#include + +#include + +#if defined(__BEOS__) && !defined(__HAIKU__) + // BeOS doesn't have , but libroot.so features fnmatch() anyway + extern "C" int fnmatch(const char *pattern, const char *string, int flags); +#else +# include +#endif + +namespace BPrivate { + + +class BasicEntryFilter { +public: + BasicEntryFilter() + : fPattern(NULL), + fIsFileName(false) + { + } + + ~BasicEntryFilter() + { + free(fPattern); + } + + bool SetTo(const char* pattern, bool isFileName) + { + free(fPattern); + + fPattern = strdup(pattern); + if (fPattern == NULL) + return false; + + fIsFileName = isFileName; + + return true; + } + + bool Filter(const char* path, const char* name) const + { + if (fPattern != NULL) { + if (fnmatch(fPattern, (fIsFileName ? name : path), 0) == 0) + return true; + } + + return false; + } + + void SetNextFilter(BasicEntryFilter* next) + { + fNextFilter = next; + } + + BasicEntryFilter* NextFilter() const + { + return fNextFilter; + } + +private: + char* fPattern; + bool fIsFileName; + BasicEntryFilter* fNextFilter; +}; + + +class EntryFilter { +public: + EntryFilter() + : fIncludeFilters(NULL), + fExcludeFilters(NULL) + { + } + + ~EntryFilter() + { + while (BasicEntryFilter* filter = fIncludeFilters) { + fIncludeFilters = filter->NextFilter(); + delete filter; + } + + while (BasicEntryFilter* filter = fExcludeFilters) { + fExcludeFilters = filter->NextFilter(); + delete filter; + } + } + + void AddIncludeFilter(BasicEntryFilter* filter) + { + _AddFilter(fIncludeFilters, filter); + } + + bool AddIncludeFilter(const char* pattern, bool isFilePattern) + { + return _AddFilter(fIncludeFilters, pattern, isFilePattern); + } + + void AddExcludeFilter(BasicEntryFilter* filter) + { + _AddFilter(fExcludeFilters, filter); + } + + bool AddExcludeFilter(const char* pattern, bool isFilePattern) + { + return _AddFilter(fExcludeFilters, pattern, isFilePattern); + } + + bool Filter(const char* path) const + { + if (fExcludeFilters == NULL && fIncludeFilters) + return true; + + // get leaf name + const char* name = strrchr(path, '/'); + name = (name != NULL ? name + 1 : path); + + // exclude filters + if (_Filter(fExcludeFilters, path, name)) + return false; + + // include filters -- if none are given, everything matches + return fIncludeFilters == NULL || _Filter(fIncludeFilters, path, name); + } + +private: + static void _AddFilter(BasicEntryFilter*& filterList, + BasicEntryFilter* filter) + { + filter->SetNextFilter(filterList); + filterList = filter; + } + + static bool _AddFilter(BasicEntryFilter*& filterList, const char* pattern, + bool isFilePattern) + { + BasicEntryFilter* filter = new(std::nothrow) BasicEntryFilter; + if (filter == NULL) + return false; + + if (!filter->SetTo(pattern, isFilePattern)) { + delete filter; + return false; + } + + _AddFilter(filterList, filter); + + return true; + } + + static bool _Filter(const BasicEntryFilter* const& filterList, + const char* path, const char* name) + { + const BasicEntryFilter* filter = filterList; + while (filter) { + if (filter->Filter(path, name)) + return true; + filter = filter->NextFilter(); + } + + return false; + } + +private: + BasicEntryFilter* fIncludeFilters; + BasicEntryFilter* fExcludeFilters; +}; + +} // namespace BPrivate + + +#endif // _ENTRY_FILTER_H