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

Contents of /navit/navit/map/textfile/textfile.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 28 - (hide annotations) (download)
Sun Jun 17 08:12:47 2012 UTC (11 years, 10 months ago) by zoff99
File MIME type: text/plain
File size: 8751 byte(s)
lots of new stuff and fixes
1 zoff99 2 /**
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 <glib.h>
21     #include <stdlib.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 "transform.h"
34     #include "file.h"
35    
36     #include "textfile.h"
37    
38     static int map_id;
39    
40     static void
41     get_line(struct map_rect_priv *mr)
42     {
43     if(mr->f) {
44     if (!mr->m->is_pipe)
45     mr->pos=ftell(mr->f);
46     else
47     mr->pos+=mr->lastlen;
48     fgets(mr->line, SIZE, mr->f);
49     mr->lastlen=strlen(mr->line)+1;
50     if (strlen(mr->line) >= SIZE-1)
51     printf("line too long\n");
52     }
53     }
54    
55     static void
56     map_destroy_textfile(struct map_priv *m)
57     {
58 zoff99 28 // dbg(1,"map_destroy_textfile\n");
59 zoff99 2 g_free(m->filename);
60     if(m->charset) {
61     g_free(m->charset);
62     }
63     g_free(m);
64     }
65    
66     static void
67     textfile_coord_rewind(void *priv_data)
68     {
69     }
70    
71     static int
72     parse_line(struct map_rect_priv *mr, int attr)
73     {
74     int pos;
75    
76     pos=coord_parse(mr->line, projection_mg, &mr->c);
77     if (pos < strlen(mr->line) && attr) {
78     strcpy(mr->attrs, mr->line+pos);
79     }
80     return pos;
81     }
82    
83     static int
84     textfile_coord_get(void *priv_data, struct coord *c, int count)
85     {
86     struct map_rect_priv *mr=priv_data;
87     int ret=0;
88 zoff99 28 // dbg(1,"textfile_coord_get %d\n",count);
89 zoff99 2 while (count--) {
90 zoff99 28 if (mr->f && !feof(mr->f) && (!mr->item.id_hi || !mr->eoc) && parse_line(mr, mr->item.id_hi))
91     {
92 zoff99 2 *c=mr->c;
93 zoff99 28 //dbg(1,"c=0x%x,0x%x\n", c->x, c->y);
94 zoff99 2 c++;
95     ret++;
96     get_line(mr);
97     if (mr->item.id_hi)
98     mr->eoc=1;
99 zoff99 28 }
100     else
101     {
102 zoff99 2 mr->more=0;
103     break;
104     }
105     }
106     return ret;
107     }
108    
109     static void
110     textfile_attr_rewind(void *priv_data)
111     {
112     struct map_rect_priv *mr=priv_data;
113     mr->attr_pos=0;
114     mr->attr_last=attr_none;
115     }
116    
117     static void
118     textfile_encode_attr(char *attr_val, enum attr_type attr_type, struct attr *attr)
119     {
120     if (attr_type >= attr_type_int_begin && attr_type <= attr_type_int_end)
121     attr->u.num=atoi(attr_val);
122     else
123     attr->u.str=attr_val;
124     }
125    
126     static int
127     textfile_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
128     {
129     struct map_rect_priv *mr=priv_data;
130     char *str=NULL;
131 zoff99 28 //dbg(1,"textfile_attr_get mr=%p attrs='%s' ", mr, mr->attrs);
132 zoff99 2 if (attr_type != mr->attr_last) {
133 zoff99 28 //dbg(1,"reset attr_pos\n");
134 zoff99 2 mr->attr_pos=0;
135     mr->attr_last=attr_type;
136     }
137     if (attr_type == attr_any) {
138 zoff99 28 //dbg(1,"attr_any");
139 zoff99 2 if (attr_from_line(mr->attrs,NULL,&mr->attr_pos,mr->attr, mr->attr_name)) {
140     attr_type=attr_from_name(mr->attr_name);
141 zoff99 28 //dbg(1,"found attr '%s' 0x%x\n", mr->attr_name, attr_type);
142 zoff99 2 attr->type=attr_type;
143     textfile_encode_attr(mr->attr, attr_type, attr);
144     return 1;
145     }
146     } else {
147     str=attr_to_name(attr_type);
148 zoff99 28 //dbg(1,"attr='%s' ",str);
149 zoff99 2 if (attr_from_line(mr->attrs,str,&mr->attr_pos,mr->attr, NULL)) {
150     textfile_encode_attr(mr->attr, attr_type, attr);
151 zoff99 28 //dbg(1,"found\n");
152 zoff99 2 return 1;
153     }
154     }
155 zoff99 28 //dbg(1,"not found\n");
156 zoff99 2 return 0;
157     }
158    
159     static struct item_methods methods_textfile = {
160     textfile_coord_rewind,
161     textfile_coord_get,
162     textfile_attr_rewind,
163     textfile_attr_get,
164     };
165    
166     static struct map_rect_priv *
167     map_rect_new_textfile(struct map_priv *map, struct map_selection *sel)
168     {
169     struct map_rect_priv *mr;
170    
171 zoff99 28 //dbg(1,"map_rect_new_textfile\n");
172 zoff99 2 mr=g_new0(struct map_rect_priv, 1);
173     mr->m=map;
174     mr->sel=sel;
175     if (map->flags & 1)
176     mr->item.id_hi=1;
177     else
178     mr->item.id_hi=0;
179     mr->item.id_lo=0;
180     mr->item.meth=&methods_textfile;
181     mr->item.priv_data=mr;
182     if (map->is_pipe) {
183     #ifdef HAVE_POPEN
184     char *oargs,*args=g_strdup(map->filename),*sep=" ";
185     enum layer_type lay;
186     g_free(mr->args);
187     while (sel) {
188     oargs=args;
189     args=g_strdup_printf("%s 0x%x 0x%x 0x%x 0x%x", oargs, sel->u.c_rect.lu.x, sel->u.c_rect.lu.y, sel->u.c_rect.rl.x, sel->u.c_rect.rl.y);
190     g_free(oargs);
191     for (lay=layer_town ; lay < layer_end ; lay++) {
192     oargs=args;
193     args=g_strdup_printf("%s%s%d", oargs, sep, sel->order);
194     g_free(oargs);
195     sep=",";
196     }
197     sel=sel->next;
198     }
199 zoff99 28 //dbg(1,"popen args %s\n", args);
200 zoff99 2 mr->args=args;
201     mr->f=popen(mr->args, "r");
202     mr->pos=0;
203     mr->lastlen=0;
204     #else
205     dbg(0,"map_rect_new_textfile is unable to work with pipes %s\n",map->filename);
206     #endif
207     } else {
208     mr->f=fopen(map->filename, "r");
209     }
210 zoff99 28 if(!mr->f)
211     {
212 zoff99 2 printf("map_rect_new_textfile unable to open textfile %s\n",map->filename);
213     }
214     get_line(mr);
215     return mr;
216     }
217    
218    
219     static void
220     map_rect_destroy_textfile(struct map_rect_priv *mr)
221     {
222 zoff99 28 if (mr->f)
223     {
224     if (mr->m->is_pipe)
225     {
226 zoff99 2 #ifdef HAVE_POPEN
227     pclose(mr->f);
228     #endif
229     }
230 zoff99 28 else
231     {
232 zoff99 2 fclose(mr->f);
233     }
234     }
235 zoff99 28 g_free(mr);
236 zoff99 2 }
237    
238     static struct item *
239     map_rect_get_item_textfile(struct map_rect_priv *mr)
240     {
241     char *p,type[SIZE];
242 zoff99 28 //dbg(1,"map_rect_get_item_textfile id_hi=%d line=%s", mr->item.id_hi, mr->line);
243 zoff99 2 if (!mr->f) {
244     return NULL;
245     }
246     while (mr->more) {
247     struct coord c;
248     textfile_coord_get(mr, &c, 1);
249     }
250     for(;;) {
251     if (feof(mr->f)) {
252 zoff99 28 //dbg(1,"map_rect_get_item_textfile: eof %d\n",mr->item.id_hi);
253 zoff99 2 if (mr->m->flags & 1) {
254     if (!mr->item.id_hi)
255     return NULL;
256     mr->item.id_hi=0;
257     } else {
258     if (mr->item.id_hi)
259     return NULL;
260     mr->item.id_hi=1;
261     }
262     if (mr->m->is_pipe) {
263     #ifdef HAVE_POPEN
264     pclose(mr->f);
265     mr->f=popen(mr->args, "r");
266     mr->pos=0;
267     mr->lastlen=0;
268     #endif
269     } else {
270     fseek(mr->f, 0, SEEK_SET);
271     clearerr(mr->f);
272     }
273     get_line(mr);
274     }
275     if ((p=strchr(mr->line,'\n')))
276     *p='\0';
277     if (mr->item.id_hi) {
278     mr->attrs[0]='\0';
279     if (!parse_line(mr, 1)) {
280     get_line(mr);
281     continue;
282     }
283 zoff99 28 //dbg(1,"map_rect_get_item_textfile: point found\n");
284 zoff99 2 mr->eoc=0;
285     mr->item.id_lo=mr->pos;
286     } else {
287     if (parse_line(mr, 1)) {
288     get_line(mr);
289     continue;
290     }
291 zoff99 28 //dbg(1,"map_rect_get_item_textfile: line found\n");
292 zoff99 2 if (! mr->line[0]) {
293     get_line(mr);
294     continue;
295     }
296     mr->item.id_lo=mr->pos;
297     strcpy(mr->attrs, mr->line);
298     get_line(mr);
299 zoff99 28 //dbg(1,"mr=%p attrs=%s\n", mr, mr->attrs);
300 zoff99 2 }
301 zoff99 28 //dbg(1,"get_attrs %s\n", mr->attrs);
302 zoff99 2 if (attr_from_line(mr->attrs,"type",NULL,type,NULL)) {
303 zoff99 28 //dbg(1,"type='%s'\n", type);
304 zoff99 2 mr->item.type=item_from_name(type);
305     if (mr->item.type == type_none)
306     printf("Warning: type '%s' unknown\n", type);
307     } else {
308     get_line(mr);
309     continue;
310     }
311     mr->attr_last=attr_none;
312     mr->more=1;
313 zoff99 28 //dbg(1,"return attr='%s'\n", mr->attrs);
314 zoff99 2 return &mr->item;
315     }
316     }
317    
318     static struct item *
319     map_rect_get_item_byid_textfile(struct map_rect_priv *mr, int id_hi, int id_lo)
320     {
321     if (mr->m->is_pipe) {
322     #ifndef _MSC_VER
323     pclose(mr->f);
324     mr->f=popen(mr->args, "r");
325     mr->pos=0;
326     mr->lastlen=0;
327     #endif /* _MSC_VER */
328     } else
329     fseek(mr->f, id_lo, SEEK_SET);
330     get_line(mr);
331     mr->item.id_hi=id_hi;
332     return map_rect_get_item_textfile(mr);
333     }
334    
335     static struct map_methods map_methods_textfile = {
336     projection_mg,
337     "iso8859-1",
338     map_destroy_textfile,
339     map_rect_new_textfile,
340     map_rect_destroy_textfile,
341     map_rect_get_item_textfile,
342     map_rect_get_item_byid_textfile,
343     };
344    
345     static struct map_priv *
346     map_new_textfile(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl)
347     {
348     struct map_priv *m;
349     struct attr *data=attr_search(attrs, NULL, attr_data);
350     struct attr *charset=attr_search(attrs, NULL, attr_charset);
351     struct attr *flags=attr_search(attrs, NULL, attr_flags);
352     struct file_wordexp *wexp;
353     int len,is_pipe=0;
354     char *wdata;
355     char **wexp_data;
356     if (! data)
357     return NULL;
358     dbg(1,"map_new_textfile %s\n", data->u.str);
359     wdata=g_strdup(data->u.str);
360     len=strlen(wdata);
361     if (len && wdata[len-1] == '|') {
362     wdata[len-1]='\0';
363     is_pipe=1;
364     }
365     wexp=file_wordexp_new(wdata);
366     wexp_data=file_wordexp_get_array(wexp);
367     *meth=map_methods_textfile;
368    
369     m=g_new0(struct map_priv, 1);
370     m->id=++map_id;
371     m->filename=g_strdup(wexp_data[0]);
372     m->is_pipe=is_pipe;
373     if (flags)
374     m->flags=flags->u.num;
375     dbg(1,"map_new_textfile %s %s\n", m->filename, wdata);
376     if (charset) {
377     m->charset=g_strdup(charset->u.str);
378     meth->charset=m->charset;
379     }
380     file_wordexp_destroy(wexp);
381     g_free(wdata);
382     return m;
383     }
384    
385     void
386     plugin_init(void)
387     {
388 zoff99 28 //dbg(1,"textfile: plugin_init\n");
389 zoff99 2 plugin_register_map_type("textfile", map_new_textfile);
390     }
391    

   
Visit the ZANavi Wiki