/[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 - (show annotations) (download)
Fri Oct 28 21:19:04 2011 UTC (8 years, 1 month ago) by zoff99
File MIME type: text/plain
File size: 8702 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 <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