1#include "FilteredQuery.h" 2 3#include <Debug.h> 4#include <Entry.h> 5#include <String.h> 6#include <Volume.h> 7 8// Helper function to copy a query. 9// Used to avoid code duplication in 10// TFilteredQuery(const BQuery &) and TFilteredQuery(const TFilteredQuery &) 11static void 12CopyQuery(const BQuery &query, BQuery *dest) 13{ 14 ASSERT(dest); 15 16 BQuery &nonConst = const_cast<BQuery &>(query); 17 18 // BQuery doesn't have a copy constructor, 19 // so we have to do the work ourselves... 20 // Copy the predicate 21 BString buffer; 22 nonConst.GetPredicate(&buffer); 23 dest->SetPredicate(buffer.String()); 24 25 // Copy the targetted volume 26 BVolume volume(nonConst.TargetDevice()); 27 dest->SetVolume(&volume); 28} 29 30 31TFilteredQuery::TFilteredQuery() 32{ 33} 34 35 36TFilteredQuery::TFilteredQuery(const BQuery &query) 37 : 38 BQuery() 39{ 40 CopyQuery(query, this); 41} 42 43 44TFilteredQuery::TFilteredQuery(const TFilteredQuery &query) 45 : 46 BQuery() 47{ 48 CopyQuery(query, this); 49 50 // copy filters 51 fFilters = query.fFilters; 52} 53 54 55TFilteredQuery::~TFilteredQuery() 56{ 57 Clear(); 58} 59 60 61bool 62TFilteredQuery::AddFilter(filter_function filter, void *arg) 63{ 64 filter_pair *filterPair = new filter_pair(filter, arg); 65 66 return fFilters.AddItem(filterPair); 67} 68 69 70void 71TFilteredQuery::RemoveFilter(filter_function function) 72{ 73 int32 count = fFilters.CountItems(); 74 for (int32 i = 0; i < count; i++) { 75 filter_pair *pair = fFilters.ItemAt(i); 76 if (pair->filter == function) { 77 delete fFilters.RemoveItemAt(i); 78 break; 79 } 80 } 81} 82 83 84status_t 85TFilteredQuery::GetNextRef(entry_ref *ref) 86{ 87 entry_ref tmpRef; 88 status_t result; 89 90 int32 filterCount = fFilters.CountItems(); 91 while ((result = BQuery::GetNextRef(&tmpRef)) == B_OK) { 92 bool accepted = true; 93 // We have a match, so let the entry_ref go through the filters 94 // and see if it passes all the requirements 95 for (int32 i = 0; i < filterCount; i++) { 96 filter_pair *pair = fFilters.ItemAt(i); 97 filter_function filter = pair->filter; 98 accepted = (*filter)(&tmpRef, pair->args); 99 if (!accepted) 100 break; 101 } 102 103 if (accepted) { 104 // Ok, this entry_ref passed all tests 105 *ref = tmpRef; 106 break; 107 } 108 } 109 110 return result; 111} 112 113 114status_t 115TFilteredQuery::GetNextEntry(BEntry *entry, bool traverse) 116{ 117 // This code is almost a full copy/paste from Haiku's 118 // BQuery::GetNextEntry(BEntry *entry, bool traverse) 119 120 entry_ref ref; 121 status_t error = GetNextRef(&ref); 122 if (error == B_OK) 123 error = entry->SetTo(&ref, traverse); 124 125 return error; 126} 127 128 129status_t 130TFilteredQuery::Clear() 131{ 132 int32 filtersCount = fFilters.CountItems(); 133 for (int32 i = 0; i < filtersCount; i++) 134 delete fFilters.RemoveItemAt(i); 135 136 return BQuery::Clear(); 137} 138