Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "stdafx.h"
00013 #include "string_func.h"
00014 #include "stringfilter_type.h"
00015
00016 static const WChar STATE_WHITESPACE = ' ';
00017 static const WChar STATE_WORD = 'w';
00018 static const WChar STATE_QUOTE1 = '\'';
00019 static const WChar STATE_QUOTE2 = '"';
00020
00025 void StringFilter::SetFilterTerm(const char *str)
00026 {
00027 this->word_index.Reset();
00028 this->word_matches = 0;
00029 free(this->filter_buffer);
00030
00031 assert(str != NULL);
00032
00033 char *dest = (char *)malloc(strlen(str) + 1);
00034 this->filter_buffer = dest;
00035
00036 WChar state = STATE_WHITESPACE;
00037 const char *pos = str;
00038 WordState *word = NULL;
00039 size_t len;
00040 for (;; pos += len) {
00041 WChar c;
00042 len = Utf8Decode(&c, pos);
00043
00044 if (c == 0 || (state == STATE_WORD && IsWhitespace(c))) {
00045
00046 if (word != NULL) {
00047 *(dest++) = '\0';
00048 word = NULL;
00049 }
00050 state = STATE_WHITESPACE;
00051 if (c != 0) continue; else break;
00052 }
00053
00054 if (state == STATE_WHITESPACE) {
00055
00056 if (IsWhitespace(c)) continue;
00057 state = STATE_WORD;
00058 }
00059
00060 if (c == STATE_QUOTE1 || c == STATE_QUOTE2) {
00061 if (state == c) {
00062
00063 state = STATE_WORD;
00064 continue;
00065 } else if (state == STATE_WORD) {
00066
00067 state = c;
00068 continue;
00069 }
00070 }
00071
00072
00073 if (word == NULL) {
00074 word = this->word_index.Append();
00075 word->start = dest;
00076 word->match = false;
00077 }
00078
00079 memcpy(dest, pos, len);
00080 dest += len;
00081 }
00082 }
00083
00087 void StringFilter::ResetState()
00088 {
00089 this->word_matches = 0;
00090 const WordState *end = this->word_index.End();
00091 for (WordState *it = this->word_index.Begin(); it != end; ++it) {
00092 it->match = false;
00093 }
00094 }
00095
00104 void StringFilter::AddLine(const char *str)
00105 {
00106 if (str == NULL) return;
00107
00108 bool match_case = this->case_sensitive != NULL && *this->case_sensitive;
00109 const WordState *end = this->word_index.End();
00110 for (WordState *it = this->word_index.Begin(); it != end; ++it) {
00111 if (!it->match) {
00112 if ((match_case ? strstr(str, it->start) : strcasestr(str, it->start)) != NULL) {
00113 it->match = true;
00114 this->word_matches++;
00115 }
00116 }
00117 }
00118 }
00119
00120