00001
00002
00003
00004
00005 #ifndef dsBoyer_h
00006 #define dsBoyer_h
00007
00008 #ifdef HAVE_CONFIG_H
00009 # include <config.h>
00010 #endif
00011
00012
00013 #include <stdio.h>
00014 #include <stdlib.h>
00015 #include <string.h>
00016 #include <ctype.h>
00017
00018 #include <dsutil.h>
00019
00020 #ifdef MAXCHAR
00021 # define BOYER_MAXCHAR MAXCHAR
00022 # else
00023 # define BOYER_MAXCHAR 256
00024 #endif
00025
00026 class boyer_base
00027 {
00028
00029 protected:
00030 int _skip[BOYER_MAXCHAR];
00031 int _len;
00032 char* _pat;
00033
00034 boyer_base(const char *pat)
00035 {
00036 int k;
00037
00038 _len = strlen(pat);
00039
00040 for( k=0; k < BOYER_MAXCHAR; k++ ) _skip[k] = _len;
00041
00042 for( k=0; k < _len-1; k++ ) _skip[ (int) (pat[k] & 0xFF) ] = _len - k -1;
00043 }
00044
00045 public:
00052 template <class T>
00053 T* find(T* text, int n ) const
00054 {
00055 int i, j, k;
00056
00057 for( k = _len-1; k < n; k += _skip[text[k] & (BOYER_MAXCHAR-1)] )
00058 {
00059 for( j=_len-1, i = k; j >= 0 && text[i] == _pat[j]; j-- ) i--;
00060
00061 if( j == -1 ) return text+i+1;
00062
00063 }
00064
00065 return 0;
00066 }
00067
00075 template <class T>
00076 T* ucfind(T* text, int n ) const
00077 {
00078 int i, j, k;
00079
00080 for( k = _len-1; k < n;
00081 k += _skip[tolower(((unsigned char *)text)[k])] )
00082 {
00083 for( j=_len-1, i = k;
00084 j >= 0 && tolower(((unsigned char *)text)[i]) == _pat[j];
00085 j-- ) i--;
00086
00087 if( j == -1 ) return text+i+1;
00088
00089 }
00090
00091 return 0;
00092 }
00093
00097 int len(){ return _len; }
00098
00102 operator const char* () const { return _pat;}
00103
00107 operator int () const { return _len;}
00108
00109 };
00110
00111
00112
00113
00114
00115
00116
00117
00118 class cboyer : public boyer_base
00119 {
00120
00121 public:
00122 cboyer(const char* pat) : boyer_base(pat)
00123 {
00124 _pat = (char *) pat;
00125 }
00126 };
00127
00128
00142 class boyer : public boyer_base
00143 {
00144
00145 public:
00146
00149 boyer(const char* pattern) :
00150 boyer_base(pattern)
00151 {
00152 _pat = ds_strdup(pattern);
00153 }
00154
00155 ~boyer()
00156 { if (_pat)
00157 delete[] _pat;
00158 }
00159 };
00160
00161 #endif