/** * @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); } static void add_substrings(const std::string &text, unsigned int index) { std::string substr; for (unsigned int i = 1; i <= text.size(); i++) { substr = text.substr(0, i); filter_index.insert(substr, index); } } static std::string reassemble_text(std::list text) { std::string res; std::list::iterator it = text.begin(); if (it == text.end()) return res; res += *it; for (it++; it != text.end(); it++) res += " " + *it; return res; } std::string filter :: add(const std::string &text, unsigned int index) { std::list parsed; std::list::iterator it; parse_text(text, parsed); for (it = parsed.begin(); it != parsed.end(); it++) add_substrings(*it, index); return reassemble_text(parsed); } 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); } std::string filter :: lowercase(const std::string &text) { std::list parsed; parse_text(text, parsed); return reassemble_text(parsed); }