Small helper class for filtering file/path names.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24583 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
/*
|
||||
* Copyright 2008, Ingo Weinhold, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _ENTRY_FILTER_H
|
||||
#define _ENTRY_FILTER_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#if defined(__BEOS__) && !defined(__HAIKU__)
|
||||
// BeOS doesn't have <fnmatch.h>, but libroot.so features fnmatch() anyway
|
||||
extern "C" int fnmatch(const char *pattern, const char *string, int flags);
|
||||
#else
|
||||
# include <fnmatch.h>
|
||||
#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
|
||||
Reference in New Issue
Block a user