1 /*
2  Copyright (C) 2016-2017 Alexander Borisov
3 
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8 
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  Lesser General Public License for more details.
13 
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 
18  Author: lex.borisov@gmail.com (Alexander Borisov)
19 */
20 
21 #include "modest/finder/match.h"
22 
modest_finder_match_attribute_only_key(myhtml_token_attr_t * attr,const char * key,size_t key_len)23 bool modest_finder_match_attribute_only_key(myhtml_token_attr_t* attr, const char* key, size_t key_len)
24 {
25     if(key == NULL)
26         return false;
27 
28     while (attr)
29     {
30         if(attr->key.length == key_len) {
31             if(mycore_strncasecmp(key, attr->key.data, key_len) == 0)
32                 return true;
33         }
34 
35         attr = attr->next;
36     }
37 
38     return false;
39 }
40 
modest_finder_match_attribute_eq(myhtml_token_attr_t * attr,const char * key,size_t key_len,const char * value,size_t value_len,bool case_sensitive)41 bool modest_finder_match_attribute_eq(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive)
42 {
43     if(key == NULL || value == NULL)
44         return false;
45 
46     while (attr)
47     {
48         if(attr->key.length == key_len) {
49             if(mycore_strncasecmp(key, attr->key.data, key_len) == 0)
50             {
51                 if(attr->value.length == value_len) {
52                     if(case_sensitive) {
53                         if(strncmp(value, attr->value.data, value_len) == 0) {
54                             return true;
55                         }
56                     }
57                     else {
58                         if(mycore_strncasecmp(value, attr->value.data, value_len) == 0) {
59                             return true;
60                         }
61                     }
62                 }
63 
64                 break;
65             }
66         }
67 
68         attr = attr->next;
69     }
70 
71     return false;
72 }
73 
modest_finder_match_attribute_ws(myhtml_token_attr_t * attr,const char * key,size_t key_len,const char * value,size_t value_len,bool case_sensitive)74 bool modest_finder_match_attribute_ws(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive)
75 {
76     if(key == NULL || value == NULL)
77         return false;
78 
79     while (attr)
80     {
81         if(attr->key.length == key_len) {
82             if(mycore_strncasecmp(key, attr->key.data, key_len) == 0)
83             {
84                 size_t i = 0;
85                 size_t begin;
86 
87                 if(attr->value.length >= value_len) {
88                     if(case_sensitive)
89                     {
90                         while(i < attr->value.length)
91                         {
92                             begin = i;
93                             while(i < attr->value.length && mycore_utils_whithspace(attr->value.data[i], !=, &&)) {i++;}
94 
95                             if((i - begin) == value_len && (mycore_strncmp(value, &attr->value.data[begin], value_len) == 0)) {
96                                 return true;
97                             }
98                             /* skip all ws */
99                             while(i < attr->value.length && mycore_utils_whithspace(attr->value.data[i], ==, ||)) {i++;}
100                         }
101                     }
102                     else {
103                         while(i < attr->value.length)
104                         {
105                             begin = i;
106                             while(i < attr->value.length && mycore_utils_whithspace(attr->value.data[i], !=, &&)) {i++;}
107 
108                             if((i - begin) == value_len && (mycore_strncasecmp(value, &attr->value.data[begin], value_len) == 0)) {
109                                 return true;
110                             }
111                             /* skip all ws */
112                             while(i < attr->value.length && mycore_utils_whithspace(attr->value.data[i], ==, ||)) {i++;}
113                         }
114                     }
115                 }
116 
117                 break;
118             }
119         }
120 
121         attr = attr->next;
122     }
123 
124     return false;
125 }
126 
modest_finder_match_attribute_begin(myhtml_token_attr_t * attr,const char * key,size_t key_len,const char * value,size_t value_len,bool case_sensitive)127 bool modest_finder_match_attribute_begin(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive)
128 {
129     if(key == NULL || value == NULL)
130         return false;
131 
132     while (attr)
133     {
134         if(attr->key.length == key_len) {
135             if(mycore_strncasecmp(key, attr->key.data, key_len) == 0)
136             {
137                 if(attr->value.length >= value_len) {
138                     if(case_sensitive) {
139                         if(mycore_strncmp(value, attr->value.data, value_len) == 0)
140                             return true;
141                     }
142                     else {
143                         if(mycore_strncasecmp(value, attr->value.data, value_len) == 0)
144                             return true;
145                     }
146                 }
147 
148                 break;
149             }
150         }
151 
152         attr = attr->next;
153     }
154 
155     return false;
156 }
157 
modest_finder_match_attribute_end(myhtml_token_attr_t * attr,const char * key,size_t key_len,const char * value,size_t value_len,bool case_sensitive)158 bool modest_finder_match_attribute_end(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive)
159 {
160     if(key == NULL || value == NULL)
161         return false;
162 
163     while (attr)
164     {
165         if(attr->key.length == key_len) {
166             if(mycore_strncasecmp(key, attr->key.data, key_len) == 0)
167             {
168                 if(attr->value.length >= value_len) {
169                     if(case_sensitive) {
170                         if(mycore_strncmp(value, &attr->value.data[ (attr->value.length - value_len) ], value_len) == 0)
171                             return true;
172                     }
173                     else {
174                         if(mycore_strncasecmp(value, &attr->value.data[ (attr->value.length - value_len) ], value_len) == 0)
175                             return true;
176                     }
177                 }
178 
179                 break;
180             }
181         }
182 
183         attr = attr->next;
184     }
185 
186     return false;
187 }
188 
modest_finder_match_attribute_sub(myhtml_token_attr_t * attr,const char * key,size_t key_len,const char * value,size_t value_len,bool case_sensitive)189 bool modest_finder_match_attribute_sub(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive)
190 {
191     if(key == NULL || value == NULL)
192         return false;
193 
194     while (attr)
195     {
196         if(attr->key.length == key_len) {
197             if(mycore_strncasecmp(key, attr->key.data, key_len) == 0)
198             {
199                 if(attr->value.length >= value_len) {
200                     size_t i = 0;
201 
202                     if(case_sensitive)
203                     {
204                         while ((i + value_len) <= attr->value.length)
205                         {
206                             if(mycore_strncmp(value, &attr->value.data[i], value_len) == 0)
207                                 return true;
208 
209                             i++;
210                         }
211                     }
212                     else {
213                         while ((i + value_len) <= attr->value.length)
214                         {
215                             if(mycore_strncasecmp(value, &attr->value.data[i], value_len) == 0)
216                                 return true;
217 
218                             i++;
219                         }
220                     }
221                 }
222 
223                 break;
224             }
225         }
226 
227         attr = attr->next;
228     }
229 
230     return false;
231 }
232 
modest_finder_match_attribute_hsp(myhtml_token_attr_t * attr,const char * key,size_t key_len,const char * value,size_t value_len,bool case_sensitive)233 bool modest_finder_match_attribute_hsp(myhtml_token_attr_t* attr, const char* key, size_t key_len, const char* value, size_t value_len, bool case_sensitive)
234 {
235     if(key == NULL || value == NULL)
236         return false;
237 
238     while (attr)
239     {
240         if(attr->key.length == key_len) {
241             if(mycore_strncasecmp(key, attr->key.data, key_len) == 0)
242             {
243                 if(attr->value.length == value_len) {
244                     if(case_sensitive) {
245                         if(mycore_strncmp(value, attr->value.data, value_len) == 0)
246                             return true;
247                     }
248                     else {
249                         if(mycore_strncasecmp(value, attr->value.data, value_len) == 0)
250                             return true;
251                     }
252                 }
253                 else if(attr->value.length > value_len) {
254                     if(case_sensitive) {
255                         if(mycore_strncmp(value, attr->value.data, value_len) == 0) {
256                             if(attr->value.data[value_len] == '-')
257                                 return true;
258                         }
259                     }
260                     else {
261                         if(mycore_strncasecmp(value, attr->value.data, value_len) == 0) {
262                             if(attr->value.data[value_len] == '-')
263                                 return true;
264                         }
265                     }
266                 }
267 
268                 break;
269             }
270         }
271 
272         attr = attr->next;
273     }
274 
275     return false;
276 }
277 
278 
279