ocarina/core/filter.cpp

72 lines
1.4 KiB
C++

/**
* Copyright 2013 (c) Anna Schumaker.
*/
#include <core/filter.h>
#include <core/index.h>
extern "C" {
#include <core/string.h>
}
#include <algorithm>
static Index filter_index("", false);
const std::string filter :: add(const std::string &text, unsigned int index)
{
gchar *g_lc = string_lowercase(text.c_str());
const std::string lc = g_lc;
size_t begin = 0, end;
g_free(g_lc);
for (end = 1; end <= lc.size(); end++) {
filter_index.insert(lc.substr(begin, end - begin), index);
if (lc[end] == ' ')
begin = ++end;
}
return lc;
}
static void do_set_intersection(IndexEntry *entry,
std::set<unsigned int> &res)
{
std::set<unsigned int> tmp;
set_intersection(entry->begin(), entry->end(), res.begin(), res.end(),
std::inserter(tmp, tmp.begin()));
res.swap(tmp);
}
void filter :: search(const std::string &text, std::set<unsigned int> &res)
{
gchar *g_lc = string_lowercase(text.c_str());
const std::string lc = g_lc;
size_t begin = 0, end;
IndexEntry *found;
g_free(g_lc);
res.clear();
for (end = 1; end <= lc.size(); end++) {
end = lc.find(' ', begin);
if (end == std::string::npos)
end = lc.size();
found = filter_index.find(lc.substr(begin, end - begin));
if (!found) {
res.clear();
return;
}
if (begin == 0)
std::copy(found->begin(), found->end(),
std::inserter(res, res.begin()));
else
do_set_intersection(found, res);
begin = ++end;
}
}