diff --git a/navit/map/binfile/binfile.c b/navit/map/binfile/binfile.c index ab65dcaf50..fbc018a5ac 100644 --- a/navit/map/binfile/binfile.c +++ b/navit/map/binfile/binfile.c @@ -85,19 +85,6 @@ struct tile { }; -struct map_download { - int state; - struct map_priv *m; - struct map_rect_priv *mr; - struct file *http,*file; - int zipfile,toffset,tlength,progress,read,dl_size; - long long offset,start_offset,cd1offset,size; - struct zip64_eoc *zip64_eoc; - struct zip64_eocl *zip64_eocl; - struct zip_eoc *zip_eoc; - struct zip_cd *cd_copy,*cd; -}; - /** * @brief Represents the map from a single binfile. * @@ -106,7 +93,7 @@ struct map_priv { int id; char *filename; //!< Filename of the binfile. char *cachedir; - struct file *fi,*http; + struct file *fi; struct file **fis; struct zip_cd *index_cd; int index_offset; @@ -118,18 +105,8 @@ struct map_priv { int search_offset; int search_size; int version; - int check_version; - int map_version; - GHashTable *changes; - char *map_release; int flags; - char *url; - int update_available; - char *progress; struct callback_list *cbl; - struct map_download *download; - int redirect; - long download_enabled; int last_searched_town_id_hi; int last_searched_town_id_lo; }; @@ -231,8 +208,6 @@ static void eoc_to_cpu(struct zip_eoc *eoc) { } } -static void binfile_check_version(struct map_priv *m); - static struct zip_eoc *binfile_read_eoc(struct file *fi) { struct zip_eoc *eoc; eoc=(struct zip_eoc *)file_data_read(fi,fi->size-sizeof(struct zip_eoc), sizeof(struct zip_eoc)); @@ -476,51 +451,6 @@ static void binfile_attr_rewind(void *priv_data) { } -static char *binfile_extract(struct map_priv *m, char *dir, char *filename, int partial) { - char *full,*fulld,*sep; - unsigned char *start; - int len,offset=m->index_offset; - struct zip_cd *cd; - struct zip_lfh *lfh; - FILE *f; - - for (;;) { - offset=binfile_search_cd(m, offset, filename, partial, 1); - if (offset == -1) - break; - cd=binfile_read_cd(m, offset, -1); - len=strlen(dir)+1+cd->zipcfnl+1; - full=g_malloc(len); - strcpy(full,dir); - strcpy(full+strlen(full),"/"); - strncpy(full+strlen(full),cd->zipcfn,cd->zipcfnl); - full[len-1]='\0'; - fulld=g_strdup(full); - sep=strrchr(fulld, '/'); - if (sep) { - *sep='\0'; - file_mkdir(fulld, 1); - } - if (full[len-2] != '/') { - lfh=binfile_read_lfh(m->fi, binfile_cd_offset(cd)); - start=binfile_read_content(m, m->fi, binfile_cd_offset(cd), lfh); - dbg(lvl_debug,"fopen '%s'", full); - f=fopen(full,"w"); - fwrite(start, lfh->zipuncmp, 1, f); - fclose(f); - file_data_free(m->fi, start); - file_data_free(m->fi, (unsigned char *)lfh); - } - file_data_free(m->fi, (unsigned char *)cd); - g_free(fulld); - g_free(full); - if (! partial) - break; - } - - return g_strdup_printf("%s/%s",dir,filename); -} - static int binfile_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { struct map_rect_priv *mr=priv_data; struct tile *t=mr->t; @@ -570,12 +500,7 @@ static int binfile_attr_get(void *priv_data, enum attr_type attr_type, struct at attr->u.attrs=mr->attrs; } else { attr_data_set_le(attr, t->pos_attr+1); - if (type == attr_url_local) { - g_free(mr->url); - mr->url=binfile_extract(mr->m, mr->m->cachedir, attr->u.str, 1); - attr->u.str=mr->url; - } - if (type == attr_flags && mr->m->map_version < 1) + if (type == attr_flags) attr->u.num |= AF_CAR; } t->pos_attr+=size; @@ -597,21 +522,13 @@ static int binfile_attr_get(void *priv_data, enum attr_type attr_type, struct at return 0; } + struct binfile_hash_entry { struct item_id id; int flags; int data[0]; }; -static guint binfile_hash_entry_hash(gconstpointer key) { - const struct binfile_hash_entry *entry=key; - return (entry->id.id_hi ^ entry->id.id_lo); -} - -static gboolean binfile_hash_entry_equal(gconstpointer a, gconstpointer b) { - const struct binfile_hash_entry *entry1=a,*entry2=b; - return (entry1->id.id_hi==entry2->id.id_hi && entry1->id.id_lo == entry2->id.id_lo); -} static int *binfile_item_dup(struct map_priv *m, struct item *item, struct tile *t, int extend) { int size=le32_to_cpu(t->pos[0]); @@ -623,9 +540,6 @@ static int *binfile_item_dup(struct map_priv *m, struct item *item, struct tile dbg(lvl_debug,"id 0x%x,0x%x",entry->id.id_hi,entry->id.id_lo); memcpy(ret, t->pos, (size+1)*sizeof(int)); - if (!m->changes) - m->changes=g_hash_table_new_full(binfile_hash_entry_hash, binfile_hash_entry_equal, g_free, NULL); - g_hash_table_replace(m->changes, entry, entry); dbg(lvl_debug,"ret %p",ret); return ret; } @@ -894,318 +808,6 @@ static int zipfile_to_tile(struct map_priv *m, struct zip_cd *cd, struct tile *t } -static int map_binfile_handle_redirect(struct map_priv *m) { - char *location=file_http_header(m->http, "location"); - if (!location) { - m->redirect=0; - return 0; - } - if (m->redirect) - return 0; - m->redirect=1; - dbg(lvl_debug,"redirected from %s to %s",m->url,location); - g_free(m->url); - m->url=g_strdup(location); - file_destroy(m->http); - m->http=NULL; - - return 1; -} - -static int map_binfile_http_request(struct map_priv *m, struct attr **attrs) { - if (!m->http) { - m->http=file_create(NULL, attrs); - } else { - file_request(m->http, attrs); - } - return 1; -} - - -static long long map_binfile_download_size(struct map_priv *m) { - struct attr url= {attr_url}; - struct attr http_method= {attr_http_method}; - struct attr persistent= {attr_persistent}; - struct attr *attrs[4]; - int size_ret; - long long ret; - void *data; - - do { - attrs[0]=&url; - url.u.str=m->url; - attrs[1]=&http_method; - http_method.u.str="HEAD"; - persistent.u.num=1; - attrs[2]=&persistent; - attrs[3]=NULL; - - map_binfile_http_request(m, attrs); - data=file_data_read_special(m->http, 0, &size_ret); - g_free(data); - if (size_ret < 0) - return 0; - } while (map_binfile_handle_redirect(m)); - - ret=file_size(m->http); - dbg(lvl_debug,"file size "LONGLONG_FMT"",ret); - return ret; -} - - -static int map_binfile_http_close(struct map_priv *m) { - if (m->http) { - file_destroy(m->http); - m->http=NULL; - } - return 1; -} - - -static struct file *map_binfile_http_range(struct map_priv *m, long long offset, int size) { - struct attr *attrs[4]; - struct attr url= {attr_url}; - struct attr http_header= {attr_http_header}; - struct attr persistent= {attr_persistent}; - - persistent.u.num=1; - attrs[0]=&url; - attrs[1]=&http_header; - attrs[2]=&persistent; - attrs[3]=NULL; - - url.u.str=m->url; - http_header.u.str=g_strdup_printf("Range: bytes="LONGLONG_FMT"-"LONGLONG_FMT,offset, offset+size-1); - map_binfile_http_request(m, attrs); - g_free(http_header.u.str); - return m->http; -} - -static unsigned char *map_binfile_download_range(struct map_priv *m, long long offset, int size) { - unsigned char *ret; - int size_ret; - struct file *http=map_binfile_http_range(m, offset, size); - - ret=file_data_read_special(http, size, &size_ret); - if (size_ret != size) { - dbg(lvl_debug,"size %d vs %d",size,size_ret); - g_free(ret); - return NULL; - } - return ret; -} - -static struct zip_cd *download_cd(struct map_download *download) { - struct map_priv *m=download->m; - struct zip64_eoc *zip64_eoc=(struct zip64_eoc *)file_data_read(m->fi, 0, sizeof(*zip64_eoc)); - struct zip_cd *cd=(struct zip_cd *)map_binfile_download_range(m, zip64_eoc->zip64eofst+download->zipfile*m->cde_size, - m->cde_size); - file_data_free(m->fi, (unsigned char *)zip64_eoc); - dbg(lvl_debug,"needed cd, result %p",cd); - return cd; -} - -static int download_request(struct map_download *download) { - struct attr url= {attr_url}; - struct attr http_header= {attr_http_header}; - struct attr persistent= {attr_persistent}; - struct attr *attrs[4]; - - if(!download->m->download_enabled) { - dbg(lvl_error,"Tried downloading while it's not allowed"); - return 0; - } - attrs[0]=&url; - persistent.u.num=1; - attrs[1]=&persistent; - attrs[2]=NULL; - if (strchr(download->m->url,'?')) { - url.u.str=g_strdup_printf("%smemberid=%d",download->m->url,download->zipfile); - download->dl_size=-1; - } else { - long long offset=binfile_cd_offset(download->cd_copy); - int size=download->cd_copy->zipcsiz+sizeof(struct zip_lfh)+download->cd_copy->zipcfnl; - url.u.str=g_strdup(download->m->url); - http_header.u.str=g_strdup_printf("Range: bytes="LONGLONG_FMT"-"LONGLONG_FMT,offset,offset+size-1); - attrs[2]=&http_header; - attrs[3]=NULL; - download->dl_size=size; - } - dbg(lvl_debug,"encountered missing tile %d %s(%s), Downloading %d bytes at "LONGLONG_FMT"",download->zipfile, url.u.str, - (char *)(download->cd_copy+1), download->dl_size, download->offset); - map_binfile_http_request(download->m, attrs); - g_free(url.u.str); - download->http=download->m->http; - return 1; -} - - -static int download_start(struct map_download *download) { - long long offset; - struct zip_eoc *eoc; - - if (!download->cd->zipcensig) { - download->cd_copy=download_cd(download); - } else { - download->cd_copy=g_malloc(download->m->cde_size); - memcpy(download->cd_copy, download->cd, download->m->cde_size); - } - file_data_remove(download->file, (unsigned char *)download->cd); - download->cd=NULL; - offset=file_size(download->file); - offset-=sizeof(struct zip_eoc); - eoc=(struct zip_eoc *)file_data_read(download->file, offset, sizeof(struct zip_eoc)); - download->zip_eoc=g_malloc(sizeof(struct zip_eoc)); - memcpy(download->zip_eoc, eoc, sizeof(struct zip_eoc)); - file_data_remove(download->file, (unsigned char *)eoc); - download->start_offset=download->offset=offset; - return download_request(download); -} - -static int download_download(struct map_download *download) { - int size=64*1024,size_ret; - unsigned char *data; - if (download->dl_size != -1 && size > download->dl_size) - size=download->dl_size; - if (!size) - return 1; - data=file_data_read_special(download->http, size, &size_ret); - if (!download->read && download->m->http && map_binfile_handle_redirect(download->m)) { - g_free(data); - download_request(download); - return 0; - } - - dbg(lvl_debug,"got %d bytes writing at offset "LONGLONG_FMT"",size_ret,download->offset); - if (size_ret <= 0) { - g_free(data); - return 1; - } - file_data_write(download->file, download->offset, size_ret, data); - download->offset+=size_ret; - download->read+=size_ret; - download->dl_size-=size_ret; - if (download->dl_size != -1) - download->progress=download->read*100/(download->read+download->dl_size); - return 0; -} - -static int download_finish(struct map_download *download) { - struct zip_lfh *lfh; - char *lfh_filename; - struct zip_cd_ext *ext; - long long lfh_offset; - file_data_write(download->file, download->offset, sizeof(struct zip_eoc), (void *)download->zip_eoc); - lfh=(struct zip_lfh *)(file_data_read(download->file,download->start_offset, sizeof(struct zip_lfh))); - ext=binfile_cd_ext(download->cd_copy); - if (ext) - ext->zipofst=download->start_offset; - else - download->cd_copy->zipofst=download->start_offset; - download->cd_copy->zipcsiz=lfh->zipsize; - download->cd_copy->zipcunc=lfh->zipuncmp; - download->cd_copy->zipccrc=lfh->zipcrc; - lfh_offset = binfile_cd_offset(download->cd_copy)+sizeof(struct zip_lfh); - lfh_filename=(char *)file_data_read(download->file,lfh_offset,lfh->zipfnln); - memcpy(download->cd_copy+1,lfh_filename,lfh->zipfnln); - file_data_remove(download->file,(void *)lfh_filename); - file_data_remove(download->file,(void *)lfh); - 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); - file_data_flush(download->file, download->m->eoc->zipeofst + download->zipfile*download->m->cde_size, - sizeof(struct zip_cd)); - - g_free(download->cd_copy); - download->cd=(struct zip_cd *)(file_data_read(download->file, - download->m->eoc->zipeofst + download->zipfile*download->m->cde_size, download->m->cde_size)); - cd_to_cpu(download->cd); - dbg(lvl_debug,"Offset %d",download->cd->zipofst); - return 1; -} - -static int download_planet_size(struct map_download *download) { - download->size=map_binfile_download_size(download->m); - dbg(lvl_debug,"Planet size "LONGLONG_FMT"",download->size); - if (!download->size) - return 0; - return 1; -} - -static int download_eoc(struct map_download *download) { - download->zip64_eoc=(struct zip64_eoc *)map_binfile_download_range(download->m, download->size-98, 98); - if (!download->zip64_eoc) - return 0; - download->zip64_eocl=(struct zip64_eocl *)(download->zip64_eoc+1); - download->zip_eoc=(struct zip_eoc *)(download->zip64_eocl+1); - if (download->zip64_eoc->zip64esig != zip64_eoc_sig || download->zip64_eocl->zip64lsig != zip64_eocl_sig - || download->zip_eoc->zipesig != zip_eoc_sig) { - dbg(lvl_error,"wrong signature on zip64_eoc downloaded from "LONGLONG_FMT"",download->size-98); - g_free(download->zip64_eoc); - return 0; - } - return 1; -} - -static int download_directory_start(struct map_download *download) { - download->http=map_binfile_http_range(download->m, download->zip64_eoc->zip64eofst, download->zip64_eoc->zip64ecsz); - if (!download->http) - return 0; - return 1; -} - -static int download_directory_do(struct map_download *download) { - int count; - - for (count = 0 ; count < 100 ; count++) { - int cd_xlen, size_ret; - unsigned char *cd_data; - struct zip_cd *cd; - cd=(struct zip_cd *)file_data_read_special(download->http, sizeof(*cd), &size_ret); - cd->zipcunc=0; - dbg(lvl_debug,"size_ret=%d",size_ret); - if (!size_ret) - return 0; - if (size_ret != sizeof(*cd) || cd->zipcensig != zip_cd_sig) { - dbg(lvl_error,"error1 size=%d vs %zu",size_ret, sizeof(*cd)); - return 0; - } - file_data_write(download->file, download->offset, sizeof(*cd), (unsigned char *)cd); - download->offset+=sizeof(*cd); - cd_xlen=cd->zipcfnl+cd->zipcxtl; - cd_data=file_data_read_special(download->http, cd_xlen, &size_ret); - if (size_ret != cd_xlen) { - dbg(lvl_error,"error2 size=%d vs %d",size_ret,cd_xlen); - return 0; - } - file_data_write(download->file, download->offset, cd_xlen, cd_data); - download->offset+=cd_xlen; - g_free(cd); - g_free(cd_data); - } - return 1; -} - -static int download_directory_finish(struct map_download *download) { - download->http=NULL; - return 1; -} - -static int download_initial_finish(struct map_download *download) { - download->zip64_eoc->zip64eofst=download->cd1offset; - download->zip64_eocl->zip64lofst=download->offset; - download->zip_eoc->zipeofst=download->cd1offset; -#if 0 - file_data_write(download->file, download->offset, sizeof(*download->zip64_eoc), (unsigned char *)download->zip64_eoc); - download->offset+=sizeof(*download->zip64_eoc); - file_data_write(download->file, download->offset, sizeof(*download->zip64_eocl), (unsigned char *)download->zip64_eocl); - download->offset+=sizeof(*download->zip64_eocl); -#endif - file_data_write(download->file, download->offset, sizeof(*download->zip_eoc), (unsigned char *)download->zip_eoc); - download->offset+=sizeof(*download->zip_eoc); - g_free(download->zip64_eoc); - download->zip64_eoc=NULL; - return 1; -} static void push_zipfile_tile_do(struct map_rect_priv *mr, struct zip_cd *cd, int zipfile, int offset, int length) @@ -1233,145 +835,6 @@ static void push_zipfile_tile_do(struct map_rect_priv *mr, struct zip_cd *cd, in } -static struct zip_cd *download(struct map_priv *m, struct map_rect_priv *mr, struct zip_cd *cd, int zipfile, int offset, - int length, - int async) { - struct map_download *download; - - if(!m->download_enabled) - return NULL; - - if (async == 2) { - download=m->download; - } else { - download=g_new0(struct map_download, 1); - if (mr) { - download->m=m; - download->mr=mr; - download->file=m->fi; - download->cd=cd; - download->zipfile=zipfile; - download->toffset=offset; - download->tlength=length; - download->state=1; - } else { - struct attr readwrite= {attr_readwrite,{(void *)1}}; - struct attr create= {attr_create,{(void *)1}}; - struct attr *attrs[3]; - attrs[0]=&readwrite; - attrs[1]=&create; - attrs[2]=NULL; - download->file=file_create(m->filename,attrs); - download->m=m; - download->state=4; - } - } - if (async == 1) { - m->download=download; - g_free(m->progress); - if (download->mr) - m->progress=g_strdup_printf("Download Tile %d 0%%",download->zipfile); - else - m->progress=g_strdup_printf("Download Map Information 0%%"); - callback_list_call_attr_0(m->cbl, attr_progress); - return NULL; - } - for (;;) { - dbg(lvl_debug,"state=%d",download->state); - switch (download->state) { - case 0: - dbg(lvl_error,"error"); - break; - case 1: - if (download_start(download)) - download->state=2; - else - download->state=0; - break; - case 2: - if (download_download(download)) - download->state=3; - else { - g_free(m->progress); - m->progress=g_strdup_printf("Download Tile %d %d%%",download->zipfile,download->progress); - callback_list_call_attr_0(m->cbl, attr_progress); - } - break; - case 3: - if (download_finish(download)) { - struct zip_cd *ret; - g_free(m->progress); - m->progress=g_strdup_printf("Download Tile %d 100%%",download->zipfile); - callback_list_call_attr_0(m->cbl, attr_progress); - if (async) { - push_zipfile_tile_do(download->mr, download->cd, download->zipfile, download->toffset, download->tlength); - ret=NULL; - } else - ret=download->cd; - g_free(m->progress); - m->progress=NULL; - g_free(download); - if (async) - m->download=NULL; - return ret; - } else - download->state=0; - break; - case 4: - if (download_planet_size(download)) - download->state=5; - else - download->state=0; - break; - case 5: - g_free(m->progress); - m->progress=g_strdup_printf("Download Map Information 50%%"); - callback_list_call_attr_0(m->cbl, attr_progress); - if (download_eoc(download)) - download->state=6; - else { - dbg(lvl_error,"download of eoc failed"); - download->state=0; - } - break; - case 6: - g_free(m->progress); - m->progress=g_strdup_printf("Download Map Information 100%%"); - callback_list_call_attr_0(m->cbl, attr_progress); - if (download_directory_start(download)) - download->state=7; - else - download->state=0; - break; - case 7: - g_free(m->progress); - m->progress=g_strdup_printf("Download Map Directory %d%%",(int)(download->offset*100/download->zip64_eoc->zip64ecsz)); - callback_list_call_attr_0(m->cbl, attr_progress); - if (!download_directory_do(download)) - download->state=8; - break; - case 8: - if (download_directory_finish(download)) - download->state=9; - else - download->state=0; - break; - case 9: - download_initial_finish(download); - m->fi=download->file; - g_free(m->progress); - m->progress=NULL; - g_free(download); - if (async) - m->download=NULL; - map_binfile_open(m); - break; - } - if (async) - return NULL; - } -} - static int push_zipfile_tile(struct map_rect_priv *mr, int zipfile, int offset, int length, int async) { struct map_priv *m=mr->m; struct file *f=m->fi; @@ -1379,10 +842,8 @@ static int push_zipfile_tile(struct map_rect_priv *mr, int zipfile, int offset, struct zip_cd *cd=(struct zip_cd *)(file_data_read(f, cdoffset + zipfile*m->cde_size, m->cde_size)); dbg(lvl_debug,"read from "LONGLONG_FMT" %d bytes",cdoffset + zipfile*m->cde_size, m->cde_size); cd_to_cpu(cd); - if (!cd->zipcunc && m->url) { - cd=download(m, mr, cd, zipfile, offset, length, async); - if (!cd) - return 1; + if (!cd->zipcunc) { + return 1; } push_zipfile_tile_do(mr, cd, zipfile, offset, length); return 0; @@ -1390,12 +851,9 @@ static int push_zipfile_tile(struct map_rect_priv *mr, int zipfile, int offset, static struct map_rect_priv *map_rect_new_binfile_int(struct map_priv *map, struct map_selection *sel) { struct map_rect_priv *mr; - - binfile_check_version(map); dbg(lvl_debug,"map_rect_new_binfile"); - if (!map->fi && !map->url) + if (!map->fi) return NULL; - map_binfile_http_close(map); mr=g_new0(struct map_rect_priv, 1); mr->m=map; mr->sel=sel; @@ -1406,76 +864,12 @@ static struct map_rect_priv *map_rect_new_binfile_int(struct map_priv *map, stru return mr; } -static void tile_bbox(char *tile, int len, struct coord_rect *r) { - struct coord c; - int overlap=1; - int xo,yo; - struct coord_rect world_bbox = { - { WORLD_BOUNDINGBOX_MIN_X, WORLD_BOUNDINGBOX_MAX_Y}, /* left upper corner */ - { WORLD_BOUNDINGBOX_MAX_X, WORLD_BOUNDINGBOX_MIN_Y}, /* right lower corner */ - }; - *r=world_bbox; - while (len) { - c.x=(r->lu.x+r->rl.x)/2; - c.y=(r->lu.y+r->rl.y)/2; - xo=(r->rl.x-r->lu.x)*overlap/100; - yo=(r->lu.y-r->rl.y)*overlap/100; - switch (*tile) { - case 'a': - r->lu.x=c.x-xo; - r->rl.y=c.y-yo; - break; - case 'b': - r->rl.x=c.x+xo; - r->rl.y=c.y-yo; - break; - case 'c': - r->lu.x=c.x-xo; - r->lu.y=c.y+yo; - break; - case 'd': - r->rl.x=c.x+xo; - r->lu.y=c.y+yo; - break; - default: - return; - } - tile++; - len--; - } -} - -static int map_download_selection_check(struct zip_cd *cd, struct map_selection *sel) { - struct coord_rect cd_rect; - if (cd->zipcunc) - return 0; - tile_bbox((char *)(cd+1), cd->zipcfnl, &cd_rect); - while (sel) { - if (coord_rect_overlap(&cd_rect, &sel->u.c_rect)) - return 1; - sel=sel->next; - } - return 0; -} -static void map_download_selection(struct map_priv *m, struct map_rect_priv *mr, struct map_selection *sel) { - int i; - struct zip_cd *cd; - for (i = 0 ; i < m->zip_members ; i++) { - cd=binfile_read_cd(m, m->cde_size*i, -1); - if (map_download_selection_check(cd, sel)) - download(m, mr, cd, i, 0, 0, 0); - file_data_free(m->fi, (unsigned char *)cd); - } -} static struct map_rect_priv *map_rect_new_binfile(struct map_priv *map, struct map_selection *sel) { struct map_rect_priv *mr=map_rect_new_binfile_int(map, sel); struct tile t; dbg(lvl_debug,"zip_members=%d", map->zip_members); - if (map->url && map->fi && sel && sel->order == 255) { - map_download_selection(map, mr, sel); - } if (map->eoc) mr->status=1; else { @@ -1488,65 +882,13 @@ static struct map_rect_priv *map_rect_new_binfile(struct map_priv *map, struct m t.zipfile_num=0; t.mode=0; push_tile(mr, &t, 0, 0); - } else if (map->url && !map->download) { - download(map, NULL, NULL, 0, 0, 0, 1); - mr->status=1; } } return mr; } -static void write_changes_do(gpointer key, gpointer value, gpointer user_data) { - struct binfile_hash_entry *entry=key; - FILE *out=user_data; - if (entry->flags) { - entry->flags=0; - fwrite(entry, sizeof(*entry)+(le32_to_cpu(entry->data[0])+1)*4, 1, out); - dbg(lvl_debug,"yes"); - } -} - -static void write_changes(struct map_priv *m) { - FILE *changes; - char *changes_file; - if (!m->changes) - return; - changes_file=g_strdup_printf("%s.log",m->filename); - changes=fopen(changes_file,"ab"); - g_hash_table_foreach(m->changes, write_changes_do, changes); - fclose(changes); - g_free(changes_file); -} - -static void load_changes(struct map_priv *m) { - FILE *changes; - char *changes_file; - struct binfile_hash_entry entry,*e; - int size; - changes_file=g_strdup_printf("%s.log",m->filename); - changes=fopen(changes_file,"rb"); - if (! changes) { - g_free(changes_file); - return; - } - m->changes=g_hash_table_new_full(binfile_hash_entry_hash, binfile_hash_entry_equal, g_free, NULL); - while (fread(&entry, sizeof(entry), 1, changes) == 1) { - if (fread(&size, sizeof(size), 1, changes) != 1) - break; - e=g_malloc(sizeof(struct binfile_hash_entry)+(le32_to_cpu(size)+1)*4); - *e=entry; - e->data[0]=size; - if (fread(e->data+1, le32_to_cpu(size)*4, 1, changes) != 1) - break; - g_hash_table_replace(m->changes, e, e); - } - fclose(changes); - g_free(changes_file); -} - static void map_rect_destroy_binfile(struct map_rect_priv *mr) { - write_changes(mr->m); while (pop_tile(mr)); #ifdef DEBUG_SIZE dbg(lvl_debug,"size=%d kb",mr->size/1024); @@ -1554,7 +896,6 @@ static void map_rect_destroy_binfile(struct map_rect_priv *mr) { if (mr->tiles[0].fi && mr->tiles[0].start) file_data_free(mr->tiles[0].fi, (unsigned char *)(mr->tiles[0].start)); g_free(mr->url); - map_binfile_http_close(mr->m); g_free(mr); } @@ -1655,31 +996,9 @@ static int map_parse_submap(struct map_rect_priv *mr, int async) { return push_zipfile_tile(mr, at.u.num, 0, 0, async); } -static int push_modified_item(struct map_rect_priv *mr) { - struct item_id id; - struct binfile_hash_entry *entry; - id.id_hi=mr->item.id_hi; - id.id_lo=mr->item.id_lo; - entry=g_hash_table_lookup(mr->m->changes, &id); - if (entry) { - struct tile tn; - tn.pos_next=tn.pos=tn.start=entry->data; - tn.zipfile_num=mr->item.id_hi; - tn.mode=2; - tn.end=tn.start+le32_to_cpu(entry->data[0])+1; - push_tile(mr, &tn, 0, 0); - return 1; - } - return 0; -} - static struct item *map_rect_get_item_binfile(struct map_rect_priv *mr) { struct tile *t; struct map_priv *m=mr->m; - if (m->download) { - download(m, NULL, NULL, 0, 0, 0, 2); - return &busy_item; - } if (mr->status == 1) { mr->status=0; if (push_zipfile_tile(mr, m->zip_members-1, 0, 0, 1)) @@ -1706,8 +1025,6 @@ static struct item *map_rect_get_item_binfile(struct map_rect_priv *mr) { if (t->mode != 2) { mr->item.id_hi=t->zipfile_num; mr->item.id_lo=t->pos-t->start; - if (mr->m->changes && push_modified_item(mr)) - continue; } if (mr->country_id) { if (mr->item.type == type_countryindex) { @@ -1733,8 +1050,6 @@ static struct item *map_rect_get_item_byid_binfile(struct map_rect_priv *mr, int t->pos=t->start+id_lo; mr->item.id_hi=id_hi; mr->item.id_lo=id_lo; - if (mr->m->changes) - push_modified_item(mr); setup_pos(mr); binfile_coord_rewind(mr); binfile_attr_rewind(mr); @@ -2335,17 +1650,6 @@ static void binmap_search_destroy(struct map_search_priv *ms) { static int binmap_get_attr(struct map_priv *m, enum attr_type type, struct attr *attr) { attr->type=type; switch (type) { - case attr_map_release: - if (m->map_release) { - attr->u.str=m->map_release; - return 1; - } - break; - case attr_progress: - if (m->progress) { - attr->u.str=m->progress; - return 1; - } default: break; } @@ -2354,9 +1658,6 @@ static int binmap_get_attr(struct map_priv *m, enum attr_type type, struct attr static int binmap_set_attr(struct map_priv *map, struct attr *attr) { switch (attr->type) { - case attr_update: - map->download_enabled = attr->u.num; - return 1; default: return 0; } @@ -2459,104 +1760,19 @@ static int map_binfile_zip_setup(struct map_priv *m, char *filename, int mmap) { return 1; } - -#if 0 -static int map_binfile_download_initial(struct map_priv *m) { - struct attr readwrite= {attr_readwrite,{(void *)1}}; - struct attr create= {attr_create,{(void *)1}}; - struct attr *attrs[4]; - struct file *out; - long long woffset=0,planet_size; - int size_ret; - int cd1size,cdisize; - long long cd1offset,cdioffset; - struct zip64_eoc *zip64_eoc; - struct zip64_eocl *zip64_eocl; - struct zip_eoc *zip_eoc; - struct zip_cd *cd1,*cdn,*cdi; - int count,chunk,cdoffset=0; - int mode=1; - struct map_download *download=g_new0(struct map_download, 1); - - attrs[0]=&readwrite; - attrs[1]=&create; - attrs[2]=NULL; - download->file=file_create(m->filename,attrs); - download->m=m; - download_planet_size(download); - download_eoc(download); - download_directory_start(download); - while (download_directory_do(download)); - download_directory_finish(download); - download_initial_finish(download); - m->fi=download->file; - g_free(download); - return 1; - - - cd1size=sizeof(*cd1); - cd1offset=zip64_eoc->zip64eofst; - cd1=(struct zip_cd *)map_binfile_download_range(m, cd1offset, cd1size); - if (!cd1) - return 0; - cd1size=sizeof(*cd1)+binfile_cd_extra(cd1); - g_free(cd1); - cd1=(struct zip_cd *)map_binfile_download_range(m, cd1offset, cd1size); - if (!cd1) - return 0; - cd1->zipcunc=0; - cdisize=sizeof(*cdi)+strlen("index")+cd1->zipcxtl; - cdioffset=zip64_eoc->zip64eofst+zip64_eoc->zip64ecsz-cdisize; - cdi=(struct zip_cd *)map_binfile_download_range(m, cdioffset, cdisize); - if (!cdi) { - g_free(cd1); - return 0; - } - cdi->zipcunc=0; - cdn=g_malloc0(cd1size*256); - - file_data_write(out, woffset, sizeof(*zip64_eoc), (unsigned char *)zip64_eoc); - woffset+=sizeof(*zip64_eoc); - cdoffset=woffset; - - file_data_write(out, woffset, cd1size, (unsigned char *)cd1); - woffset+=cd1size; - count=(cdioffset-cd1offset)/cd1size-1; - while (count > 0) { - if (count > 256) - chunk=256; - else - chunk=count; - file_data_write(out, woffset, cd1size*chunk, (unsigned char *)cdn); - woffset+=cd1size*chunk; - count-=chunk; - } - g_free(cdn); - g_free(cd1); - file_data_write(out, woffset, cdisize, (unsigned char *)cdi); - woffset+=cdisize; - -} -#endif - static int map_binfile_open(struct map_priv *m) { int *magic; - struct map_rect_priv *mr; - struct item *item; - struct attr attr; struct attr readwrite= {attr_readwrite, {(void *)1}}; struct attr *attrs[]= {&readwrite, NULL}; dbg(lvl_debug,"file_create %s", m->filename); - m->fi=file_create(m->filename, m->url?attrs:NULL); - if (! m->fi && m->url) + m->fi=file_create(m->filename, attrs); + if (! m->fi) return 0; if (! m->fi) { dbg(lvl_error,"Failed to load '%s'", m->filename); return 0; } - if (m->check_version) - m->version=file_version(m->fi, m->check_version); magic=(int *)file_data_read(m->fi, 0, 4); if (!magic) { file_destroy(m->fi); @@ -2581,30 +1797,6 @@ static int map_binfile_open(struct map_priv *m) { file_mmap(m->fi); file_data_free(m->fi, (unsigned char *)magic); m->cachedir=g_strdup("/tmp/navit"); - m->map_version=0; - mr=map_rect_new_binfile(m, NULL); - if (mr) { - while ((item=map_rect_get_item_binfile(mr)) == &busy_item); - if (item && item->type == type_map_information) { - if (binfile_attr_get(item->priv_data, attr_version, &attr)) - m->map_version=attr.u.num; - if (binfile_attr_get(item->priv_data, attr_map_release, &attr)) - m->map_release=g_strdup(attr.u.str); - if (m->url && binfile_attr_get(item->priv_data, attr_url, &attr)) { - dbg(lvl_debug,"url config %s map %s",m->url,attr.u.str); - if (strcmp(m->url, attr.u.str)) - m->update_available=1; - g_free(m->url); - m->url=g_strdup(attr.u.str); - } - } - map_rect_destroy_binfile(mr); - if (m->map_version >= 16) { - dbg(lvl_error,"%s: This map is incompatible with your navit version. Please update navit. (map version %d)", - m->filename, m->map_version); - return 0; - } - } return 1; } @@ -2614,7 +1806,6 @@ static void map_binfile_close(struct map_priv *m) { file_data_free(m->fi, (unsigned char *)m->eoc); file_data_free(m->fi, (unsigned char *)m->eoc64); g_free(m->cachedir); - g_free(m->map_release); if (m->fis) { for (i = 0 ; i < m->eoc->zipedsk ; i++) { file_destroy(m->fis[i]); @@ -2625,30 +1816,14 @@ static void map_binfile_close(struct map_priv *m) { static void map_binfile_destroy(struct map_priv *m) { g_free(m->filename); - g_free(m->url); - g_free(m->progress); g_free(m); } -static void binfile_check_version(struct map_priv *m) { - int version=-1; - if (!m->check_version) - return; - if (m->fi) - version=file_version(m->fi, m->check_version); - if (version != m->version) { - if (m->fi) - map_binfile_close(m); - map_binfile_open(m); - } -} - - static struct map_priv *map_new_binfile(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) { struct map_priv *m; struct attr *data=attr_search(attrs, attr_data); - struct attr *check_version,*flags,*url,*download_enabled; + struct attr *flags; struct file_wordexp *wexp; char **wexp_data; if (! data) @@ -2664,24 +1839,13 @@ static struct map_priv *map_new_binfile(struct map_methods *meth, struct attr ** m->id=++map_id; m->filename=g_strdup(wexp_data[0]); file_wordexp_destroy(wexp); - check_version=attr_search(attrs, attr_check_version); - if (check_version) - m->check_version=check_version->u.num; flags=attr_search(attrs, attr_flags); if (flags) m->flags=flags->u.num; - url=attr_search(attrs, attr_url); - if (url) - m->url=g_strdup(url->u.str); - download_enabled = attr_search(attrs, attr_update); - if (download_enabled) - m->download_enabled=download_enabled->u.num; - - if (!map_binfile_open(m) && !m->check_version && !m->url) { + + if (!map_binfile_open(m)) { map_binfile_destroy(m); m=NULL; - } else { - load_changes(m); } return m; }