/[zanavi_public1]/navit/navit/map/filter/filter.c
ZANavi

Contents of /navit/navit/map/filter/filter.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations) (download)
Fri Oct 28 21:19:04 2011 UTC (9 years, 5 months ago) by zoff99
File MIME type: text/plain
File size: 9207 byte(s)
import files
1 /**
2 * Navit, a modular navigation system.
3 * Copyright (C) 2005-2008 Navit Team
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 *
9 * This program 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
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 #include <stdlib.h>
21 #include <glib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <math.h>
25 #include "config.h"
26 #include "debug.h"
27 #include "plugin.h"
28 #include "projection.h"
29 #include "item.h"
30 #include "map.h"
31 #include "maptype.h"
32 #include "attr.h"
33 #include "coord.h"
34 #include "transform.h"
35 #include "file.h"
36 #include "zipfile.h"
37 #include "linguistics.h"
38 #include "endianess.h"
39
40 struct filter_entry {
41 enum item_type first,last;
42 enum attr_type cond_attr;
43 char *cond_str;
44 };
45
46 struct filter {
47 GList *old;
48 GList *new;
49 };
50
51 struct map_priv {
52 struct map *parent;
53 GList *filters;
54 };
55
56 struct map_rect_priv {
57 struct map_selection *sel;
58 struct map_priv *m;
59 struct map_rect *parent;
60 struct item item,*parent_item;
61 };
62
63 struct map_search_priv {
64 struct map_rect_priv *mr;
65 };
66
67 static enum item_type
68 filter_type(struct map_priv *m, struct item *item)
69 {
70 GList *filters=m->filters;
71 struct filter_entry *entry;
72 while (filters) {
73 struct filter *filter=filters->data;
74 int pos=0,count=0;
75 GList *old,*new;
76 old=filter->old;
77 while (old) {
78 entry=old->data;
79 if (item->type >= entry->first && item->type <= entry->last)
80 break;
81 pos+=entry->last-entry->first+1;
82 old=g_list_next(old);
83 }
84 if (old && entry && entry->cond_attr != attr_none) {
85 struct attr attr;
86 if (!item_attr_get(item, entry->cond_attr, &attr)) {
87 old=NULL;
88 } else {
89 char *wildcard=strchr(entry->cond_str,'*');
90 int len;
91 if (!wildcard)
92 len=strlen(entry->cond_str)+1;
93 else
94 len=wildcard-entry->cond_str;
95 if (strncmp(entry->cond_str, attr.u.str, len))
96 old=NULL;
97 }
98 item_attr_rewind(item);
99 }
100 if (old) {
101 new=filter->new;
102 if (!new)
103 return item->type;
104 while (new) {
105 struct filter_entry *entry=new->data;
106 count+=entry->last-entry->first+1;
107 new=g_list_next(new);
108 }
109 pos%=count;
110 new=filter->new;
111 while (new) {
112 struct filter_entry *entry=new->data;
113 if (pos <= entry->last-entry->first)
114 return entry->first+pos;
115 pos-=entry->last-entry->first+1;
116 new=g_list_next(new);
117 }
118 }
119 filters=g_list_next(filters);
120 }
121 return item->type;
122 }
123
124 static void
125 free_filter_entry(struct filter_entry *filter)
126 {
127 g_free(filter->cond_str);
128 g_free(filter);
129 }
130
131 static void
132 free_filter(struct filter *filter)
133 {
134 g_list_foreach(filter->old, (GFunc)free_filter_entry, NULL);
135 g_list_free(filter->old);
136 filter->old=NULL;
137 g_list_foreach(filter->new, (GFunc)free_filter_entry, NULL);
138 g_list_free(filter->new);
139 filter->new=NULL;
140 }
141
142 static void
143 free_filters(struct map_priv *m)
144 {
145 g_list_foreach(m->filters, (GFunc)free_filter, NULL);
146 g_list_free(m->filters);
147 m->filters=NULL;
148 }
149
150 static GList *
151 parse_filter(char *filter)
152 {
153 GList *ret=NULL;
154 for (;;) {
155 char *condition,*range,*next=strchr(filter,',');
156 struct filter_entry *entry=g_new0(struct filter_entry, 1);
157 if (next)
158 *next++='\0';
159 condition=strchr(filter,'[');
160 if (condition)
161 *condition++='\0';
162 range=strchr(filter,'-');
163 if (range)
164 *range++='\0';
165 if (!strcmp(filter,"*") && !range) {
166 entry->first=type_none;
167 entry->last=type_last;
168 } else {
169 entry->first=item_from_name(filter);
170 if (range)
171 entry->last=item_from_name(range);
172 else
173 entry->last=entry->first;
174 }
175 if (condition) {
176 char *end=strchr(condition,']');
177 char *eq=strchr(condition,'=');
178 if (end && eq && eq < end) {
179 *end='\0';
180 *eq++='\0';
181 if (eq[0] == '"' || eq[0] == '\'') {
182 char *quote=strchr(eq+1,eq[0]);
183 if (quote) {
184 eq++;
185 *quote='\0';
186 }
187 }
188 entry->cond_attr=attr_from_name(condition);
189 entry->cond_str=g_strdup(eq);
190 }
191 }
192 ret=g_list_append(ret, entry);
193 if (!next)
194 break;
195 filter=next;
196 }
197 return ret;
198 }
199
200 static void
201 parse_filters(struct map_priv *m, char *filter)
202 {
203 char *filter_copy=g_strdup(filter);
204 char *str=filter_copy;
205
206 free_filters(m);
207 for (;;) {
208 char *pos,*bracket,*eq,*next=strchr(str,';');
209 struct filter *filter=g_new0(struct filter, 1);
210 if (next)
211 *next++='\0';
212 pos=str;
213 for (;;) {
214 eq=strchr(pos,'=');
215 if (eq) {
216 bracket=strchr(pos,'[');
217 if (bracket && bracket < eq) {
218 bracket=strchr(pos,']');
219 if (bracket)
220 pos=bracket+1;
221 else {
222 eq=NULL;
223 break;
224 }
225 } else {
226 *eq++='\0';
227 break;
228 }
229 } else
230 break;
231 }
232 filter->old=parse_filter(str);
233 if (eq)
234 filter->new=parse_filter(eq);
235 m->filters=g_list_append(m->filters,filter);
236 if (!next)
237 break;
238 str=next;
239 }
240 g_free(filter_copy);
241 }
242
243 static void
244 map_filter_coord_rewind(void *priv_data)
245 {
246 struct map_rect_priv *mr=priv_data;
247 item_coord_rewind(mr->parent_item);
248 }
249
250 static int
251 map_filter_coord_get(void *priv_data, struct coord *c, int count)
252 {
253 struct map_rect_priv *mr=priv_data;
254 return item_coord_get(mr->parent_item, c, count);
255 }
256
257 static void
258 map_filter_attr_rewind(void *priv_data)
259 {
260 struct map_rect_priv *mr=priv_data;
261 item_attr_rewind(mr->parent_item);
262 }
263
264 static int
265 map_filter_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
266 {
267 struct map_rect_priv *mr=priv_data;
268 return item_attr_get(mr->parent_item, attr_type, attr);
269 }
270
271 static struct item_methods methods_filter = {
272 map_filter_coord_rewind,
273 map_filter_coord_get,
274 map_filter_attr_rewind,
275 map_filter_attr_get,
276 };
277
278 static struct map_rect_priv *
279 map_filter_rect_new(struct map_priv *map, struct map_selection *sel)
280 {
281 struct map_rect_priv *mr=NULL;
282 struct map_rect *parent;
283 parent=map_rect_new(map->parent, sel);
284 if (parent) {
285 mr=g_new0(struct map_rect_priv, 1);
286 mr->m=map;
287 mr->sel=sel;
288 mr->parent=parent;
289 mr->item.meth=&methods_filter;
290 mr->item.priv_data=mr;
291 }
292 return mr;
293 }
294
295 static void
296 map_filter_rect_destroy(struct map_rect_priv *mr)
297 {
298 map_rect_destroy(mr->parent);
299 g_free(mr);
300 }
301
302 static struct item *
303 map_filter_rect_get_item(struct map_rect_priv *mr)
304 {
305 mr->parent_item=map_rect_get_item(mr->parent);
306 if (!mr->parent_item)
307 return NULL;
308 mr->item.type=filter_type(mr->m,mr->parent_item);
309 mr->item.id_lo=mr->parent_item->id_lo;
310 mr->item.id_hi=mr->parent_item->id_hi;
311 return &mr->item;
312 }
313
314 static struct item *
315 map_filter_rect_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo)
316 {
317 dbg(0,"enter\n");
318 mr->parent_item=map_rect_get_item_byid(mr->parent, id_hi, id_lo);
319 if (!mr->parent_item)
320 return NULL;
321 mr->item.type=filter_type(mr->m,mr->parent_item);
322 mr->item.id_lo=mr->parent_item->id_lo;
323 mr->item.id_hi=mr->parent_item->id_hi;
324 return &mr->item;
325 }
326
327 static struct map_search_priv *
328 map_filter_search_new(struct map_priv *map, struct item *item, struct attr *search, int partial)
329 {
330 dbg(0,"enter\n");
331 return NULL;
332 }
333
334 static struct item *
335 map_filter_search_get_item(struct map_search_priv *map_search)
336 {
337 dbg(0,"enter\n");
338 return NULL;
339 }
340
341 static void
342 map_filter_search_destroy(struct map_search_priv *ms)
343 {
344 dbg(0,"enter\n");
345 }
346
347 static void
348 map_filter_destroy(struct map_priv *m)
349 {
350 map_destroy(m->parent);
351 g_free(m);
352 }
353
354 static int
355 map_filter_set_attr(struct map_priv *m, struct attr *attr)
356 {
357 switch (attr->type) {
358 case attr_filter:
359 parse_filters(m,attr->u.str);
360 return 1;
361 default:
362 return 0;
363 }
364 }
365
366
367 static struct map_methods map_methods_filter = {
368 projection_mg,
369 "utf-8",
370 map_filter_destroy,
371 map_filter_rect_new,
372 map_filter_rect_destroy,
373 map_filter_rect_get_item,
374 map_filter_rect_get_item_byid,
375 map_filter_search_new,
376 map_filter_search_destroy,
377 map_filter_search_get_item,
378 NULL,
379 NULL,
380 map_filter_set_attr,
381 };
382
383
384
385 static struct map_priv *
386 map_filter_new(struct map_methods *meth, struct attr **attrs)
387 {
388 struct map_priv *m=NULL;
389 struct attr **parent_attrs,type,*subtype=attr_search(attrs, NULL, attr_subtype),*filter=attr_search(attrs, NULL, attr_filter);
390 struct map *map;
391 int i,j;
392 if (! subtype || !filter)
393 return NULL;
394 i=0;
395 while (attrs[i])
396 i++;
397 parent_attrs=g_new(struct attr *,i+1);
398 i=0;
399 j=0;
400 while (attrs[i]) {
401 if (attrs[i]->type != attr_filter && attrs[i]->type != attr_type) {
402 if (attrs[i]->type == attr_subtype) {
403 type=*attrs[i];
404 type.type = attr_type;
405 parent_attrs[j]=&type;
406 } else
407 parent_attrs[j]=attrs[i];
408 j++;
409 }
410 i++;
411 }
412 parent_attrs[j]=NULL;
413 *meth=map_methods_filter;
414 map=map_new(NULL, parent_attrs);
415 if (map) {
416 m=g_new0(struct map_priv, 1);
417 m->parent=map;
418 parse_filters(m,filter->u.str);
419 }
420 g_free(parent_attrs);
421 return m;
422 }
423
424 void
425 plugin_init(void)
426 {
427 dbg(1,"filter: plugin_init\n");
428 plugin_register_map_type("filter", map_filter_new);
429 }
430

   
Visit the ZANavi Wiki