+
+
+static inline uchar * next_char(uchar *s, size_t &numtexts)
+{
+ uchar c;
+ s++;
+ c = *s;
+ while (c <= 1){
+ if (c == 0) {
+ numtexts--;
+ if (numtexts == 0) return 0;
+ };
+ s++;
+ c = *s;
+ };
+ return s;
+}
+
+static inline bool naive_char_contains(uchar const *s, uchar c, size_t numtexts)
+{
+ uchar sc;
+ while(numtexts != 0){
+ sc = *s;
+ if (c == sc) return true;
+ if (sc == 0) numtexts--;
+ s++;
+ };
+ return false;
+}
+
+bool xml_tree::naive_contains(xml_tree::node_t n, uchar const *w) const
+{
+ if (w[0] == 0)
+ return true;
+ // fprintf(stderr, "Calling naive_contains on node: %i, with tag: %s\n",
+ // n,
+ // get_tag_name_by_ref(tag(n)));
+ // fflush(stderr);
+ std::pair<int32_t, int32_t> range = text_id_range(n);
+
+ //pattern is at least one char
+ if (range.first == xml_tree::NIL)
+ return false;
+
+ uchar * text = this->text_collection->GetText(range.first, range.second);
+ size_t num_texts =
+ subtree_tags(n, ATTRIBUTE_DATA_OPEN_TAG_ID) +
+ subtree_tags(n, PCDATA_OPEN_TAG_ID);
+
+ if (w[1] == 0)
+ return naive_char_contains(text, w[0], num_texts);
+
+ //KMP is overkill
+ uchar * s = text;
+ uchar * ss;
+ uchar const *ww;
+ size_t nnum_texts;
+ while (true) {
+ // fprintf(stderr, "Current char in s: %c, num_texts is: %lu\n", *s, num_texts);
+ // fflush(stderr);
+ ss = s;
+ ww = w;
+ nnum_texts = num_texts;
+ while (true){
+ // fprintf(stderr, " Current char in w: %c, num_texts is: %lu\n", *ww, num_texts);
+ // fprintf(stderr, " Current char in s: %c\n", *ss);
+ // fflush(stderr);
+
+ if (*ww == 0) return true;
+ if (*ww != *ss) break;
+ ww++;
+ ss = next_char(ss, nnum_texts);
+ if (ss == 0) return (*ww == 0);
+ };
+ // fprintf(stderr, "Not found, returning\n");
+ // fflush(stderr);
+ // fprintf(stderr, "Current string s is: %s\n", s);
+ s = next_char(s, num_texts);
+ if (s == 0) return false;
+// fprintf(stderr, "After next_char, string s is: %s\n", s);
+// fflush(stderr);
+ };
+
+}