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

   
Visit the ZANavi Wiki