/* * Copyright 2013 (c) Anna Schumaker. */ #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 track_id) { std::string substr; for (unsigned int i = 1; i <= text.size(); i++) { substr = text.substr(0, i); filter_index.insert(substr, track_id); } } 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 track_id) { std::list parsed; std::list::iterator it; parse_text(text, parsed); for (it = parsed.begin(); it != parsed.end(); it++) add_substrings(*it, track_id); return reassemble_text(parsed); } static void do_set_intersection(std::set &a, std::set &b, std::set &res) { set_intersection(a.begin(), a.end(), b.begin(), b.end(), std::inserter >(res, res.begin())); } static void find_intersection(std::string &text, std::set &res) { std::set tmp; IndexEntry *it = filter_index.find(text); if (it) do_set_intersection(res, it->values, tmp); res.swap(tmp); } 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; res = found->values; 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); }