/[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 - (show annotations) (download)
Sun Jun 17 08:12:47 2012 UTC (7 years, 4 months ago) by zoff99
File MIME type: text/plain
File size: 8751 byte(s)
lots of new stuff and fixes
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 <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 {
92 *c=mr->c;
93 //dbg(1,"c=0x%x,0x%x\n", c->x, c->y);
94 c++;
95 ret++;
96 get_line(mr);
97 if (mr->item.id_hi)
98 mr->eoc=1;
99 }
100 else
101 {
102 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 //dbg(1,"textfile_attr_get mr=%p attrs='%s' ", mr, mr->attrs);
132 if (attr_type != mr->attr_last) {
133 //dbg(1,"reset attr_pos\n");
134 mr->attr_pos=0;
135 mr->attr_last=attr_type;
136 }
137 if (attr_type == attr_any) {
138 //dbg(1,"attr_any");
139 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 //dbg(1,"found attr '%s' 0x%x\n", mr->attr_name, attr_type);
142 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 //dbg(1,"attr='%s' ",str);
149 if (attr_from_line(mr->attrs,str,&mr->attr_pos,mr->attr, NULL)) {
150 textfile_encode_attr(mr->attr, attr_type, attr);
151 //dbg(1,"found\n");
152 return 1;
153 }
154 }
155 //dbg(1,"not found\n");
156 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 //dbg(1,"map_rect_new_textfile\n");
172 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 //dbg(1,"popen args %s\n", args);
200 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 if(!mr->f)
211 {
212 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 if (mr->f)
223 {
224 if (mr->m->is_pipe)
225 {
226 #ifdef HAVE_POPEN
227 pclose(mr->f);
228 #endif
229 }
230 else
231 {
232 fclose(mr->f);
233 }
234 }
235 g_free(mr);
236 }
237
238 static struct item *
239 map_rect_get_item_textfile(struct map_rect_priv *mr)
240 {
241 char *p,type[SIZE];
242 //dbg(1,"map_rect_get_item_textfile id_hi=%d line=%s", mr->item.id_hi, mr->line);
243 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 //dbg(1,"map_rect_get_item_textfile: eof %d\n",mr->item.id_hi);
253 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 //dbg(1,"map_rect_get_item_textfile: point found\n");
284 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 //dbg(1,"map_rect_get_item_textfile: line found\n");
292 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 //dbg(1,"mr=%p attrs=%s\n", mr, mr->attrs);
300 }
301 //dbg(1,"get_attrs %s\n", mr->attrs);
302 if (attr_from_line(mr->attrs,"type",NULL,type,NULL)) {
303 //dbg(1,"type='%s'\n", type);
304 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 //dbg(1,"return attr='%s'\n", mr->attrs);
314 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 //dbg(1,"textfile: plugin_init\n");
389 plugin_register_map_type("textfile", map_new_textfile);
390 }
391

   
Visit the ZANavi Wiki