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

Contents of /navit/navit/map/binfile/binfile.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 41 - (hide annotations) (download)
Tue Aug 11 18:50:37 2015 UTC (5 years, 1 month ago) by zoff99
File MIME type: text/plain
File size: 77684 byte(s)
many fixes, and new features
1 zoff99 2 /**
2 zoff99 27 * ZANavi, Zoff Android Navigation system.
3     * Copyright (C) 2011-2012 Zoff <zoff@zoff.cc>
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     /**
21 zoff99 2 * Navit, a modular navigation system.
22     * Copyright (C) 2005-2008 Navit Team
23     *
24     * This program is free software; you can redistribute it and/or
25     * modify it under the terms of the GNU General Public License
26     * version 2 as published by the Free Software Foundation.
27     *
28     * This program is distributed in the hope that it will be useful,
29     * but WITHOUT ANY WARRANTY; without even the implied warranty of
30     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31     * GNU General Public License for more details.
32     *
33     * You should have received a copy of the GNU General Public License
34     * along with this program; if not, write to the
35     * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
36     * Boston, MA 02110-1301, USA.
37     */
38    
39     #include <stdlib.h>
40     #include <glib.h>
41     #include <stdio.h>
42     #include <string.h>
43     #include <math.h>
44     #include "config.h"
45     #include "debug.h"
46     #include "plugin.h"
47     #include "projection.h"
48     #include "item.h"
49     #include "map.h"
50     #include "maptype.h"
51     #include "attr.h"
52     #include "coord.h"
53     #include "transform.h"
54     #include "file.h"
55     #include "zipfile.h"
56     #include "linguistics.h"
57     #include "endianess.h"
58     #include "callback.h"
59     #include "types.h"
60 zoff99 15 #include "navit.h"
61 zoff99 2
62     static int map_id;
63    
64 zoff99 27 struct tile
65     {
66 zoff99 2 int *start;
67     int *end;
68     int *pos;
69     int *pos_coord_start;
70     int *pos_coord;
71     int *pos_attr_start;
72     int *pos_attr;
73     int *pos_next;
74     struct file *fi;
75     int zipfile_num;
76     int mode;
77     };
78    
79 zoff99 27 struct map_download
80     {
81 zoff99 2 int state;
82     struct map_priv *m;
83     struct map_rect_priv *mr;
84 zoff99 27 struct file *http, *file;
85     int zipfile, toffset, tlength, progress, read, dl_size;
86     long long offset, start_offset, cd1offset, size;
87 zoff99 2 struct zip64_eoc *zip64_eoc;
88     struct zip64_eocl *zip64_eocl;
89     struct zip_eoc *zip_eoc;
90 zoff99 27 struct zip_cd *cd_copy, *cd;
91 zoff99 2 };
92    
93 zoff99 27 struct map_priv
94     {
95 zoff99 2 int id;
96     char *filename;
97     char *cachedir;
98 zoff99 27 struct file *fi, *http;
99 zoff99 2 struct file **fis;
100     struct zip_cd *index_cd;
101     int index_offset;
102     int cde_size;
103     struct zip_eoc *eoc;
104     struct zip64_eoc *eoc64;
105     int zip_members;
106     unsigned char *search_data;
107     int search_offset;
108     int search_size;
109     int version;
110     int check_version;
111     int map_version;
112     GHashTable *changes;
113     char *passwd;
114     char *map_release;
115     int flags;
116     char *url;
117     int update_available;
118     char *progress;
119     struct callback_list *cbl;
120     struct map_download *download;
121     int redirect;
122     long download_enabled;
123     };
124    
125 zoff99 27 struct map_rect_priv
126     {
127 zoff99 2 int *start;
128     int *end;
129     enum attr_type attr_last;
130     int label;
131     int *label_attr[5];
132 zoff99 27 struct map_selection *sel;
133     struct map_priv *m;
134     struct item item;
135 zoff99 2 int tile_depth;
136     struct tile tiles[8];
137     struct tile *t;
138     int country_id;
139     char *url;
140     struct attr attrs[8];
141     int status;
142     #ifdef DEBUG_SIZE
143 zoff99 27 int size;
144 zoff99 2 #endif
145     };
146    
147 zoff99 27 struct map_search_priv
148     {
149 zoff99 2 struct map_priv *map;
150     struct map_rect_priv *mr;
151     struct map_rect_priv *mr_item;
152     struct item *item;
153     struct attr *search;
154     struct map_selection ms;
155     int partial;
156     int mode;
157     GHashTable *search_results;
158     char *str;
159     };
160    
161     static void push_tile(struct map_rect_priv *mr, struct tile *t, int offset, int length);
162     static void setup_pos(struct map_rect_priv *mr);
163     static void map_binfile_close(struct map_priv *m);
164     static int map_binfile_open(struct map_priv *m);
165     static void map_binfile_destroy(struct map_priv *m);
166    
167 zoff99 27 static void lfh_to_cpu(struct zip_lfh *lfh)
168     {
169 zoff99 2 dbg_assert(lfh != NULL);
170 zoff99 27 if (lfh->ziplocsig != zip_lfh_sig)
171     {
172     // dbg(0,"_endian 3\n");
173 zoff99 2 lfh->ziplocsig = le32_to_cpu(lfh->ziplocsig);
174 zoff99 27 lfh->zipver = le16_to_cpu(lfh->zipver);
175 zoff99 2 lfh->zipgenfld = le16_to_cpu(lfh->zipgenfld);
176 zoff99 27 lfh->zipmthd = le16_to_cpu(lfh->zipmthd);
177     lfh->ziptime = le16_to_cpu(lfh->ziptime);
178     lfh->zipdate = le16_to_cpu(lfh->zipdate);
179     lfh->zipcrc = le32_to_cpu(lfh->zipcrc);
180     lfh->zipsize = le32_to_cpu(lfh->zipsize);
181     lfh->zipuncmp = le32_to_cpu(lfh->zipuncmp);
182     lfh->zipfnln = le16_to_cpu(lfh->zipfnln);
183 zoff99 2 lfh->zipxtraln = le16_to_cpu(lfh->zipxtraln);
184 zoff99 27 }
185 zoff99 2 }
186    
187 zoff99 27 static void cd_to_cpu(struct zip_cd *zcd)
188     {
189 zoff99 2 dbg_assert(zcd != NULL);
190 zoff99 27 if (zcd->zipcensig != zip_cd_sig)
191     {
192     // dbg(0,"_endian 1\n");
193 zoff99 2 zcd->zipcensig = le32_to_cpu(zcd->zipcensig);
194 zoff99 27 zcd->zipccrc = le32_to_cpu(zcd->zipccrc);
195     zcd->zipcsiz = le32_to_cpu(zcd->zipcsiz);
196     zcd->zipcunc = le32_to_cpu(zcd->zipcunc);
197     zcd->zipcfnl = le16_to_cpu(zcd->zipcfnl);
198     zcd->zipcxtl = le16_to_cpu(zcd->zipcxtl);
199     zcd->zipccml = le16_to_cpu(zcd->zipccml);
200     zcd->zipdsk = le16_to_cpu(zcd->zipdsk);
201     zcd->zipint = le16_to_cpu(zcd->zipint);
202     zcd->zipext = le32_to_cpu(zcd->zipext);
203     zcd->zipofst = le32_to_cpu(zcd->zipofst);
204 zoff99 2 }
205     }
206    
207 zoff99 27 static void eoc_to_cpu(struct zip_eoc *eoc)
208     {
209 zoff99 2 dbg_assert(eoc != NULL);
210 zoff99 27 if (eoc->zipesig != zip_eoc_sig)
211     {
212     // dbg(0,"_endian 2\n");
213     eoc->zipesig = le32_to_cpu(eoc->zipesig);
214     eoc->zipedsk = le16_to_cpu(eoc->zipedsk);
215     eoc->zipecen = le16_to_cpu(eoc->zipecen);
216     eoc->zipenum = le16_to_cpu(eoc->zipenum);
217     eoc->zipecenn = le16_to_cpu(eoc->zipecenn);
218     eoc->zipecsz = le32_to_cpu(eoc->zipecsz);
219     eoc->zipeofst = le32_to_cpu(eoc->zipeofst);
220     eoc->zipecoml = le16_to_cpu(eoc->zipecoml);
221 zoff99 2 }
222     }
223    
224     static void binfile_check_version(struct map_priv *m);
225    
226     static struct zip_eoc *
227     binfile_read_eoc(struct file *fi)
228     {
229     struct zip_eoc *eoc;
230 zoff99 27 eoc = (struct zip_eoc *) file_data_read(fi, fi->size - sizeof(struct zip_eoc), sizeof(struct zip_eoc));
231     if (eoc)
232     {
233 zoff99 2 eoc_to_cpu(eoc);
234 zoff99 27 // dbg(0, "sig 0x%x\n", eoc->zipesig);
235     if (eoc->zipesig != zip_eoc_sig)
236     {
237     file_data_free(fi, (unsigned char *) eoc);
238     eoc = NULL;
239 zoff99 2 }
240     }
241     return eoc;
242     }
243    
244     static struct zip64_eoc *
245     binfile_read_eoc64(struct file *fi)
246     {
247     struct zip64_eocl *eocl;
248     struct zip64_eoc *eoc;
249 zoff99 27 eocl = (struct zip64_eocl *) file_data_read(fi, fi->size - sizeof(struct zip_eoc) - sizeof(struct zip64_eocl), sizeof(struct zip64_eocl));
250 zoff99 2 if (!eocl)
251 zoff99 27 {
252 zoff99 2 return NULL;
253 zoff99 27 }
254     //dbg(0, "sig 0x%x\n", eocl->zip64lsig);
255     if (eocl->zip64lsig != zip64_eocl_sig)
256     {
257     file_data_free(fi, (unsigned char *) eocl);
258     //dbg(0, "eocl wrong\n");
259 zoff99 2 return NULL;
260     }
261 zoff99 27 eoc = (struct zip64_eoc *) file_data_read(fi, eocl->zip64lofst, sizeof(struct zip64_eoc));
262     if (eoc)
263     {
264     if (eoc->zip64esig != zip64_eoc_sig)
265     {
266     file_data_free(fi, (unsigned char *) eoc);
267     //dbg(0, "eoc wrong\n");
268     eoc = NULL;
269 zoff99 2 }
270 zoff99 27 //dbg(0, "eoc64 ok 0x%Lx 0x%Lx\n", eoc->zip64eofst, eoc->zip64ecsz);
271 zoff99 2 }
272 zoff99 27 file_data_free(fi, (unsigned char *) eocl);
273 zoff99 2 return eoc;
274     }
275    
276 zoff99 27 static int binfile_cd_extra(struct zip_cd *cd)
277 zoff99 2 {
278 zoff99 27 return cd->zipcfnl + cd->zipcxtl;
279 zoff99 2 }
280    
281     static struct zip_cd *
282     binfile_read_cd(struct map_priv *m, int offset, int len)
283     {
284 zoff99 27 //dbg(0,"_enter\n");
285 zoff99 2 struct zip_cd *cd;
286 zoff99 27 long long cdoffset = m->eoc64 ? m->eoc64->zip64eofst : m->eoc->zipeofst;
287     //dbg(0,"_cdoffset="LONGLONG_FMT"\n", cdoffset);
288    
289     if (len == -1)
290     {
291     //dbg(0,"_len = -1\n");
292     cd = (struct zip_cd *) file_data_read(m->fi, cdoffset + offset, sizeof(*cd));
293 zoff99 2 cd_to_cpu(cd);
294 zoff99 27 len = binfile_cd_extra(cd);
295     //dbg(0,"_len = %d\n", len);
296     file_data_free(m->fi, (unsigned char *) cd);
297 zoff99 2 }
298 zoff99 27
299     cd = (struct zip_cd *) file_data_read(m->fi, cdoffset + offset, sizeof(*cd) + len);
300    
301     if (cd)
302     {
303     //dbg(0,"cd at "LONGLONG_FMT" %d bytes\n",cdoffset+offset, sizeof(*cd)+len);
304 zoff99 2 cd_to_cpu(cd);
305 zoff99 27 //dbg(0, "sig 0x%x\n", cd->zipcensig);
306     if (cd->zipcensig != zip_cd_sig)
307     {
308     file_data_free(m->fi, (unsigned char *) cd);
309     //dbg(0,"_cd=NULL\n");
310     cd = NULL;
311 zoff99 2 }
312     }
313 zoff99 27
314     //dbg(0,"leave\n");
315 zoff99 2 return cd;
316     }
317    
318     static struct zip_cd_ext *
319     binfile_cd_ext(struct zip_cd *cd)
320     {
321     struct zip_cd_ext *ext;
322     if (cd->zipofst != 0xffffffff)
323     return NULL;
324     if (cd->zipcxtl != sizeof(*ext))
325     return NULL;
326 zoff99 27 ext = (struct zip_cd_ext *) ((unsigned char *) cd + sizeof(*cd) + cd->zipcfnl);
327 zoff99 2 if (ext->tag != 0x0001 || ext->size != 8)
328     return NULL;
329     return ext;
330     }
331    
332 zoff99 27 static long long binfile_cd_offset(struct zip_cd *cd)
333 zoff99 2 {
334 zoff99 27 struct zip_cd_ext *ext = binfile_cd_ext(cd);
335 zoff99 2 if (ext)
336     return ext->zipofst;
337     else
338     return cd->zipofst;
339     }
340    
341     static struct zip_lfh *
342     binfile_read_lfh(struct file *fi, long long offset)
343     {
344     struct zip_lfh *lfh;
345    
346 zoff99 27 lfh = (struct zip_lfh *) (file_data_read(fi, offset, sizeof(struct zip_lfh)));
347     if (lfh)
348     {
349 zoff99 2 lfh_to_cpu(lfh);
350 zoff99 27 if (lfh->ziplocsig != zip_lfh_sig)
351     {
352     file_data_free(fi, (unsigned char *) lfh);
353     lfh = NULL;
354 zoff99 2 }
355     }
356     return lfh;
357     }
358    
359     static unsigned char *
360     binfile_read_content(struct map_priv *m, struct file *fi, long long offset, struct zip_lfh *lfh)
361     {
362     struct zip_enc *enc;
363 zoff99 27 unsigned char *ret = NULL;
364 zoff99 2
365 zoff99 27 offset += sizeof(struct zip_lfh) + lfh->zipfnln;
366     switch (lfh->zipmthd)
367     {
368 zoff99 2 case 0:
369 zoff99 27 offset += lfh->zipxtraln;
370     ret = file_data_read(fi, offset, lfh->zipuncmp);
371 zoff99 2 break;
372     case 8:
373 zoff99 27 offset += lfh->zipxtraln;
374     ret = file_data_read_compressed(fi, offset, lfh->zipsize, lfh->zipuncmp);
375 zoff99 2 break;
376 zoff99 27 case 99:
377     if (!m->passwd)
378     {
379     break;
380     }
381     enc = (struct zip_enc *) file_data_read(fi, offset, sizeof(*enc));
382     offset += lfh->zipxtraln;
383     switch (enc->compress_method)
384     {
385     case 0:
386     ret = file_data_read_encrypted(fi, offset, lfh->zipsize, lfh->zipuncmp, 0, m->passwd);
387     break;
388     case 8:
389     ret = file_data_read_encrypted(fi, offset, lfh->zipsize, lfh->zipuncmp, 1, m->passwd);
390     break;
391     default:
392     // dbg(0, "Unknown encrypted compression method %d\n", enc->compress_method);
393     break;
394     }
395     file_data_free(fi, (unsigned char *) enc);
396     break;
397 zoff99 2 default:
398 zoff99 27 // dbg(0, "Unknown compression method %d\n", lfh->zipmthd);
399     break;
400 zoff99 2 }
401     return ret;
402     }
403    
404 zoff99 27 static int binfile_search_cd(struct map_priv *m, int offset, char *name, int partial, int skip)
405 zoff99 2 {
406 zoff99 27 //dbg(0,"_enter\n");
407    
408     int size = 4096;
409     int end = m->eoc64 ? m->eoc64->zip64ecsz : m->eoc->zipecsz;
410     int len = strlen(name);
411     long long cdoffset = m->eoc64 ? m->eoc64->zip64eofst : m->eoc->zipeofst;
412 zoff99 2 struct zip_cd *cd;
413     #if 0
414 zoff99 27 // dbg(0,"end=%d\n",end);
415 zoff99 2 #endif
416 zoff99 27 while (offset < end)
417     {
418     cd = (struct zip_cd *) (m->search_data + offset - m->search_offset);
419     if (!m->search_data || m->search_offset > offset || offset - m->search_offset + sizeof(*cd) > m->search_size || offset - m->search_offset + sizeof(*cd) + cd->zipcfnl + cd->zipcxtl > m->search_size)
420     {
421 zoff99 2 #if 0
422 zoff99 27 // dbg(0,"reload %p %d %d\n", m->search_data, m->search_offset, offset);
423 zoff99 2 #endif
424     if (m->search_data)
425 zoff99 27 {
426     file_data_free(m->fi, m->search_data);
427     }
428     m->search_offset = offset;
429     m->search_size = end - offset;
430 zoff99 2 if (m->search_size > size)
431 zoff99 27 {
432     m->search_size = size;
433     }
434     m->search_data = file_data_read(m->fi, cdoffset + m->search_offset, m->search_size);
435     cd = (struct zip_cd *) m->search_data;
436 zoff99 2 }
437     #if 0
438 zoff99 27 // dbg(0,"offset=%d search_offset=%d search_size=%d search_data=%p cd=%p\n", offset, m->search_offset, m->search_size, m->search_data, cd);
439     // dbg(0,"offset=%d fn='%s'\n",offset,cd->zipcfn);
440 zoff99 2 #endif
441 zoff99 27 if (!skip && (partial || cd->zipcfnl == len) && !strncmp(cd->zipcfn, name, len))
442     {
443 zoff99 2 return offset;
444 zoff99 27 }
445     skip = 0;
446     offset += sizeof(*cd) + cd->zipcfnl + cd->zipcxtl + cd->zipccml;
447     ;
448 zoff99 2 }
449     return -1;
450     }
451    
452 zoff99 27 static void map_destroy_binfile(struct map_priv *m)
453 zoff99 2 {
454 zoff99 27 // dbg(1, "map_destroy_binfile\n");
455 zoff99 2 if (m->fi)
456     map_binfile_close(m);
457     map_binfile_destroy(m);
458     }
459    
460 zoff99 27 static void binfile_coord_rewind(void *priv_data)
461 zoff99 2 {
462 zoff99 27 struct map_rect_priv *mr = priv_data;
463     struct tile *t = mr->t;
464     t->pos_coord = t->pos_coord_start;
465 zoff99 2 }
466    
467 zoff99 27 static int binfile_coord_get(void *priv_data, struct coord *c, int count)
468 zoff99 2 {
469 zoff99 27 struct map_rect_priv *mr = priv_data;
470     struct tile *t = mr->t;
471     int max, ret = 0;
472     max = (t->pos_attr_start - t->pos_coord) / 2;
473 zoff99 2 if (count > max)
474 zoff99 27 {
475     count = max;
476     }
477 zoff99 2 #if __BYTE_ORDER == __LITTLE_ENDIAN
478 zoff99 27 memcpy(c, t->pos_coord, count * sizeof(struct coord));
479 zoff99 2 #else
480     {
481     int i=0,end=count*sizeof(struct coord)/sizeof(int);
482     int *src=(int *)t->pos_coord;
483     int *dst=(int *)c;
484 zoff99 27 while (i++ < end)
485     {
486 zoff99 2 *dst++=le32_to_cpu(*src);
487     src++;
488     }
489     }
490     #endif
491 zoff99 27 t->pos_coord += count * 2;
492     ret = count;
493 zoff99 2 return ret;
494     }
495    
496 zoff99 27 static void binfile_attr_rewind(void *priv_data)
497 zoff99 2 {
498 zoff99 27 struct map_rect_priv *mr = priv_data;
499     struct tile *t = mr->t;
500     t->pos_attr = t->pos_attr_start;
501     mr->label = 0;
502 zoff99 2 memset(mr->label_attr, 0, sizeof(mr->label_attr));
503 zoff99 27
504 zoff99 2 }
505    
506     static char *
507     binfile_extract(struct map_priv *m, char *dir, char *filename, int partial)
508     {
509 zoff99 27 char *full, *fulld, *sep;
510 zoff99 2 unsigned char *start;
511 zoff99 27 int len, offset = m->index_offset;
512 zoff99 2 struct zip_cd *cd;
513     struct zip_lfh *lfh;
514     FILE *f;
515    
516 zoff99 27 for (;;)
517     {
518     offset = binfile_search_cd(m, offset, filename, partial, 1);
519 zoff99 2 if (offset == -1)
520     break;
521 zoff99 27 cd = binfile_read_cd(m, offset, -1);
522     len = strlen(dir) + 1 + cd->zipcfnl + 1;
523     full = g_malloc(len);
524     strcpy(full, dir);
525     strcpy(full + strlen(full), "/");
526     strncpy(full + strlen(full), cd->zipcfn, cd->zipcfnl);
527     full[len - 1] = '\0';
528     fulld = g_strdup(full);
529     sep = strrchr(fulld, '/');
530     if (sep)
531     {
532     *sep = '\0';
533 zoff99 2 file_mkdir(fulld, 1);
534     }
535 zoff99 27 if (full[len - 2] != '/')
536     {
537     lfh = binfile_read_lfh(m->fi, binfile_cd_offset(cd));
538     start = binfile_read_content(m, m->fi, binfile_cd_offset(cd), lfh);
539     // dbg(0, "fopen '%s'\n", full);
540     f = fopen(full, "w");
541 zoff99 2 fwrite(start, lfh->zipuncmp, 1, f);
542     fclose(f);
543     file_data_free(m->fi, start);
544 zoff99 27 file_data_free(m->fi, (unsigned char *) lfh);
545 zoff99 2 }
546 zoff99 27 file_data_free(m->fi, (unsigned char *) cd);
547 zoff99 2 g_free(fulld);
548     g_free(full);
549 zoff99 27 if (!partial)
550     {
551 zoff99 2 break;
552 zoff99 27 }
553 zoff99 2 }
554 zoff99 27
555     return g_strdup_printf("%s/%s", dir, filename);
556 zoff99 2 }
557    
558 zoff99 27 static int binfile_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
559     {
560 zoff99 31 // try to return "0" on any problem, to avoid crash!!
561    
562 zoff99 27 struct map_rect_priv *mr = priv_data;
563     struct tile *t = mr->t;
564 zoff99 2 enum attr_type type;
565 zoff99 27 int i, size;
566 zoff99 2
567 zoff99 27 if (attr_type != mr->attr_last)
568     {
569     t->pos_attr = t->pos_attr_start;
570     mr->attr_last = attr_type;
571 zoff99 2 }
572 zoff99 31
573 zoff99 27 while (t->pos_attr < t->pos_next)
574     {
575 zoff99 31 //dbg(0,"batg:002 %d %d\n",t->pos_attr,(t->pos_attr+1));
576 zoff99 27 size = le32_to_cpu(*(t->pos_attr++));
577 zoff99 31 // dbg(0,"batg:002.1 %d %d\n",t->pos_attr, t->pos_attr[0]);
578 zoff99 27 type = le32_to_cpu(t->pos_attr[0]);
579 zoff99 31 // dbg(0, "type=%d\n", type);
580    
581     #ifdef NAVIT_ATTR_SAFETY_CHECK
582     // safety check (always keep value in sync with "attr_def.h" !!) ---------------
583     if (type > 0x000effff)
584     {
585     return 0;
586     }
587     // safety check (always keep value in sync with "attr_def.h" !!) ---------------
588     #endif
589    
590     //dbg(0,"batg:002.2\n");
591 zoff99 27 if (type == attr_label)
592     mr->label = 1;
593 zoff99 2 if (type == attr_house_number)
594 zoff99 27 mr->label_attr[0] = t->pos_attr;
595 zoff99 2 if (type == attr_street_name)
596 zoff99 27 mr->label_attr[1] = t->pos_attr;
597 zoff99 2 if (type == attr_street_name_systematic)
598 zoff99 27 mr->label_attr[2] = t->pos_attr;
599 zoff99 2 if (type == attr_district_name && mr->item.type < type_line)
600 zoff99 27 mr->label_attr[3] = t->pos_attr;
601 zoff99 2 if (type == attr_town_name && mr->item.type < type_line)
602 zoff99 27 mr->label_attr[4] = t->pos_attr;
603 zoff99 31
604 zoff99 27 if (type == attr_type || attr_type == attr_any)
605     {
606     if (attr_type == attr_any)
607     {
608     // dbg(1, "pos %p attr %s size %d\n", t->pos_attr - 1, attr_to_name(type), size);
609 zoff99 2 }
610 zoff99 27 attr->type = type;
611     if (ATTR_IS_GROUP(type))
612     {
613     int i = 0;
614     int *subpos = t->pos_attr + 1;
615     int size_rem = size - 1;
616     i = 0;
617     while (size_rem > 0 && i < 7)
618     {
619     int subsize = le32_to_cpu(*subpos++);
620     int subtype = le32_to_cpu(subpos[0]);
621     mr->attrs[i].type = subtype;
622     attr_data_set_le(&mr->attrs[i], subpos + 1);
623     subpos += subsize;
624     size_rem -= subsize + 1;
625 zoff99 2 i++;
626     }
627 zoff99 31
628 zoff99 27 mr->attrs[i].type = type_none;
629     mr->attrs[i].u.data = NULL;
630     attr->u.attrs = mr->attrs;
631     }
632     else
633     {
634     attr_data_set_le(attr, t->pos_attr + 1);
635     if (type == attr_url_local)
636     {
637 zoff99 2 g_free(mr->url);
638 zoff99 27 mr->url = binfile_extract(mr->m, mr->m->cachedir, attr->u.str, 1);
639     attr->u.str = mr->url;
640 zoff99 2 }
641 zoff99 31
642 zoff99 27 if (type == attr_flags && mr->m->map_version < 1)
643 zoff99 31 {
644 zoff99 34 attr->u.num |= NAVIT_AF_CAR;
645 zoff99 31 }
646 zoff99 2 }
647 zoff99 27 t->pos_attr += size;
648 zoff99 2 return 1;
649     }
650 zoff99 27 else
651     {
652     t->pos_attr += size;
653     }
654 zoff99 2 }
655 zoff99 31
656 zoff99 27 if (!mr->label && (attr_type == attr_any || attr_type == attr_label))
657     {
658     for (i = 0; i < sizeof(mr->label_attr) / sizeof(int *); i++)
659     {
660     if (mr->label_attr[i])
661     {
662     mr->label = 1;
663     attr->type = attr_label;
664     attr_data_set_le(attr, mr->label_attr[i] + 1);
665 zoff99 2 return 1;
666     }
667     }
668     }
669 zoff99 31
670     #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
671     dbg(0,"+#+:leave\n");
672     #endif
673    
674 zoff99 2 return 0;
675     }
676    
677 zoff99 27 struct binfile_hash_entry
678     {
679 zoff99 2 struct item_id id;
680     int flags;
681     int data[0];
682     };
683    
684 zoff99 27 static guint binfile_hash_entry_hash(gconstpointer key)
685 zoff99 2 {
686 zoff99 27 const struct binfile_hash_entry *entry = key;
687 zoff99 2 return (entry->id.id_hi ^ entry->id.id_lo);
688     }
689    
690 zoff99 27 static gboolean binfile_hash_entry_equal(gconstpointer a, gconstpointer b)
691 zoff99 2 {
692 zoff99 27 const struct binfile_hash_entry *entry1 = a, *entry2 = b;
693     return (entry1->id.id_hi == entry2->id.id_hi && entry1->id.id_lo == entry2->id.id_lo);
694 zoff99 2 }
695    
696     static int *
697     binfile_item_dup(struct map_priv *m, struct item *item, struct tile *t, int extend)
698     {
699 zoff99 27 int size = le32_to_cpu(t->pos[0]);
700     struct binfile_hash_entry *entry = g_malloc(sizeof(struct binfile_hash_entry) + (size + 1 + extend) * sizeof(int));
701     void *ret = entry->data;
702     entry->id.id_hi = item->id_hi;
703     entry->id.id_lo = item->id_lo;
704     entry->flags = 1;
705     // dbg(0, "id 0x%x,0x%x\n", entry->id.id_hi, entry->id.id_lo);
706    
707     memcpy(ret, t->pos, (size + 1) * sizeof(int));
708     if (!m->changes)
709 zoff99 31 m->changes = g_hash_table_new_full(binfile_hash_entry_hash, binfile_hash_entry_equal, g_free_func, NULL);
710 zoff99 2 g_hash_table_replace(m->changes, entry, entry);
711 zoff99 27 // dbg(0, "ret %p\n", ret);
712 zoff99 2 return ret;
713     }
714    
715 zoff99 27 static int binfile_coord_set(void *priv_data, struct coord *c, int count, enum change_mode mode)
716 zoff99 2 {
717 zoff99 27 struct map_rect_priv *mr = priv_data;
718     struct tile *t = mr->t, *tn, new;
719     int i, delta, move_len;
720     int write_offset, move_offset, aoffset, coffset, clen;
721 zoff99 2 int *data;
722    
723 zoff99 27 //{
724     //int *i = t->pos, j = 0;
725     // dbg(0, "Before: pos_coord=%d\n", t->pos_coord - i);
726     //while (i < t->pos_next)
727     //{
728     // // dbg(0, "%d:0x%x\n", j++, *i++);
729     //}
730    
731     //}
732    
733     aoffset = t->pos_attr - t->pos_attr_start;
734     coffset = t->pos_coord - t->pos_coord_start - 2;
735     clen = t->pos_attr_start - t->pos_coord + 2;
736     // dbg(0, "coffset=%d clen=%d\n", coffset, clen);
737     switch (mode)
738 zoff99 2 {
739 zoff99 27 case change_mode_delete:
740     if (count * 2 > clen)
741     count = clen / 2;
742     delta = -count * 2;
743     move_offset = coffset + count * 2;
744     move_len = t->pos_next - t->pos_coord_start - move_offset;
745     write_offset = 0;
746     break;
747     case change_mode_modify:
748     write_offset = coffset;
749     if (count * 2 > clen)
750     {
751     delta = count * 2 - clen;
752     move_offset = t->pos_attr_start - t->pos_coord_start;
753     move_len = t->pos_next - t->pos_coord_start - move_offset;
754     }
755     else
756     {
757     move_len = 0;
758     move_offset = 0;
759     delta = 0;
760     }
761     break;
762     case change_mode_prepend:
763     delta = count * 2;
764     move_offset = coffset - 2;
765     move_len = t->pos_next - t->pos_coord_start - move_offset;
766     write_offset = coffset - 2;
767     break;
768     case change_mode_append:
769     delta = count * 2;
770     move_offset = coffset;
771     move_len = t->pos_next - t->pos_coord_start - move_offset;
772     write_offset = coffset;
773     break;
774     default:
775     return 0;
776 zoff99 2 }
777 zoff99 27 // dbg(0, "delta %d\n", delta);
778     data = binfile_item_dup(mr->m, &mr->item, t, delta > 0 ? delta : 0);
779     data[0] = cpu_to_le32(le32_to_cpu(data[0]) + delta);
780     data[2] = cpu_to_le32(le32_to_cpu(data[2]) + delta);
781     new.pos = new.start = data;
782     new.zipfile_num = t->zipfile_num;
783     new.mode = 2;
784 zoff99 2 push_tile(mr, &new, 0, 0);
785     setup_pos(mr);
786 zoff99 27 tn = mr->t;
787     tn->pos_coord = tn->pos_coord_start + coffset;
788     tn->pos_attr = tn->pos_attr_start + aoffset;
789     // dbg(0, "moving %d ints from offset %d to %d\n", move_len, tn->pos_coord_start + move_offset - data, tn->pos_coord_start + move_offset + delta - data);
790     memmove(tn->pos_coord_start + move_offset + delta, tn->pos_coord_start + move_offset, move_len * 4);
791     //{
792     //int *i = tn->pos, j = 0;
793     // dbg(0, "After move: pos_coord=%d\n", tn->pos_coord - i);
794     //while (i < tn->pos_next)
795     //{
796     // // dbg(0, "%d:0x%x\n", j++, *i++);
797     //}
798     //}
799     if (mode != change_mode_append)
800 zoff99 2 {
801 zoff99 27 tn->pos_coord += move_offset;
802 zoff99 2 }
803 zoff99 27 if (mode != change_mode_delete)
804     {
805     // dbg(0, "writing %d ints at offset %d\n", count * 2, write_offset + tn->pos_coord_start - data);
806     for (i = 0; i < count; i++)
807     {
808     tn->pos_coord_start[write_offset++] = c[i].x;
809     tn->pos_coord_start[write_offset++] = c[i].y;
810 zoff99 2 }
811 zoff99 27
812 zoff99 2 }
813 zoff99 27 //{
814     //int *i = tn->pos, j = 0;
815     //// dbg(0, "After: pos_coord=%d\n", tn->pos_coord - i);
816     //while (i < tn->pos_next)
817     //{
818     // // dbg(0, "%d:0x%x\n", j++, *i++);
819     //}
820     //}
821 zoff99 2 return 1;
822     }
823    
824 zoff99 27 static int binfile_attr_set(void *priv_data, struct attr *attr, enum change_mode mode)
825 zoff99 2 {
826 zoff99 27 struct map_rect_priv *mr = priv_data;
827     struct tile *t = mr->t, *tn, new;
828     int extend, offset, delta, move_len;
829     int write_offset, move_offset, naoffset, coffset, oattr_len;
830     int nattr_size, nattr_len, pad;
831 zoff99 2 int *data;
832    
833 zoff99 27 //{
834     //int *i = t->pos, j = 0;
835     //// dbg(0, "Before: pos_attr=%d\n", t->pos_attr - i);
836     //while (i < t->pos_next)
837     //{
838     // // dbg(0, "%d:0x%x\n", j++, *i++);
839     //}
840     //}
841    
842     write_offset = 0;
843     naoffset = t->pos_attr - t->pos_attr_start;
844     coffset = t->pos_coord - t->pos_coord_start;
845     offset = 0;
846     oattr_len = 0;
847     if (!naoffset)
848 zoff99 2 {
849 zoff99 27 if (mode == change_mode_delete || mode == change_mode_modify)
850     {
851     // dbg(0, "no attribute selected\n");
852 zoff99 2 return 0;
853     }
854     if (mode == change_mode_append)
855 zoff99 27 {
856     naoffset = t->pos_next - t->pos_attr_start;
857     }
858 zoff99 2 }
859 zoff99 27 while (offset < naoffset)
860     {
861     oattr_len = le32_to_cpu(t->pos_attr_start[offset]) + 1;
862     // dbg(0, "len %d\n", oattr_len);
863     write_offset = offset;
864     offset += oattr_len;
865 zoff99 2 }
866 zoff99 27 move_len = t->pos_next - t->pos_attr_start - offset;
867     move_offset = offset;
868     switch (mode)
869     {
870     case change_mode_delete:
871     nattr_size = 0;
872     nattr_len = 0;
873     pad = 0;
874     extend = 0;
875     break;
876     case change_mode_modify:
877     case change_mode_prepend:
878     case change_mode_append:
879     nattr_size = attr_data_size(attr);
880     pad = (4 - (nattr_size % 4)) % 4;
881     nattr_len = (nattr_size + pad) / 4 + 2;
882     if (mode == change_mode_prepend)
883     {
884     move_offset = write_offset;
885     move_len += oattr_len;
886     }
887     if (mode == change_mode_append)
888     {
889     write_offset = move_offset;
890     }
891     break;
892     default:
893     return 0;
894 zoff99 2 }
895 zoff99 27 if (mode == change_mode_delete || mode == change_mode_modify)
896     {
897     delta = nattr_len - oattr_len;
898     }
899 zoff99 2 else
900 zoff99 27 {
901     delta = nattr_len;
902     }
903     // dbg(0, "delta %d oattr_len %d nattr_len %d\n", delta, oattr_len, nattr_len);
904     data = binfile_item_dup(mr->m, &mr->item, t, delta > 0 ? delta : 0);
905     data[0] = cpu_to_le32(le32_to_cpu(data[0]) + delta);
906     new.pos = new.start = data;
907     new.zipfile_num = t->zipfile_num;
908     new.mode = 2;
909 zoff99 2 push_tile(mr, &new, 0, 0);
910     setup_pos(mr);
911 zoff99 27 tn = mr->t;
912     tn->pos_coord = tn->pos_coord_start + coffset;
913     tn->pos_attr = tn->pos_attr_start + offset;
914     // dbg(0, "attr start %d offset %d\n", tn->pos_attr_start - data, offset);
915     // dbg(0, "moving %d ints from offset %d to %d\n", move_len, tn->pos_attr_start + move_offset - data, tn->pos_attr_start + move_offset + delta - data);
916     memmove(tn->pos_attr_start + move_offset + delta, tn->pos_attr_start + move_offset, move_len * 4);
917 zoff99 2 if (mode != change_mode_append)
918 zoff99 27 tn->pos_attr += delta;
919 zoff99 2 {
920 zoff99 27 int *i = tn->pos, j = 0;
921     // dbg(0, "After move: pos_attr=%d\n", tn->pos_attr - i);
922     while (i < tn->pos_next)
923     {
924     // dbg(0, "%d:0x%x\n", j++, *i++);
925     }
926 zoff99 2 }
927 zoff99 27
928     if (nattr_len)
929 zoff99 2 {
930 zoff99 27 int *nattr = tn->pos_attr_start + write_offset;
931     // dbg(0, "writing %d ints at %d\n", nattr_len, nattr - data);
932     nattr[0] = cpu_to_le32(nattr_len - 1);
933     nattr[1] = cpu_to_le32(attr->type);
934     memcpy(nattr + 2, attr_data_get(attr), nattr_size);
935     memset((unsigned char *) (nattr + 2) + nattr_size, 0, pad);
936 zoff99 2 }
937 zoff99 27
938     //{
939     //int *i = tn->pos, j = 0;
940     //// dbg(0, "After: pos_attr=%d\n", tn->pos_attr - i);
941     //while (i < tn->pos_next)
942     //{
943     // // dbg(0, "%d:0x%x\n", j++, *i++);
944     //}
945     //}
946 zoff99 2 return 1;
947     }
948    
949 zoff99 27 static struct item_methods methods_binfile =
950     { binfile_coord_rewind, binfile_coord_get, binfile_attr_rewind, binfile_attr_get, NULL, binfile_attr_set, binfile_coord_set, };
951 zoff99 2
952 zoff99 27 static void push_tile(struct map_rect_priv *mr, struct tile *t, int offset, int length)
953 zoff99 2 {
954     dbg_assert(mr->tile_depth < 8);
955 zoff99 27 mr->t = &mr->tiles[mr->tile_depth++];
956     *(mr->t) = *t;
957     mr->t->pos = mr->t->pos_next = mr->t->start + offset;
958 zoff99 2 if (length == -1)
959 zoff99 27 length = le32_to_cpu(mr->t->pos[0]) + 1;
960     if (length > 0)
961     mr->t->end = mr->t->pos + length;
962 zoff99 2 }
963    
964 zoff99 27 static int pop_tile(struct map_rect_priv *mr)
965 zoff99 2 {
966     if (mr->tile_depth <= 1)
967     return 0;
968     if (mr->t->mode < 2)
969 zoff99 27 file_data_free(mr->m->fi, (unsigned char *) (mr->t->start));
970 zoff99 2 #ifdef DEBUG_SIZE
971     #if DEBUG_SIZE > 0
972 zoff99 27 // dbg(0,"leave %d\n",mr->t->zipfile_num);
973 zoff99 2 #endif
974     #endif
975 zoff99 27 mr->t = &mr->tiles[--mr->tile_depth - 1];
976 zoff99 2 return 1;
977     }
978    
979 zoff99 27 static int zipfile_to_tile(struct map_priv *m, struct zip_cd *cd, struct tile *t)
980 zoff99 2 {
981     char buffer[1024];
982     struct zip_lfh *lfh;
983     char *zipfn;
984     struct file *fi;
985 zoff99 27 // dbg(1, "enter %p %p %p\n", m, cd, t);
986     // dbg(1, "cd->zipofst=0x%Lx\n", binfile_cd_offset(cd));
987     t->start = NULL;
988     t->mode = 1;
989 zoff99 2 if (m->fis)
990 zoff99 27 fi = m->fis[cd->zipdsk];
991 zoff99 2 else
992 zoff99 27 fi = m->fi;
993     lfh = binfile_read_lfh(fi, binfile_cd_offset(cd));
994     zipfn = (char *) (file_data_read(fi, binfile_cd_offset(cd) + sizeof(struct zip_lfh), lfh->zipfnln));
995 zoff99 2 strncpy(buffer, zipfn, lfh->zipfnln);
996 zoff99 27 buffer[lfh->zipfnln] = '\0';
997     t->start = (int *) binfile_read_content(m, fi, binfile_cd_offset(cd), lfh);
998     t->end = t->start + lfh->zipuncmp / 4;
999     t->fi = fi;
1000     // dbg(1, "0x%x '%s' %d %d,%d\n", lfh->ziplocsig, buffer, sizeof(*cd) + cd->zipcfnl, lfh->zipsize, lfh->zipuncmp);
1001     file_data_free(fi, (unsigned char *) zipfn);
1002     file_data_free(fi, (unsigned char *) lfh);
1003 zoff99 2 return t->start != NULL;
1004     }
1005    
1006 zoff99 27 static int map_binfile_handle_redirect(struct map_priv *m)
1007 zoff99 2 {
1008 zoff99 27 char *location = file_http_header(m->http, "location");
1009     if (!location)
1010     {
1011     m->redirect = 0;
1012 zoff99 2 return 0;
1013     }
1014 zoff99 27 if (m->redirect)
1015 zoff99 2 return 0;
1016 zoff99 27 m->redirect = 1;
1017     // dbg(0, "redirected from %s to %s\n", m->url, location);
1018 zoff99 2 g_free(m->url);
1019 zoff99 27 m->url = g_strdup(location);
1020 zoff99 2 file_destroy(m->http);
1021 zoff99 27 m->http = NULL;
1022 zoff99 2
1023     return 1;
1024     }
1025    
1026 zoff99 27 static int map_binfile_http_request(struct map_priv *m, struct attr **attrs)
1027 zoff99 2 {
1028 zoff99 27 if (!m->http)
1029     {
1030     m->http = file_create(NULL, attrs);
1031     }
1032     else
1033     {
1034 zoff99 2 file_request(m->http, attrs);
1035     }
1036     return 1;
1037     }
1038    
1039 zoff99 27 static long long map_binfile_download_size(struct map_priv *m)
1040 zoff99 2 {
1041 zoff99 27 struct attr url =
1042     { attr_url };
1043     struct attr http_method =
1044     { attr_http_method };
1045     struct attr persistent =
1046     { attr_persistent };
1047 zoff99 2 struct attr *attrs[4];
1048     int size_ret;
1049     long long ret;
1050     void *data;
1051    
1052 zoff99 27 do
1053     {
1054     attrs[0] = &url;
1055     url.u.str = m->url;
1056     attrs[1] = &http_method;
1057     http_method.u.str = "HEAD";
1058     persistent.u.num = 1;
1059     attrs[2] = &persistent;
1060     attrs[3] = NULL;
1061 zoff99 2
1062     map_binfile_http_request(m, attrs);
1063 zoff99 27 data = file_data_read_special(m->http, 0, &size_ret);
1064 zoff99 2 g_free(data);
1065 zoff99 27 if (size_ret < 0)
1066 zoff99 2 return 0;
1067 zoff99 27 }
1068     while (map_binfile_handle_redirect(m));
1069    
1070     ret = file_size(m->http);
1071     // dbg(1,"file size "LONGLONG_FMT"\n",ret);
1072 zoff99 2 return ret;
1073     }
1074    
1075 zoff99 27 static int map_binfile_http_close(struct map_priv *m)
1076 zoff99 2 {
1077 zoff99 27 if (m->http)
1078     {
1079 zoff99 2 file_destroy(m->http);
1080 zoff99 27 m->http = NULL;
1081 zoff99 2 }
1082     return 1;
1083     }
1084    
1085     static struct file *
1086     map_binfile_http_range(struct map_priv *m, long long offset, int size)
1087     {
1088     struct attr *attrs[4];
1089 zoff99 27 struct attr url =
1090     { attr_url };
1091     struct attr http_header =
1092     { attr_http_header };
1093     struct attr persistent =
1094     { attr_persistent };
1095 zoff99 2
1096 zoff99 27 persistent.u.num = 1;
1097     attrs[0] = &url;
1098     attrs[1] = &http_header;
1099     attrs[2] = &persistent;
1100     attrs[3] = NULL;
1101 zoff99 2
1102 zoff99 27 url.u.str = m->url;
1103 zoff99 2 http_header.u.str=g_strdup_printf("Range: bytes="LONGLONG_FMT"-"LONGLONG_FMT,offset, offset+size-1);
1104     map_binfile_http_request(m, attrs);
1105     g_free(http_header.u.str);
1106     return m->http;
1107     }
1108    
1109     static unsigned char *
1110     map_binfile_download_range(struct map_priv *m, long long offset, int size)
1111     {
1112     unsigned char *ret;
1113     int size_ret;
1114 zoff99 27 struct file *http = map_binfile_http_range(m, offset, size);
1115 zoff99 2
1116 zoff99 27 ret = file_data_read_special(http, size, &size_ret);
1117     if (size_ret != size)
1118     {
1119     // dbg(0, "size %d vs %d\n", size, size_ret);
1120 zoff99 2 g_free(ret);
1121     return NULL;
1122     }
1123     return ret;
1124     }
1125    
1126     static struct zip_cd *
1127     download_cd(struct map_download *download)
1128     {
1129 zoff99 27 struct map_priv *m = download->m;
1130     struct zip64_eoc *zip64_eoc = (struct zip64_eoc *) file_data_read(m->fi, 0, sizeof(*zip64_eoc));
1131     struct zip_cd *cd = (struct zip_cd *) map_binfile_download_range(m, zip64_eoc->zip64eofst + download->zipfile * m->cde_size, m->cde_size);
1132     file_data_free(m->fi, (unsigned char *) zip64_eoc);
1133     // dbg(0, "needed cd, result %p\n", cd);
1134 zoff99 2 return cd;
1135     }
1136    
1137 zoff99 27 static int download_request(struct map_download *download)
1138 zoff99 2 {
1139 zoff99 27 struct attr url =
1140     { attr_url };
1141     struct attr http_header =
1142     { attr_http_header };
1143     struct attr persistent =
1144     { attr_persistent };
1145 zoff99 2 struct attr *attrs[4];
1146    
1147 zoff99 27 if (!download->m->download_enabled)
1148 zoff99 2 {
1149 zoff99 27 // dbg(0, "Tried downloading while it's not allowed\n");
1150 zoff99 2 return 0;
1151     }
1152 zoff99 27 attrs[0] = &url;
1153     persistent.u.num = 1;
1154     attrs[1] = &persistent;
1155     attrs[2] = NULL;
1156     if (strchr(download->m->url, '?'))
1157     {
1158     url.u.str = g_strdup_printf("%smemberid=%d", download->m->url, download->zipfile);
1159     download->dl_size = -1;
1160     }
1161     else
1162     {
1163     long long offset = binfile_cd_offset(download->cd_copy);
1164     int size = download->cd_copy->zipcsiz + sizeof(struct zip_lfh) + download->cd_copy->zipcfnl;
1165     url.u.str = g_strdup(download->m->url);
1166 zoff99 2 http_header.u.str=g_strdup_printf("Range: bytes="LONGLONG_FMT"-"LONGLONG_FMT,offset,offset+size-1);
1167 zoff99 27 attrs[2] = &http_header;
1168     attrs[3] = NULL;
1169     download->dl_size = size;
1170 zoff99 2 }
1171 zoff99 27 // dbg(0,"encountered missing tile %d %s(%s), Downloading %d bytes at "LONGLONG_FMT"\n",download->zipfile, url.u.str,(char *)(download->cd_copy+1), download->dl_size, download->offset);
1172 zoff99 2 map_binfile_http_request(download->m, attrs);
1173     g_free(url.u.str);
1174 zoff99 27 download->http = download->m->http;
1175 zoff99 2 return 1;
1176     }
1177    
1178 zoff99 27 static int download_start(struct map_download *download)
1179 zoff99 2 {
1180     long long offset;
1181     struct zip_eoc *eoc;
1182    
1183 zoff99 27 if (!download->cd->zipcensig)
1184     {
1185     download->cd_copy = download_cd(download);
1186     }
1187     else
1188     {
1189     download->cd_copy = g_malloc(download->m->cde_size);
1190 zoff99 2 memcpy(download->cd_copy, download->cd, download->m->cde_size);
1191     }
1192 zoff99 27 file_data_remove(download->file, (unsigned char *) download->cd);
1193     download->cd = NULL;
1194     offset = file_size(download->file);
1195     offset -= sizeof(struct zip_eoc);
1196     eoc = (struct zip_eoc *) file_data_read(download->file, offset, sizeof(struct zip_eoc));
1197     download->zip_eoc = g_malloc(sizeof(struct zip_eoc));
1198 zoff99 2 memcpy(download->zip_eoc, eoc, sizeof(struct zip_eoc));
1199 zoff99 27 file_data_remove(download->file, (unsigned char *) eoc);
1200     download->start_offset = download->offset = offset;
1201 zoff99 2 return download_request(download);
1202     }
1203    
1204 zoff99 27 static int download_download(struct map_download *download)
1205 zoff99 2 {
1206 zoff99 27 int size = 64 * 1024, size_ret;
1207 zoff99 2 unsigned char *data;
1208     if (download->dl_size != -1 && size > download->dl_size)
1209 zoff99 27 size = download->dl_size;
1210 zoff99 2 if (!size)
1211     return 1;
1212 zoff99 27 data = file_data_read_special(download->http, size, &size_ret);
1213     if (!download->read && download->m->http && map_binfile_handle_redirect(download->m))
1214     {
1215 zoff99 2 g_free(data);
1216     download_request(download);
1217     return 0;
1218     }
1219    
1220 zoff99 27 // dbg(1,"got %d bytes writing at offset "LONGLONG_FMT"\n",size_ret,download->offset);
1221     if (size_ret <= 0)
1222     {
1223 zoff99 2 g_free(data);
1224     return 1;
1225     }
1226     file_data_write(download->file, download->offset, size_ret, data);
1227 zoff99 27 download->offset += size_ret;
1228     download->read += size_ret;
1229     download->dl_size -= size_ret;
1230 zoff99 2 if (download->dl_size != -1)
1231 zoff99 27 download->progress = download->read * 100 / (download->read + download->dl_size);
1232 zoff99 2 return 0;
1233     }
1234    
1235 zoff99 27 static int download_finish(struct map_download *download)
1236 zoff99 2 {
1237     struct zip_lfh *lfh;
1238     char *lfh_filename;
1239     struct zip_cd_ext *ext;
1240     long long lfh_offset;
1241 zoff99 27 file_data_write(download->file, download->offset, sizeof(struct zip_eoc), (void *) download->zip_eoc);
1242     lfh = (struct zip_lfh *) (file_data_read(download->file, download->start_offset, sizeof(struct zip_lfh)));
1243     ext = binfile_cd_ext(download->cd_copy);
1244 zoff99 2 if (ext)
1245 zoff99 27 ext->zipofst = download->start_offset;
1246 zoff99 2 else
1247 zoff99 27 download->cd_copy->zipofst = download->start_offset;
1248     download->cd_copy->zipcsiz = lfh->zipsize;
1249     download->cd_copy->zipcunc = lfh->zipuncmp;
1250     download->cd_copy->zipccrc = lfh->zipcrc;
1251     lfh_offset = binfile_cd_offset(download->cd_copy) + sizeof(struct zip_lfh);
1252     lfh_filename = (char *) file_data_read(download->file, lfh_offset, lfh->zipfnln);
1253     memcpy(download->cd_copy + 1, lfh_filename, lfh->zipfnln);
1254     file_data_remove(download->file, (void *) lfh_filename);
1255     file_data_remove(download->file, (void *) lfh);
1256     file_data_write(download->file, download->m->eoc->zipeofst + download->zipfile * download->m->cde_size, binfile_cd_extra(download->cd_copy) + sizeof(struct zip_cd), (void *) download->cd_copy);
1257     file_data_flush(download->file, download->m->eoc->zipeofst + download->zipfile * download->m->cde_size, sizeof(struct zip_cd));
1258 zoff99 2
1259     g_free(download->cd_copy);
1260 zoff99 27 download->cd = (struct zip_cd *) (file_data_read(download->file, download->m->eoc->zipeofst + download->zipfile * download->m->cde_size, download->m->cde_size));
1261 zoff99 2 cd_to_cpu(download->cd);
1262 zoff99 27 // dbg(1, "Offset %d\n", download->cd->zipofst);
1263 zoff99 2 return 1;
1264     }
1265    
1266 zoff99 27 static int download_planet_size(struct map_download *download)
1267 zoff99 2 {
1268 zoff99 27 download->size = map_binfile_download_size(download->m);
1269     // dbg(0,"Planet size "LONGLONG_FMT"\n",download->size);
1270 zoff99 2 if (!download->size)
1271     return 0;
1272     return 1;
1273     }
1274    
1275 zoff99 27 static int download_eoc(struct map_download *download)
1276 zoff99 2 {
1277 zoff99 27 download->zip64_eoc = (struct zip64_eoc *) map_binfile_download_range(download->m, download->size - 98, 98);
1278 zoff99 2 if (!download->zip64_eoc)
1279     return 0;
1280 zoff99 27 download->zip64_eocl = (struct zip64_eocl *) (download->zip64_eoc + 1);
1281     download->zip_eoc = (struct zip_eoc *) (download->zip64_eocl + 1);
1282 zoff99 2 if (download->zip64_eoc->zip64esig != zip64_eoc_sig || download->zip64_eocl->zip64lsig != zip64_eocl_sig || download->zip_eoc->zipesig != zip_eoc_sig)
1283     {
1284 zoff99 27 // dbg(0,"wrong signature on zip64_eoc downloaded from "LONGLONG_FMT"\n",download->size-98);
1285 zoff99 2 g_free(download->zip64_eoc);
1286     return 0;
1287     }
1288     return 1;
1289     }
1290    
1291 zoff99 27 static int download_directory_start(struct map_download *download)
1292 zoff99 2 {
1293 zoff99 27 download->http = map_binfile_http_range(download->m, download->zip64_eoc->zip64eofst, download->zip64_eoc->zip64ecsz);
1294 zoff99 2 if (!download->http)
1295     return 0;
1296     return 1;
1297     }
1298    
1299 zoff99 27 static int download_directory_do(struct map_download *download)
1300 zoff99 2 {
1301     int count;
1302    
1303 zoff99 27 for (count = 0; count < 100; count++)
1304     {
1305 zoff99 2 int cd_xlen, size_ret;
1306     unsigned char *cd_data;
1307     struct zip_cd *cd;
1308 zoff99 27 cd = (struct zip_cd *) file_data_read_special(download->http, sizeof(*cd), &size_ret);
1309     cd->zipcunc = 0;
1310     // dbg(1, "size_ret=%d\n", size_ret);
1311 zoff99 2 if (!size_ret)
1312     return 0;
1313 zoff99 27 if (size_ret != sizeof(*cd) || cd->zipcensig != zip_cd_sig)
1314     {
1315     // dbg(0, "error1 size=%d vs %d\n", size_ret, sizeof(*cd));
1316 zoff99 2 return 0;
1317     }
1318 zoff99 27 file_data_write(download->file, download->offset, sizeof(*cd), (unsigned char *) cd);
1319     download->offset += sizeof(*cd);
1320     cd_xlen = cd->zipcfnl + cd->zipcxtl;
1321     cd_data = file_data_read_special(download->http, cd_xlen, &size_ret);
1322     if (size_ret != cd_xlen)
1323     {
1324     // dbg(0, "error2 size=%d vs %d\n", size_ret, cd_xlen);
1325 zoff99 2 return 0;
1326     }
1327     file_data_write(download->file, download->offset, cd_xlen, cd_data);
1328 zoff99 27 download->offset += cd_xlen;
1329 zoff99 2 g_free(cd);
1330     g_free(cd_data);
1331     }
1332     return 1;
1333     }
1334    
1335 zoff99 27 static int download_directory_finish(struct map_download *download)
1336 zoff99 2 {
1337 zoff99 27 download->http = NULL;
1338 zoff99 2 return 1;
1339     }
1340    
1341 zoff99 27 static int download_initial_finish(struct map_download *download)
1342 zoff99 2 {
1343 zoff99 27 download->zip64_eoc->zip64eofst = download->cd1offset;
1344     download->zip64_eocl->zip64lofst = download->offset;
1345     download->zip_eoc->zipeofst = download->cd1offset;
1346 zoff99 2 #if 0
1347     file_data_write(download->file, download->offset, sizeof(*download->zip64_eoc), (unsigned char *)download->zip64_eoc);
1348     download->offset+=sizeof(*download->zip64_eoc);
1349     file_data_write(download->file, download->offset, sizeof(*download->zip64_eocl), (unsigned char *)download->zip64_eocl);
1350     download->offset+=sizeof(*download->zip64_eocl);
1351     #endif
1352 zoff99 27 file_data_write(download->file, download->offset, sizeof(*download->zip_eoc), (unsigned char *) download->zip_eoc);
1353     download->offset += sizeof(*download->zip_eoc);
1354 zoff99 2 g_free(download->zip64_eoc);
1355 zoff99 27 download->zip64_eoc = NULL;
1356 zoff99 2 return 1;
1357     }
1358    
1359 zoff99 27 static void push_zipfile_tile_do(struct map_rect_priv *mr, struct zip_cd *cd, int zipfile, int offset, int length)
1360 zoff99 2
1361     {
1362     struct tile t;
1363 zoff99 27 struct map_priv *m = mr->m;
1364     struct file *f = m->fi;
1365 zoff99 2
1366 zoff99 27 // dbg(1, "enter %p %d\n", mr, zipfile);
1367 zoff99 2 #ifdef DEBUG_SIZE
1368     #if DEBUG_SIZE > 0
1369     {
1370     char filename[cd->zipcfnl+1];
1371     memcpy(filename, cd+1, cd->zipcfnl);
1372     filename[cd->zipcfnl]='\0';
1373 zoff99 27 // dbg(0,"enter %d (%s) %d\n",zipfile, filename, cd->zipcunc);
1374 zoff99 2 }
1375     #endif
1376     mr->size+=cd->zipcunc;
1377     #endif
1378 zoff99 27 t.zipfile_num = zipfile;
1379     if (zipfile_to_tile(m, cd, &t))
1380 zoff99 2 push_tile(mr, &t, offset, length);
1381 zoff99 27 file_data_free(f, (unsigned char *) cd);
1382 zoff99 2 }
1383    
1384     static struct zip_cd *
1385     download(struct map_priv *m, struct map_rect_priv *mr, struct zip_cd *cd, int zipfile, int offset, int length, int async)
1386     {
1387     struct map_download *download;
1388    
1389 zoff99 27 if (!m->download_enabled)
1390 zoff99 2 return NULL;
1391    
1392 zoff99 27 if (async == 2)
1393     {
1394     download = m->download;
1395     }
1396     else
1397     {
1398 zoff99 2 download=g_new0(struct map_download, 1);
1399 zoff99 27 if (mr)
1400     {
1401     download->m = m;
1402     download->mr = mr;
1403     download->file = m->fi;
1404     download->cd = cd;
1405     download->zipfile = zipfile;
1406     download->toffset = offset;
1407     download->tlength = length;
1408     download->state = 1;
1409     }
1410     else
1411     {
1412     struct attr readwrite =
1413     { attr_readwrite,
1414     { (void *) 1 } };
1415     struct attr create =
1416     { attr_create,
1417     { (void *) 1 } };
1418 zoff99 2 struct attr *attrs[3];
1419 zoff99 27 attrs[0] = &readwrite;
1420     attrs[1] = &create;
1421     attrs[2] = NULL;
1422     download->file = file_create(m->filename, attrs);
1423     download->m = m;
1424     download->state = 4;
1425 zoff99 2 }
1426     }
1427 zoff99 27 if (async == 1)
1428     {
1429     m->download = download;
1430 zoff99 2 g_free(m->progress);
1431 zoff99 27 if (download->mr)
1432     m->progress = g_strdup_printf("Download Tile %d 0%%", download->zipfile);
1433 zoff99 2 else
1434 zoff99 40 m->progress = g_strdup("Download Map Information 0%%");
1435 zoff99 2 callback_list_call_attr_0(m->cbl, attr_progress);
1436     return NULL;
1437     }
1438 zoff99 27 for (;;)
1439     {
1440     // dbg(0, "state=%d\n", download->state);
1441     switch (download->state)
1442     {
1443     case 0:
1444     // dbg(0, "error\n");
1445     break;
1446     case 1:
1447     if (download_start(download))
1448     download->state = 2;
1449     else
1450     download->state = 0;
1451     break;
1452     case 2:
1453     if (download_download(download))
1454     download->state = 3;
1455     else
1456     {
1457     g_free(m->progress);
1458     m->progress = g_strdup_printf("Download Tile %d %d%%", download->zipfile, download->progress);
1459     callback_list_call_attr_0(m->cbl, attr_progress);
1460     }
1461     break;
1462     case 3:
1463     if (download_finish(download))
1464     {
1465     struct zip_cd *ret;
1466     g_free(m->progress);
1467     m->progress = g_strdup_printf("Download Tile %d 100%%", download->zipfile);
1468     callback_list_call_attr_0(m->cbl, attr_progress);
1469     if (async)
1470     {
1471     push_zipfile_tile_do(download->mr, download->cd, download->zipfile, download->toffset, download->tlength);
1472     ret = NULL;
1473     }
1474     else
1475     ret = download->cd;
1476     g_free(m->progress);
1477     m->progress = NULL;
1478     g_free(download);
1479     if (async)
1480     m->download = NULL;
1481     return ret;
1482     }
1483     else
1484     download->state = 0;
1485     break;
1486     case 4:
1487     if (download_planet_size(download))
1488     download->state = 5;
1489     else
1490     download->state = 0;
1491     break;
1492     case 5:
1493 zoff99 2 g_free(m->progress);
1494 zoff99 40 m->progress = g_strdup("Download Map Information 50%%");
1495 zoff99 2 callback_list_call_attr_0(m->cbl, attr_progress);
1496 zoff99 27 if (download_eoc(download))
1497     download->state = 6;
1498     else
1499     {
1500     // dbg(0, "download of eoc failed\n");
1501     download->state = 0;
1502     }
1503     break;
1504     case 6:
1505 zoff99 2 g_free(m->progress);
1506 zoff99 40 m->progress = g_strdup("Download Map Information 100%%");
1507 zoff99 2 callback_list_call_attr_0(m->cbl, attr_progress);
1508 zoff99 27 if (download_directory_start(download))
1509     download->state = 7;
1510     else
1511     download->state = 0;
1512     break;
1513     case 7:
1514 zoff99 2 g_free(m->progress);
1515 zoff99 27 m->progress = g_strdup_printf("Download Map Directory %d%%", (int) (download->offset * 100 / download->zip64_eoc->zip64ecsz));
1516     callback_list_call_attr_0(m->cbl, attr_progress);
1517     if (!download_directory_do(download))
1518     download->state = 8;
1519     break;
1520     case 8:
1521     if (download_directory_finish(download))
1522     download->state = 9;
1523     else
1524     download->state = 0;
1525     break;
1526     case 9:
1527     download_initial_finish(download);
1528     m->fi = download->file;
1529     g_free(m->progress);
1530     m->progress = NULL;
1531 zoff99 2 g_free(download);
1532     if (async)
1533 zoff99 27 m->download = NULL;
1534     map_binfile_open(m);
1535     break;
1536 zoff99 2 }
1537     if (async)
1538     return NULL;
1539     }
1540     }
1541    
1542 zoff99 27 static int push_zipfile_tile(struct map_rect_priv *mr, int zipfile, int offset, int length, int async)
1543 zoff99 2 {
1544 zoff99 27 struct map_priv *m = mr->m;
1545     struct file *f = m->fi;
1546     long long cdoffset = m->eoc64 ? m->eoc64->zip64eofst : m->eoc->zipeofst;
1547     struct zip_cd *cd = (struct zip_cd *) (file_data_read(f, cdoffset + zipfile * m->cde_size, m->cde_size));
1548     // dbg(1,"read from "LONGLONG_FMT" %d bytes\n",cdoffset + zipfile*m->cde_size, m->cde_size);
1549 zoff99 2 cd_to_cpu(cd);
1550 zoff99 27 if (!cd->zipcunc && m->url)
1551     {
1552     cd = download(m, mr, cd, zipfile, offset, length, async);
1553 zoff99 2 if (!cd)
1554     return 1;
1555     }
1556     push_zipfile_tile_do(mr, cd, zipfile, offset, length);
1557     return 0;
1558     }
1559    
1560     static struct map_rect_priv *
1561     map_rect_new_binfile_int(struct map_priv *map, struct map_selection *sel)
1562     {
1563     struct map_rect_priv *mr;
1564    
1565     binfile_check_version(map);
1566 zoff99 27 // dbg(1, "map_rect_new_binfile\n");
1567 zoff99 2 if (!map->fi && !map->url)
1568 zoff99 34 {
1569 zoff99 2 return NULL;
1570 zoff99 34 }
1571 zoff99 2 map_binfile_http_close(map);
1572     mr=g_new0(struct map_rect_priv, 1);
1573 zoff99 27 mr->m = map;
1574     mr->sel = sel;
1575     mr->item.id_hi = 0;
1576     mr->item.id_lo = 0;
1577     mr->item.meth = &methods_binfile;
1578     mr->item.priv_data = mr;
1579 zoff99 2 return mr;
1580     }
1581    
1582 zoff99 27 static void tile_bbox(char *tile, int len, struct coord_rect *r)
1583 zoff99 2 {
1584 zoff99 27 struct coord c;
1585     int overlap = 1;
1586     int xo, yo;
1587     struct coord_rect world_bbox =
1588     {
1589     { -20000000, 20000000 }, /* lu */
1590     { 20000000, -20000000 }, /* rl */
1591 zoff99 2 };
1592 zoff99 27 *r = world_bbox;
1593     while (len)
1594     {
1595     c.x = (r->lu.x + r->rl.x) / 2;
1596     c.y = (r->lu.y + r->rl.y) / 2;
1597     xo = (r->rl.x - r->lu.x) * overlap / 100;
1598     yo = (r->lu.y - r->rl.y) * overlap / 100;
1599     switch (*tile)
1600     {
1601     case 'a':
1602     r->lu.x = c.x - xo;
1603     r->rl.y = c.y - yo;
1604     break;
1605     case 'b':
1606     r->rl.x = c.x + xo;
1607     r->rl.y = c.y - yo;
1608     break;
1609     case 'c':
1610     r->lu.x = c.x - xo;
1611     r->lu.y = c.y + yo;
1612     break;
1613     case 'd':
1614     r->rl.x = c.x + xo;
1615     r->lu.y = c.y + yo;
1616     break;
1617     default:
1618     return;
1619     }
1620     tile++;
1621     len--;
1622     }
1623 zoff99 2 }
1624    
1625 zoff99 27 static int map_download_selection_check(struct zip_cd *cd, struct map_selection *sel)
1626 zoff99 2 {
1627 zoff99 27 //// dbg(0,"EEnter\n");
1628 zoff99 2
1629     struct coord_rect cd_rect;
1630     if (cd->zipcunc)
1631     return 0;
1632 zoff99 27 tile_bbox((char *) (cd + 1), cd->zipcfnl, &cd_rect);
1633     while (sel)
1634     {
1635 zoff99 2 if (coord_rect_overlap(&cd_rect, &sel->u.c_rect))
1636     return 1;
1637 zoff99 27 sel = sel->next;
1638 zoff99 2 }
1639     return 0;
1640     }
1641    
1642 zoff99 27 static void map_download_selection(struct map_priv *m, struct map_rect_priv *mr, struct map_selection *sel)
1643 zoff99 2 {
1644     int i;
1645     struct zip_cd *cd;
1646 zoff99 27 for (i = 0; i < m->zip_members; i++)
1647     {
1648     cd = binfile_read_cd(m, m->cde_size * i, -1);
1649     if (map_download_selection_check(cd, sel))
1650 zoff99 2 download(m, mr, cd, i, 0, 0, 0);
1651 zoff99 27 file_data_free(m->fi, (unsigned char *) cd);
1652 zoff99 2 }
1653     }
1654    
1655     static struct map_rect_priv *
1656     map_rect_new_binfile(struct map_priv *map, struct map_selection *sel)
1657     {
1658 zoff99 27 struct map_rect_priv *mr = map_rect_new_binfile_int(map, sel);
1659 zoff99 2 struct tile t;
1660 zoff99 27 // dbg(1, "zip_members=%d\n", map->zip_members);
1661     if (map->url && map->fi && sel && sel->order == 255)
1662     {
1663 zoff99 2 map_download_selection(map, mr, sel);
1664     }
1665     if (map->eoc)
1666 zoff99 27 mr->status = 1;
1667     else
1668     {
1669 zoff99 2 unsigned char *d;
1670 zoff99 27 if (map->fi)
1671     {
1672     d = file_data_read(map->fi, 0, map->fi->size);
1673     t.start = (int *) d;
1674     t.end = (int *) (d + map->fi->size);
1675     t.fi = map->fi;
1676     t.zipfile_num = 0;
1677     t.mode = 0;
1678 zoff99 2 push_tile(mr, &t, 0, 0);
1679 zoff99 27 }
1680     else if (map->url && !map->download)
1681     {
1682 zoff99 2 download(map, NULL, NULL, 0, 0, 0, 1);
1683 zoff99 27 mr->status = 1;
1684 zoff99 2 }
1685     }
1686     return mr;
1687     }
1688    
1689 zoff99 27 static void write_changes_do(gpointer key, gpointer value, gpointer user_data)
1690 zoff99 2 {
1691 zoff99 27 struct binfile_hash_entry *entry = key;
1692     FILE *out = user_data;
1693     if (entry->flags)
1694     {
1695     entry->flags = 0;
1696     fwrite(entry, sizeof(*entry) + (le32_to_cpu(entry->data[0]) + 1) * 4, 1, out);
1697     // dbg(0, "yes\n");
1698 zoff99 2 }
1699     }
1700    
1701 zoff99 27 static void write_changes(struct map_priv *m)
1702 zoff99 2 {
1703     FILE *changes;
1704     char *changes_file;
1705     if (!m->changes)
1706     return;
1707 zoff99 27 changes_file = g_strdup_printf("%s.log", m->filename);
1708     changes = fopen(changes_file, "ab");
1709 zoff99 2 g_hash_table_foreach(m->changes, write_changes_do, changes);
1710     fclose(changes);
1711     g_free(changes_file);
1712     }
1713    
1714 zoff99 27 static void load_changes(struct map_priv *m)
1715 zoff99 2 {
1716     FILE *changes;
1717     char *changes_file;
1718 zoff99 27 struct binfile_hash_entry entry, *e;
1719 zoff99 2 int size;
1720 zoff99 27 changes_file = g_strdup_printf("%s.log", m->filename);
1721     changes = fopen(changes_file, "rb");
1722     if (!changes)
1723     {
1724 zoff99 2 g_free(changes_file);
1725     return;
1726     }
1727 zoff99 31 m->changes = g_hash_table_new_full(binfile_hash_entry_hash, binfile_hash_entry_equal, g_free_func, NULL);
1728 zoff99 27 while (fread(&entry, sizeof(entry), 1, changes) == 1)
1729     {
1730 zoff99 2 if (fread(&size, sizeof(size), 1, changes) != 1)
1731     break;
1732 zoff99 27 e = g_malloc(sizeof(struct binfile_hash_entry) + (le32_to_cpu(size) + 1) * 4);
1733     *e = entry;
1734     e->data[0] = size;
1735     if (fread(e->data + 1, le32_to_cpu(size) * 4, 1, changes) != 1)
1736 zoff99 2 break;
1737     g_hash_table_replace(m->changes, e, e);
1738     }
1739     fclose(changes);
1740     g_free(changes_file);
1741     }
1742    
1743 zoff99 27 static void map_rect_destroy_binfile(struct map_rect_priv *mr)
1744 zoff99 2 {
1745     write_changes(mr->m);
1746 zoff99 27 while (pop_tile(mr))
1747     ;
1748 zoff99 2 #ifdef DEBUG_SIZE
1749 zoff99 27 // dbg(0,"size=%d kb\n",mr->size/1024);
1750 zoff99 2 #endif
1751     if (mr->tiles[0].fi && mr->tiles[0].start)
1752 zoff99 27 file_data_free(mr->tiles[0].fi, (unsigned char *) (mr->tiles[0].start));
1753 zoff99 2 g_free(mr->url);
1754     map_binfile_http_close(mr->m);
1755 zoff99 27 g_free(mr);
1756 zoff99 2 }
1757    
1758 zoff99 27 static void setup_pos(struct map_rect_priv *mr)
1759 zoff99 2 {
1760 zoff99 27 int size, coord_size;
1761     struct tile *t = mr->t;
1762     size = le32_to_cpu(t->pos[0]);
1763     if (size > 1024 * 1024 || size < 0)
1764     {
1765     // dbg(0, "size=0x%x\n", size);
1766 zoff99 2 #if 0
1767     fprintf(stderr,"offset=%d\n", (unsigned char *)(mr->pos)-mr->m->f->begin);
1768     #endif
1769 zoff99 27 // dbg(0, "size error");
1770 zoff99 2 }
1771 zoff99 27 t->pos_next = t->pos + size + 1;
1772     mr->item.type = le32_to_cpu(t->pos[1]);
1773     coord_size = le32_to_cpu(t->pos[2]);
1774     t->pos_coord_start = t->pos + 3;
1775     t->pos_attr_start = t->pos_coord_start + coord_size;
1776 zoff99 2 }
1777    
1778 zoff99 27 static int selection_contains(struct map_selection *sel, struct coord_rect *r, struct range *mima)
1779 zoff99 2 {
1780 zoff99 27 //// dbg(0,"EEnter\n");
1781 zoff99 2
1782     int order;
1783 zoff99 27 if (!sel)
1784 zoff99 2 return 1;
1785 zoff99 27 while (sel)
1786     {
1787     if (coord_rect_overlap(r, &sel->u.c_rect))
1788     {
1789     order = sel->order;
1790     // dbg(1, "min %d max %d order %d\n", mima->min, mima->max, order);
1791 zoff99 2 if (!mima->min && !mima->max)
1792     return 1;
1793     if (order >= mima->min && order <= mima->max)
1794     return 1;
1795     }
1796 zoff99 27 sel = sel->next;
1797 zoff99 2 }
1798     return 0;
1799     }
1800    
1801 zoff99 27 static void map_parse_country_binfile(struct map_rect_priv *mr)
1802 zoff99 2 {
1803     struct attr at;
1804 zoff99 27 if (binfile_attr_get(mr->item.priv_data, attr_country_id, &at))
1805     {
1806 zoff99 2 if (at.u.num == mr->country_id)
1807     {
1808     if (binfile_attr_get(mr->item.priv_data, attr_zipfile_ref, &at))
1809     {
1810     push_zipfile_tile(mr, at.u.num, 0, 0, 0);
1811     }
1812     }
1813     }
1814     }
1815    
1816 zoff99 27 static int map_parse_submap(struct map_rect_priv *mr, int async)
1817 zoff99 2 {
1818     struct coord_rect r;
1819     struct coord c[2];
1820     struct attr at;
1821     struct range mima;
1822     if (binfile_coord_get(mr->item.priv_data, c, 2) != 2)
1823     return 0;
1824 zoff99 40
1825 zoff99 27 r.lu.x = c[0].x;
1826     r.lu.y = c[1].y;
1827     r.rl.x = c[1].x;
1828     r.rl.y = c[0].y;
1829 zoff99 2 if (!binfile_attr_get(mr->item.priv_data, attr_order, &at))
1830     return 0;
1831 zoff99 40
1832 zoff99 2 #if __BYTE_ORDER == __BIG_ENDIAN
1833 zoff99 27 mima.min = le16_to_cpu(at.u.range.max);
1834     mima.max = le16_to_cpu(at.u.range.min);
1835 zoff99 2 #else
1836     mima=at.u.range;
1837     #endif
1838     if (!mr->m->eoc || !selection_contains(mr->sel, &r, &mima))
1839     return 0;
1840     if (!binfile_attr_get(mr->item.priv_data, attr_zipfile_ref, &at))
1841     return 0;
1842 zoff99 27 // dbg(1, "pushing zipfile %d from %d\n", at.u.num, mr->t->zipfile_num);
1843 zoff99 2 return push_zipfile_tile(mr, at.u.num, 0, 0, async);
1844     }
1845    
1846 zoff99 27 static int push_modified_item(struct map_rect_priv *mr)
1847 zoff99 2 {
1848     struct item_id id;
1849     struct binfile_hash_entry *entry;
1850 zoff99 27 id.id_hi = mr->item.id_hi;
1851     id.id_lo = mr->item.id_lo;
1852     entry = g_hash_table_lookup(mr->m->changes, &id);
1853     if (entry)
1854     {
1855 zoff99 2 struct tile tn;
1856 zoff99 27 tn.pos_next = tn.pos = tn.start = entry->data;
1857     tn.zipfile_num = mr->item.id_hi;
1858     tn.mode = 2;
1859     tn.end = tn.start + le32_to_cpu(entry->data[0]) + 1;
1860 zoff99 2 push_tile(mr, &tn, 0, 0);
1861     return 1;
1862     }
1863     return 0;
1864     }
1865    
1866     static struct item *
1867     map_rect_get_item_binfile(struct map_rect_priv *mr)
1868     {
1869 zoff99 31 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1870     dbg(0,"+#+:enter\n");
1871     #endif
1872    
1873 zoff99 2 struct tile *t;
1874 zoff99 27 struct map_priv *m = mr->m;
1875 zoff99 31
1876 zoff99 27 if (m->download)
1877     {
1878 zoff99 2 download(m, NULL, NULL, 0, 0, 0, 2);
1879 zoff99 31 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1880     dbg(0,"+#+:leave9\n");
1881     #endif
1882 zoff99 2 return &busy_item;
1883     }
1884 zoff99 31
1885 zoff99 27 if (mr->status == 1)
1886     {
1887     mr->status = 0;
1888     if (push_zipfile_tile(mr, m->zip_members - 1, 0, 0, 1))
1889 zoff99 31 {
1890     #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1891     dbg(0,"+#+:leave8\n");
1892     #endif
1893 zoff99 2 return &busy_item;
1894 zoff99 31 }
1895 zoff99 2 }
1896 zoff99 31
1897 zoff99 27 for (;;)
1898     {
1899     t = mr->t;
1900 zoff99 31
1901 zoff99 27 if (!t)
1902 zoff99 31 {
1903     #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1904     dbg(0,"+#+:leave6\n");
1905     #endif
1906 zoff99 2 return NULL;
1907 zoff99 31 }
1908    
1909 zoff99 27 t->pos = t->pos_next;
1910 zoff99 31
1911 zoff99 27 if (t->pos >= t->end)
1912     {
1913 zoff99 2 if (pop_tile(mr))
1914 zoff99 31 {
1915 zoff99 2 continue;
1916 zoff99 31 }
1917    
1918     #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1919     dbg(0,"+#+:leave5\n");
1920     #endif
1921    
1922 zoff99 2 return NULL;
1923     }
1924 zoff99 31
1925 zoff99 2 setup_pos(mr);
1926     binfile_coord_rewind(mr);
1927     binfile_attr_rewind(mr);
1928 zoff99 27 if ((mr->item.type == type_submap) && (!mr->country_id))
1929     {
1930 zoff99 2 if (map_parse_submap(mr, 1))
1931 zoff99 31 {
1932     #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1933     dbg(0,"+#+:leave4\n");
1934     #endif
1935 zoff99 2 return &busy_item;
1936 zoff99 31 }
1937 zoff99 2 continue;
1938     }
1939 zoff99 27 if (t->mode != 2)
1940     {
1941     mr->item.id_hi = t->zipfile_num;
1942     mr->item.id_lo = t->pos - t->start;
1943 zoff99 2 if (mr->m->changes && push_modified_item(mr))
1944     continue;
1945     }
1946     if (mr->country_id)
1947     {
1948 zoff99 27 if (mr->item.type == type_countryindex)
1949     {
1950 zoff99 2 map_parse_country_binfile(mr);
1951     }
1952     if (item_is_town(mr->item))
1953     {
1954 zoff99 31 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1955     dbg(0,"+#+:leave3\n");
1956     #endif
1957 zoff99 2 return &mr->item;
1958 zoff99 27 }
1959     else
1960     {
1961 zoff99 2 continue;
1962     }
1963     }
1964 zoff99 31 #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1965     dbg(0,"+#+:leave 2\n");
1966     #endif
1967 zoff99 2 return &mr->item;
1968     }
1969 zoff99 31
1970     #ifdef NAVIT_FUNC_CALLS_DEBUG_PRINT
1971     dbg(0,"+#+:leave\n");
1972     #endif
1973 zoff99 2 }
1974    
1975     static struct item *
1976     map_rect_get_item_byid_binfile(struct map_rect_priv *mr, int id_hi, int id_lo)
1977     {
1978     struct tile *t;
1979 zoff99 15 if (mr->m->eoc)
1980     {
1981 zoff99 27 while (pop_tile(mr))
1982     ;
1983 zoff99 2 push_zipfile_tile(mr, id_hi, 0, 0, 0);
1984     }
1985 zoff99 27 t = mr->t;
1986     t->pos = t->start + id_lo;
1987     mr->item.id_hi = id_hi;
1988     mr->item.id_lo = id_lo;
1989 zoff99 2 if (mr->m->changes)
1990 zoff99 15 {
1991 zoff99 2 push_modified_item(mr);
1992 zoff99 15 }
1993 zoff99 2 setup_pos(mr);
1994     binfile_coord_rewind(mr);
1995     binfile_attr_rewind(mr);
1996 zoff99 15
1997 zoff99 2 return &mr->item;
1998     }
1999    
2000 zoff99 27 static int binmap_search_by_index(struct map_priv *map, struct item *item, struct map_rect_priv **ret)
2001 zoff99 2 {
2002     struct attr zipfile_ref;
2003     int *data;
2004    
2005 zoff99 27 if (!item)
2006     {
2007     *ret = NULL;
2008 zoff99 2 return 0;
2009     }
2010 zoff99 27 if (item_attr_get(item, attr_item_id, &zipfile_ref))
2011     {
2012     data = zipfile_ref.u.data;
2013     *ret = map_rect_new_binfile_int(map, NULL);
2014 zoff99 2 push_zipfile_tile(*ret, le32_to_cpu(data[0]), le32_to_cpu(data[1]), -1, 0);
2015     return 3;
2016     }
2017 zoff99 27 if (item_attr_get(item, attr_zipfile_ref, &zipfile_ref))
2018     {
2019     *ret = map_rect_new_binfile_int(map, NULL);
2020 zoff99 2 push_zipfile_tile(*ret, zipfile_ref.u.num, 0, 0, 0);
2021     return 1;
2022     }
2023 zoff99 27 if (item_attr_get(item, attr_zipfile_ref_block, &zipfile_ref))
2024     {
2025     data = zipfile_ref.u.data;
2026     *ret = map_rect_new_binfile_int(map, NULL);
2027 zoff99 2 push_zipfile_tile(*ret, le32_to_cpu(data[0]), le32_to_cpu(data[1]), le32_to_cpu(data[2]), 0);
2028     return 2;
2029     }
2030 zoff99 27 *ret = NULL;
2031 zoff99 2 return 0;
2032     }
2033    
2034     static struct map_rect_priv *
2035     binmap_search_street_by_place(struct map_priv *map, struct item *town, struct coord *c, struct map_selection *sel)
2036     {
2037     struct attr town_name, poly_town_name;
2038     struct map_rect_priv *map_rec2;
2039     struct item *place;
2040 zoff99 27 int found = 0;
2041 zoff99 2
2042     if (!item_attr_get(town, attr_label, &town_name))
2043     return NULL;
2044     sel->range = item_range_all;
2045     sel->order = 18;
2046     sel->next = NULL;
2047 zoff99 27 sel->u.c_rect.lu = *c;
2048     sel->u.c_rect.rl = *c;
2049     map_rec2 = map_rect_new_binfile(map, sel);
2050     while ((place = map_rect_get_item_binfile(map_rec2)))
2051     {
2052     if (item_is_poly_place(*place) && item_attr_get(place, attr_label, &poly_town_name) && !strcmp(poly_town_name.u.str, town_name.u.str))
2053     {
2054     struct coord c[128];
2055     int i, count;
2056     found = 1;
2057     while ((count = item_coord_get(place, c, 128)))
2058     {
2059     for (i = 0; i < count; i++)
2060     {
2061     coord_rect_extend(&sel->u.c_rect, &c[i]);
2062 zoff99 2 }
2063 zoff99 27 }
2064 zoff99 2 }
2065     }
2066 zoff99 27
2067 zoff99 2 map_rect_destroy_binfile(map_rec2);
2068     if (found)
2069 zoff99 27 {
2070 zoff99 2 return map_rect_new_binfile(map, sel);
2071 zoff99 27 }
2072 zoff99 2 return NULL;
2073     }
2074    
2075     static struct map_rect_priv *
2076     binmap_search_street_by_estimate(struct map_priv *map, struct item *town, struct coord *c, struct map_selection *sel)
2077     {
2078     int size = 10000;
2079 zoff99 27 switch (town->type)
2080     {
2081 zoff99 2 case type_town_label_1e7:
2082     case type_town_label_5e6:
2083     case type_town_label_2e6:
2084     case type_town_label_1e6:
2085     case type_town_label_5e5:
2086     case type_town_label_2e5:
2087     size = 10000;
2088     break;
2089     case type_town_label_1e5:
2090     case type_town_label_5e4:
2091     case type_town_label_2e4:
2092     size = 5000;
2093     break;
2094     case type_town_label_1e4:
2095     case type_town_label_5e3:
2096     case type_town_label_2e3:
2097     size = 2500;
2098     break;
2099     case type_town_label_1e3:
2100     case type_town_label_5e2:
2101     case type_town_label_2e2:
2102     case type_town_label_1e2:
2103     case type_town_label_5e1:
2104     case type_town_label_2e1:
2105     case type_town_label_1e1:
2106     case type_town_label_5e0:
2107     case type_town_label_2e0:
2108     case type_town_label_1e0:
2109     case type_town_label_0e0:
2110     size = 1000;
2111     break;
2112     default:
2113     break;
2114     }
2115 zoff99 27
2116     if (global_search_street_size_factor > 1)
2117     {
2118     size = size * global_search_street_size_factor;
2119     }
2120    
2121     sel->u.c_rect.lu.x = c->x - size;
2122     sel->u.c_rect.lu.y = c->y + size;
2123     sel->u.c_rect.rl.x = c->x + size;
2124     sel->u.c_rect.rl.y = c->y - size;
2125 zoff99 2 return map_rect_new_binfile(map, sel);
2126     }
2127    
2128     static struct map_rect_priv *
2129     binmap_search_housenumber_by_estimate(struct map_priv *map, struct coord *c, struct map_selection *sel)
2130     {
2131     int size = 20;
2132 zoff99 27 sel->u.c_rect.lu.x = c->x - size;
2133     sel->u.c_rect.lu.y = c->y + size;
2134     sel->u.c_rect.rl.x = c->x + size;
2135     sel->u.c_rect.rl.y = c->y - size;
2136 zoff99 2
2137     sel->range = item_range_all;
2138     sel->order = 18;
2139     //sel->next = NULL;
2140    
2141     return map_rect_new_binfile(map, sel);
2142     }
2143    
2144     static struct map_search_priv *
2145     binmap_search_new(struct map_priv *map, struct item *item, struct attr *search, int partial)
2146     {
2147     struct map_rect_priv *map_rec;
2148     struct map_search_priv *msp=g_new0(struct map_search_priv, 1);
2149     struct item *town;
2150 zoff99 27 int willsearch = 0;
2151    
2152 zoff99 2 msp->search = search;
2153     msp->partial = partial;
2154     /*
2155 zoff99 27 * NOTE: If you implement search for other attributes than attr_town_name and attr_street_name,
2156     * please update this comment and the documentation for map_search_new() in map.c
2157     */
2158 zoff99 15 switch (search->type)
2159     {
2160 zoff99 2 case attr_country_name:
2161     break;
2162     case attr_town_name:
2163     case attr_town_or_district_name:
2164     map_rec = map_rect_new_binfile(map, NULL);
2165 zoff99 27 if (!map_rec)
2166 zoff99 28 {
2167 zoff99 2 break;
2168 zoff99 28 }
2169 zoff99 2 map_rec->country_id = item->id_lo;
2170     msp->mr = map_rec;
2171 zoff99 27 willsearch = 1;
2172 zoff99 2 break;
2173     case attr_town_postal:
2174     break;
2175     case attr_street_name:
2176 zoff99 27 if (!item->map)
2177 zoff99 2 break;
2178     if (!map_priv_is(item->map, map))
2179     break;
2180     map_rec = map_rect_new_binfile(map, NULL);
2181     town = map_rect_get_item_byid_binfile(map_rec, item->id_hi, item->id_lo);
2182 zoff99 15 if (town)
2183     {
2184 zoff99 2 struct coord c;
2185    
2186     if (binmap_search_by_index(map, town, &msp->mr))
2187 zoff99 15 {
2188 zoff99 30 //dbg(0, "search:mode=1\n");
2189 zoff99 2 msp->mode = 1;
2190 zoff99 15 }
2191     else
2192     {
2193     if (item_coord_get(town, &c, 1))
2194     {
2195 zoff99 27 if ((msp->mr = binmap_search_street_by_place(map, town, &c, &msp->ms)))
2196 zoff99 15 {
2197 zoff99 30 //dbg(0, "search:mode=2\n");
2198 zoff99 2 msp->mode = 2;
2199 zoff99 15 }
2200     else
2201     {
2202 zoff99 27 msp->mr = binmap_search_street_by_estimate(map, town, &c, &msp->ms);
2203 zoff99 30 //dbg(0, "search:mode=3\n");
2204 zoff99 2 msp->mode = 3;
2205 zoff99 27 }
2206 zoff99 2 }
2207     }
2208     map_rect_destroy_binfile(map_rec);
2209     if (!msp->mr)
2210 zoff99 15 {
2211 zoff99 2 break;
2212 zoff99 15 }
2213 zoff99 27 willsearch = 1;
2214 zoff99 2 break;
2215     }
2216     map_rect_destroy_binfile(map_rec);
2217     break;
2218     case attr_house_number:
2219 zoff99 27 // dbg(1, "case house_number");
2220     if (!item->map)
2221 zoff99 2 break;
2222     if (!map_priv_is(item->map, map))
2223     break;
2224 zoff99 27 msp->map = map;
2225 zoff99 2 msp->mr_item = map_rect_new_binfile(map, NULL);
2226     msp->item = map_rect_get_item_byid_binfile(msp->mr_item, item->id_hi, item->id_lo);
2227 zoff99 15 if (binmap_search_by_index(map, msp->item, &msp->mr) != 3)
2228     {
2229 zoff99 2 struct coord c;
2230     if (item_coord_get(msp->item, &c, 1))
2231     {
2232 zoff99 27 msp->mr = binmap_search_housenumber_by_estimate(map, &c, &msp->ms);
2233 zoff99 2 msp->mode = 2;
2234     }
2235     map_rect_destroy_binfile(msp->mr_item);
2236 zoff99 27 msp->mr_item = NULL;
2237 zoff99 2 }
2238     if (!msp->mr)
2239     {
2240     break;
2241     }
2242 zoff99 27 willsearch = 1;
2243 zoff99 2 break;
2244     default:
2245     break;
2246     }
2247 zoff99 15
2248     if (!willsearch)
2249     {
2250 zoff99 2 g_free(msp);
2251 zoff99 27 msp = NULL;
2252 zoff99 15 }
2253     else
2254     {
2255 zoff99 27 msp->str = linguistics_casefold(search->u.str);
2256 zoff99 2 }
2257     return msp;
2258     }
2259    
2260 zoff99 27 static int ascii_cmp(char *name, char *match, int partial)
2261 zoff99 2 {
2262 zoff99 27 int ret = 1;
2263 zoff99 15
2264 zoff99 27 if (name == NULL)
2265 zoff99 15 {
2266     return ret;
2267     }
2268    
2269 zoff99 27 if (match == NULL)
2270 zoff99 15 {
2271     return ret;
2272     }
2273    
2274 zoff99 27 char *s2 = linguistics_casefold(match); // user entered search string
2275     char *s1 = linguistics_casefold(name); // string from mapfile
2276     char *s1_1 = linguistics_expand_special(s1, 1);
2277     char *s2_1 = linguistics_expand_special(s2, 1);
2278 zoff99 15
2279     if (s1_1)
2280     {
2281     if (s2_1)
2282     {
2283 zoff99 27 ret = linguistics_compare(s1_1, s2_1, partial);
2284 zoff99 15 }
2285     else
2286     {
2287 zoff99 27 ret = linguistics_compare(s1_1, s2, partial);
2288 zoff99 15 }
2289     }
2290     else
2291     {
2292     if (s2_1)
2293     {
2294 zoff99 27 ret = linguistics_compare(s1, s2_1, partial);
2295 zoff99 15 }
2296     else
2297     {
2298 zoff99 27 ret = linguistics_compare(s1, s2, partial);
2299 zoff99 15 }
2300     }
2301    
2302     if (s1_1)
2303     g_free(s1_1);
2304     if (s2_1)
2305     g_free(s2_1);
2306     if (s1)
2307     g_free(s1);
2308     if (s2)
2309     g_free(s2);
2310 zoff99 2 return ret;
2311     }
2312    
2313     struct duplicate
2314     {
2315     struct coord c;
2316     char str[0];
2317     };
2318    
2319 zoff99 27 static guint duplicate_hash(gconstpointer key)
2320 zoff99 2 {
2321 zoff99 27 const struct duplicate *d = key;
2322     return d->c.x ^ d->c.y ^ g_str_hash(d->str);
2323 zoff99 2 }
2324    
2325 zoff99 27 static gboolean duplicate_equal(gconstpointer a, gconstpointer b)
2326 zoff99 2 {
2327 zoff99 27 const struct duplicate *da = a;
2328     const struct duplicate *db = b;
2329 zoff99 40 return (da->c.x == db->c.x && da->c.y == db->c.y && g_str_equal(da->str, db->str));
2330 zoff99 2 }
2331    
2332 zoff99 40
2333 zoff99 27 static int duplicate(struct map_search_priv *msp, struct item *item, enum attr_type attr_type)
2334 zoff99 2 {
2335     struct attr attr;
2336 zoff99 40
2337 zoff99 2 if (!msp->search_results)
2338 zoff99 40 {
2339 zoff99 31 msp->search_results = g_hash_table_new_full(duplicate_hash, duplicate_equal, g_free_func, NULL);
2340 zoff99 40 }
2341    
2342 zoff99 2 binfile_attr_rewind(item->priv_data);
2343 zoff99 40
2344 zoff99 2 if (!item_attr_get(item, attr_type, &attr))
2345 zoff99 40 {
2346 zoff99 2 return 1;
2347 zoff99 40 }
2348    
2349 zoff99 2 {
2350 zoff99 27 int len = sizeof(struct coord) + strlen(attr.u.str) + 1;
2351     char *buffer = g_alloca(sizeof(char) * len);
2352     struct duplicate *d = (struct duplicate *) buffer;
2353     if (!item_coord_get(item, &d->c, 1))
2354     {
2355     d->c.x = 0;
2356     d->c.y = 0;
2357 zoff99 2 }
2358     binfile_coord_rewind(item->priv_data);
2359     strcpy(d->str, attr.u.str);
2360 zoff99 27 if (!g_hash_table_lookup(msp->search_results, d))
2361     {
2362     struct duplicate *dc = g_malloc(len);
2363 zoff99 2 memcpy(dc, d, len);
2364     g_hash_table_insert(msp->search_results, dc, GINT_TO_POINTER(1));
2365     binfile_attr_rewind(item->priv_data);
2366     return 0;
2367     }
2368     }
2369     return 2;
2370     }
2371    
2372     static struct item *
2373     binmap_search_get_item(struct map_search_priv *map_search)
2374     {
2375     struct item* it;
2376     struct attr at;
2377    
2378 zoff99 27 // // dbg(0,"Enter\n");
2379    
2380 zoff99 15 for (;;)
2381     {
2382 zoff99 27 while ((it = map_rect_get_item_binfile(map_search->mr)))
2383 zoff99 15 {
2384     switch (map_search->search->type)
2385     {
2386 zoff99 27 case attr_town_name:
2387     case attr_district_name:
2388     case attr_town_or_district_name:
2389 zoff99 15
2390     #if 0
2391 zoff99 27 if (map_search->mr->tile_depth > 1 && item_is_town(*it) && !item_is_district(*it) && map_search->search->type != attr_district_name)
2392     {
2393     if (binfile_attr_get(it->priv_data, attr_town_name_match, &at) || binfile_attr_get(it->priv_data, attr_town_name, &at))
2394     {
2395     if (!ascii_cmp(at.u.str, map_search->str, map_search->partial) && !duplicate(map_search, it, attr_town_name))
2396 zoff99 2 return it;
2397 zoff99 27 }
2398 zoff99 2 }
2399 zoff99 15 #endif
2400    
2401     #if 1
2402 zoff99 27 if (map_search->mr->tile_depth > 1 && item_is_town(*it) && !item_is_district(*it) && map_search->search->type != attr_district_name)
2403 zoff99 15 {
2404 zoff99 27 if (binfile_attr_get(it->priv_data, attr_town_name, &at))
2405 zoff99 15 {
2406 zoff99 27 //// dbg(0,"22town n:%s\n",at.u.str);
2407     if (!ascii_cmp(at.u.str, map_search->str, map_search->partial)
2408     // && !duplicate(map_search, it, attr_town_name)
2409 zoff99 15 )
2410 zoff99 27 {
2411     //// dbg(0,"town n:%s\n",at.u.str);
2412     return it;
2413     }
2414 zoff99 15 }
2415    
2416 zoff99 27 if (binfile_attr_get(it->priv_data, attr_town_name_match, &at))
2417 zoff99 15 {
2418 zoff99 27 //// dbg(0,"11town M:%s\n",at.u.str);
2419     if (!ascii_cmp(at.u.str, map_search->str, map_search->partial)
2420     // && !duplicate(map_search, it, attr_town_name)
2421     )
2422 zoff99 15 {
2423 zoff99 27 //// dbg(0,"town M:%s\n",at.u.str);
2424 zoff99 15 return it;
2425     }
2426 zoff99 2 }
2427     }
2428 zoff99 27 #endif
2429 zoff99 15
2430 zoff99 27 if (map_search->mr->tile_depth > 1 && item_is_district(*it) && map_search->search->type != attr_town_name)
2431 zoff99 15 {
2432 zoff99 27 if (binfile_attr_get(it->priv_data, attr_district_name_match, &at) || binfile_attr_get(it->priv_data, attr_district_name, &at))
2433 zoff99 15 {
2434 zoff99 27 if (!ascii_cmp(at.u.str, map_search->str, map_search->partial) && !duplicate(map_search, it, attr_town_name))
2435 zoff99 15 return it;
2436     }
2437     }
2438 zoff99 27 break;
2439 zoff99 15
2440 zoff99 27 case attr_street_name:
2441 zoff99 15
2442 zoff99 27 if (map_search->mode == 1)
2443 zoff99 15 {
2444 zoff99 27 //dbg(0,"*in here 00*\n");
2445 zoff99 15
2446 zoff99 27 //if (binfile_attr_get(it->priv_data, attr_street_name_match, &at) || binfile_attr_get(it->priv_data, attr_street_name, &at)) {
2447     // if (!ascii_cmp(at.u.str, map_search->str, map_search->partial) && !duplicate(map_search, it, attr_street_name)) {
2448     // return it;
2449     // }
2450     //}
2451 zoff99 15
2452 zoff99 27 if (binfile_attr_get(it->priv_data, attr_street_name, &at))
2453     {
2454     //// dbg(0,"str AA:%s\n", at.u.str);
2455 zoff99 15
2456 zoff99 27 if (!ascii_cmp(at.u.str, map_search->str, map_search->partial))
2457 zoff99 15 {
2458 zoff99 27 if ((offline_search_filter_duplicates != 1) || (!duplicate(map_search, it, attr_street_name)))
2459 zoff99 15 {
2460 zoff99 27 return it;
2461 zoff99 15 }
2462     else
2463     {
2464 zoff99 27 //// dbg(0,"dup street 1:%s\n",at.u.str);
2465 zoff99 15 }
2466 zoff99 27 }
2467     }
2468 zoff99 15
2469 zoff99 27 if (binfile_attr_get(it->priv_data, attr_street_name_match, &at))
2470     {
2471     //// dbg(0,"str BB:%s\n", at.u.str);
2472    
2473     if (!ascii_cmp(at.u.str, map_search->str, map_search->partial))
2474 zoff99 15 {
2475 zoff99 27 if ((offline_search_filter_duplicates != 1) || (!duplicate(map_search, it, attr_street_name_match)))
2476 zoff99 15 {
2477     return it;
2478     }
2479 zoff99 27 else
2480     {
2481     //// dbg(0,"dup street 2:%s\n",at.u.str);
2482     }
2483 zoff99 15 }
2484 zoff99 2 }
2485 zoff99 27
2486     continue;
2487 zoff99 2 }
2488 zoff99 27
2489     #if 1
2490     // ------------------------------------
2491     // map_search->mode == 2 or 3
2492     // ------------------------------------
2493     if (item_is_street(*it))
2494 zoff99 2 {
2495 zoff99 27 // dbg(0,"*in here 11*\n");
2496    
2497     struct attr at;
2498     if (map_selection_contains_item_rect(map_search->mr->sel, it))
2499 zoff99 2 {
2500 zoff99 27 if (binfile_attr_get(it->priv_data, attr_label, &at))
2501     {
2502     int match = 0;
2503     char *str = g_strdup(at.u.str);
2504     // dbg(0,"search=%s str is:%s\n",map_search->str, at.u.str);
2505     if (!ascii_cmp(str, map_search->str, map_search->partial))
2506     {
2507     match = 1;
2508     }
2509     g_free(str);
2510     if (match)
2511     {
2512     if ((offline_search_filter_duplicates != 1) || (!duplicate(map_search, it, attr_label)))
2513     {
2514     item_coord_rewind(it);
2515     return it;
2516     }
2517     }
2518     }
2519 zoff99 15
2520 zoff99 27 if (binfile_attr_get(it->priv_data, attr_street_name_match, &at))
2521 zoff99 2 {
2522 zoff99 27 int match = 0;
2523     char *str = g_strdup(at.u.str);
2524     // dbg(0,"search=%s mstr is:%s\n",map_search->str, at.u.str);
2525     if (!ascii_cmp(str, map_search->str, map_search->partial))
2526     {
2527     match = 1;
2528     }
2529     g_free(str);
2530     if (match)
2531     {
2532     if ((offline_search_filter_duplicates != 1) || (!duplicate(map_search, it, attr_street_name_match)))
2533     {
2534     item_coord_rewind(it);
2535     return it;
2536     }
2537     }
2538 zoff99 2 }
2539 zoff99 27 //else
2540     //{
2541     // if (binfile_attr_get(it->priv_data, attr_street_name, &at))
2542     // {
2543     // // dbg(0,"---str X*X:%s\n", at.u.str);
2544     // }
2545     //}
2546 zoff99 2 }
2547 zoff99 15 }
2548 zoff99 27 #endif
2549     break;
2550     case attr_house_number:
2551     //if (it->type == type_house_number)
2552     if ((it->type == type_house_number) || (type_house_number_interpolation_even) || (type_house_number_interpolation_odd) || (type_house_number_interpolation_all))
2553 zoff99 15 {
2554 zoff99 27 // is it a housenumber?
2555     if (binfile_attr_get(it->priv_data, attr_house_number, &at))
2556     {
2557     // match housenumber to our string
2558     if (!ascii_cmp(at.u.str, map_search->str, map_search->partial))
2559     {
2560     //binfile_attr_get(it->priv_data, attr_street_name, &at);
2561     //// dbg(0,"hnnn B1 street_name=%s",at.u.str);
2562    
2563     if (!duplicate(map_search, it, attr_house_number))
2564     {
2565     binfile_attr_rewind(it->priv_data);
2566     return it;
2567     }
2568     }
2569     }
2570     else
2571     {
2572     return it;
2573     }
2574 zoff99 15 }
2575 zoff99 27 continue;
2576     default:
2577     return NULL;
2578 zoff99 2 }
2579     }
2580 zoff99 27
2581 zoff99 2 if (!map_search->mr_item)
2582 zoff99 27 {
2583 zoff99 2 return NULL;
2584 zoff99 27 }
2585 zoff99 2 map_rect_destroy_binfile(map_search->mr);
2586     if (!binmap_search_by_index(map_search->map, map_search->item, &map_search->mr))
2587 zoff99 27 {
2588 zoff99 2 return NULL;
2589 zoff99 27 }
2590     } // endless for-loop
2591    
2592     return NULL; // this is never reached
2593 zoff99 2 }
2594    
2595 zoff99 27 static void binmap_search_destroy(struct map_search_priv *ms)
2596 zoff99 2 {
2597     if (ms->search_results)
2598     g_hash_table_destroy(ms->search_results);
2599     if (ms->mr_item)
2600     map_rect_destroy_binfile(ms->mr_item);
2601     if (ms->mr)
2602     map_rect_destroy_binfile(ms->mr);
2603     if (ms->str)
2604     g_free(ms->str);
2605     g_free(ms);
2606     }
2607    
2608 zoff99 27 static int binmap_get_attr(struct map_priv *m, enum attr_type type, struct attr *attr)
2609 zoff99 2 {
2610 zoff99 27 attr->type = type;
2611     switch (type)
2612     {
2613     case attr_map_release:
2614     if (m->map_release)
2615     {
2616     attr->u.str = m->map_release;
2617     return 1;
2618     }
2619     break;
2620     case attr_progress:
2621     if (m->progress)
2622     {
2623     attr->u.str = m->progress;
2624     return 1;
2625     }
2626     default:
2627     break;
2628 zoff99 2 }
2629     return 0;
2630     }
2631    
2632 zoff99 27 static int binmap_set_attr(struct map_priv *map, struct attr *attr)
2633 zoff99 2 {
2634 zoff99 27 switch (attr->type)
2635     {
2636     case attr_update:
2637     map->download_enabled = attr->u.num;
2638     return 1;
2639     default:
2640     return 0;
2641 zoff99 2 }
2642    
2643     }
2644    
2645 zoff99 27 static struct map_methods map_methods_binfile =
2646     { projection_mg, "utf-8", map_destroy_binfile, map_rect_new_binfile, map_rect_destroy_binfile, map_rect_get_item_binfile, map_rect_get_item_byid_binfile, binmap_search_new, binmap_search_destroy, binmap_search_get_item, NULL, binmap_get_attr, binmap_set_attr, };
2647 zoff99 2
2648 zoff99 27 static int binfile_get_index(struct map_priv *m)
2649 zoff99 2 {
2650 zoff99 27 //dbg(0,"_enter\n");
2651 zoff99 2 int len;
2652     int cde_index_size;
2653 zoff99 27 long long offset; // int or long long ?
2654 zoff99 2 struct zip_cd *cd;
2655    
2656     len = strlen("index");
2657 zoff99 27 cde_index_size = sizeof(struct zip_cd) + len;
2658     //dbg(0,"_cde_index_size=%d\n", cde_index_size);
2659     if (m->eoc64)
2660     {
2661     //dbg(0,"_m->eoc64->zip64ecsz=%d\n", m->eoc64->zip64ecsz);
2662     offset = m->eoc64->zip64ecsz - cde_index_size;
2663     //dbg(0,"_eoc64 offset="LONGLONG_FMT"\n", offset);
2664     }
2665 zoff99 2 else
2666 zoff99 27 {
2667     //dbg(0,"_m->eoc->zipecsz=%d\n", m->eoc->zipecsz);
2668     offset = m->eoc->zipecsz - cde_index_size;
2669     //dbg(0,"_eoc offset="LONGLONG_FMT"\n", offset);
2670     }
2671 zoff99 2 cd = binfile_read_cd(m, offset, len);
2672    
2673 zoff99 27 if (!cd)
2674     {
2675     //dbg(0,"_!cd\n");
2676     cde_index_size += sizeof(struct zip_cd_ext);
2677     //dbg(0,"_cde_index_size=%d\n", cde_index_size);
2678 zoff99 2 if (m->eoc64)
2679 zoff99 27 {
2680     offset = m->eoc64->zip64ecsz - cde_index_size;
2681     //dbg(0,"_eoc64 offset aa.1="LONGLONG_FMT"\n", offset);
2682     }
2683 zoff99 2 else
2684 zoff99 27 {
2685     offset = m->eoc->zipecsz - cde_index_size;
2686     //dbg(0,"_offset 22.0="LONGLONG_FMT"\n", offset);
2687     }
2688     cd = binfile_read_cd(m, offset, len + sizeof(struct zip_cd_ext));
2689 zoff99 2 }
2690 zoff99 27 //dbg(0,"_offset 22="LONGLONG_FMT"\n", offset);
2691    
2692     if (cd)
2693     {
2694     //dbg(0,"_cd 001\n");
2695     if (cd->zipcfnl == len && !strncmp(cd->zipcfn, "index", len))
2696     {
2697     m->index_offset = offset;
2698     m->index_cd = cd;
2699     //dbg(0,"_leave:offset 33="LONGLONG_FMT"\n", offset);
2700 zoff99 2 return 1;
2701     }
2702 zoff99 27 //dbg(0,"_cd 002\n");
2703 zoff99 2 }
2704 zoff99 27
2705     offset = binfile_search_cd(m, 0, "index", 0, 0);
2706     //dbg(0,"_offset 44="LONGLONG_FMT"\n", offset);
2707    
2708 zoff99 2 if (offset == -1)
2709 zoff99 27 {
2710     //dbg(0,"_leave:55\n");
2711 zoff99 2 return 0;
2712 zoff99 27 }
2713    
2714     cd = binfile_read_cd(m, offset, -1);
2715    
2716 zoff99 2 if (!cd)
2717 zoff99 27 {
2718     //dbg(0,"_leave:66\n");
2719 zoff99 2 return 0;
2720 zoff99 27 }
2721    
2722     m->index_offset = offset;
2723     m->index_cd = cd;
2724    
2725     //dbg(0,"_leave:normal:offset 77="LONGLONG_FMT"\n", offset);
2726 zoff99 2 return 1;
2727     }
2728    
2729 zoff99 27 static int map_binfile_zip_setup(struct map_priv *m, char *filename, int mmap)
2730 zoff99 2 {
2731 zoff99 27 //dbg(0,"_enter\n");
2732    
2733 zoff99 2 struct zip_cd *first_cd;
2734     int i;
2735 zoff99 27 if (!(m->eoc = binfile_read_eoc(m->fi)))
2736     {
2737     //dbg(0,"_leave:1\n");
2738 zoff99 2 return 0;
2739 zoff99 27 }
2740 zoff99 2 dbg_assert(m->eoc->zipedsk == m->eoc->zipecen);
2741 zoff99 27 if (m->eoc->zipedsk && strlen(filename) > 3)
2742     {
2743     char *tmpfilename = g_strdup(filename);
2744     char *ext = tmpfilename + strlen(tmpfilename) - 3;
2745    
2746     //dbg(0,"_ff-1:%s\n", tmpfilename);
2747     //dbg(0,"_ff-2:%s\n", ext);
2748    
2749 zoff99 2 m->fis=g_new(struct file *,m->eoc->zipedsk);
2750 zoff99 27 for (i = 0; i < m->eoc->zipedsk - 1; i++)
2751     {
2752     sprintf(ext, "b%02d", i + 1);
2753     //dbg(0,"_ff--3:%s\n", ext);
2754     m->fis[i] = file_create(tmpfilename, 0);
2755 zoff99 2 if (mmap)
2756 zoff99 27 {
2757     //dbg(0,"_want mmap 2 %s\n", m->fis[i]->name);
2758 zoff99 2 file_mmap(m->fis[i]);
2759 zoff99 27 }
2760 zoff99 2 }
2761 zoff99 27 m->fis[m->eoc->zipedsk - 1] = m->fi;
2762 zoff99 2 g_free(tmpfilename);
2763     }
2764 zoff99 27 else
2765     {
2766     //dbg(0,"_ff-XX\n");
2767     }
2768     //dbg(0, "_num_disk %d\n", m->eoc->zipedsk);
2769     m->eoc64 = binfile_read_eoc64(m->fi);
2770    
2771 zoff99 2 if (!binfile_get_index(m))
2772 zoff99 27 {
2773     //dbg(0,"_leave:2\n");
2774 zoff99 2 return 0;
2775 zoff99 27 }
2776    
2777     if (!(first_cd = binfile_read_cd(m, 0, 0)))
2778     {
2779     //dbg(0,"_leave:3\n");
2780 zoff99 2 return 0;
2781 zoff99 27 }
2782    
2783     m->cde_size = sizeof(struct zip_cd) + first_cd->zipcfnl + first_cd->zipcxtl;
2784     m->zip_members = m->index_offset / m->cde_size + 1;
2785     //dbg(0, "_cde_size %d\n", m->cde_size);
2786     //dbg(0, "_members %d\n", m->zip_members);
2787     file_data_free(m->fi, (unsigned char *) first_cd);
2788 zoff99 2 if (mmap)
2789 zoff99 27 {
2790     //dbg(0,"_want mmap 3 %s\n", m->fi->name);
2791 zoff99 2 file_mmap(m->fi);
2792 zoff99 27 }
2793 zoff99 2 return 1;
2794     }
2795    
2796     #if 0
2797     static int
2798     map_binfile_download_initial(struct map_priv *m)
2799     {
2800 zoff99 27 struct attr readwrite=
2801     { attr_readwrite,
2802     { (void *)1}};
2803     struct attr create=
2804     { attr_create,
2805     { (void *)1}};
2806 zoff99 2 struct attr *attrs[4];
2807     struct file *out;
2808     long long woffset=0,planet_size;
2809     int size_ret;
2810     int cd1size,cdisize;
2811     long long cd1offset,cdioffset;
2812     struct zip64_eoc *zip64_eoc;
2813     struct zip64_eocl *zip64_eocl;
2814     struct zip_eoc *zip_eoc;
2815     struct zip_cd *cd1,*cdn,*cdi;
2816     int count,chunk,cdoffset=0;
2817     int mode=1;
2818     struct map_download *download=g_new0(struct map_download, 1);
2819    
2820     attrs[0]=&readwrite;
2821     attrs[1]=&create;
2822     attrs[2]=NULL;
2823     download->file=file_create(m->filename,attrs);
2824     download->m=m;
2825     download_planet_size(download);
2826     download_eoc(download);
2827     download_directory_start(download);
2828     while (download_directory_do(download));
2829     download_directory_finish(download);
2830     download_initial_finish(download);
2831     m->fi=download->file;
2832     g_free(download);
2833     return 1;
2834    
2835 zoff99 27 cd1size=sizeof(*cd1);
2836     cd1offset=zip64_eoc->zip64eofst;
2837     cd1=(struct zip_cd *)map_binfile_download_range(m, cd1offset, cd1size);
2838     if (!cd1)
2839     return 0;
2840     cd1size=sizeof(*cd1)+binfile_cd_extra(cd1);
2841     g_free(cd1);
2842     cd1=(struct zip_cd *)map_binfile_download_range(m, cd1offset, cd1size);
2843     if (!cd1)
2844     return 0;
2845     cd1->zipcunc=0;
2846     cdisize=sizeof(*cdi)+strlen("index")+cd1->zipcxtl;
2847     cdioffset=zip64_eoc->zip64eofst+zip64_eoc->zip64ecsz-cdisize;
2848     cdi=(struct zip_cd *)map_binfile_download_range(m, cdioffset, cdisize);
2849     if (!cdi)
2850     {
2851 zoff99 2 g_free(cd1);
2852 zoff99 27 return 0;
2853     }
2854     cdi->zipcunc=0;
2855     cdn=g_malloc0(cd1size*256);
2856 zoff99 2
2857 zoff99 27 file_data_write(out, woffset, sizeof(*zip64_eoc), (unsigned char *)zip64_eoc);
2858     woffset+=sizeof(*zip64_eoc);
2859     cdoffset=woffset;
2860 zoff99 2
2861 zoff99 27 file_data_write(out, woffset, cd1size, (unsigned char *)cd1);
2862     woffset+=cd1size;
2863     count=(cdioffset-cd1offset)/cd1size-1;
2864     while (count > 0)
2865     {
2866     if (count > 256)
2867     chunk=256;
2868     else
2869     chunk=count;
2870     file_data_write(out, woffset, cd1size*chunk, (unsigned char *)cdn);
2871     woffset+=cd1size*chunk;
2872     count-=chunk;
2873     }
2874     g_free(cdn);
2875     g_free(cd1);
2876     file_data_write(out, woffset, cdisize, (unsigned char *)cdi);
2877     woffset+=cdisize;
2878 zoff99 2
2879     }
2880     #endif
2881    
2882 zoff99 34
2883     static int string_endswith(const char* ending, const char* instring)
2884     {
2885     int l1;
2886     int l2;
2887    
2888     if (!ending)
2889     {
2890     return 0;
2891     }
2892    
2893     if (!instring)
2894     {
2895     return 0;
2896     }
2897    
2898     l1 = strlen(ending);
2899     l2 = strlen(instring);
2900    
2901     if (l1 < 1)
2902     {
2903     return 0;
2904     }
2905    
2906     if (l1 > l2)
2907     {
2908     return 0;
2909     }
2910    
2911     int ret = strcmp(ending, instring + (l2 - l1));
2912     //dbg(0, "ending=%s in=%s ret=%d\n", ending, instring + (l2 - l1), (ret == 0));
2913     return (ret == 0);
2914     }
2915    
2916    
2917 zoff99 27 static int map_binfile_open(struct map_priv *m)
2918 zoff99 2 {
2919     int *magic;
2920 zoff99 34 int version_exception = 0;
2921 zoff99 2 struct map_rect_priv *mr;
2922     struct item *item;
2923     struct attr attr;
2924 zoff99 34
2925 zoff99 27 struct attr readwrite =
2926     { attr_readwrite,
2927     { (void *) 1 } };
2928 zoff99 34
2929 zoff99 27 struct attr *attrs[] =
2930     { &readwrite, NULL };
2931 zoff99 2
2932 zoff99 27 // dbg(0, "file_create %s\n", m->filename);
2933     m->fi = file_create(m->filename, m->url ? attrs : NULL);
2934     if (!m->fi && m->url)
2935     {
2936 zoff99 2 return 0;
2937 zoff99 27 }
2938 zoff99 34
2939 zoff99 27 if (!m->fi)
2940     {
2941     // dbg(0, "Failed to load '%s'\n", m->filename);
2942 zoff99 2 return 0;
2943     }
2944 zoff99 34
2945 zoff99 2 if (m->check_version)
2946 zoff99 27 {
2947     m->version = file_version(m->fi, m->check_version);
2948     }
2949    
2950     magic = (int *) file_data_read(m->fi, 0, 4);
2951     if (!magic)
2952     {
2953 zoff99 2 file_destroy(m->fi);
2954 zoff99 27 m->fi = NULL;
2955 zoff99 2 return 0;
2956     }
2957 zoff99 27
2958     //dbg(0,"_zip_lfh_sig=%d\n", zip_lfh_sig);
2959    
2960     //dbg(0,"_magic1=%d\n", magic[0]);
2961     //dbg(0,"_magic1=%d\n", magic[1]);
2962     //dbg(0,"_magic1=%d\n", magic[2]);
2963     //dbg(0,"_magic1=%d\n", magic[3]);
2964 zoff99 2 *magic = le32_to_cpu(*magic);
2965 zoff99 27 //dbg(0,"_magic2=%d\n", magic[0]);
2966     //dbg(0,"_magic2=%d\n", magic[1]);
2967     //dbg(0,"_magic2=%d\n", magic[2]);
2968     //dbg(0,"_magic2=%d\n", magic[3]);
2969     if (*magic == zip_lfh_sig || *magic == zip_split_sig || *magic == zip_cd_sig || *magic == zip64_eoc_sig)
2970     {
2971     if (!map_binfile_zip_setup(m, m->filename, m->flags & 1))
2972     {
2973     dbg(0, "invalid file format for '%s'\n", m->filename);
2974 zoff99 2 file_destroy(m->fi);
2975 zoff99 27 m->fi = NULL;
2976 zoff99 2 return 0;
2977     }
2978 zoff99 27 }
2979     else
2980     {
2981     //dbg(0,"_want mmap %s\n", m->fi->name);
2982 zoff99 2 file_mmap(m->fi);
2983 zoff99 27 }
2984    
2985     //dbg(0,"_cont\n");
2986    
2987     file_data_free(m->fi, (unsigned char *) magic);
2988     m->cachedir = g_strdup("/tmp/navit");
2989     m->map_version = 0;
2990    
2991     mr = map_rect_new_binfile(m, NULL);
2992     if (mr)
2993     {
2994     while ((item = map_rect_get_item_binfile(mr)) == &busy_item)
2995     {
2996     ;
2997     }
2998 zoff99 30
2999 zoff99 27 if (item && item->type == type_map_information)
3000     {
3001 zoff99 2 if (binfile_attr_get(item->priv_data, attr_version, &attr))
3002 zoff99 27 {
3003     m->map_version = attr.u.num;
3004 zoff99 34 dbg(0, "map version=%d\n", m->map_version);
3005 zoff99 27 }
3006 zoff99 34
3007 zoff99 2 if (binfile_attr_get(item->priv_data, attr_map_release, &attr))
3008 zoff99 27 {
3009     m->map_release = g_strdup(attr.u.str);
3010 zoff99 34 dbg(0, "maptool version used=%s\n", m->map_release);
3011 zoff99 27 }
3012 zoff99 34
3013     if (string_endswith("borders.bin", m->filename) == 1)
3014 zoff99 27 {
3015 zoff99 34 dbg(0, "map exception added!\n");
3016     version_exception = 1;
3017 zoff99 2 }
3018 zoff99 34
3019     if (string_endswith("coastline.bin", m->filename) == 1)
3020     {
3021     dbg(0, "map exception added!\n");
3022     version_exception = 1;
3023     }
3024    
3025     //if (m->url && binfile_attr_get(item->priv_data, attr_url, &attr))
3026     //{
3027     // dbg(0, "url config %s map %s\n", m->url, attr.u.str);
3028     // if (strcmp(m->url, attr.u.str))
3029     // {
3030     // m->update_available = 1;
3031     // }
3032     // g_free(m->url);
3033     // m->url = g_strdup(attr.u.str);
3034     //}
3035 zoff99 2 }
3036 zoff99 30
3037 zoff99 2 map_rect_destroy_binfile(mr);
3038 zoff99 30
3039 zoff99 34 if (version_exception == 0)
3040 zoff99 27 {
3041 zoff99 34 if (m->map_version < (int)NEED_MIN_BINFILE_MAPVERSION)
3042     {
3043     dbg(0, "!!**Warning**!!: This map is too old for your version of ZANavi. You need at least a version %d map\n", (int)NEED_MIN_BINFILE_MAPVERSION);
3044 zoff99 41
3045     #ifdef HAVE_API_ANDROID
3046     gchar* xy=g_strdup_printf("%d:%d:%s\n", (int)m->map_version, (int)NEED_MIN_BINFILE_MAPVERSION, m->filename);
3047     android_send_generic_text(31,xy);
3048     g_free(xy);
3049     #endif
3050 zoff99 34 return 0;
3051     }
3052 zoff99 2 }
3053     }
3054     return 1;
3055     }
3056    
3057 zoff99 27 static void map_binfile_close(struct map_priv *m)
3058 zoff99 2 {
3059     int i;
3060 zoff99 27 file_data_free(m->fi, (unsigned char *) m->index_cd);
3061     file_data_free(m->fi, (unsigned char *) m->eoc);
3062     file_data_free(m->fi, (unsigned char *) m->eoc64);
3063 zoff99 2 g_free(m->cachedir);
3064     g_free(m->map_release);
3065 zoff99 34
3066 zoff99 27 if (m->fis)
3067     {
3068     for (i = 0; i < m->eoc->zipedsk; i++)
3069     {
3070 zoff99 2 file_destroy(m->fis[i]);
3071     }
3072 zoff99 27 }
3073     else
3074 zoff99 34 {
3075 zoff99 2 file_destroy(m->fi);
3076 zoff99 34 }
3077 zoff99 2 }
3078    
3079 zoff99 27 static void map_binfile_destroy(struct map_priv *m)
3080 zoff99 2 {
3081     g_free(m->filename);
3082     g_free(m->url);
3083     g_free(m->progress);
3084     g_free(m);
3085     }
3086    
3087 zoff99 27 static void binfile_check_version(struct map_priv *m)
3088 zoff99 2 {
3089 zoff99 27 int version = -1;
3090 zoff99 41
3091 zoff99 2 if (!m->check_version)
3092 zoff99 41 {
3093 zoff99 2 return;
3094 zoff99 41 }
3095    
3096 zoff99 27 if (m->fi)
3097 zoff99 41 {
3098 zoff99 27 version = file_version(m->fi, m->check_version);
3099 zoff99 41 }
3100    
3101 zoff99 27 if (version != m->version)
3102     {
3103 zoff99 2 if (m->fi)
3104 zoff99 41 {
3105 zoff99 2 map_binfile_close(m);
3106 zoff99 41 }
3107 zoff99 2 map_binfile_open(m);
3108     }
3109     }
3110    
3111 zoff99 40 struct map_priv *
3112 zoff99 2 map_new_binfile(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl)
3113     {
3114     struct map_priv *m;
3115 zoff99 27 struct attr *data = attr_search(attrs, NULL, attr_data);
3116     struct attr *check_version, *map_pass, *flags, *url, *download_enabled;
3117 zoff99 2 struct file_wordexp *wexp;
3118     char **wexp_data;
3119 zoff99 41
3120 zoff99 27 if (!data)
3121 zoff99 41 {
3122 zoff99 2 return NULL;
3123 zoff99 41 }
3124 zoff99 2
3125 zoff99 31 // wexp = file_wordexp_new(data->u.str);
3126     // wexp_data = file_wordexp_get_array(wexp);
3127 zoff99 27 // dbg(0, "map_new_binfile %s\n", data->u.str);
3128     *meth = map_methods_binfile;
3129 zoff99 2
3130     m=g_new0(struct map_priv, 1);
3131 zoff99 27 m->cbl = cbl;
3132     m->id = ++map_id;
3133 zoff99 31 m->filename = g_strdup(data->u.str);
3134     // file_wordexp_destroy(wexp);
3135 zoff99 27 check_version = attr_search(attrs, NULL, attr_check_version);
3136 zoff99 34
3137 zoff99 27 if (check_version)
3138 zoff99 41 {
3139 zoff99 27 m->check_version = check_version->u.num;
3140 zoff99 41 }
3141 zoff99 34
3142 zoff99 27 map_pass = attr_search(attrs, NULL, attr_map_pass);
3143 zoff99 34
3144 zoff99 2 if (map_pass)
3145 zoff99 41 {
3146 zoff99 27 m->passwd = g_strdup(map_pass->u.str);
3147 zoff99 41 }
3148 zoff99 34
3149 zoff99 27 flags = attr_search(attrs, NULL, attr_flags);
3150 zoff99 34
3151 zoff99 2 if (flags)
3152 zoff99 41 {
3153 zoff99 27 m->flags = flags->u.num;
3154 zoff99 41 }
3155 zoff99 34
3156 zoff99 27 url = attr_search(attrs, NULL, attr_url);
3157 zoff99 34
3158 zoff99 2 if (url)
3159 zoff99 41 {
3160 zoff99 27 m->url = g_strdup(url->u.str);
3161 zoff99 41 }
3162 zoff99 34
3163 zoff99 2 download_enabled = attr_search(attrs, NULL, attr_update);
3164 zoff99 34
3165 zoff99 2 if (download_enabled)
3166 zoff99 41 {
3167 zoff99 27 m->download_enabled = download_enabled->u.num;
3168 zoff99 41 }
3169 zoff99 2
3170 zoff99 27 if (!map_binfile_open(m) && !m->check_version && !m->url)
3171     {
3172 zoff99 2 map_binfile_destroy(m);
3173 zoff99 27 m = NULL;
3174     }
3175     else
3176     {
3177 zoff99 2 load_changes(m);
3178     }
3179     return m;
3180     }
3181    
3182 zoff99 40 #ifdef PLUGSSS
3183 zoff99 27 void plugin_init(void)
3184 zoff99 2 {
3185 zoff99 27 // dbg(1, "binfile: plugin_init\n");
3186     if (sizeof(struct zip_cd) != 46)
3187     {
3188     // dbg(0, "error: sizeof(struct zip_cd)=%d\n", sizeof(struct zip_cd));
3189 zoff99 2 }
3190     plugin_register_map_type("binfile", map_new_binfile);
3191     }
3192 zoff99 40 #endif
3193 zoff99 2

   
Visit the ZANavi Wiki