/** * @file * Copyright 2013 (c) Anna Schumaker. */ #include #include #include #include #include static Index filter_index("", false); static void parse_text(const std::string &text, std::list &ret) { std::string word; char c; for (unsigned int i = 0; i < text.size(); i++) { c = text[i]; if ( (c >= 'a') && (c <= 'z') ) { word += c; continue; } else if ( (c >= 'A') && (c <= 'Z') ) { word += (c + ('a' - 'A')); continue; } else if ( (c >= '0') && (c <= '9') ) { word += c; continue; } switch (c) { case '\\': case '/': case ',': case ';': case '(': case ')': case '_': case '-': case '~': case '+': case '"': case ' ': case ' ': if (word != "") { ret.push_back(word); word = ""; } default: break; }; } if (word != "") ret.push_back(word); } const std::string filter :: add(const std::string &text, unsigned int index) { const std::string lc = string :: lowercase(text); size_t begin = 0, end; 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 &res) { std::set tmp; set_intersection(entry->begin(), entry->end(), res.begin(), res.end(), std::inserter >(tmp, tmp.begin())); res.swap(tmp); } static void find_intersection(std::string &text, std::set &res) { IndexEntry *it = filter_index.find(text); if (it) do_set_intersection(it, res); else res.clear(); } void filter :: search(const std::string &text, std::set &res) { std::list parsed; std::list::iterator it; IndexEntry *found; res.clear(); parse_text(text, parsed); if (parsed.size() == 0) return; it = parsed.begin(); found = filter_index.find(*it); if (!found) return; std::copy(found->begin(), found->end(), std::inserter(res, res.begin())); for (it++; it != parsed.end(); it++) find_intersection(*it, res); }