diff options
Diffstat (limited to 'navit/map/mg')
-rw-r--r-- | navit/map/mg/block.c | 460 | ||||
-rw-r--r-- | navit/map/mg/map.c | 1011 | ||||
-rw-r--r-- | navit/map/mg/poly.c | 427 | ||||
-rw-r--r-- | navit/map/mg/street.c | 1880 | ||||
-rw-r--r-- | navit/map/mg/town.c | 443 | ||||
-rw-r--r-- | navit/map/mg/tree.c | 469 |
6 files changed, 2270 insertions, 2420 deletions
diff --git a/navit/map/mg/block.c b/navit/map/mg/block.c index b2bb64ac0..1b2dbeec7 100644 --- a/navit/map/mg/block.c +++ b/navit/map/mg/block.c @@ -26,273 +26,259 @@ int block_lin_count,block_idx_count,block_active_count,block_mem,block_active_mem; struct block_index_item { - /*unsigned int blocknum; - unsigned int blocks;*/ - unsigned char p[8]; + /*unsigned int blocknum; + unsigned int blocks;*/ + unsigned char p[8]; }; -static inline unsigned int block_index_item_get_blocknum(struct block_index_item * blk) { unsigned char *p = blk->p; return get_u32(&p); } -static inline unsigned int block_index_item_get_blocks(struct block_index_item * blk) { unsigned char *p = blk->p+4; return get_u32(&p); } +static inline unsigned int block_index_item_get_blocknum(struct block_index_item * blk) { + unsigned char *p = blk->p; + return get_u32(&p); +} +static inline unsigned int block_index_item_get_blocks(struct block_index_item * blk) { + unsigned char *p = blk->p+4; + return get_u32(&p); +} struct block_index { -/* unsigned int blocks; - unsigned int size; - unsigned int next; - struct block_index_item list[0];*/ - unsigned char p[12]; + /* unsigned int blocks; + unsigned int size; + unsigned int next; + struct block_index_item list[0];*/ + unsigned char p[12]; }; -static inline unsigned int block_index_get_blocks(struct block_index * blk) { unsigned char *p = blk->p; return get_u32(&p); } -static inline unsigned int block_index_get_size(struct block_index * blk) { unsigned char *p = blk->p+4; return get_u32(&p); } -static inline unsigned int block_index_get_next(struct block_index * blk) { unsigned char *p = blk->p+8; return get_u32(&p); } -static inline struct block_index_item * block_index_get_list(struct block_index * blk) { return (struct block_index_item *)(blk->p+12); } +static inline unsigned int block_index_get_blocks(struct block_index * blk) { + unsigned char *p = blk->p; + return get_u32(&p); +} +static inline unsigned int block_index_get_size(struct block_index * blk) { + unsigned char *p = blk->p+4; + return get_u32(&p); +} +static inline unsigned int block_index_get_next(struct block_index * blk) { + unsigned char *p = blk->p+8; + return get_u32(&p); +} +static inline struct block_index_item * block_index_get_list(struct block_index * blk) { + return (struct block_index_item *)(blk->p+12); +} -static struct block * -block_get(unsigned char **p) -{ - struct block *ret=(struct block *)(*p); - *p += sizeof(*ret); - return ret; +static struct block *block_get(unsigned char **p) { + struct block *ret=(struct block *)(*p); + *p += sizeof(*ret); + return ret; } -static struct block * -block_get_byid(struct file *file, int id, unsigned char **p_ret) -{ - struct block_index *blk_idx; - int blk_num,max; +static struct block *block_get_byid(struct file *file, int id, unsigned char **p_ret) { + struct block_index *blk_idx; + int blk_num,max; - blk_idx=(struct block_index *)(file->begin+0x1000); - max=(block_index_get_size(blk_idx)-sizeof(struct block_index))/sizeof(struct block_index_item); - block_mem+=24; - while (id >= max) { - blk_idx=(struct block_index *)(file->begin+block_index_get_next(blk_idx)*512); - id-=max; - } - blk_num=block_index_item_get_blocknum(&block_index_get_list(blk_idx)[id]); + blk_idx=(struct block_index *)(file->begin+0x1000); + max=(block_index_get_size(blk_idx)-sizeof(struct block_index))/sizeof(struct block_index_item); + block_mem+=24; + while (id >= max) { + blk_idx=(struct block_index *)(file->begin+block_index_get_next(blk_idx)*512); + id-=max; + } + blk_num=block_index_item_get_blocknum(&block_index_get_list(blk_idx)[id]); - *p_ret=file->begin+blk_num*512; - return block_get(p_ret); + *p_ret=file->begin+blk_num*512; + return block_get(p_ret); } -int -block_get_byindex(struct file *file, int idx, struct block_priv *blk) -{ - dbg(lvl_debug,"idx=%d\n", idx); - blk->b=block_get_byid(file, idx, &blk->p); - blk->block_start=(unsigned char *)(blk->b); - blk->p_start=blk->p; - blk->end=blk->block_start+block_get_size(blk->b); +int block_get_byindex(struct file *file, int idx, struct block_priv *blk) { + dbg(lvl_debug,"idx=%d", idx); + blk->b=block_get_byid(file, idx, &blk->p); + blk->block_start=(unsigned char *)(blk->b); + blk->p_start=blk->p; + blk->end=blk->block_start+block_get_size(blk->b); - return 1; + return 1; } -static void -block_setup_tags(struct map_rect_priv *mr) -{ - int len; - unsigned char *p,*t; - char *str; +static void block_setup_tags(struct map_rect_priv *mr) { + int len; + unsigned char *p,*t; + char *str; - mr->b.binarytree=0; + mr->b.binarytree=0; - p=mr->file->begin+0x0c; - while (*p) { - str=get_string(&p); - len=get_u32_unal(&p); - t=p; - /* printf("String '%s' len %d\n", str, len); */ - if (! strcmp(str,"FirstBatBlock")) { - /* printf("%ld\n", get_u32_unal(&t)); */ - } else if (! strcmp(str,"MaxBlockSize")) { - /* printf("%ld\n", get_u32_unal(&t)); */ - } else if (! strcmp(str,"FREE_BLOCK_LIST")) { - /* printf("%ld\n", get_u32_unal(&t)); */ - } else if (! strcmp(str,"TotalRect")) { - mr->b.b_rect.lu.x=get_u32_unal(&t); - mr->b.b_rect.lu.y=get_u32_unal(&t); - mr->b.b_rect.rl.x=get_u32_unal(&t); - mr->b.b_rect.rl.y=get_u32_unal(&t); - /* printf("0x%x,0x%x-0x%x,0x%x\n", mr->b.b_rect.lu.x, mr->b.b_rect.lu.y, mr->b.b_rect.rl.x, mr->b.b_rect.rl.y); */ - } else if (! strcmp(str,"Version")) { - /* printf("0x%lx\n", get_u32_unal(&t)); */ - } else if (! strcmp(str,"Categories")) { - /* printf("0x%x\n", get_u16(&t)); */ - } else if (! strcmp(str,"binaryTree")) { - mr->b.binarytree=get_u32_unal(&t); - /* printf("%d\n", mr->b.binarytree); */ - } else if (! strcmp(str,"CategorySets")) { - /* printf("0x%x\n", get_u16(&t)); */ - } else if (! strcmp(str,"Kommentar")) { - /* printf("%s\n", get_string(&t)); */ - } - p+=len; - } + p=mr->file->begin+0x0c; + while (*p) { + str=get_string(&p); + len=get_u32_unal(&p); + t=p; + /* printf("String '%s' len %d\n", str, len); */ + if (! strcmp(str,"FirstBatBlock")) { + /* printf("%ld\n", get_u32_unal(&t)); */ + } else if (! strcmp(str,"MaxBlockSize")) { + /* printf("%ld\n", get_u32_unal(&t)); */ + } else if (! strcmp(str,"FREE_BLOCK_LIST")) { + /* printf("%ld\n", get_u32_unal(&t)); */ + } else if (! strcmp(str,"TotalRect")) { + mr->b.b_rect.lu.x=get_u32_unal(&t); + mr->b.b_rect.lu.y=get_u32_unal(&t); + mr->b.b_rect.rl.x=get_u32_unal(&t); + mr->b.b_rect.rl.y=get_u32_unal(&t); + /* printf("0x%x,0x%x-0x%x,0x%x\n", mr->b.b_rect.lu.x, mr->b.b_rect.lu.y, mr->b.b_rect.rl.x, mr->b.b_rect.rl.y); */ + } else if (! strcmp(str,"Version")) { + /* printf("0x%lx\n", get_u32_unal(&t)); */ + } else if (! strcmp(str,"Categories")) { + /* printf("0x%x\n", get_u16(&t)); */ + } else if (! strcmp(str,"binaryTree")) { + mr->b.binarytree=get_u32_unal(&t); + /* printf("%d\n", mr->b.binarytree); */ + } else if (! strcmp(str,"CategorySets")) { + /* printf("0x%x\n", get_u16(&t)); */ + } else if (! strcmp(str,"Kommentar")) { + /* printf("%s\n", get_string(&t)); */ + } + p+=len; + } } #if 0 -static void -block_rect_print(struct coord_rect *r) -{ - printf ("0x%x,0x%x-0x%x,0x%x (0x%x,0x%x)", r->lu.x, r->lu.y, r->rl.x, r->rl.y, r->lu.x/2+r->rl.x/2,r->lu.y/2+r->rl.y/2); +static void block_rect_print(struct coord_rect *r) { + printf ("0x%x,0x%x-0x%x,0x%x (0x%x,0x%x)", r->lu.x, r->lu.y, r->rl.x, r->rl.y, r->lu.x/2+r->rl.x/2,r->lu.y/2+r->rl.y/2); } #endif -static void -block_rect_same(struct coord_rect *r1, struct coord_rect *r2) -{ - dbg_assert(r1->lu.x==r2->lu.x); - dbg_assert(r1->lu.y==r2->lu.y); - dbg_assert(r1->rl.x==r2->rl.x); - dbg_assert(r1->rl.y==r2->rl.y); +static void block_rect_same(struct coord_rect *r1, struct coord_rect *r2) { + dbg_assert(r1->lu.x==r2->lu.x); + dbg_assert(r1->lu.y==r2->lu.y); + dbg_assert(r1->rl.x==r2->rl.x); + dbg_assert(r1->rl.y==r2->rl.y); } -int -block_init(struct map_rect_priv *mr) -{ - mr->b.block_num=-1; - mr->b.bt.b=NULL; - mr->b.bt.next=0; - block_setup_tags(mr); - if (mr->b.binarytree) { - mr->b.bt.next=mr->b.binarytree; - mr->b.bt.p=NULL; - mr->b.bt.block_count=0; - } - if (mr->cur_sel && !coord_rect_overlap(&mr->cur_sel->u.c_rect, &mr->b.b_rect)) - return 0; - return block_next(mr); +int block_init(struct map_rect_priv *mr) { + mr->b.block_num=-1; + mr->b.bt.b=NULL; + mr->b.bt.next=0; + block_setup_tags(mr); + if (mr->b.binarytree) { + mr->b.bt.next=mr->b.binarytree; + mr->b.bt.p=NULL; + mr->b.bt.block_count=0; + } + if (mr->cur_sel && !coord_rect_overlap(&mr->cur_sel->u.c_rect, &mr->b.b_rect)) + return 0; + return block_next(mr); } -int -block_next_lin(struct map_rect_priv *mr) -{ - struct coord_rect r; - for (;;) { - block_lin_count++; - block_mem+=sizeof(struct block *); - mr->b.block_num++; - if (! mr->b.block_num) - mr->b.p=mr->file->begin+0x2000; - else - mr->b.p=mr->b.block_start+block_get_blocks(mr->b.b)*512; - if (mr->b.p >= mr->file->end) { - dbg(lvl_debug,"end of blocks %p vs %p\n", mr->b.p, mr->file->end); - return 0; - } - mr->b.block_start=mr->b.p; - mr->b.b=block_get(&mr->b.p); - mr->b.p_start=mr->b.p; - mr->b.end=mr->b.block_start+block_get_size(mr->b.b); - if (block_get_count(mr->b.b) == -1) { - dbg(lvl_warning,"empty blocks\n"); - return 0; - } - block_get_r(mr->b.b, &r); - if (!mr->cur_sel || coord_rect_overlap(&mr->cur_sel->u.c_rect, &r)) { - block_active_count++; - block_active_mem+=block_get_blocks(mr->b.b)*512-sizeof(struct block *); - dbg(lvl_debug,"block ok\n"); - return 1; - } - dbg(lvl_info,"block not in cur_sel\n"); - } +int block_next_lin(struct map_rect_priv *mr) { + struct coord_rect r; + for (;;) { + block_lin_count++; + block_mem+=sizeof(struct block *); + mr->b.block_num++; + if (! mr->b.block_num) + mr->b.p=mr->file->begin+0x2000; + else + mr->b.p=mr->b.block_start+block_get_blocks(mr->b.b)*512; + if (mr->b.p >= mr->file->end) { + dbg(lvl_debug,"end of blocks %p vs %p", mr->b.p, mr->file->end); + return 0; + } + mr->b.block_start=mr->b.p; + mr->b.b=block_get(&mr->b.p); + mr->b.p_start=mr->b.p; + mr->b.end=mr->b.block_start+block_get_size(mr->b.b); + if (block_get_count(mr->b.b) == -1) { + dbg(lvl_warning,"empty blocks"); + return 0; + } + block_get_r(mr->b.b, &r); + if (!mr->cur_sel || coord_rect_overlap(&mr->cur_sel->u.c_rect, &r)) { + block_active_count++; + block_active_mem+=block_get_blocks(mr->b.b)*512-sizeof(struct block *); + dbg(lvl_debug,"block ok"); + return 1; + } + dbg(lvl_info,"block not in cur_sel"); + } } -int -block_next(struct map_rect_priv *mr) -{ - int blk_num,coord,r_h,r_w; - struct block_bt_priv *bt=&mr->b.bt; - struct coord_rect r; +int block_next(struct map_rect_priv *mr) { + int blk_num,coord,r_h,r_w; + struct block_bt_priv *bt=&mr->b.bt; + struct coord_rect r; - if (!mr->b.binarytree || ! mr->cur_sel) - return block_next_lin(mr); - for (;;) { - if (! bt->p) { - dbg(lvl_debug,"block 0x%x\n", bt->next); - if (bt->next == -1) - return 0; - bt->b=block_get_byid(mr->file, bt->next, &bt->p); - bt->end=(unsigned char *)mr->b.bt.b+block_get_size(mr->b.bt.b); - bt->next=block_get_next(bt->b); - bt->order=0; - dbg(lvl_debug,"size 0x%x next 0x%x\n", block_get_size(bt->b), block_get_next(bt->b)); - if (! mr->b.bt.block_count) { -#if 0 - if (debug) { - printf("idx rect "); - block_rect_print(&mr->b.bt.b->r); - } -#endif - block_get_r(bt->b, &bt->r); - bt->r_curr=bt->r; - coord=get_u32(&mr->b.bt.p); - } else { - bt->p=(unsigned char *)bt->b+0xc; - } - bt->block_count++; - } - while (mr->b.bt.p < mr->b.bt.end) { - block_idx_count++; - blk_num=get_u32(&mr->b.bt.p); - coord=get_u32(&mr->b.bt.p); - block_mem+=8; - dbg(lvl_debug,"%p vs %p coord 0x%x ", mr->b.bt.end, mr->b.bt.p, coord); - dbg(lvl_debug,"block 0x%x", blk_num); - - r_w=bt->r_curr.rl.x-bt->r_curr.lu.x; - r_h=bt->r_curr.lu.y-bt->r_curr.rl.y; -#if 0 - if (debug) { - printf(" rect1 "); - block_rect_print(&bt->r_curr); - printf(" %dx%d", r_w, r_h); - } -#endif - mr->b.b=NULL; - if (blk_num != -1) { - block_mem+=8; - if (coord_rect_overlap(&mr->cur_sel->u.c_rect, &bt->r_curr)) { - mr->b.b=block_get_byid(mr->file, blk_num, &mr->b.p); - mr->b.block_num=blk_num; - dbg_assert(mr->b.b != NULL); - mr->b.block_start=(unsigned char *)(mr->b.b); - mr->b.p_start=mr->b.p; - mr->b.end=mr->b.block_start+block_get_size(mr->b.b); - block_get_r(mr->b.b, &r); - block_rect_same(&r, &bt->r_curr); - } - } - if (coord != -1) { - bt->stack[bt->stackp]=bt->r_curr; - if (r_w > r_h) { - bt->r_curr.rl.x=coord; - bt->stack[bt->stackp].lu.x=coord+1; - } else { - bt->r_curr.lu.y=coord; - bt->stack[bt->stackp].rl.y=coord+1; - } - bt->stackp++; - dbg_assert(bt->stackp < BT_STACK_SIZE); - } else { - if (bt->stackp) { - bt->stackp--; - bt->r_curr=bt->stack[bt->stackp]; - } else { - bt->r_curr=bt->r; - bt->order++; - if (bt->order > 100) - return 0; - } - } - if (mr->b.b) { - block_active_count++; - block_active_mem+=block_get_blocks(mr->b.b)*512; - return 1; - } - } - bt->p=NULL; - } - return 0; + if (!mr->b.binarytree || ! mr->cur_sel) + return block_next_lin(mr); + for (;;) { + if (! bt->p) { + dbg(lvl_debug,"block 0x%x", bt->next); + if (bt->next == -1) + return 0; + bt->b=block_get_byid(mr->file, bt->next, &bt->p); + bt->end=(unsigned char *)mr->b.bt.b+block_get_size(mr->b.bt.b); + bt->next=block_get_next(bt->b); + bt->order=0; + dbg(lvl_debug,"size 0x%x next 0x%x", block_get_size(bt->b), block_get_next(bt->b)); + if (! mr->b.bt.block_count) { + block_get_r(bt->b, &bt->r); + bt->r_curr=bt->r; + coord=get_u32(&mr->b.bt.p); + } else { + bt->p=(unsigned char *)bt->b+0xc; + } + bt->block_count++; + } + while (mr->b.bt.p < mr->b.bt.end) { + block_idx_count++; + blk_num=get_u32(&mr->b.bt.p); + coord=get_u32(&mr->b.bt.p); + block_mem+=8; + dbg(lvl_debug,"%p vs %p coord 0x%x ", mr->b.bt.end, mr->b.bt.p, coord); + dbg(lvl_debug,"block 0x%x", blk_num); + + r_w=bt->r_curr.rl.x-bt->r_curr.lu.x; + r_h=bt->r_curr.lu.y-bt->r_curr.rl.y; + mr->b.b=NULL; + if (blk_num != -1) { + block_mem+=8; + if (coord_rect_overlap(&mr->cur_sel->u.c_rect, &bt->r_curr)) { + mr->b.b=block_get_byid(mr->file, blk_num, &mr->b.p); + mr->b.block_num=blk_num; + dbg_assert(mr->b.b != NULL); + mr->b.block_start=(unsigned char *)(mr->b.b); + mr->b.p_start=mr->b.p; + mr->b.end=mr->b.block_start+block_get_size(mr->b.b); + block_get_r(mr->b.b, &r); + block_rect_same(&r, &bt->r_curr); + } + } + if (coord != -1) { + bt->stack[bt->stackp]=bt->r_curr; + if (r_w > r_h) { + bt->r_curr.rl.x=coord; + bt->stack[bt->stackp].lu.x=coord+1; + } else { + bt->r_curr.lu.y=coord; + bt->stack[bt->stackp].rl.y=coord+1; + } + bt->stackp++; + dbg_assert(bt->stackp < BT_STACK_SIZE); + } else { + if (bt->stackp) { + bt->stackp--; + bt->r_curr=bt->stack[bt->stackp]; + } else { + bt->r_curr=bt->r; + bt->order++; + if (bt->order > 100) + return 0; + } + } + if (mr->b.b) { + block_active_count++; + block_active_mem+=block_get_blocks(mr->b.b)*512; + return 1; + } + } + bt->p=NULL; + } + return 0; } diff --git a/navit/map/mg/map.c b/navit/map/mg/map.c index 13561e154..50860e193 100644 --- a/navit/map/mg/map.c +++ b/navit/map/mg/map.c @@ -29,585 +29,562 @@ GList *maps; static struct country_isonum { - int country; - int isonum; - int postal_len; - char *postal_prefix; -} country_isonums[]={ - { 1,203}, - { 2,703}, - { 7,674}, - { 11,233}, - { 12,268}, - { 13,428}, - { 14,440}, - { 15,498}, - { 16,643}, - { 17,804}, - { 18,112}, - { 20,818}, - { 30,300}, - { 31,528}, - { 32, 56}, - { 33,250}, - { 34,724}, - { 36,348}, - { 39,380}, - { 40,642}, - { 41,756}, - { 43, 40}, - { 44,826}, - { 45,208}, - { 46,752}, - { 47,578}, - { 48,616}, - { 49,276,5,"D@@"}, - { 50,292}, - { 51,620}, - { 52,442}, - { 53,372}, - { 54,352}, - { 55, 8}, - { 56,470}, - { 57,196}, - { 58,246}, - { 59,100}, - { 61,422}, - { 62, 20}, - { 63,760}, - { 66,682}, - { 71,434}, - { 72,376}, - { 73,275}, - { 75,438}, - { 76,504}, - { 77, 12}, - { 78,788}, - { 81,688}, - { 83,400}, - { 85,191}, - { 86,705}, - { 87, 70}, - { 89,807}, - { 90,792}, - { 93,492}, - { 94, 31}, - { 95, 51}, - { 98,234}, - { 99,732}, - {336,774}, + int country; + int isonum; + int postal_len; + char *postal_prefix; +} country_isonums[]= { + { 1,203}, + { 2,703}, + { 7,674}, + { 11,233}, + { 12,268}, + { 13,428}, + { 14,440}, + { 15,498}, + { 16,643}, + { 17,804}, + { 18,112}, + { 20,818}, + { 30,300}, + { 31,528}, + { 32, 56}, + { 33,250}, + { 34,724}, + { 36,348}, + { 39,380}, + { 40,642}, + { 41,756}, + { 43, 40}, + { 44,826}, + { 45,208}, + { 46,752}, + { 47,578}, + { 48,616}, + { 49,276,5,"D@@"}, + { 50,292}, + { 51,620}, + { 52,442}, + { 53,372}, + { 54,352}, + { 55, 8}, + { 56,470}, + { 57,196}, + { 58,246}, + { 59,100}, + { 61,422}, + { 62, 20}, + { 63,760}, + { 66,682}, + { 71,434}, + { 72,376}, + { 73,275}, + { 75,438}, + { 76,504}, + { 77, 12}, + { 78,788}, + { 81,688}, + { 83,400}, + { 85,191}, + { 86,705}, + { 87, 70}, + { 89,807}, + { 90,792}, + { 93,492}, + { 94, 31}, + { 95, 51}, + { 98,234}, + { 99,732}, + {336,774}, }; struct map_priv * map_new_mg(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl); static int map_id; -static char *file[]={ - [file_border_ply]="border.ply", - [file_bridge_ply]="bridge.ply", - [file_build_ply]="build.ply", - [file_golf_ply]="golf.ply", - [file_height_ply]="height.ply", - [file_natpark_ply]="natpark.ply", - [file_nature_ply]="nature.ply", - [file_other_ply]="other.ply", - [file_rail_ply]="rail.ply", - [file_sea_ply]="sea.ply", - [file_street_bti]="street.bti", - [file_street_str]="street.str", - [file_strname_stn]="strname.stn", - [file_town_twn]="town.twn", - [file_tunnel_ply]="tunnel.ply", - [file_water_ply]="water.ply", - [file_woodland_ply]="woodland.ply", +static char *file[]= { + [file_border_ply]="border.ply", + [file_bridge_ply]="bridge.ply", + [file_build_ply]="build.ply", + [file_golf_ply]="golf.ply", + [file_height_ply]="height.ply", + [file_natpark_ply]="natpark.ply", + [file_nature_ply]="nature.ply", + [file_other_ply]="other.ply", + [file_rail_ply]="rail.ply", + [file_sea_ply]="sea.ply", + [file_street_bti]="street.bti", + [file_street_str]="street.str", + [file_strname_stn]="strname.stn", + [file_town_twn]="town.twn", + [file_tunnel_ply]="tunnel.ply", + [file_water_ply]="water.ply", + [file_woodland_ply]="woodland.ply", }; -int mg_country_from_isonum(int isonum) -{ - int i; - for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++) - if (country_isonums[i].isonum == isonum) - return country_isonums[i].country; - return 0; +int mg_country_from_isonum(int isonum) { + int i; + for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++) + if (country_isonums[i].isonum == isonum) + return country_isonums[i].country; + return 0; } -int mg_country_to_isonum(int country) -{ - int i; - for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++) - if (country_isonums[i].country == country) - return country_isonums[i].isonum; - return 0; +int mg_country_to_isonum(int country) { + int i; + for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++) + if (country_isonums[i].country == country) + return country_isonums[i].isonum; + return 0; } -int mg_country_postal_len(int country) -{ - int i; - for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++) - if (country_isonums[i].country == country) - return country_isonums[i].postal_len; - return 0; +int mg_country_postal_len(int country) { + int i; + for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++) + if (country_isonums[i].country == country) + return country_isonums[i].postal_len; + return 0; } -static char *mg_country_postal_prefix(int isonum) -{ - int i; - for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++) - if (country_isonums[i].isonum == isonum) - return country_isonums[i].postal_prefix; - return NULL; +static char *mg_country_postal_prefix(int isonum) { + int i; + for (i = 0 ; i < sizeof(country_isonums)/sizeof(struct country_isonum) ; i++) + if (country_isonums[i].isonum == isonum) + return country_isonums[i].postal_prefix; + return NULL; } -struct item_range town_ranges[]={ - {type_town_label,type_port_label}, +struct item_range town_ranges[]= { + {type_town_label,type_port_label}, }; -struct item_range street_ranges[]={ - {type_street_nopass,type_street_unkn}, +struct item_range street_ranges[]= { + {type_street_nopass,type_street_unkn}, }; -struct item_range poly_ranges[]={ - {type_border_country,type_water_line}, - {type_street_unkn,type_street_unkn}, - {type_area,type_last}, +struct item_range poly_ranges[]= { + {type_border_country,type_water_line}, + {type_street_unkn,type_street_unkn}, + {type_area,type_last}, }; -static int -file_next(struct map_rect_priv *mr) -{ - int debug=0; - - for (;;) { - mr->current_file++; - if (mr->current_file >= file_end) - return 0; - mr->file=mr->m->file[mr->current_file]; - if (! mr->file) - continue; - switch (mr->current_file) { - case file_strname_stn: - continue; - case file_town_twn: - if (mr->cur_sel && !map_selection_contains_item_range(mr->cur_sel, 0, town_ranges, sizeof(town_ranges)/sizeof(struct item_range))) - continue; - break; - case file_street_str: - if (mr->cur_sel && !map_selection_contains_item_range(mr->cur_sel, 0, street_ranges, sizeof(street_ranges)/sizeof(struct item_range))) - continue; - break; - default: - if (mr->cur_sel && !map_selection_contains_item_range(mr->cur_sel, 0, poly_ranges, sizeof(poly_ranges)/sizeof(struct item_range))) - continue; - break; - } - if (debug) - printf("current file: '%s'\n", file[mr->current_file]); - mr->cur_sel=mr->xsel; - if (block_init(mr)) - return 1; - } +static int file_next(struct map_rect_priv *mr) { + int debug=0; + + for (;;) { + mr->current_file++; + if (mr->current_file >= file_end) + return 0; + mr->file=mr->m->file[mr->current_file]; + if (! mr->file) + continue; + switch (mr->current_file) { + case file_strname_stn: + continue; + case file_town_twn: + if (mr->cur_sel + && !map_selection_contains_item_range(mr->cur_sel, 0, town_ranges, sizeof(town_ranges)/sizeof(struct item_range))) + continue; + break; + case file_street_str: + if (mr->cur_sel + && !map_selection_contains_item_range(mr->cur_sel, 0, street_ranges, sizeof(street_ranges)/sizeof(struct item_range))) + continue; + break; + default: + if (mr->cur_sel + && !map_selection_contains_item_range(mr->cur_sel, 0, poly_ranges, sizeof(poly_ranges)/sizeof(struct item_range))) + continue; + break; + } + if (debug) + printf("current file: '%s'\n", file[mr->current_file]); + mr->cur_sel=mr->xsel; + if (block_init(mr)) + return 1; + } } -static void -map_destroy_mg(struct map_priv *m) -{ - int i; +static void map_destroy_mg(struct map_priv *m) { + int i; - printf("mg_map_destroy\n"); - for (i = 0 ; i < file_end ; i++) { - if (m->file[i]) - file_destroy(m->file[i]); - } + printf("mg_map_destroy\n"); + for (i = 0 ; i < file_end ; i++) { + if (m->file[i]) + file_destroy(m->file[i]); + } } extern int block_lin_count,block_idx_count,block_active_count,block_mem,block_active_mem; struct map_rect_priv * -map_rect_new_mg(struct map_priv *map, struct map_selection *sel) -{ - struct map_rect_priv *mr; - int i; - - block_lin_count=0; - block_idx_count=0; - block_active_count=0; - block_mem=0; - block_active_mem=0; - mr=g_new0(struct map_rect_priv, 1); - mr->m=map; - mr->xsel=sel; - mr->current_file=-1; - if (sel && sel->next) - for (i=0 ; i < file_end ; i++) - mr->block_hash[i]=g_hash_table_new(g_int_hash,g_int_equal); - file_next(mr); - return mr; +map_rect_new_mg(struct map_priv *map, struct map_selection *sel) { + struct map_rect_priv *mr; + int i; + + block_lin_count=0; + block_idx_count=0; + block_active_count=0; + block_mem=0; + block_active_mem=0; + mr=g_new0(struct map_rect_priv, 1); + mr->m=map; + mr->xsel=sel; + mr->current_file=-1; + if (sel && sel->next) + for (i=0 ; i < file_end ; i++) + mr->block_hash[i]=g_hash_table_new(g_int_hash,g_int_equal); + file_next(mr); + return mr; } -static struct item * -map_rect_get_item_mg(struct map_rect_priv *mr) -{ - for (;;) { - switch (mr->current_file) { - case file_town_twn: - if (town_get(mr, &mr->town, &mr->item)) - return &mr->item; - break; - case file_border_ply: - case file_bridge_ply: - case file_build_ply: - case file_golf_ply: - /* case file_height_ply: */ - case file_natpark_ply: - case file_nature_ply: - case file_other_ply: - case file_rail_ply: - case file_sea_ply: - /* case file_tunnel_ply: */ - case file_water_ply: - case file_woodland_ply: - if (poly_get(mr, &mr->poly, &mr->item)) - return &mr->item; - break; - case file_street_str: - if (street_get(mr, &mr->street, &mr->item)) - return &mr->item; - break; - case file_end: - return NULL; - default: - break; - } - if (block_next(mr)) - continue; - if (mr->cur_sel->next) { - mr->cur_sel=mr->cur_sel->next; - if (block_init(mr)) - continue; - } - if (file_next(mr)) - continue; - dbg(lvl_debug,"lin_count %d idx_count %d active_count %d %d kB (%d kB)\n", block_lin_count, block_idx_count, block_active_count, (block_mem+block_active_mem)/1024, block_active_mem/1024); - return NULL; - } +static struct item *map_rect_get_item_mg(struct map_rect_priv *mr) { + for (;;) { + switch (mr->current_file) { + case file_town_twn: + if (town_get(mr, &mr->town, &mr->item)) + return &mr->item; + break; + case file_border_ply: + case file_bridge_ply: + case file_build_ply: + case file_golf_ply: + /* case file_height_ply: */ + case file_natpark_ply: + case file_nature_ply: + case file_other_ply: + case file_rail_ply: + case file_sea_ply: + /* case file_tunnel_ply: */ + case file_water_ply: + case file_woodland_ply: + if (poly_get(mr, &mr->poly, &mr->item)) + return &mr->item; + break; + case file_street_str: + if (street_get(mr, &mr->street, &mr->item)) + return &mr->item; + break; + case file_end: + return NULL; + default: + break; + } + if (block_next(mr)) + continue; + if (mr->cur_sel->next) { + mr->cur_sel=mr->cur_sel->next; + if (block_init(mr)) + continue; + } + if (file_next(mr)) + continue; + dbg(lvl_debug,"lin_count %d idx_count %d active_count %d %d kB (%d kB)", block_lin_count, block_idx_count, + block_active_count, (block_mem+block_active_mem)/1024, block_active_mem/1024); + return NULL; + } } struct item * -map_rect_get_item_byid_mg(struct map_rect_priv *mr, int id_hi, int id_lo) -{ - mr->current_file = (id_hi >> 16) & 0xff; - switch (mr->current_file) { - case file_town_twn: - if (town_get_byid(mr, &mr->town, id_hi, id_lo, &mr->item)) - return &mr->item; - break; - case file_street_str: - if (street_get_byid(mr, &mr->street, id_hi, id_lo, &mr->item)) - return &mr->item; - break; - case file_strname_stn: - if (street_name_get_byid(mr, &mr->street, id_hi, id_lo, &mr->item)) - return &mr->item; - break; - default: - if (poly_get_byid(mr, &mr->poly, id_hi, id_lo, &mr->item)) - return &mr->item; - break; - } - return NULL; +map_rect_get_item_byid_mg(struct map_rect_priv *mr, int id_hi, int id_lo) { + mr->current_file = (id_hi >> 16) & 0xff; + switch (mr->current_file) { + case file_town_twn: + if (town_get_byid(mr, &mr->town, id_hi, id_lo, &mr->item)) + return &mr->item; + break; + case file_street_str: + if (street_get_byid(mr, &mr->street, id_hi, id_lo, &mr->item)) + return &mr->item; + break; + case file_strname_stn: + if (street_name_get_byid(mr, &mr->street, id_hi, id_lo, &mr->item)) + return &mr->item; + break; + default: + if (poly_get_byid(mr, &mr->poly, id_hi, id_lo, &mr->item)) + return &mr->item; + break; + } + return NULL; } -void -map_rect_destroy_mg(struct map_rect_priv *mr) -{ - int i; - for (i=0 ; i < file_end ; i++) - if (mr->block_hash[i]) - g_hash_table_destroy(mr->block_hash[i]); - g_free(mr); +void map_rect_destroy_mg(struct map_rect_priv *mr) { + int i; + for (i=0 ; i < file_end ; i++) + if (mr->block_hash[i]) + g_hash_table_destroy(mr->block_hash[i]); + g_free(mr); } -static char * -map_search_mg_convert_special(char *str) -{ - char *ret,*c=g_malloc(strlen(str)*2+1); - - ret=c; - for (;;) { - switch ((unsigned char)(*str)) { - case 0xc4: - *c++='A'; - break; - case 0xd6: - *c++='O'; - break; - case 0xdc: - *c++='U'; - break; - case 0xdf: - *c++='s'; - *c++='s'; - break; - case 0xe4: - *c++='a'; - break; - case 0xf6: - *c++='o'; - break; - case 0xfc: - *c++='u'; - break; - default: - dbg(lvl_debug,"0x%x\n", *str); - *c++=*str; - break; - } - if (! *str) - return ret; - str++; - } +static char *map_search_mg_convert_special(char *str) { + char *ret,*c=g_malloc(strlen(str)*2+1); + + ret=c; + for (;;) { + switch ((unsigned char)(*str)) { + case 0xc4: + *c++='A'; + break; + case 0xd6: + *c++='O'; + break; + case 0xdc: + *c++='U'; + break; + case 0xdf: + *c++='s'; + *c++='s'; + break; + case 0xe4: + *c++='a'; + break; + case 0xf6: + *c++='o'; + break; + case 0xfc: + *c++='u'; + break; + default: + dbg(lvl_debug,"0x%x", *str); + *c++=*str; + break; + } + if (! *str) + return ret; + str++; + } } -static int -map_search_setup(struct map_rect_priv *mr) -{ - char *prefix; - dbg(lvl_debug,"%s\n", attr_to_name(mr->search_type)); - switch (mr->search_type) { - case attr_town_postal: - if (mr->search_item.type != type_country_label) { - dbg(lvl_error,"wrong parent type %s\n", item_to_name(mr->search_item.type)); - return 0; - } - prefix=mg_country_postal_prefix(mr->search_item.id_lo); - if (! prefix) - return 0; - tree_search_init(mr->m->dirname, "town.b1", &mr->ts, 0); - mr->current_file=file_town_twn; - mr->search_str=g_strdup_printf("%s%s",prefix,mr->search_attr->u.str); - dbg(lvl_debug,"search_str='%s'\n",mr->search_str); - mr->search_country=mg_country_from_isonum(mr->search_item.id_lo); - break; - case attr_town_name: - if (mr->search_item.type != type_country_label) { - dbg(lvl_error,"wrong parent type %s\n", item_to_name(mr->search_item.type)); - return 0; - } - tree_search_init(mr->m->dirname, "town.b2", &mr->ts, 0x1000); - mr->current_file=file_town_twn; - mr->search_str=map_search_mg_convert_special(mr->search_attr->u.str); - mr->search_country=mg_country_from_isonum(mr->search_item.id_lo); - break; - case attr_district_name: - if (mr->search_item.type != type_country_label) { - dbg(lvl_error,"wrong parent type %s\n", item_to_name(mr->search_item.type)); - return 0; - } - tree_search_init(mr->m->dirname, "town.b3", &mr->ts, 0x1000); - mr->current_file=file_town_twn; - mr->search_str=map_search_mg_convert_special(mr->search_attr->u.str); - mr->search_country=mg_country_from_isonum(mr->search_item.id_lo); - break; - case attr_street_name: - if (mr->search_item.type != type_town_streets) { - GList *tmp=maps; - struct item *item=NULL; - struct attr attr; - struct map_rect_priv *mr2; - while (tmp) { - mr2=map_rect_new_mg(tmp->data, NULL); - item=map_rect_get_item_byid_mg(mr2, mr->search_item.id_hi, mr->search_item.id_lo); - if (item) - break; - map_rect_destroy_mg(mr2); - tmp=g_list_next(tmp); - } - if (item) { - if (item_attr_get(item, attr_town_streets_item, &attr)) { - mr->search_item=*attr.u.item; - map_rect_destroy_mg(mr2); - } else { - map_rect_destroy_mg(mr2); - return 0; - } - } else { - dbg(lvl_error,"wrong parent type %s %p 0x%x 0x%x\n", item_to_name(mr->search_item.type), item, mr->search_item.id_hi, mr->search_item.id_lo); - return 0; - } - } - dbg(lvl_debug,"street_assoc=0x%x\n", mr->search_item.id_lo); - tree_search_init(mr->m->dirname, "strname.b1", &mr->ts, 0); - mr->current_file=file_strname_stn; - mr->search_str=g_strdup(mr->search_attr->u.str); - break; - case attr_house_number: - if (!map_priv_is(mr->search_item.map, mr->m)) - return 0; - if (!housenumber_search_setup(mr)) { - dbg(lvl_error,"failed to search for attr_house_number\n"); - return 0; - } - break; - default: - dbg(lvl_error,"unknown search %s\n",attr_to_name(mr->search_type)); - return 0; - } - mr->file=mr->m->file[mr->current_file]; - block_init(mr); - return 1; +static int map_search_setup(struct map_rect_priv *mr) { + char *prefix; + dbg(lvl_debug,"%s", attr_to_name(mr->search_type)); + switch (mr->search_type) { + case attr_town_postal: + if (mr->search_item.type != type_country_label) { + dbg(lvl_error,"wrong parent type %s", item_to_name(mr->search_item.type)); + return 0; + } + prefix=mg_country_postal_prefix(mr->search_item.id_lo); + if (! prefix) + return 0; + tree_search_init(mr->m->dirname, "town.b1", &mr->ts, 0); + mr->current_file=file_town_twn; + mr->search_str=g_strdup_printf("%s%s",prefix,mr->search_attr->u.str); + dbg(lvl_debug,"search_str='%s'",mr->search_str); + mr->search_country=mg_country_from_isonum(mr->search_item.id_lo); + break; + case attr_town_name: + if (mr->search_item.type != type_country_label) { + dbg(lvl_error,"wrong parent type %s", item_to_name(mr->search_item.type)); + return 0; + } + tree_search_init(mr->m->dirname, "town.b2", &mr->ts, 0x1000); + mr->current_file=file_town_twn; + mr->search_str=map_search_mg_convert_special(mr->search_attr->u.str); + mr->search_country=mg_country_from_isonum(mr->search_item.id_lo); + break; + case attr_district_name: + if (mr->search_item.type != type_country_label) { + dbg(lvl_error,"wrong parent type %s", item_to_name(mr->search_item.type)); + return 0; + } + tree_search_init(mr->m->dirname, "town.b3", &mr->ts, 0x1000); + mr->current_file=file_town_twn; + mr->search_str=map_search_mg_convert_special(mr->search_attr->u.str); + mr->search_country=mg_country_from_isonum(mr->search_item.id_lo); + break; + case attr_street_name: + if (mr->search_item.type != type_town_streets) { + GList *tmp=maps; + struct item *item=NULL; + struct attr attr; + struct map_rect_priv *mr2; + while (tmp) { + mr2=map_rect_new_mg(tmp->data, NULL); + item=map_rect_get_item_byid_mg(mr2, mr->search_item.id_hi, mr->search_item.id_lo); + if (item) + break; + map_rect_destroy_mg(mr2); + tmp=g_list_next(tmp); + } + if (item) { + if (item_attr_get(item, attr_town_streets_item, &attr)) { + mr->search_item=*attr.u.item; + map_rect_destroy_mg(mr2); + } else { + map_rect_destroy_mg(mr2); + return 0; + } + } else { + dbg(lvl_error,"wrong parent type %s %p 0x%x 0x%x", item_to_name(mr->search_item.type), item, mr->search_item.id_hi, + mr->search_item.id_lo); + return 0; + } + } + dbg(lvl_debug,"street_assoc=0x%x", mr->search_item.id_lo); + tree_search_init(mr->m->dirname, "strname.b1", &mr->ts, 0); + mr->current_file=file_strname_stn; + mr->search_str=g_strdup(mr->search_attr->u.str); + break; + case attr_house_number: + if (!map_priv_is(mr->search_item.map, mr->m)) + return 0; + if (!housenumber_search_setup(mr)) { + dbg(lvl_error,"failed to search for attr_house_number"); + return 0; + } + break; + default: + dbg(lvl_error,"unknown search %s",attr_to_name(mr->search_type)); + return 0; + } + mr->file=mr->m->file[mr->current_file]; + block_init(mr); + return 1; } static void map_search_cleanup(struct map_rect_priv *mr); static struct item * map_search_get_item_mg(struct map_search_priv *ms); -static struct map_search_priv * -map_search_new_mg(struct map_priv *map, struct item *item, struct attr *search, int partial) -{ - struct map_rect_priv *mr=g_new0(struct map_rect_priv, 1); - dbg(lvl_debug,"searching for %s '%s'\n", attr_to_name(search->type), search->u.str); - dbg(lvl_debug,"id_lo=0x%x\n", item->id_lo); - dbg(lvl_debug,"search=%s\n", search->u.str); - mr->m=map; - mr->search_attr=attr_dup(search); - mr->search_type=search->type; - mr->search_item=*item; - mr->search_partial=partial; - if (search->type == attr_town_or_district_name) { - mr->search_type=attr_town_name; - mr->search_type_next=attr_district_name; - } - if (!map_search_setup(mr)) { - dbg(lvl_warning,"map_search_new_mg failed\n"); - g_free(mr); - return NULL; - } - mr->search_mr_tmp=map_rect_new_mg(map, NULL); - - return (struct map_search_priv *)mr; +static struct map_search_priv *map_search_new_mg(struct map_priv *map, struct item *item, struct attr *search, + int partial) { + struct map_rect_priv *mr=g_new0(struct map_rect_priv, 1); + dbg(lvl_debug,"searching for %s '%s'", attr_to_name(search->type), search->u.str); + dbg(lvl_debug,"id_lo=0x%x", item->id_lo); + dbg(lvl_debug,"search=%s", search->u.str); + mr->m=map; + mr->search_attr=attr_dup(search); + mr->search_type=search->type; + mr->search_item=*item; + mr->search_partial=partial; + if (search->type == attr_town_or_district_name) { + mr->search_type=attr_town_name; + mr->search_type_next=attr_district_name; + } + if (!map_search_setup(mr)) { + dbg(lvl_warning,"map_search_new_mg failed"); + g_free(mr); + return NULL; + } + mr->search_mr_tmp=map_rect_new_mg(map, NULL); + + return (struct map_search_priv *)mr; } -static void -map_search_cleanup(struct map_rect_priv *mr) -{ - g_free(mr->search_str); - mr->search_str=NULL; - tree_search_free(&mr->ts); - mr->search_linear=0; - mr->search_p=NULL; - mr->search_blk_count=0; - mr->search_blk_off=NULL; - mr->search_block=0; +static void map_search_cleanup(struct map_rect_priv *mr) { + g_free(mr->search_str); + mr->search_str=NULL; + tree_search_free(&mr->ts); + mr->search_linear=0; + mr->search_p=NULL; + mr->search_blk_count=0; + mr->search_blk_off=NULL; + mr->search_block=0; } -static void -map_search_destroy_mg(struct map_search_priv *ms) -{ - struct map_rect_priv *mr=(struct map_rect_priv *)ms; - - dbg(lvl_debug,"mr=%p\n", mr); - if (! mr) - return; - map_search_cleanup(mr); - if (mr->search_mr_tmp) - map_rect_destroy_mg(mr->search_mr_tmp); - attr_free(mr->search_attr); - g_free(mr); +static void map_search_destroy_mg(struct map_search_priv *ms) { + struct map_rect_priv *mr=(struct map_rect_priv *)ms; + + dbg(lvl_debug,"mr=%p", mr); + if (! mr) + return; + map_search_cleanup(mr); + if (mr->search_mr_tmp) + map_rect_destroy_mg(mr->search_mr_tmp); + attr_free(mr->search_attr); + g_free(mr); } -static struct item * -map_search_get_item_mg(struct map_search_priv *ms) -{ - struct map_rect_priv *mr=(struct map_rect_priv *)ms; - struct item *ret=NULL; - - if (! mr) - return NULL; - switch (mr->search_type) { - case attr_town_postal: - case attr_town_name: - case attr_district_name: - ret=town_search_get_item(mr); - break; - case attr_street_name: - ret=street_search_get_item(mr); - break; - case attr_house_number: - ret=housenumber_search_get_item(mr); - break; - default: - dbg(lvl_error,"unknown search %s\n",attr_to_name(mr->search_type)); - break; - } - if (!ret && mr->search_type_next != attr_none) { - mr->search_type=mr->search_type_next; - mr->search_type_next=attr_none; - map_search_cleanup(mr); - map_search_setup(mr); - return map_search_get_item_mg(ms); - } - return ret; +static struct item *map_search_get_item_mg(struct map_search_priv *ms) { + struct map_rect_priv *mr=(struct map_rect_priv *)ms; + struct item *ret=NULL; + + if (! mr) + return NULL; + switch (mr->search_type) { + case attr_town_postal: + case attr_town_name: + case attr_district_name: + ret=town_search_get_item(mr); + break; + case attr_street_name: + ret=street_search_get_item(mr); + break; + case attr_house_number: + ret=housenumber_search_get_item(mr); + break; + default: + dbg(lvl_error,"unknown search %s",attr_to_name(mr->search_type)); + break; + } + if (!ret && mr->search_type_next != attr_none) { + mr->search_type=mr->search_type_next; + mr->search_type_next=attr_none; + map_search_cleanup(mr); + map_search_setup(mr); + return map_search_get_item_mg(ms); + } + return ret; } static struct map_methods map_methods_mg = { - projection_mg, - "iso8859-1", - map_destroy_mg, - map_rect_new_mg, - map_rect_destroy_mg, - map_rect_get_item_mg, - map_rect_get_item_byid_mg, - map_search_new_mg, - map_search_destroy_mg, - map_search_get_item_mg, + projection_mg, + "iso8859-1", + map_destroy_mg, + map_rect_new_mg, + map_rect_destroy_mg, + map_rect_get_item_mg, + map_rect_get_item_byid_mg, + map_search_new_mg, + map_search_destroy_mg, + map_search_get_item_mg, }; struct map_priv * -map_new_mg(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) -{ - struct map_priv *m; - int i,maybe_missing; - struct attr *data=attr_search(attrs, NULL, attr_data); - char *filename; - struct file_wordexp *wexp; - char **wexp_data; - - if (! data) - return NULL; - - wexp=file_wordexp_new(data->u.str); - wexp_data=file_wordexp_get_array(wexp); - - *meth=map_methods_mg; - data=attr_search(attrs, NULL, attr_data); - - m=g_new(struct map_priv, 1); - m->id=++map_id; - m->dirname=g_strdup(wexp_data[0]); - file_wordexp_destroy(wexp); - for (i = 0 ; i < file_end ; i++) { - if (file[i]) { - filename=g_strdup_printf("%s/%s", m->dirname, file[i]); - m->file[i]=file_create_caseinsensitive(filename, 0); - if (! m->file[i]) { - maybe_missing=(i == file_border_ply || i == file_height_ply || i == file_sea_ply); - if (! maybe_missing) - dbg(lvl_error,"Failed to load %s\n", filename); - } else - file_mmap(m->file[i]); - g_free(filename); - } - } - maps=g_list_append(maps, m); - - return m; +map_new_mg(struct map_methods *meth, struct attr **attrs, struct callback_list *cbl) { + struct map_priv *m; + int i,maybe_missing; + struct attr *data=attr_search(attrs, NULL, attr_data); + char *filename; + struct file_wordexp *wexp; + char **wexp_data; + + if (! data) + return NULL; + + wexp=file_wordexp_new(data->u.str); + wexp_data=file_wordexp_get_array(wexp); + + *meth=map_methods_mg; + data=attr_search(attrs, NULL, attr_data); + + m=g_new(struct map_priv, 1); + m->id=++map_id; + m->dirname=g_strdup(wexp_data[0]); + file_wordexp_destroy(wexp); + for (i = 0 ; i < file_end ; i++) { + if (file[i]) { + filename=g_strdup_printf("%s/%s", m->dirname, file[i]); + m->file[i]=file_create_caseinsensitive(filename, 0); + if (! m->file[i]) { + maybe_missing=(i == file_border_ply || i == file_height_ply || i == file_sea_ply); + if (! maybe_missing) + dbg(lvl_error,"Failed to load %s", filename); + } else + file_mmap(m->file[i]); + g_free(filename); + } + } + maps=g_list_append(maps, m); + + return m; } -void -plugin_init(void) -{ - plugin_register_category_map("mg", map_new_mg); +void plugin_init(void) { + plugin_register_category_map("mg", map_new_mg); } diff --git a/navit/map/mg/poly.c b/navit/map/mg/poly.c index 7c73d4587..2c42d9740 100644 --- a/navit/map/mg/poly.c +++ b/navit/map/mg/poly.c @@ -21,245 +21,232 @@ #include "debug.h" #include "mg.h" -static void -poly_coord_rewind(void *priv_data) -{ - struct poly_priv *poly=priv_data; +static void poly_coord_rewind(void *priv_data) { + struct poly_priv *poly=priv_data; - poly->p=poly->subpoly_start; + poly->p=poly->subpoly_start; } -static int -poly_coord_get(void *priv_data, struct coord *c, int count) -{ - struct poly_priv *poly=priv_data; - int ret=0; - - while (count--) { - if (poly->p >= poly->subpoly_next) - break; - c->x=get_u32_unal(&poly->p); - c->y=get_u32_unal(&poly->p); - c++; - ret++; - } - return ret; +static int poly_coord_get(void *priv_data, struct coord *c, int count) { + struct poly_priv *poly=priv_data; + int ret=0; + + while (count--) { + if (poly->p >= poly->subpoly_next) + break; + c->x=get_u32_unal(&poly->p); + c->y=get_u32_unal(&poly->p); + c++; + ret++; + } + return ret; } -static void -poly_attr_rewind(void *priv_data) -{ - struct poly_priv *poly=priv_data; +static void poly_attr_rewind(void *priv_data) { + struct poly_priv *poly=priv_data; - poly->aidx=0; + poly->aidx=0; } -static int -poly_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) -{ - struct poly_priv *poly=priv_data; +static int poly_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { + struct poly_priv *poly=priv_data; - attr->type=attr_type; - switch (attr_type) { - case attr_any: - while (poly->attr_next != attr_none) { - if (poly_attr_get(poly, poly->attr_next, attr)) - return 1; - } - return 0; - case attr_label: - attr->u.str=poly->name; - poly->attr_next=attr_none; - if (attr->u.str[0]) - return 1; - return 0; - default: - return 0; - } - return 1; + attr->type=attr_type; + switch (attr_type) { + case attr_any: + while (poly->attr_next != attr_none) { + if (poly_attr_get(poly, poly->attr_next, attr)) + return 1; + } + return 0; + case attr_label: + attr->u.str=poly->name; + poly->attr_next=attr_none; + if (attr->u.str[0]) + return 1; + return 0; + default: + return 0; + } + return 1; } static struct item_methods poly_meth = { - poly_coord_rewind, - poly_coord_get, - poly_attr_rewind, - poly_attr_get, + poly_coord_rewind, + poly_coord_get, + poly_attr_rewind, + poly_attr_get, }; -static void -poly_get_data(struct poly_priv *poly, unsigned char **p) -{ - poly->c[0].x=get_u32_unal(p); - poly->c[0].y=get_u32_unal(p); - poly->c[1].x=get_u32_unal(p); - poly->c[1].y=get_u32_unal(p); - *p+=sizeof(struct coord); - poly->name=(char *)(*p); - while (**p) { - (*p)++; - } - (*p)++; - poly->order=*(*p)++; - poly->type=*(*p)++; - poly->polys=get_u32_unal(p); - poly->count=(unsigned int *)(*p); (*p)+=poly->polys*sizeof(unsigned int); - poly->count_sum=get_u32_unal(p); +static void poly_get_data(struct poly_priv *poly, unsigned char **p) { + poly->c[0].x=get_u32_unal(p); + poly->c[0].y=get_u32_unal(p); + poly->c[1].x=get_u32_unal(p); + poly->c[1].y=get_u32_unal(p); + *p+=sizeof(struct coord); + poly->name=(char *)(*p); + while (**p) { + (*p)++; + } + (*p)++; + poly->order=*(*p)++; + poly->type=*(*p)++; + poly->polys=get_u32_unal(p); + poly->count=(unsigned int *)(*p); + (*p)+=poly->polys*sizeof(unsigned int); + poly->count_sum=get_u32_unal(p); } -int -poly_get(struct map_rect_priv *mr, struct poly_priv *poly, struct item *item) -{ - struct coord_rect r; - - for (;;) { - if (mr->b.p >= mr->b.end) - return 0; - if (mr->b.p == mr->b.p_start) { - poly->poly_num=0; - poly->subpoly_num=0; - poly->subpoly_num_all=0; - poly->poly_next=mr->b.p; - item->meth=&poly_meth; - } - if (poly->poly_num >= block_get_count(mr->b.b)) - return 0; - if (!poly->subpoly_num) { - mr->b.p=poly->poly_next; - item->id_lo=mr->b.p-mr->file->begin; - poly_get_data(poly, &mr->b.p); - poly->poly_next=mr->b.p+poly->count_sum*sizeof(struct coord); - poly->poly_num++; - r.lu=poly->c[0]; - r.rl=poly->c[1]; - if (mr->cur_sel && (poly->order > mr->cur_sel->order*3 || !coord_rect_overlap(&mr->cur_sel->u.c_rect, &r))) { - poly->subpoly_num_all+=poly->polys; - mr->b.p=poly->poly_next; - continue; - } - switch(poly->type) { - case 0x13: - item->type=type_poly_wood; - break; - case 0x14: - item->type=type_poly_town; - break; - case 0x15: - item->type=type_poly_cemetery; - break; - case 0x16: - item->type=type_poly_building; - break; - case 0x17: - item->type=type_poly_museum; - break; - case 0x19: - item->type=type_poly_place; - break; - case 0x1b: - item->type=type_poly_commercial_center; - break; - case 0x1e: - item->type=type_poly_industry; - break; - case 0x23: - /* FIXME: what is this ?*/ - item->type=type_poly_place; - break; - case 0x24: - item->type=type_poly_car_parking; - break; - case 0x28: - item->type=type_poly_airport; - break; - case 0x29: - item->type=type_poly_station; - break; - case 0x2d: - item->type=type_poly_hospital; - break; - case 0x2e: - item->type=type_poly_hospital; - break; - case 0x2f: - item->type=type_poly_university; - break; - case 0x30: - item->type=type_poly_university; - break; - case 0x32: - item->type=type_poly_park; - break; - case 0x34: - item->type=type_poly_sport; - break; - case 0x35: - item->type=type_poly_sport; - break; - case 0x37: - item->type=type_poly_golf_course; - break; - case 0x38: - item->type=type_poly_national_park; - break; - case 0x39: - item->type=type_poly_nature_park; - break; - case 0x3c: - item->type=type_poly_water; - break; - case 0xbc: - item->type=type_water_line; - break; - case 0xc3: - /* FIXME: what is this ?*/ - item->type=type_border_state; - break; - case 0xc6: - item->type=type_border_country; - break; - case 0xc7: - item->type=type_border_state; - break; - case 0xd0: - item->type=type_rail; - break; - default: - dbg(lvl_error,"Unknown poly type 0x%x '%s' 0x%x,0x%x\n", poly->type,poly->name,r.lu.x,r.lu.y); - item->type=type_street_unkn; - } - if (!map_selection_contains_item(mr->cur_sel, 0, item->type)) { - poly->subpoly_num_all+=poly->polys; - mr->b.p=poly->poly_next; - continue; - } - } else - mr->b.p=poly->subpoly_next; - dbg(lvl_debug,"%d %d %s\n", poly->subpoly_num_all, mr->b.block_num, poly->name); - item->id_lo=poly->subpoly_num_all | (mr->b.block_num << 16); - item->id_hi=(mr->current_file << 16); - dbg(lvl_debug,"0x%x 0x%x\n", item->id_lo, item->id_hi); - poly->subpoly_next=mr->b.p+L(poly->count[poly->subpoly_num])*sizeof(struct coord); - poly->subpoly_num++; - poly->subpoly_num_all++; - if (poly->subpoly_num >= poly->polys) - poly->subpoly_num=0; - poly->subpoly_start=poly->p=mr->b.p; - item->priv_data=poly; - poly->attr_next=attr_label; - return 1; +int poly_get(struct map_rect_priv *mr, struct poly_priv *poly, struct item *item) { + struct coord_rect r; + + for (;;) { + if (mr->b.p >= mr->b.end) + return 0; + if (mr->b.p == mr->b.p_start) { + poly->poly_num=0; + poly->subpoly_num=0; + poly->subpoly_num_all=0; + poly->poly_next=mr->b.p; + item->meth=&poly_meth; } + if (poly->poly_num >= block_get_count(mr->b.b)) + return 0; + if (!poly->subpoly_num) { + mr->b.p=poly->poly_next; + item->id_lo=mr->b.p-mr->file->begin; + poly_get_data(poly, &mr->b.p); + poly->poly_next=mr->b.p+poly->count_sum*sizeof(struct coord); + poly->poly_num++; + r.lu=poly->c[0]; + r.rl=poly->c[1]; + if (mr->cur_sel && (poly->order > mr->cur_sel->order*3 || !coord_rect_overlap(&mr->cur_sel->u.c_rect, &r))) { + poly->subpoly_num_all+=poly->polys; + mr->b.p=poly->poly_next; + continue; + } + switch(poly->type) { + case 0x13: + item->type=type_poly_wood; + break; + case 0x14: + item->type=type_poly_town; + break; + case 0x15: + item->type=type_poly_cemetery; + break; + case 0x16: + item->type=type_poly_building; + break; + case 0x17: + item->type=type_poly_museum; + break; + case 0x19: + item->type=type_poly_place; + break; + case 0x1b: + item->type=type_poly_commercial_center; + break; + case 0x1e: + item->type=type_poly_industry; + break; + case 0x23: + /* FIXME: what is this ?*/ + item->type=type_poly_place; + break; + case 0x24: + item->type=type_poly_car_parking; + break; + case 0x28: + item->type=type_poly_airport; + break; + case 0x29: + item->type=type_poly_station; + break; + case 0x2d: + item->type=type_poly_hospital; + break; + case 0x2e: + item->type=type_poly_hospital; + break; + case 0x2f: + item->type=type_poly_university; + break; + case 0x30: + item->type=type_poly_university; + break; + case 0x32: + item->type=type_poly_park; + break; + case 0x34: + item->type=type_poly_sport; + break; + case 0x35: + item->type=type_poly_sport; + break; + case 0x37: + item->type=type_poly_golf_course; + break; + case 0x38: + item->type=type_poly_national_park; + break; + case 0x39: + item->type=type_poly_nature_park; + break; + case 0x3c: + item->type=type_poly_water; + break; + case 0xbc: + item->type=type_water_line; + break; + case 0xc3: + /* FIXME: what is this ?*/ + item->type=type_border_state; + break; + case 0xc6: + item->type=type_border_country; + break; + case 0xc7: + item->type=type_border_state; + break; + case 0xd0: + item->type=type_rail; + break; + default: + dbg(lvl_error,"Unknown poly type 0x%x '%s' 0x%x,0x%x", poly->type,poly->name,r.lu.x,r.lu.y); + item->type=type_street_unkn; + } + if (!map_selection_contains_item(mr->cur_sel, 0, item->type)) { + poly->subpoly_num_all+=poly->polys; + mr->b.p=poly->poly_next; + continue; + } + } else + mr->b.p=poly->subpoly_next; + dbg(lvl_debug,"%d %d %s", poly->subpoly_num_all, mr->b.block_num, poly->name); + item->id_lo=poly->subpoly_num_all | (mr->b.block_num << 16); + item->id_hi=(mr->current_file << 16); + dbg(lvl_debug,"0x%x 0x%x", item->id_lo, item->id_hi); + poly->subpoly_next=mr->b.p+L(poly->count[poly->subpoly_num])*sizeof(struct coord); + poly->subpoly_num++; + poly->subpoly_num_all++; + if (poly->subpoly_num >= poly->polys) + poly->subpoly_num=0; + poly->subpoly_start=poly->p=mr->b.p; + item->priv_data=poly; + poly->attr_next=attr_label; + return 1; + } } -int -poly_get_byid(struct map_rect_priv *mr, struct poly_priv *poly, int id_hi, int id_lo, struct item *item) -{ - int count=id_lo & 0xffff; - int ret=0; - block_get_byindex(mr->m->file[mr->current_file], id_lo >> 16, &mr->b); - while (count-- >= 0) { - ret=poly_get(mr, poly, item); - } - return ret; +int poly_get_byid(struct map_rect_priv *mr, struct poly_priv *poly, int id_hi, int id_lo, struct item *item) { + int count=id_lo & 0xffff; + int ret=0; + block_get_byindex(mr->m->file[mr->current_file], id_lo >> 16, &mr->b); + while (count-- >= 0) { + ret=poly_get(mr, poly, item); + } + return ret; } diff --git a/navit/map/mg/street.c b/navit/map/mg/street.c index 6aad6e5a0..d0841f4bc 100644 --- a/navit/map/mg/street.c +++ b/navit/map/mg/street.c @@ -30,780 +30,689 @@ int coord_debug; static void street_name_numbers_get(struct street_name_numbers *name_numbers, unsigned char **p); static void street_name_number_get(struct street_name_number *name_number, unsigned char **p); -static void -street_name_debug(struct street_name *sn, FILE *out) -{ - struct street_name_numbers nns; - unsigned char *p=sn->aux_data; - unsigned char *end=p+sn->aux_len; - int i; - - while (p < end) { - unsigned char *pn,*pn_end; - struct street_name_number nn; - street_name_numbers_get(&nns, &p); - fprintf(out,"0x%x 0x%x type=town_label label=\"%s(%d):0x%x:%d%s-%d%s\" debug=\"len=0x%x\"",nns.c->x,nns.c->y,sn->name2, sn->segment_count, nns.tag, nns.first.number,nns.first.suffix,nns.last.number,nns.last.suffix,nns.len); - for (i = 0 ; i < sn->segment_count ; i++) { - fprintf(out," debug=\"segment(%d)=0x%x\"",i,sn->segments[i].segid); - } - fprintf(out,"\n"); - pn=nns.aux_data; - pn_end=nns.aux_data+nns.aux_len; - while (pn < pn_end) { - street_name_number_get(&nn, &pn); - fprintf(out,"0x%x 0x%x type=town_label label=\"%s:0x%x:%d%s-%d%s\" debug=\"len=0x%x\"\n", nn.c->x, nn.c->y, sn->name2, nn.tag, nn.first.number, nn.first.suffix, nn.last.number,nn.last.suffix,nn.len); - } - } - fflush(out); +static void street_name_debug(struct street_name *sn, FILE *out) { + struct street_name_numbers nns; + unsigned char *p=sn->aux_data; + unsigned char *end=p+sn->aux_len; + int i; + + while (p < end) { + unsigned char *pn,*pn_end; + struct street_name_number nn; + street_name_numbers_get(&nns, &p); + fprintf(out,"0x%x 0x%x type=town_label label=\"%s(%d):0x%x:%d%s-%d%s\" debug=\"len=0x%x\"",nns.c->x,nns.c->y,sn->name2, + sn->segment_count, nns.tag, nns.first.number,nns.first.suffix,nns.last.number,nns.last.suffix,nns.len); + for (i = 0 ; i < sn->segment_count ; i++) { + fprintf(out," debug=\"segment(%d)=0x%x\"",i,sn->segments[i].segid); + } + fprintf(out,"\n"); + pn=nns.aux_data; + pn_end=nns.aux_data+nns.aux_len; + while (pn < pn_end) { + street_name_number_get(&nn, &pn); + fprintf(out,"0x%x 0x%x type=town_label label=\"%s:0x%x:%d%s-%d%s\" debug=\"len=0x%x\"\n", nn.c->x, nn.c->y, sn->name2, + nn.tag, nn.first.number, nn.first.suffix, nn.last.number,nn.last.suffix,nn.len); + } + } + fflush(out); } #endif -static void -street_name_get(struct street_name *name, unsigned char **p) -{ -#if 0 - static FILE *out; - static GHashTable *hash; -#endif - unsigned char *start=*p; - name->len=get_u16_unal(p); - name->country=get_u16_unal(p); - name->townassoc=get_u32_unal(p); - name->name1=get_string(p); - name->name2=get_string(p); - name->segment_count=get_u32_unal(p); - name->segments=(struct street_name_segment *)(*p); - (*p)+=(sizeof (struct street_name_segment))*name->segment_count; - name->aux_len=name->len-(*p-start); - name->aux_data=*p; - name->tmp_len=name->aux_len; - name->tmp_data=name->aux_data; - *p=start+name->len; -#if 0 - if (! out) { - out=fopen("hn.txt","a"); - } - if (! hash) { - hash=g_hash_table_new(NULL,NULL); - } - if (! g_hash_table_lookup(hash, *p)) { - g_hash_table_insert(hash, *p, (void *)1); - street_name_debug(name, out); - } -#endif -} - -static int -street_name_eod(struct street_name *name) -{ - return (name->tmp_data >= name->aux_data+name->aux_len); -} - -static void -street_name_numbers_get(struct street_name_numbers *name_numbers, unsigned char **p) -{ - unsigned char *start=*p; - name_numbers->len=get_u16_unal(p); - name_numbers->tag=get_u8(p); - name_numbers->dist=get_u32_unal(p); - name_numbers->country=get_u32_unal(p); - name_numbers->c=coord_get(p); - name_numbers->first.number=get_u16_unal(p); - name_numbers->first.suffix=get_string(p); - name_numbers->last.number=get_u16_unal(p); - name_numbers->last.suffix=get_string(p); - name_numbers->segment_count=get_u32_unal(p); - name_numbers->segments=(struct street_name_segment *)(*p); - (*p)+=sizeof(struct street_name_segment)*name_numbers->segment_count; - name_numbers->aux_len=name_numbers->len-(*p-start); - name_numbers->aux_data=*p; - name_numbers->tmp_len=name_numbers->aux_len; - name_numbers->tmp_data=name_numbers->aux_data; - *p=start+name_numbers->len; -} - -static int -street_name_numbers_eod(struct street_name_numbers *name_numbers) -{ - return (name_numbers->tmp_data >= name_numbers->aux_data+name_numbers->aux_len); -} - -static void -street_name_number_get(struct street_name_number *name_number, unsigned char **p) -{ - unsigned char *start=*p; - name_number->len=get_u16_unal(p); - name_number->tag=get_u8(p); - name_number->c=coord_get(p); - name_number->first.number=get_u16_unal(p); - name_number->first.suffix=get_string(p); - name_number->last.number=get_u16_unal(p); - name_number->last.suffix=get_string(p); - name_number->segment=(struct street_name_segment *)p; - *p=start+name_number->len; -} - -static void -street_name_get_by_id(struct street_name *name, struct file *file, unsigned long id) -{ - unsigned char *p; - if (id) { - p=file->begin+id+0x2000; - street_name_get(name, &p); - } -} - -static int street_get_bytes(struct coord_rect *r) -{ - int bytes,dx,dy; - bytes=2; - dx=r->rl.x-r->lu.x; - dy=r->lu.y-r->rl.y; - dbg_assert(dx > 0); - dbg_assert(dy > 0); - if (dx > 32767 || dy > 32767) - bytes=3; - if (dx > 8388608 || dy > 8388608) - bytes=4; - - return bytes; -} - -static int street_get_coord(unsigned char **pos, int bytes, struct coord_rect *ref, struct coord *f) -{ - unsigned char *p; - int x,y,flags=0; - - p=*pos; - x=*p++; - x|=(*p++) << 8; - if (bytes == 2) { - if ( x > 0x7fff) { - x=0x10000-x; - flags=1; - } - } - else if (bytes == 3) { - x|=(*p++) << 16; - if ( x > 0x7fffff) { - x=0x1000000-x; - flags=1; - } - } else { - x|=(*p++) << 16; - x|=(*p++) << 24; - if (x < 0) { - x=-x; - flags=1; - } - } - y=*p++; - y|=(*p++) << 8; - if (bytes == 3) { - y|=(*p++) << 16; - } else if (bytes == 4) { - y|=(*p++) << 16; - y|=(*p++) << 24; - } - if (f) { - f->x=ref->lu.x+x; - f->y=ref->rl.y+y; - dbg(lvl_debug,"0x%x,0x%x + 0x%x,0x%x = 0x%x,0x%x\n", x, y, ref->lu.x, ref->rl.y, f->x, f->y); - } - *pos=p; - return flags; -} - -static void -street_coord_get_begin(unsigned char **p) -{ - struct street_str *str; - - str=(struct street_str *)(*p); - while (street_str_get_segid(str)) { - str++; - } - (*p)=(unsigned char *)str; - (*p)+=4; -} - - -static void -street_coord_rewind(void *priv_data) -{ - struct street_priv *street=priv_data; - - street->p=street->next=NULL; - street->status=street->status_rewind; -} - -static int -street_coord_get_helper(struct street_priv *street, struct coord *c) -{ - unsigned char *n; - if (street->p+street->bytes*2 >= street->end) - return 0; - if (street->status >= 4) - return 0; - n=street->p; - if (street_get_coord(&street->p, street->bytes, &street->ref, c)) { - if (street->status) - street->next=n; - street->status+=2; - if (street->status == 5) - return 0; - } - return 1; -} - -static int -street_coord_get(void *priv_data, struct coord *c, int count) -{ - struct street_priv *street=priv_data; - int ret=0,i,scount; +static void street_name_get(struct street_name *name, unsigned char **p) { + unsigned char *start=*p; + name->len=get_u16_unal(p); + name->country=get_u16_unal(p); + name->townassoc=get_u32_unal(p); + name->name1=get_string(p); + name->name2=get_string(p); + name->segment_count=get_u32_unal(p); + name->segments=(struct street_name_segment *)(*p); + (*p)+=(sizeof (struct street_name_segment))*name->segment_count; + name->aux_len=name->len-(*p-start); + name->aux_data=*p; + name->tmp_len=name->aux_len; + name->tmp_data=name->aux_data; + *p=start+name->len; +} + +static int street_name_eod(struct street_name *name) { + return (name->tmp_data >= name->aux_data+name->aux_len); +} + +static void street_name_numbers_get(struct street_name_numbers *name_numbers, unsigned char **p) { + unsigned char *start=*p; + name_numbers->len=get_u16_unal(p); + name_numbers->tag=get_u8(p); + name_numbers->dist=get_u32_unal(p); + name_numbers->country=get_u32_unal(p); + name_numbers->c=coord_get(p); + name_numbers->first.number=get_u16_unal(p); + name_numbers->first.suffix=get_string(p); + name_numbers->last.number=get_u16_unal(p); + name_numbers->last.suffix=get_string(p); + name_numbers->segment_count=get_u32_unal(p); + name_numbers->segments=(struct street_name_segment *)(*p); + (*p)+=sizeof(struct street_name_segment)*name_numbers->segment_count; + name_numbers->aux_len=name_numbers->len-(*p-start); + name_numbers->aux_data=*p; + name_numbers->tmp_len=name_numbers->aux_len; + name_numbers->tmp_data=name_numbers->aux_data; + *p=start+name_numbers->len; +} + +static int street_name_numbers_eod(struct street_name_numbers *name_numbers) { + return (name_numbers->tmp_data >= name_numbers->aux_data+name_numbers->aux_len); +} + +static void street_name_number_get(struct street_name_number *name_number, unsigned char **p) { + unsigned char *start=*p; + name_number->len=get_u16_unal(p); + name_number->tag=get_u8(p); + name_number->c=coord_get(p); + name_number->first.number=get_u16_unal(p); + name_number->first.suffix=get_string(p); + name_number->last.number=get_u16_unal(p); + name_number->last.suffix=get_string(p); + name_number->segment=(struct street_name_segment *)p; + *p=start+name_number->len; +} + +static void street_name_get_by_id(struct street_name *name, struct file *file, unsigned long id) { + unsigned char *p; + if (id) { + p=file->begin+id+0x2000; + street_name_get(name, &p); + } +} + +static int street_get_bytes(struct coord_rect *r) { + int bytes,dx,dy; + bytes=2; + dx=r->rl.x-r->lu.x; + dy=r->lu.y-r->rl.y; + dbg_assert(dx > 0); + dbg_assert(dy > 0); + if (dx > 32767 || dy > 32767) + bytes=3; + if (dx > 8388608 || dy > 8388608) + bytes=4; + + return bytes; +} + +static int street_get_coord(unsigned char **pos, int bytes, struct coord_rect *ref, struct coord *f) { + unsigned char *p; + int x,y,flags=0; + + p=*pos; + x=*p++; + x|=(*p++) << 8; + if (bytes == 2) { + if ( x > 0x7fff) { + x=0x10000-x; + flags=1; + } + } else if (bytes == 3) { + x|=(*p++) << 16; + if ( x > 0x7fffff) { + x=0x1000000-x; + flags=1; + } + } else { + x|=(*p++) << 16; + x|=(*p++) << 24; + if (x < 0) { + x=-x; + flags=1; + } + } + y=*p++; + y|=(*p++) << 8; + if (bytes == 3) { + y|=(*p++) << 16; + } else if (bytes == 4) { + y|=(*p++) << 16; + y|=(*p++) << 24; + } + if (f) { + f->x=ref->lu.x+x; + f->y=ref->rl.y+y; + dbg(lvl_debug,"0x%x,0x%x + 0x%x,0x%x = 0x%x,0x%x", x, y, ref->lu.x, ref->rl.y, f->x, f->y); + } + *pos=p; + return flags; +} + +static void street_coord_get_begin(unsigned char **p) { + struct street_str *str; + + str=(struct street_str *)(*p); + while (street_str_get_segid(str)) { + str++; + } + (*p)=(unsigned char *)str; + (*p)+=4; +} + + +static void street_coord_rewind(void *priv_data) { + struct street_priv *street=priv_data; + + street->p=street->next=NULL; + street->status=street->status_rewind; +} + +static int street_coord_get_helper(struct street_priv *street, struct coord *c) { + unsigned char *n; + if (street->p+street->bytes*2 >= street->end) + return 0; + if (street->status >= 4) + return 0; + n=street->p; + if (street_get_coord(&street->p, street->bytes, &street->ref, c)) { + if (street->status) + street->next=n; + street->status+=2; + if (street->status == 5) + return 0; + } + return 1; +} + +static int street_coord_get(void *priv_data, struct coord *c, int count) { + struct street_priv *street=priv_data; + int ret=0,i,scount; #ifdef DEBUG_COORD_GET - int segid,debug=0; + int segid,debug=0; #endif - if (! street->p && count) { - street->p=street->coord_begin; - scount=street->str-street->str_start; - for (i = 0 ; i < scount ; i++) { - street->status=street_str_get_segid(&street->str[i+1]) >= 0 ? 0:1; - while (street_coord_get_helper(street, c)); - street->p=street->next; - } - street->status_rewind=street->status=street_str_get_segid(&street->str[1]) >= 0 ? 0:1; - } + if (! street->p && count) { + street->p=street->coord_begin; + scount=street->str-street->str_start; + for (i = 0 ; i < scount ; i++) { + street->status=street_str_get_segid(&street->str[i+1]) >= 0 ? 0:1; + while (street_coord_get_helper(street, c)); + street->p=street->next; + } + street->status_rewind=street->status=street_str_get_segid(&street->str[1]) >= 0 ? 0:1; + } #ifdef DEBUG_COORD_GET - segid=street_str_get_segid(&street->str[0]); - if (segid < 0) - segid=-segid; - if (segid == 0x15) - debug=1; - if (debug) { - dbg(lvl_debug,"enter 0x%x\n",segid); - } + segid=street_str_get_segid(&street->str[0]); + if (segid < 0) + segid=-segid; + if (segid == 0x15) + debug=1; + if (debug) { + dbg(lvl_debug,"enter 0x%x",segid); + } #endif - while (count > 0) { - if (street_coord_get_helper(street, c)) { + while (count > 0) { + if (street_coord_get_helper(street, c)) { #ifdef DEBUG_COORD_GET - if (debug) { - dbg(lvl_debug,"0x%x,0x%x\n", c->x, c->y); - } + if (debug) { + dbg(lvl_debug,"0x%x,0x%x", c->x, c->y); + } #endif - c++; - ret++; - count--; - } else { - street->more=0; - return ret; - } - } - return ret; -} - - static void -street_attr_rewind(void *priv_data) -{ - /* struct street_priv *street=priv_data; */ - -} - -static int -street_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) -{ - struct street_priv *street=priv_data; - int nameid; - - dbg(lvl_debug,"segid 0x%x\n", street_str_get_segid(street->str)); - attr->type=attr_type; - switch (attr_type) { - case attr_any: - while (street->attr_next != attr_none) { - if (street_attr_get(street, street->attr_next, attr)) - return 1; - } - return 0; - case attr_label: - street->attr_next=attr_street_name; - nameid=street_str_get_nameid(street->str); - if (! nameid) - return 0; - if (! street->name.len) - street_name_get_by_id(&street->name,street->name_file,nameid); - attr->u.str=street->name.name2; - if (attr->u.str && attr->u.str[0]) - return 1; - attr->u.str=street->name.name1; - if (attr->u.str && attr->u.str[0]) - return 1; - return 0; - case attr_street_name: - street->attr_next=attr_street_name_systematic; - nameid=street_str_get_nameid(street->str); - if (! nameid) - return 0; - if (! street->name.len) - street_name_get_by_id(&street->name,street->name_file,nameid); - attr->u.str=street->name.name2; - return ((attr->u.str && attr->u.str[0]) ? 1:0); - case attr_street_name_systematic: - street->attr_next=attr_flags; - nameid=street_str_get_nameid(street->str); - if (! nameid) - return 0; - if (! street->name.len) - street_name_get_by_id(&street->name,street->name_file,nameid); - attr->u.str=street->name.name1; - return ((attr->u.str && attr->u.str[0]) ? 1:0); - case attr_flags: - attr->u.num=street->flags; - street->attr_next=attr_country_id; - return 1; - case attr_country_id: - street->attr_next=attr_debug; - nameid=street_str_get_nameid(street->str); - if (! nameid) - return 0; - if (! street->name.len) - street_name_get_by_id(&street->name,street->name_file,nameid); - attr->u.num=mg_country_to_isonum(street->name.country); - return 1; - case attr_debug: - street->attr_next=attr_none; - { - struct street_str *str=street->str; - sprintf(street->debug,"order:0x%x\nsegid:0x%x\nlimit:0x%x\nunknown2:0x%x\nunknown3:0x%x\ntype:0x%x\nnameid:0x%x\ntownassoc:0x%x",street_header_get_order(street->header),street_str_get_segid(str),street_str_get_limit(str),street_str_get_unknown2(str),street_str_get_unknown3(str),street_str_get_type(str),street_str_get_nameid(str), street->name.len ? street->name.townassoc : 0); - attr->u.str=street->debug; - } - return 1; - default: - return 0; - } - return 1; + c++; + ret++; + count--; + } else { + street->more=0; + return ret; + } + } + return ret; +} + +static void street_attr_rewind(void *priv_data) { + /* struct street_priv *street=priv_data; */ + +} + +static int street_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { + struct street_priv *street=priv_data; + int nameid; + + dbg(lvl_debug,"segid 0x%x", street_str_get_segid(street->str)); + attr->type=attr_type; + switch (attr_type) { + case attr_any: + while (street->attr_next != attr_none) { + if (street_attr_get(street, street->attr_next, attr)) + return 1; + } + return 0; + case attr_label: + street->attr_next=attr_street_name; + nameid=street_str_get_nameid(street->str); + if (! nameid) + return 0; + if (! street->name.len) + street_name_get_by_id(&street->name,street->name_file,nameid); + attr->u.str=street->name.name2; + if (attr->u.str && attr->u.str[0]) + return 1; + attr->u.str=street->name.name1; + if (attr->u.str && attr->u.str[0]) + return 1; + return 0; + case attr_street_name: + street->attr_next=attr_street_name_systematic; + nameid=street_str_get_nameid(street->str); + if (! nameid) + return 0; + if (! street->name.len) + street_name_get_by_id(&street->name,street->name_file,nameid); + attr->u.str=street->name.name2; + return ((attr->u.str && attr->u.str[0]) ? 1:0); + case attr_street_name_systematic: + street->attr_next=attr_flags; + nameid=street_str_get_nameid(street->str); + if (! nameid) + return 0; + if (! street->name.len) + street_name_get_by_id(&street->name,street->name_file,nameid); + attr->u.str=street->name.name1; + return ((attr->u.str && attr->u.str[0]) ? 1:0); + case attr_flags: + attr->u.num=street->flags; + street->attr_next=attr_country_id; + return 1; + case attr_country_id: + street->attr_next=attr_debug; + nameid=street_str_get_nameid(street->str); + if (! nameid) + return 0; + if (! street->name.len) + street_name_get_by_id(&street->name,street->name_file,nameid); + attr->u.num=mg_country_to_isonum(street->name.country); + return 1; + case attr_debug: + street->attr_next=attr_none; + { + struct street_str *str=street->str; + sprintf(street->debug, + "order:0x%x\nsegid:0x%x\nlimit:0x%x\nunknown2:0x%x\nunknown3:0x%x\ntype:0x%x\nnameid:0x%x\ntownassoc:0x%x", + street_header_get_order(street->header),street_str_get_segid(str),street_str_get_limit(str), + street_str_get_unknown2(str),street_str_get_unknown3(str),street_str_get_type(str),street_str_get_nameid(str), + street->name.len ? street->name.townassoc : 0); + attr->u.str=street->debug; + } + return 1; + default: + return 0; + } + return 1; } static struct item_methods street_meth = { - street_coord_rewind, - street_coord_get, - street_attr_rewind, - street_attr_get, + street_coord_rewind, + street_coord_get, + street_attr_rewind, + street_attr_get, }; -static void -street_get_data(struct street_priv *street, unsigned char **p) -{ - street->header=(struct street_header *)(*p); - (*p)+=sizeof(struct street_header); - street->type_count=street_header_get_count(street->header); - street->type=(struct street_type *)(*p); - (*p)+=street->type_count*sizeof(struct street_type); -} - - /*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 */ -static unsigned char limit[]={0,0,1,1,1,2,2,4,6,6,12,13,14,20,20,20,20,20,20}; - -int -street_get(struct map_rect_priv *mr, struct street_priv *street, struct item *item) -{ - int *flags; - struct coord_rect r; - for (;;) { - while (street->more) { - struct coord c; - street_coord_get(street, &c, 1); - } -#if 0 - if (street->housenumber) { - if (street_get_housenumber(mr, street, item)) - return 1; - street->housenumber=0; - } -#endif - if (mr->b.p == mr->b.p_start) { - street_get_data(street, &mr->b.p); - street->name_file=mr->m->file[file_strname_stn]; - if (mr->cur_sel && street_header_get_order(street->header) > limit[mr->cur_sel->order]) - return 0; - street->end=mr->b.end; - block_get_r(mr->b.b, &r); - street->ref=r; - street->bytes=street_get_bytes(&r); - street->str_start=street->str=(struct street_str *)mr->b.p; - street->coord_begin=mr->b.p; - street_coord_get_begin(&street->coord_begin); - street->p=street->coord_begin; - street->type--; - item->meth=&street_meth; - item->priv_data=street; - } else { - street->str++; - street->p=street->next; - } - if (! street_str_get_segid(street->str)) - return 0; - if (street_str_get_segid(street->str) < 0) - street->type++; -#if 0 - dbg_assert(street->p != NULL); -#endif - street->next=NULL; - street->status_rewind=street->status=street_str_get_segid(&street->str[1]) >= 0 ? 0:1; -#if 0 - if (street->type->country != 0x31) { - printf("country=0x%x\n", street->type->country); - } -#endif - item->id_hi=street_type_get_country(street->type) | (mr->current_file << 16); - item->id_lo=street_str_get_segid(street->str) > 0 ? street_str_get_segid(street->str) : -street_str_get_segid(street->str); - switch(street_str_get_type(street->str) & 0x1f) { - case 0xf: /* very small street */ - if (street_str_get_limit(street->str) == 0x33) - item->type=type_street_nopass; - else - item->type=type_street_0; - break; - case 0xd: - item->type=type_ferry; - break; - case 0xc: /* small street */ - item->type=type_street_1_city; - break; - case 0xb: - item->type=type_street_2_city; - break; - case 0xa: - if ((street_str_get_limit(street->str) == 0x03 || street_str_get_limit(street->str) == 0x30) && street_header_get_order(street->header) < 4) - item->type=type_street_4_city; - else - item->type=type_street_3_city; - break; - case 0x9: - if (street_header_get_order(street->header) < 5) - item->type=type_street_4_city; - else if (street_header_get_order(street->header) < 7) - item->type=type_street_2_city; - else - item->type=type_street_1_city; - break; - case 0x8: - item->type=type_street_2_land; - break; - case 0x7: - if ((street_str_get_limit(street->str) == 0x03 || street_str_get_limit(street->str) == 0x30) && street_header_get_order(street->header) < 4) - item->type=type_street_4_city; - else - item->type=type_street_3_land; - break; - case 0x6: - item->type=type_ramp; - break; - case 0x5: - item->type=type_street_4_land; - break; - case 0x4: - item->type=type_street_4_land; - break; - case 0x3: - item->type=type_street_n_lanes; - break; - case 0x2: - item->type=type_highway_city; - break; - case 0x1: - item->type=type_highway_land; - break; - default: - item->type=type_street_unkn; - dbg(lvl_error,"unknown type 0x%x\n",street_str_get_type(street->str)); - } - flags=item_get_default_flags(item->type); - if (flags) - street->flags=*flags; - else - street->flags=0; - if (street_str_get_type(street->str) & 0x40) { - street->flags|=(street_str_get_limit(street->str) & 0x30) ? AF_ONEWAYREV:0; - street->flags|=(street_str_get_limit(street->str) & 0x03) ? AF_ONEWAY:0; - } else { - street->flags|=(street_str_get_limit(street->str) & 0x30) ? AF_ONEWAY:0; - street->flags|=(street_str_get_limit(street->str) & 0x03) ? AF_ONEWAYREV:0; - } -#if 0 - coord_debug=(street->str->unknown2 != 0x40 || street->str->unknown3 != 0x40); - if (coord_debug) { - item->type=type_street_unkn; - printf("%d %02x %02x %02x %02x\n", street->str->segid, street->str->type, street->str->limit, street->str->unknown2, street->str->unknown3); - } -#endif - street->p_rewind=street->p; - street->name.len=0; - street->attr_next=attr_label; - street->more=1; - street->housenumber=1; - street->hn_count=0; - if (!map_selection_contains_item(mr->cur_sel, 0, item->type)) - continue; - item->meth=&street_meth; - item->priv_data=street; - return 1; - } -} - -int -street_get_byid(struct map_rect_priv *mr, struct street_priv *street, int id_hi, int id_lo, struct item *item) -{ - int country=id_hi & 0xffff; - int res; - struct coord_rect r; - dbg(lvl_debug,"enter(%p,%p,0x%x,0x%x,%p)\n", mr, street, id_hi, id_lo, item); - if (! country) - return 0; - if (! tree_search_hv(mr->m->dirname, "street", (id_lo >> 8) | (country << 24), id_lo & 0xff, &res)) - return 0; - dbg(lvl_debug,"res=0x%x (blk=0x%x)\n", res, res >> 12); - block_get_byindex(mr->m->file[mr->current_file], res >> 12, &mr->b); - street_get_data(street, &mr->b.p); - street->name_file=mr->m->file[file_strname_stn]; - street->end=mr->b.end; - block_get_r(mr->b.b, &r); - street->ref=r; - street->bytes=street_get_bytes(&r); - street->str_start=street->str=(struct street_str *)mr->b.p; - street->coord_begin=mr->b.p; - street_coord_get_begin(&street->coord_begin); - street->p=street->coord_begin; - street->type--; - item->meth=&street_meth; - item->priv_data=street; - street->str+=(res & 0xfff)-1; - dbg(lvl_debug,"segid 0x%x\n", street_str_get_segid(&street->str[1])); - return street_get(mr, street, item); -#if 0 - mr->b.p=mr->b.block_start+(res & 0xffff); - return town_get(mr, twn, item); -#endif - - return 0; +static void street_get_data(struct street_priv *street, unsigned char **p) { + street->header=(struct street_header *)(*p); + (*p)+=sizeof(struct street_header); + street->type_count=street_header_get_count(street->header); + street->type=(struct street_type *)(*p); + (*p)+=street->type_count*sizeof(struct street_type); +} + +/*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 */ +static unsigned char limit[]= {0,0,1,1,1,2,2,4,6,6,12,13,14,20,20,20,20,20,20}; + +int street_get(struct map_rect_priv *mr, struct street_priv *street, struct item *item) { + int *flags; + struct coord_rect r; + for (;;) { + while (street->more) { + struct coord c; + street_coord_get(street, &c, 1); + } + if (mr->b.p == mr->b.p_start) { + street_get_data(street, &mr->b.p); + street->name_file=mr->m->file[file_strname_stn]; + if (mr->cur_sel && street_header_get_order(street->header) > limit[mr->cur_sel->order]) + return 0; + street->end=mr->b.end; + block_get_r(mr->b.b, &r); + street->ref=r; + street->bytes=street_get_bytes(&r); + street->str_start=street->str=(struct street_str *)mr->b.p; + street->coord_begin=mr->b.p; + street_coord_get_begin(&street->coord_begin); + street->p=street->coord_begin; + street->type--; + item->meth=&street_meth; + item->priv_data=street; + } else { + street->str++; + street->p=street->next; + } + if (! street_str_get_segid(street->str)) + return 0; + if (street_str_get_segid(street->str) < 0) + street->type++; + street->next=NULL; + street->status_rewind=street->status=street_str_get_segid(&street->str[1]) >= 0 ? 0:1; + item->id_hi=street_type_get_country(street->type) | (mr->current_file << 16); + item->id_lo=street_str_get_segid(street->str) > 0 ? street_str_get_segid(street->str) : -street_str_get_segid( + street->str); + switch(street_str_get_type(street->str) & 0x1f) { + case 0xf: /* very small street */ + if (street_str_get_limit(street->str) == 0x33) + item->type=type_street_nopass; + else + item->type=type_street_0; + break; + case 0xd: + item->type=type_ferry; + break; + case 0xc: /* small street */ + item->type=type_street_1_city; + break; + case 0xb: + item->type=type_street_2_city; + break; + case 0xa: + if ((street_str_get_limit(street->str) == 0x03 || street_str_get_limit(street->str) == 0x30) + && street_header_get_order(street->header) < 4) + item->type=type_street_4_city; + else + item->type=type_street_3_city; + break; + case 0x9: + if (street_header_get_order(street->header) < 5) + item->type=type_street_4_city; + else if (street_header_get_order(street->header) < 7) + item->type=type_street_2_city; + else + item->type=type_street_1_city; + break; + case 0x8: + item->type=type_street_2_land; + break; + case 0x7: + if ((street_str_get_limit(street->str) == 0x03 || street_str_get_limit(street->str) == 0x30) + && street_header_get_order(street->header) < 4) + item->type=type_street_4_city; + else + item->type=type_street_3_land; + break; + case 0x6: + item->type=type_ramp; + break; + case 0x5: + item->type=type_street_4_land; + break; + case 0x4: + item->type=type_street_4_land; + break; + case 0x3: + item->type=type_street_n_lanes; + break; + case 0x2: + item->type=type_highway_city; + break; + case 0x1: + item->type=type_highway_land; + break; + default: + item->type=type_street_unkn; + dbg(lvl_error,"unknown type 0x%x",street_str_get_type(street->str)); + } + flags=item_get_default_flags(item->type); + if (flags) + street->flags=*flags; + else + street->flags=0; + if (street_str_get_type(street->str) & 0x40) { + street->flags|=(street_str_get_limit(street->str) & 0x30) ? AF_ONEWAYREV:0; + street->flags|=(street_str_get_limit(street->str) & 0x03) ? AF_ONEWAY:0; + } else { + street->flags|=(street_str_get_limit(street->str) & 0x30) ? AF_ONEWAY:0; + street->flags|=(street_str_get_limit(street->str) & 0x03) ? AF_ONEWAYREV:0; + } + street->p_rewind=street->p; + street->name.len=0; + street->attr_next=attr_label; + street->more=1; + street->housenumber=1; + street->hn_count=0; + if (!map_selection_contains_item(mr->cur_sel, 0, item->type)) + continue; + item->meth=&street_meth; + item->priv_data=street; + return 1; + } +} + +int street_get_byid(struct map_rect_priv *mr, struct street_priv *street, int id_hi, int id_lo, struct item *item) { + int country=id_hi & 0xffff; + int res; + struct coord_rect r; + dbg(lvl_debug,"enter(%p,%p,0x%x,0x%x,%p)", mr, street, id_hi, id_lo, item); + if (! country) + return 0; + if (! tree_search_hv(mr->m->dirname, "street", (id_lo >> 8) | (country << 24), id_lo & 0xff, &res)) + return 0; + dbg(lvl_debug,"res=0x%x (blk=0x%x)", res, res >> 12); + block_get_byindex(mr->m->file[mr->current_file], res >> 12, &mr->b); + street_get_data(street, &mr->b.p); + street->name_file=mr->m->file[file_strname_stn]; + street->end=mr->b.end; + block_get_r(mr->b.b, &r); + street->ref=r; + street->bytes=street_get_bytes(&r); + street->str_start=street->str=(struct street_str *)mr->b.p; + street->coord_begin=mr->b.p; + street_coord_get_begin(&street->coord_begin); + street->p=street->coord_begin; + street->type--; + item->meth=&street_meth; + item->priv_data=street; + street->str+=(res & 0xfff)-1; + dbg(lvl_debug,"segid 0x%x", street_str_get_segid(&street->str[1])); + return street_get(mr, street, item); } struct street_name_index { - int block; - unsigned short country; - int town_assoc; - char name[0]; + int block; + unsigned short country; + int town_assoc; + char name[0]; } __attribute__((packed)); -static unsigned char -latin1_tolower(unsigned char c) -{ - if (c >= 'A' && c <= 'Z') - return c - 'A' + 'a'; - if (c == 0xc4 || c == 0xc9 || c == 0xd6 || c == 0xdc) - return c+0x20; - return c; -} - -static unsigned char -latin1_tolower_ascii(unsigned char c) -{ - unsigned char ret=latin1_tolower(c); - switch (ret) { - case 0xe4: - return 'a'; - case 0xe9: - return 'e'; - case 0xf6: - return 'o'; - case 0xfc: - return 'u'; - default: - if (ret >= 0x80) - dbg(lvl_debug,"ret=0x%x\n",c); - return ret; - } -} - -static int -strncasecmp_latin1(char *str1, char *str2, int len) -{ - int d; - while (len--) { - d=latin1_tolower((unsigned char)(*str1))-latin1_tolower((unsigned char)(*str2)); - if (d) - return d; - if (! *str1) - return 0; - str1++; - str2++; - } - return 0; -} - -static int -strncasecmp_latin1_ascii(char *str1, char *str2, int len) -{ - int d; - while (len--) { - d=latin1_tolower_ascii((unsigned char)(*str1))-latin1_tolower_ascii((unsigned char)(*str2)); - if (d) - return d; - if (! *str1) - return 0; - str1++; - str2++; - } - return 0; -} - -static int -street_search_compare_do(struct map_rect_priv *mr, int country, int town_assoc, char *name) -{ - int d,len; - - dbg(lvl_debug,"enter"); - dbg(lvl_debug,"country 0x%x town_assoc 0x%x name '%s'\n", country, town_assoc, name); - d=(mr->search_item.id_hi & 0xffff)-country; - dbg(lvl_debug,"country %d (%d vs %d)\n", d, mr->search_item.id_hi & 0xffff, country); - if (!d) { - if (mr->search_item.id_lo == town_assoc ) { - dbg(lvl_debug,"town_assoc match (0x%x)\n", town_assoc); - len=mr->search_partial ? strlen(mr->search_str):INT_MAX; - d=strncasecmp_latin1(mr->search_str, name, len); - if (!strncasecmp_latin1_ascii(mr->search_str, name, len)) - d=0; - dbg(lvl_debug,"string %d\n", d); - } else { - if (town_assoc < mr->search_item.id_lo) - d=1; - else - d=-1; - dbg(lvl_debug,"assoc %d 0x%x-0x%x\n",d, mr->search_item.id_lo, town_assoc); - } - } - dbg(lvl_debug,"d=%d\n", d); - return d; -} - -static int -street_search_compare(unsigned char **p, struct map_rect_priv *mr) -{ - struct street_name_index *i; - int ret; - - dbg(lvl_debug,"enter\n"); - i=(struct street_name_index *)(*p); - *p+=sizeof(*i)+strlen(i->name)+1; - - dbg(lvl_debug,"block 0x%x\n", i->block); - - ret=street_search_compare_do(mr, i->country, i->town_assoc, i->name); - if (ret <= 0) - mr->search_block=i->block; - return ret; -} - -static void -street_name_coord_rewind(void *priv_data) -{ - /* struct street_priv *street=priv_data; */ - -} - -static void -street_name_attr_rewind(void *priv_data) -{ - /* struct street_priv *street=priv_data; */ - -} - -static int -street_name_coord_get(void *priv_data, struct coord *c, int count) -{ - struct map_rect_priv *mr=priv_data; - struct street_name_numbers snns; - unsigned char *p=mr->street.name.aux_data; - - dbg(lvl_debug,"aux_data=%p\n", p); - if (count) { - street_name_numbers_get(&snns, &p); - street_name_numbers_get_coord(&snns, c); - return 1; - } - - return 0; +static unsigned char latin1_tolower(unsigned char c) { + if (c >= 'A' && c <= 'Z') + return c - 'A' + 'a'; + if (c == 0xc4 || c == 0xc9 || c == 0xd6 || c == 0xdc) + return c+0x20; + return c; +} + +static unsigned char latin1_tolower_ascii(unsigned char c) { + unsigned char ret=latin1_tolower(c); + switch (ret) { + case 0xe4: + return 'a'; + case 0xe9: + return 'e'; + case 0xf6: + return 'o'; + case 0xfc: + return 'u'; + default: + if (ret >= 0x80) + dbg(lvl_debug,"ret=0x%x",c); + return ret; + } +} + +static int strncasecmp_latin1(char *str1, char *str2, int len) { + int d; + while (len--) { + d=latin1_tolower((unsigned char)(*str1))-latin1_tolower((unsigned char)(*str2)); + if (d) + return d; + if (! *str1) + return 0; + str1++; + str2++; + } + return 0; +} + +static int strncasecmp_latin1_ascii(char *str1, char *str2, int len) { + int d; + while (len--) { + d=latin1_tolower_ascii((unsigned char)(*str1))-latin1_tolower_ascii((unsigned char)(*str2)); + if (d) + return d; + if (! *str1) + return 0; + str1++; + str2++; + } + return 0; +} + +static int street_search_compare_do(struct map_rect_priv *mr, int country, int town_assoc, char *name) { + int d,len; + + dbg(lvl_debug,"enter"); + dbg(lvl_debug,"country 0x%x town_assoc 0x%x name '%s'", country, town_assoc, name); + d=(mr->search_item.id_hi & 0xffff)-country; + dbg(lvl_debug,"country %d (%d vs %d)", d, mr->search_item.id_hi & 0xffff, country); + if (!d) { + if (mr->search_item.id_lo == town_assoc ) { + dbg(lvl_debug,"town_assoc match (0x%x)", town_assoc); + len=mr->search_partial ? strlen(mr->search_str):INT_MAX; + d=strncasecmp_latin1(mr->search_str, name, len); + if (!strncasecmp_latin1_ascii(mr->search_str, name, len)) + d=0; + dbg(lvl_debug,"string %d", d); + } else { + if (town_assoc < mr->search_item.id_lo) + d=1; + else + d=-1; + dbg(lvl_debug,"assoc %d 0x%x-0x%x",d, mr->search_item.id_lo, town_assoc); + } + } + dbg(lvl_debug,"d=%d", d); + return d; +} + +static int street_search_compare(unsigned char **p, struct map_rect_priv *mr) { + struct street_name_index *i; + int ret; + + dbg(lvl_debug,"enter"); + i=(struct street_name_index *)(*p); + *p+=sizeof(*i)+strlen(i->name)+1; + + dbg(lvl_debug,"block 0x%x", i->block); + + ret=street_search_compare_do(mr, i->country, i->town_assoc, i->name); + if (ret <= 0) + mr->search_block=i->block; + return ret; +} + +static void street_name_coord_rewind(void *priv_data) { + /* struct street_priv *street=priv_data; */ + +} + +static void street_name_attr_rewind(void *priv_data) { + /* struct street_priv *street=priv_data; */ + +} + +static int street_name_coord_get(void *priv_data, struct coord *c, int count) { + struct map_rect_priv *mr=priv_data; + struct street_name_numbers snns; + unsigned char *p=mr->street.name.aux_data; + + dbg(lvl_debug,"aux_data=%p", p); + if (count) { + street_name_numbers_get(&snns, &p); + street_name_numbers_get_coord(&snns, c); + return 1; + } + + return 0; } #if 0 -static void -debug(struct map_rect_priv *mr) -{ - int i; - struct street_name_numbers nns; - unsigned char *p=mr->street.name.aux_data; - unsigned char *end=p+mr->street.name.aux_len; - printf("len=0x%x\n", mr->street.name.aux_len); - for (i = 0 ; i < mr->street.name.aux_len ; i++) { - printf("%02x ",mr->street.name.aux_data[i]); - } - printf("\n"); - { - while (p < end) { - unsigned char *pn,*pn_end; - struct street_name_number nn; - street_name_numbers_get(&nns, &p); - printf("name_numbers:\n"); - printf(" len 0x%x\n", nns.len); - printf(" tag 0x%x\n", nns.tag); - printf(" dist 0x%x\n", nns.dist); - printf(" country 0x%x\n", nns.country); - printf(" coord 0x%x,0x%x\n", nns.c->x, nns.c->y); - printf(" first %d\n", nns.first.number); - printf(" last %d\n", nns.last.number); - printf(" segment count 0x%x\n", nns.segment_count); - printf(" aux_len 0x%x\n", nns.aux_len); - pn=nns.aux_data; - pn_end=nns.aux_data+nns.aux_len; - while (pn < pn_end) { - printf(" number:\n"); - street_name_number_get(&nn, &pn); - printf(" len 0x%x\n", nn.len); - printf(" tag 0x%x\n", nn.tag); - printf(" coord 0x%x,0x%x\n", nn.c->x, nn.c->y); - printf(" first %d\n", nn.first.number); - printf(" last %d\n", nn.last.number); - } - } - } +static void debug(struct map_rect_priv *mr) { + int i; + struct street_name_numbers nns; + unsigned char *p=mr->street.name.aux_data; + unsigned char *end=p+mr->street.name.aux_len; + printf("len=0x%x\n", mr->street.name.aux_len); + for (i = 0 ; i < mr->street.name.aux_len ; i++) { + printf("%02x ",mr->street.name.aux_data[i]); + } + printf("\n"); + { + while (p < end) { + unsigned char *pn,*pn_end; + struct street_name_number nn; + street_name_numbers_get(&nns, &p); + printf("name_numbers:\n"); + printf(" len 0x%x\n", nns.len); + printf(" tag 0x%x\n", nns.tag); + printf(" dist 0x%x\n", nns.dist); + printf(" country 0x%x\n", nns.country); + printf(" coord 0x%x,0x%x\n", nns.c->x, nns.c->y); + printf(" first %d\n", nns.first.number); + printf(" last %d\n", nns.last.number); + printf(" segment count 0x%x\n", nns.segment_count); + printf(" aux_len 0x%x\n", nns.aux_len); + pn=nns.aux_data; + pn_end=nns.aux_data+nns.aux_len; + while (pn < pn_end) { + printf(" number:\n"); + street_name_number_get(&nn, &pn); + printf(" len 0x%x\n", nn.len); + printf(" tag 0x%x\n", nn.tag); + printf(" coord 0x%x,0x%x\n", nn.c->x, nn.c->y); + printf(" first %d\n", nn.first.number); + printf(" last %d\n", nn.last.number); + } + } + } } #endif -static int -street_name_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) -{ - struct map_rect_priv *mr=priv_data; - - attr->type=attr_type; - switch (attr_type) { - case attr_street_name: - attr->u.str=mr->street.name.name2; - return ((attr->u.str && attr->u.str[0]) ? 1:0); - case attr_street_name_systematic: - attr->u.str=mr->street.name.name1; - return ((attr->u.str && attr->u.str[0]) ? 1:0); - case attr_town_name: - case attr_district_name: - case attr_postal: - if (!mr->search_item_tmp) - mr->search_item_tmp=map_rect_get_item_byid_mg(mr->search_mr_tmp, mr->street.name_numbers.country | (file_town_twn << 16), mr->street.name_numbers.dist); - if (!mr->search_item_tmp) - return 0; - return item_attr_get(mr->search_item_tmp, attr_type, attr); - default: - dbg(lvl_error,"unknown attr %s\n",attr_to_name(attr_type)); - return 0; - } +static int street_name_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { + struct map_rect_priv *mr=priv_data; + + attr->type=attr_type; + switch (attr_type) { + case attr_street_name: + attr->u.str=mr->street.name.name2; + return ((attr->u.str && attr->u.str[0]) ? 1:0); + case attr_street_name_systematic: + attr->u.str=mr->street.name.name1; + return ((attr->u.str && attr->u.str[0]) ? 1:0); + case attr_town_name: + case attr_district_name: + case attr_postal: + if (!mr->search_item_tmp) + mr->search_item_tmp=map_rect_get_item_byid_mg(mr->search_mr_tmp, + mr->street.name_numbers.country | (file_town_twn << 16), mr->street.name_numbers.dist); + if (!mr->search_item_tmp) + return 0; + return item_attr_get(mr->search_item_tmp, attr_type, attr); + default: + dbg(lvl_error,"unknown attr %s",attr_to_name(attr_type)); + return 0; + } } @@ -811,264 +720,247 @@ street_name_attr_get(void *priv_data, enum attr_type attr_type, struct attr *att static struct item_methods street_name_meth = { - street_name_coord_rewind, - street_name_coord_get, - street_name_attr_rewind, - street_name_attr_get, + street_name_coord_rewind, + street_name_coord_get, + street_name_attr_rewind, + street_name_attr_get, }; -int -street_name_get_byid(struct map_rect_priv *mr, struct street_priv *street, int id_hi, int id_lo, struct item *item) -{ - mr->current_file=id_hi >> 16; - street->name_file=mr->m->file[mr->current_file]; - item->type=type_street_name; - item->id_hi=id_hi; - item->id_lo=id_lo; - item->meth=&street_name_meth; - item->map=NULL; - item->priv_data=mr; - mr->b.p=street->name_file->begin+item->id_lo; - dbg(lvl_debug,"last %p map %p file %d begin %p\n", mr->b.p, mr->m, mr->current_file, mr->m->file[mr->current_file]->begin); - street_name_get(&street->name, &mr->b.p); - return 1; -} - -static struct item * -street_search_get_item_street_name(struct map_rect_priv *mr) -{ - int dir=1,leaf; - unsigned char *last; - - dbg(lvl_debug,"enter\n"); - if (! mr->search_blk_count) { - dbg(lvl_debug,"partial 0x%x '%s' ***\n", mr->town.street_assoc, mr->search_str); - if (mr->search_linear) - return NULL; - dbg(lvl_debug,"tree_search_next\n"); - mr->search_block=-1; - while ((leaf=tree_search_next(&mr->ts, &mr->search_p, dir)) != -1) { - dir=street_search_compare(&mr->search_p, mr); - } - dbg(lvl_debug,"dir=%d mr->search_block=0x%x\n", dir, mr->search_block); - if (mr->search_block == -1) - return NULL; - mr->search_blk_count=1; - block_get_byindex(mr->m->file[file_strname_stn], mr->search_block, &mr->b); - mr->b.p=mr->b.block_start+12; - } - dbg(lvl_debug,"name id %td\n", mr->b.p-mr->m->file[file_strname_stn]->begin); - if (! mr->search_blk_count) - return NULL; - for (;;) { - if (mr->b.p >= mr->b.end) { - if (!block_next_lin(mr)) { - dbg(lvl_debug,"end of blocks in %p, %p\n", mr->m->file[file_strname_stn]->begin, mr->m->file[file_strname_stn]->end); - return NULL; - } - mr->b.p=mr->b.block_start+12; - } - while (mr->b.p < mr->b.end) { - last=mr->b.p; - street_name_get(&mr->street.name, &mr->b.p); - dir=street_search_compare_do(mr, mr->street.name.country, mr->street.name.townassoc, mr->street.name.name2); - dbg(lvl_debug,"country 0x%x assoc 0x%x name1 '%s' name2 '%s' dir=%d\n", mr->street.name.country, mr->street.name.townassoc, mr->street.name.name1, mr->street.name.name2, dir); - if (dir < 0) { - dbg(lvl_debug,"end of data\n"); - mr->search_blk_count=0; - return NULL; - } - if (!dir) { - dbg(lvl_debug,"result country 0x%x assoc 0x%x name1 '%s' name2 '%s' dir=%d aux_data=%p len=0x%x\n", mr->street.name.country, mr->street.name.townassoc, mr->street.name.name1, mr->street.name.name2, dir, mr->street.name.aux_data, mr->street.name.aux_len); - mr->item.type = type_street_name; - mr->item.id_hi=(file_strname_stn << 16); - mr->item.id_lo=last-mr->m->file[file_strname_stn]->begin; - dbg(lvl_debug,"id 0x%x 0x%x last %p map %p file %d begin %p\n", mr->item.id_hi, mr->item.id_lo, last, mr->m, mr->current_file, mr->m->file[mr->current_file]->begin); - mr->item.meth=&street_name_meth; - mr->item.map=NULL; - mr->item.priv_data=mr; - /* debug(mr); */ - dbg(lvl_debug,"last %p\n",last); - return &mr->item; - } - } - } +int street_name_get_byid(struct map_rect_priv *mr, struct street_priv *street, int id_hi, int id_lo, + struct item *item) { + mr->current_file=id_hi >> 16; + street->name_file=mr->m->file[mr->current_file]; + item->type=type_street_name; + item->id_hi=id_hi; + item->id_lo=id_lo; + item->meth=&street_name_meth; + item->map=NULL; + item->priv_data=mr; + mr->b.p=street->name_file->begin+item->id_lo; + dbg(lvl_debug,"last %p map %p file %d begin %p", mr->b.p, mr->m, mr->current_file, + mr->m->file[mr->current_file]->begin); + street_name_get(&street->name, &mr->b.p); + return 1; +} + +static struct item *street_search_get_item_street_name(struct map_rect_priv *mr) { + int dir=1,leaf; + unsigned char *last; + + dbg(lvl_debug,"enter"); + if (! mr->search_blk_count) { + dbg(lvl_debug,"partial 0x%x '%s' ***", mr->town.street_assoc, mr->search_str); + if (mr->search_linear) + return NULL; + dbg(lvl_debug,"tree_search_next"); + mr->search_block=-1; + while ((leaf=tree_search_next(&mr->ts, &mr->search_p, dir)) != -1) { + dir=street_search_compare(&mr->search_p, mr); + } + dbg(lvl_debug,"dir=%d mr->search_block=0x%x", dir, mr->search_block); + if (mr->search_block == -1) + return NULL; + mr->search_blk_count=1; + block_get_byindex(mr->m->file[file_strname_stn], mr->search_block, &mr->b); + mr->b.p=mr->b.block_start+12; + } + dbg(lvl_debug,"name id %td", mr->b.p-mr->m->file[file_strname_stn]->begin); + if (! mr->search_blk_count) + return NULL; + for (;;) { + if (mr->b.p >= mr->b.end) { + if (!block_next_lin(mr)) { + dbg(lvl_debug,"end of blocks in %p, %p", mr->m->file[file_strname_stn]->begin, mr->m->file[file_strname_stn]->end); + return NULL; + } + mr->b.p=mr->b.block_start+12; + } + while (mr->b.p < mr->b.end) { + last=mr->b.p; + street_name_get(&mr->street.name, &mr->b.p); + dir=street_search_compare_do(mr, mr->street.name.country, mr->street.name.townassoc, mr->street.name.name2); + dbg(lvl_debug,"country 0x%x assoc 0x%x name1 '%s' name2 '%s' dir=%d", mr->street.name.country, + mr->street.name.townassoc, mr->street.name.name1, mr->street.name.name2, dir); + if (dir < 0) { + dbg(lvl_debug,"end of data"); + mr->search_blk_count=0; + return NULL; + } + if (!dir) { + dbg(lvl_debug,"result country 0x%x assoc 0x%x name1 '%s' name2 '%s' dir=%d aux_data=%p len=0x%x", + mr->street.name.country, mr->street.name.townassoc, mr->street.name.name1, mr->street.name.name2, dir, + mr->street.name.aux_data, mr->street.name.aux_len); + mr->item.type = type_street_name; + mr->item.id_hi=(file_strname_stn << 16); + mr->item.id_lo=last-mr->m->file[file_strname_stn]->begin; + dbg(lvl_debug,"id 0x%x 0x%x last %p map %p file %d begin %p", mr->item.id_hi, mr->item.id_lo, last, mr->m, + mr->current_file, mr->m->file[mr->current_file]->begin); + mr->item.meth=&street_name_meth; + mr->item.map=NULL; + mr->item.priv_data=mr; + /* debug(mr); */ + dbg(lvl_debug,"last %p",last); + return &mr->item; + } + } + } } struct item * -street_search_get_item(struct map_rect_priv *mr) -{ - struct item *item; - for (;;) { - if (!mr->street.name.tmp_data || street_name_eod(&mr->street.name)) { - item=street_search_get_item_street_name(mr); - if (!item) - return NULL; - if (!mr->street.name.aux_len) - return item; - } - mr->item.id_hi++; - street_name_numbers_get(&mr->street.name_numbers, &mr->street.name.tmp_data); - mr->search_item_tmp=NULL; - return &mr->item; - } -} - -static int -street_name_numbers_next(struct map_rect_priv *mr) -{ - if (street_name_eod(&mr->street.name)) - return 0; - dbg(lvl_debug,"%p vs %p\n",mr->street.name.tmp_data, mr->street.name.aux_data); - street_name_numbers_get(&mr->street.name_numbers, &mr->street.name.tmp_data); - return 1; -} - -static int -street_name_number_next(struct map_rect_priv *mr) -{ - if (street_name_numbers_eod(&mr->street.name_numbers)) - return 0; - street_name_number_get(&mr->street.name_number, &mr->street.name_numbers.tmp_data); - sprintf(mr->street.first_number,"%d%s",mr->street.name_number.first.number,mr->street.name_number.first.suffix); - sprintf(mr->street.last_number,"%d%s",mr->street.name_number.last.number,mr->street.name_number.last.suffix); - mr->street.current_number[0]='\0'; - return 1; -} - -static void -housenumber_coord_rewind(void *priv_data) -{ - /* struct street_priv *street=priv_data; */ - -} - -static void -housenumber_attr_rewind(void *priv_data) -{ - /* struct street_priv *street=priv_data; */ - -} - -static int -housenumber_coord_get(void *priv_data, struct coord *c, int count) -{ - return 0; -} - -static int -housenumber_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) -{ - struct map_rect_priv *mr=priv_data; - attr->type=attr_type; - switch (attr_type) { - case attr_house_number: - attr->u.str=mr->street.current_number; - return 1; - case attr_town_name: - case attr_district_name: - case attr_postal: - if (!mr->search_item_tmp) - mr->search_item_tmp=map_rect_get_item_byid_mg(mr->search_mr_tmp, mr->street.name_numbers.country | (file_town_twn << 16), mr->street.name_numbers.dist); - if (!mr->search_item_tmp) - return 0; - return item_attr_get(mr->search_item_tmp, attr_type, attr); - default: - dbg(lvl_error,"unknown attr %s\n",attr_to_name(attr_type)); - return 0; - } +street_search_get_item(struct map_rect_priv *mr) { + struct item *item; + for (;;) { + if (!mr->street.name.tmp_data || street_name_eod(&mr->street.name)) { + item=street_search_get_item_street_name(mr); + if (!item) + return NULL; + if (!mr->street.name.aux_len) + return item; + } + mr->item.id_hi++; + street_name_numbers_get(&mr->street.name_numbers, &mr->street.name.tmp_data); + mr->search_item_tmp=NULL; + return &mr->item; + } +} + +static int street_name_numbers_next(struct map_rect_priv *mr) { + if (street_name_eod(&mr->street.name)) + return 0; + dbg(lvl_debug,"%p vs %p",mr->street.name.tmp_data, mr->street.name.aux_data); + street_name_numbers_get(&mr->street.name_numbers, &mr->street.name.tmp_data); + return 1; +} + +static int street_name_number_next(struct map_rect_priv *mr) { + if (street_name_numbers_eod(&mr->street.name_numbers)) + return 0; + street_name_number_get(&mr->street.name_number, &mr->street.name_numbers.tmp_data); + sprintf(mr->street.first_number,"%d%s",mr->street.name_number.first.number,mr->street.name_number.first.suffix); + sprintf(mr->street.last_number,"%d%s",mr->street.name_number.last.number,mr->street.name_number.last.suffix); + mr->street.current_number[0]='\0'; + return 1; +} + +static void housenumber_coord_rewind(void *priv_data) { + /* struct street_priv *street=priv_data; */ + +} + +static void housenumber_attr_rewind(void *priv_data) { + /* struct street_priv *street=priv_data; */ + +} + +static int housenumber_coord_get(void *priv_data, struct coord *c, int count) { + return 0; +} + +static int housenumber_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { + struct map_rect_priv *mr=priv_data; + attr->type=attr_type; + switch (attr_type) { + case attr_house_number: + attr->u.str=mr->street.current_number; + return 1; + case attr_town_name: + case attr_district_name: + case attr_postal: + if (!mr->search_item_tmp) + mr->search_item_tmp=map_rect_get_item_byid_mg(mr->search_mr_tmp, + mr->street.name_numbers.country | (file_town_twn << 16), mr->street.name_numbers.dist); + if (!mr->search_item_tmp) + return 0; + return item_attr_get(mr->search_item_tmp, attr_type, attr); + default: + dbg(lvl_error,"unknown attr %s",attr_to_name(attr_type)); + return 0; + } } static struct item_methods housenumber_meth = { - housenumber_coord_rewind, - housenumber_coord_get, - housenumber_attr_rewind, - housenumber_attr_get, + housenumber_coord_rewind, + housenumber_coord_get, + housenumber_attr_rewind, + housenumber_attr_get, }; -int -housenumber_search_setup(struct map_rect_priv *mr) -{ - dbg(lvl_debug,"enter (0x%x,0x%x)\n",mr->search_item.id_hi,mr->search_item.id_lo); - int id=mr->search_item.id_hi & 0xff; - mr->current_file=file_strname_stn; - mr->street.name_file=mr->m->file[mr->current_file]; - mr->b.p=mr->street.name_file->begin+mr->search_item.id_lo; - mr->search_str=g_strdup(mr->search_attr->u.str); - dbg(lvl_debug,"last %p\n",mr->b.p); - street_name_get(&mr->street.name, &mr->b.p); -#if 0 - debug(mr); -#endif - while (id > 0) { - id--; - dbg(lvl_debug,"loop\n"); - if (!street_name_numbers_next(mr)) - return 0; - } - mr->item.type=type_house_number; - mr->item.priv_data=mr; - mr->item.id_hi=mr->search_item.id_hi + 0x100; - mr->item.meth=&housenumber_meth; - if (!id) - mr->item.id_hi+=1; - mr->item.id_lo=mr->search_item.id_lo; - dbg(lvl_debug,"getting name_number %p vs %p + %d\n",mr->street.name_numbers.tmp_data,mr->street.name_numbers.aux_data, mr->street.name_numbers.aux_len); - if (!street_name_number_next(mr)) - return 0; - dbg(lvl_debug,"enter\n"); - // debug(mr); - return 1; -} - -static int -house_number_next(char *number, char *first, char *last, int interpolation, int *percentage) -{ - int firstn=atoi(first); - int lastn=atoi(last); - int current,delta,len=lastn-firstn; - if (interpolation) { - len/=2; - } - if (!number[0]) { - strcpy(number,first); - delta=0; - } else { - current=atoi(number)+(interpolation ? 2:1); - if (current > lastn) - return 0; - sprintf(number,"%d",current); - delta=current-firstn; - } - if (percentage) { - if (len) - *percentage=delta*100/len; - else - *percentage=50; - } - return 1; +int housenumber_search_setup(struct map_rect_priv *mr) { + dbg(lvl_debug,"enter (0x%x,0x%x)",mr->search_item.id_hi,mr->search_item.id_lo); + int id=mr->search_item.id_hi & 0xff; + mr->current_file=file_strname_stn; + mr->street.name_file=mr->m->file[mr->current_file]; + mr->b.p=mr->street.name_file->begin+mr->search_item.id_lo; + mr->search_str=g_strdup(mr->search_attr->u.str); + dbg(lvl_debug,"last %p",mr->b.p); + street_name_get(&mr->street.name, &mr->b.p); + while (id > 0) { + id--; + dbg(lvl_debug,"loop"); + if (!street_name_numbers_next(mr)) + return 0; + } + mr->item.type=type_house_number; + mr->item.priv_data=mr; + mr->item.id_hi=mr->search_item.id_hi + 0x100; + mr->item.meth=&housenumber_meth; + if (!id) + mr->item.id_hi+=1; + mr->item.id_lo=mr->search_item.id_lo; + dbg(lvl_debug,"getting name_number %p vs %p + %d",mr->street.name_numbers.tmp_data,mr->street.name_numbers.aux_data, + mr->street.name_numbers.aux_len); + if (!street_name_number_next(mr)) + return 0; + dbg(lvl_debug,"enter"); + // debug(mr); + return 1; +} + +static int house_number_next(char *number, char *first, char *last, int interpolation, int *percentage) { + int firstn=atoi(first); + int lastn=atoi(last); + int current,delta,len=lastn-firstn; + if (interpolation) { + len/=2; + } + if (!number[0]) { + strcpy(number,first); + delta=0; + } else { + current=atoi(number)+(interpolation ? 2:1); + if (current > lastn) + return 0; + sprintf(number,"%d",current); + delta=current-firstn; + } + if (percentage) { + if (len) + *percentage=delta*100/len; + else + *percentage=50; + } + return 1; } struct item * -housenumber_search_get_item(struct map_rect_priv *mr) -{ - int d; - dbg(lvl_debug,"enter %s %s\n",mr->street.first_number,mr->street.last_number); - for (;;) { - if (!house_number_next(mr->street.current_number, mr->street.first_number, mr->street.last_number, 0, NULL)) { - if (!street_name_number_next(mr)) - return NULL; - continue; - } - if (mr->search_partial) - d=strncasecmp(mr->search_str, mr->street.current_number, strlen(mr->search_str)); - else - d=strcasecmp(mr->search_str, mr->street.current_number); - if (!d) { - mr->search_item_tmp=NULL; - return &mr->item; - } - } -} +housenumber_search_get_item(struct map_rect_priv *mr) { + int d; + dbg(lvl_debug,"enter %s %s",mr->street.first_number,mr->street.last_number); + for (;;) { + if (!house_number_next(mr->street.current_number, mr->street.first_number, mr->street.last_number, 0, NULL)) { + if (!street_name_number_next(mr)) + return NULL; + continue; + } + if (mr->search_partial) + d=strncasecmp(mr->search_str, mr->street.current_number, strlen(mr->search_str)); + else + d=strcasecmp(mr->search_str, mr->street.current_number); + if (!d) { + mr->search_item_tmp=NULL; + return &mr->item; + } + } +} diff --git a/navit/map/mg/town.c b/navit/map/mg/town.c index 0fd19be0d..b7b7eb487 100644 --- a/navit/map/mg/town.c +++ b/navit/map/mg/town.c @@ -24,264 +24,245 @@ -static void -town_coord_rewind(void *priv_data) -{ - struct town_priv *twn=priv_data; +static void town_coord_rewind(void *priv_data) { + struct town_priv *twn=priv_data; - twn->cidx=0; + twn->cidx=0; } -static int -town_coord_get(void *priv_data, struct coord *c, int count) -{ - struct town_priv *twn=priv_data; +static int town_coord_get(void *priv_data, struct coord *c, int count) { + struct town_priv *twn=priv_data; - if (twn->cidx || count <= 0) - return 0; - twn->cidx=1; - *c=twn->c; - return 1; + if (twn->cidx || count <= 0) + return 0; + twn->cidx=1; + *c=twn->c; + return 1; } -static void -town_attr_rewind(void *priv_data) -{ - struct town_priv *twn=priv_data; +static void town_attr_rewind(void *priv_data) { + struct town_priv *twn=priv_data; - twn->aidx=0; - twn->attr_next=attr_label; + twn->aidx=0; + twn->attr_next=attr_label; } -static int -town_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) -{ - struct town_priv *twn=priv_data; - int len; +static int town_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr) { + struct town_priv *twn=priv_data; + int len; - attr->type=attr_type; - switch (attr_type) { - case attr_any: - while (twn->attr_next != attr_none) { - if (town_attr_get(twn, twn->attr_next, attr)) - return 1; - } - return 0; - case attr_label: - attr->u.str=twn->district; - twn->attr_next=attr_town_name; - if (attr->u.str[0]) - return 1; - attr->u.str=twn->name; - return ((attr->u.str && attr->u.str[0]) ? 1:0); - case attr_town_name: - attr->u.str=twn->name; - twn->attr_next=attr_town_postal; - return ((attr->u.str && attr->u.str[0]) ? 1:0); - case attr_town_postal: - case attr_postal: - strncpy(twn->postal, twn->postal_code1, 32); - attr->u.str=twn->postal; - len=mg_country_postal_len(twn->country); - if (!len) - len=31; - twn->postal[len]='\0'; - twn->attr_next=attr_district_name; - return ((attr->u.str && attr->u.str[0]) ? 1:0); - case attr_district_name: - attr->u.str=twn->district; - twn->attr_next=attr_debug; - return ((attr->u.str && attr->u.str[0]) ? 1:0); - case attr_town_streets_item: - twn->town_attr_item.type=type_town_streets; - twn->town_attr_item.id_hi=twn->country | (file_town_twn << 16) | 0x10000000; - twn->town_attr_item.id_lo=twn->street_assoc; - attr->u.item=&twn->town_attr_item; - twn->attr_next=attr_debug; - return 1; - case attr_debug: - sprintf(twn->debug, "order %d\nsize %d\nstreet_assoc 0x%x", twn->order, twn->size, twn->street_assoc); - attr->u.str=twn->debug; - twn->attr_next=attr_none; - return 1; - default: - dbg(lvl_warning, "Don't know about attribute %d[%04X]=%s yet\n", - attr_type, attr_type, attr_to_name(attr_type)); - return 0; - } - return 1; + attr->type=attr_type; + switch (attr_type) { + case attr_any: + while (twn->attr_next != attr_none) { + if (town_attr_get(twn, twn->attr_next, attr)) + return 1; + } + return 0; + case attr_label: + attr->u.str=twn->district; + twn->attr_next=attr_town_name; + if (attr->u.str[0]) + return 1; + attr->u.str=twn->name; + return ((attr->u.str && attr->u.str[0]) ? 1:0); + case attr_town_name: + attr->u.str=twn->name; + twn->attr_next=attr_town_postal; + return ((attr->u.str && attr->u.str[0]) ? 1:0); + case attr_town_postal: + case attr_postal: + strncpy(twn->postal, twn->postal_code1, 32); + attr->u.str=twn->postal; + len=mg_country_postal_len(twn->country); + if (!len) + len=31; + twn->postal[len]='\0'; + twn->attr_next=attr_district_name; + return ((attr->u.str && attr->u.str[0]) ? 1:0); + case attr_district_name: + attr->u.str=twn->district; + twn->attr_next=attr_debug; + return ((attr->u.str && attr->u.str[0]) ? 1:0); + case attr_town_streets_item: + twn->town_attr_item.type=type_town_streets; + twn->town_attr_item.id_hi=twn->country | (file_town_twn << 16) | 0x10000000; + twn->town_attr_item.id_lo=twn->street_assoc; + attr->u.item=&twn->town_attr_item; + twn->attr_next=attr_debug; + return 1; + case attr_debug: + sprintf(twn->debug, "order %d\nsize %d\nstreet_assoc 0x%x", twn->order, twn->size, twn->street_assoc); + attr->u.str=twn->debug; + twn->attr_next=attr_none; + return 1; + default: + dbg(lvl_warning, "Don't know about attribute %d[%04X]=%s yet", + attr_type, attr_type, attr_to_name(attr_type)); + return 0; + } + return 1; } static struct item_methods town_meth = { - town_coord_rewind, - town_coord_get, - town_attr_rewind, - town_attr_get, + town_coord_rewind, + town_coord_get, + town_attr_rewind, + town_attr_get, }; -static void -town_get_data(struct town_priv *twn, unsigned char **p) -{ - twn->id=get_u32_unal(p); - twn->c.x=get_u32_unal(p); - twn->c.y=get_u32_unal(p); - twn->name=get_string(p); - twn->district=get_string(p); - twn->postal_code1=get_string(p); - twn->order=get_u8(p); /* 1-15 (19) */ - twn->country=get_u16_unal(p); - twn->type=get_u8(p); - twn->unknown2=get_u32_unal(p); - twn->size=get_u8(p); - twn->street_assoc=get_u32_unal(p); - twn->unknown3=get_u8(p); - twn->postal_code2=get_string(p); - twn->unknown4=get_u32_unal(p); -#if 0 - printf("%s\t%s\t%s\t%d\t%d\t%d\n",twn->name,twn->district,twn->postal_code1,twn->order, twn->country, twn->type); -#endif +static void town_get_data(struct town_priv *twn, unsigned char **p) { + twn->id=get_u32_unal(p); + twn->c.x=get_u32_unal(p); + twn->c.y=get_u32_unal(p); + twn->name=get_string(p); + twn->district=get_string(p); + twn->postal_code1=get_string(p); + twn->order=get_u8(p); /* 1-15 (19) */ + twn->country=get_u16_unal(p); + twn->type=get_u8(p); + twn->unknown2=get_u32_unal(p); + twn->size=get_u8(p); + twn->street_assoc=get_u32_unal(p); + twn->unknown3=get_u8(p); + twn->postal_code2=get_string(p); + twn->unknown4=get_u32_unal(p); } - /*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 */ -static unsigned char limit[]={0,1,2,2,4,6,8,10,11,13,14,14,14,20,20,20,20,20,20}; +/*0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 */ +static unsigned char limit[]= {0,1,2,2,4,6,8,10,11,13,14,14,14,20,20,20,20,20,20}; -static enum item_type town_item[]={type_town_label_5e1, type_town_label_1e2, type_town_label_2e2, type_town_label_5e2, type_town_label_1e3, type_town_label_1e3, type_town_label_2e3, type_town_label_5e3, type_town_label_1e4, type_town_label_2e4, type_town_label_5e4, type_town_label_1e5, type_town_label_1e5, type_town_label_2e5, type_town_label_5e5, type_town_label_1e6, type_town_label_2e6}; -static enum item_type district_item[]={type_district_label_5e1, type_district_label_1e2, type_district_label_2e2, type_district_label_5e2, type_district_label_1e3, type_district_label_1e3, type_district_label_2e3, type_district_label_5e3, type_district_label_1e4, type_district_label_2e4, type_district_label_5e4, type_district_label_1e5, type_district_label_1e5, type_district_label_2e5, type_district_label_5e5, type_district_label_1e6, type_district_label_2e6}; -int -town_get(struct map_rect_priv *mr, struct town_priv *twn, struct item *item) -{ - int size; - for (;;) { - if (mr->b.p >= mr->b.end) - return 0; - town_get_data(twn, &mr->b.p); - twn->cidx=0; - twn->aidx=0; - twn->attr_next=attr_label; - if (! mr->cur_sel || (twn->order <= limit[mr->cur_sel->order] && coord_rect_contains(&mr->cur_sel->u.c_rect,&twn->c))) { - switch(twn->type) { - case 1: - size=twn->size; - if (size >= sizeof(town_item)/sizeof(enum item_type)) - size=sizeof(town_item)/sizeof(enum item_type)-1; - item->type=town_item[size]; - break; - case 3: - size=twn->size; - if (size == 6 && twn->order < 14) - size++; - if (size == 5 && twn->order < 14) - size+=2; - if (size >= sizeof(district_item)/sizeof(enum item_type)) - size=sizeof(district_item)/sizeof(enum item_type)-1; - item->type=district_item[size]; - break; - case 4: - item->type=type_port_label; - break; - case 9: - item->type=type_highway_exit_label; - break; - default: - printf("unknown town type 0x%x '%s' '%s' 0x%x,0x%x\n", twn->type, twn->name, twn->district, twn->c.x, twn->c.y); - item->type=type_town_label; - } - if (map_selection_contains_item(mr->cur_sel, 0, item->type)) { - item->id_hi=twn->country | (mr->current_file << 16); - item->id_lo=twn->id; - item->priv_data=twn; - item->meth=&town_meth; - return 1; - } - } - } +static enum item_type town_item[]= {type_town_label_5e1, type_town_label_1e2, type_town_label_2e2, type_town_label_5e2, type_town_label_1e3, type_town_label_1e3, type_town_label_2e3, type_town_label_5e3, type_town_label_1e4, type_town_label_2e4, type_town_label_5e4, type_town_label_1e5, type_town_label_1e5, type_town_label_2e5, type_town_label_5e5, type_town_label_1e6, type_town_label_2e6}; +static enum item_type district_item[]= {type_district_label_5e1, type_district_label_1e2, type_district_label_2e2, type_district_label_5e2, type_district_label_1e3, type_district_label_1e3, type_district_label_2e3, type_district_label_5e3, type_district_label_1e4, type_district_label_2e4, type_district_label_5e4, type_district_label_1e5, type_district_label_1e5, type_district_label_2e5, type_district_label_5e5, type_district_label_1e6, type_district_label_2e6}; +int town_get(struct map_rect_priv *mr, struct town_priv *twn, struct item *item) { + int size; + for (;;) { + if (mr->b.p >= mr->b.end) + return 0; + town_get_data(twn, &mr->b.p); + twn->cidx=0; + twn->aidx=0; + twn->attr_next=attr_label; + if (! mr->cur_sel || (twn->order <= limit[mr->cur_sel->order] && coord_rect_contains(&mr->cur_sel->u.c_rect,&twn->c))) { + switch(twn->type) { + case 1: + size=twn->size; + if (size >= sizeof(town_item)/sizeof(enum item_type)) + size=sizeof(town_item)/sizeof(enum item_type)-1; + item->type=town_item[size]; + break; + case 3: + size=twn->size; + if (size == 6 && twn->order < 14) + size++; + if (size == 5 && twn->order < 14) + size+=2; + if (size >= sizeof(district_item)/sizeof(enum item_type)) + size=sizeof(district_item)/sizeof(enum item_type)-1; + item->type=district_item[size]; + break; + case 4: + item->type=type_port_label; + break; + case 9: + item->type=type_highway_exit_label; + break; + default: + printf("unknown town type 0x%x '%s' '%s' 0x%x,0x%x\n", twn->type, twn->name, twn->district, twn->c.x, twn->c.y); + item->type=type_town_label; + } + if (map_selection_contains_item(mr->cur_sel, 0, item->type)) { + item->id_hi=twn->country | (mr->current_file << 16); + item->id_lo=twn->id; + item->priv_data=twn; + item->meth=&town_meth; + return 1; + } + } + } } -int -town_get_byid(struct map_rect_priv *mr, struct town_priv *twn, int id_hi, int id_lo, struct item *item) -{ - int country=id_hi & 0xffff; - int res; - if (!tree_search_hv(mr->m->dirname, "town", (id_lo >> 8) | (country << 24), id_lo & 0xff, &res)) - return 0; - block_get_byindex(mr->m->file[mr->current_file], res >> 16, &mr->b); - mr->b.p=mr->b.block_start+(res & 0xffff); - return town_get(mr, twn, item); +int town_get_byid(struct map_rect_priv *mr, struct town_priv *twn, int id_hi, int id_lo, struct item *item) { + int country=id_hi & 0xffff; + int res; + if (!tree_search_hv(mr->m->dirname, "town", (id_lo >> 8) | (country << 24), id_lo & 0xff, &res)) + return 0; + block_get_byindex(mr->m->file[mr->current_file], res >> 16, &mr->b); + mr->b.p=mr->b.block_start+(res & 0xffff); + return town_get(mr, twn, item); } -static int -town_search_compare(unsigned char **p, struct map_rect_priv *mr) -{ - int country, d; - char *name; +static int town_search_compare(unsigned char **p, struct map_rect_priv *mr) { + int country, d; + char *name; - if (mr->search_type == attr_town_postal) { - mr->search_blk_count=1; - mr->search_blk_off=(struct block_offset *)(*p); - *p+=4; - name=get_string(p); - d=0; - } else { - country=get_u16_unal(p); - dbg(lvl_debug,"country 0x%x ", country); - name=get_string(p); - dbg(lvl_debug,"name '%s' ",name); - mr->search_blk_count=get_u32_unal(p); - mr->search_blk_off=(struct block_offset *)(*p); - dbg(lvl_debug,"len %d ", mr->search_blk_count); - (*p)+=mr->search_blk_count*4; - d=mr->search_country-country; - } - if (!d) { - if (mr->search_partial) - d=strncasecmp(mr->search_str, name, strlen(mr->search_str)); - else - d=strcasecmp(mr->search_str, name); - } - dbg(lvl_debug,"%d \n",d); - return d; + if (mr->search_type == attr_town_postal) { + mr->search_blk_count=1; + mr->search_blk_off=(struct block_offset *)(*p); + *p+=4; + name=get_string(p); + d=0; + } else { + country=get_u16_unal(p); + dbg(lvl_debug,"country 0x%x ", country); + name=get_string(p); + dbg(lvl_debug,"name '%s' ",name); + mr->search_blk_count=get_u32_unal(p); + mr->search_blk_off=(struct block_offset *)(*p); + dbg(lvl_debug,"len %d ", mr->search_blk_count); + (*p)+=mr->search_blk_count*4; + d=mr->search_country-country; + } + if (!d) { + if (mr->search_partial) + d=strncasecmp(mr->search_str, name, strlen(mr->search_str)); + else + d=strcasecmp(mr->search_str, name); + } + dbg(lvl_debug,"%d ",d); + return d; } struct item * -town_search_get_item(struct map_rect_priv *mr) -{ - int dir=1,leaf; +town_search_get_item(struct map_rect_priv *mr) { + int dir=1,leaf; - if (! mr->search_blk_count) { - dbg(lvl_debug,"partial %d 0x%x '%s' ***\n", mr->search_partial, mr->search_country, mr->search_str); - if (! mr->search_linear) { - while ((leaf=tree_search_next(&mr->ts, &mr->search_p, dir)) != -1) { - dir=town_search_compare(&mr->search_p, mr); - if (! dir) { - mr->search_linear=1; - mr->search_p=NULL; - break; - } - } - if (! mr->search_linear) { - dbg(lvl_warning,"not found\n"); - return NULL; - } - } - if (! tree_search_next_lin(&mr->ts, &mr->search_p)) { - dbg(lvl_debug,"linear not found\n"); - return NULL; - } - if (town_search_compare(&mr->search_p, mr)) { - dbg(lvl_debug,"no match\n"); - return NULL; - } - dbg(lvl_debug,"found %d blocks\n",mr->search_blk_count); - } - if (! mr->search_blk_count) - return NULL; - dbg(lvl_debug,"block 0x%x offset 0x%x\n", block_offset_get_block(mr->search_blk_off), block_offset_get_offset(mr->search_blk_off)); - block_get_byindex(mr->m->file[mr->current_file], block_offset_get_block(mr->search_blk_off), &mr->b); - mr->b.p=mr->b.block_start+block_offset_get_offset(mr->search_blk_off); - town_get(mr, &mr->town, &mr->item); - mr->search_blk_off++; - mr->search_blk_count--; - return &mr->item; + if (! mr->search_blk_count) { + dbg(lvl_debug,"partial %d 0x%x '%s' ***", mr->search_partial, mr->search_country, mr->search_str); + if (! mr->search_linear) { + while ((leaf=tree_search_next(&mr->ts, &mr->search_p, dir)) != -1) { + dir=town_search_compare(&mr->search_p, mr); + if (! dir) { + mr->search_linear=1; + mr->search_p=NULL; + break; + } + } + if (! mr->search_linear) { + dbg(lvl_warning,"not found"); + return NULL; + } + } + if (! tree_search_next_lin(&mr->ts, &mr->search_p)) { + dbg(lvl_debug,"linear not found"); + return NULL; + } + if (town_search_compare(&mr->search_p, mr)) { + dbg(lvl_debug,"no match"); + return NULL; + } + dbg(lvl_debug,"found %d blocks",mr->search_blk_count); + } + if (! mr->search_blk_count) + return NULL; + dbg(lvl_debug,"block 0x%x offset 0x%x", block_offset_get_block(mr->search_blk_off), + block_offset_get_offset(mr->search_blk_off)); + block_get_byindex(mr->m->file[mr->current_file], block_offset_get_block(mr->search_blk_off), &mr->b); + mr->b.p=mr->b.block_start+block_offset_get_offset(mr->search_blk_off); + town_get(mr, &mr->town, &mr->item); + mr->search_blk_off++; + mr->search_blk_count--; + return &mr->item; } diff --git a/navit/map/mg/tree.c b/navit/map/mg/tree.c index e456ca87c..baa448e3c 100644 --- a/navit/map/mg/tree.c +++ b/navit/map/mg/tree.c @@ -23,258 +23,285 @@ #include "mg.h" struct tree_hdr { - /*unsigned int addr; - unsigned int size; - unsigned int low;*/ - unsigned char p[12]; + /*unsigned int addr; + unsigned int size; + unsigned int low;*/ + unsigned char p[12]; }; -static inline unsigned int tree_hdr_get_addr(struct tree_hdr * tree) { unsigned char *p = tree->p; return get_u32(&p); } -static inline unsigned int tree_hdr_get_size(struct tree_hdr * tree) { unsigned char *p = tree->p+4; return get_u32(&p); } -static inline unsigned int tree_hdr_get_low(struct tree_hdr * tree) { unsigned char *p = tree->p+8; return get_u32(&p); } +static inline unsigned int tree_hdr_get_addr(struct tree_hdr * tree) { + unsigned char *p = tree->p; + return get_u32(&p); +} +static inline unsigned int tree_hdr_get_size(struct tree_hdr * tree) { + unsigned char *p = tree->p+4; + return get_u32(&p); +} +static inline unsigned int tree_hdr_get_low(struct tree_hdr * tree) { + unsigned char *p = tree->p+8; + return get_u32(&p); +} struct tree_hdr_h { -/* unsigned int addr; - unsigned int size;*/ - unsigned char p[8]; + /* unsigned int addr; + unsigned int size;*/ + unsigned char p[8]; }; -static inline unsigned int tree_hdr_h_get_addr(struct tree_hdr_h * tree) { unsigned char *p = tree->p; return get_u32(&p); } -static inline unsigned int tree_hdr_h_get_size(struct tree_hdr_h * tree) { unsigned char *p = tree->p+4; return get_u32(&p); } +static inline unsigned int tree_hdr_h_get_addr(struct tree_hdr_h * tree) { + unsigned char *p = tree->p; + return get_u32(&p); +} +static inline unsigned int tree_hdr_h_get_size(struct tree_hdr_h * tree) { + unsigned char *p = tree->p+4; + return get_u32(&p); +} struct tree_leaf_h { -/* unsigned int lower; - unsigned int higher; - unsigned int match; - unsigned int value;*/ - unsigned char p[16]; + /* unsigned int lower; + unsigned int higher; + unsigned int match; + unsigned int value;*/ + unsigned char p[16]; }; -static inline unsigned int tree_leaf_h_get_lower(struct tree_leaf_h * tree) { unsigned char *p = tree->p; return get_u32(&p); } -static inline unsigned int tree_leaf_h_get_higher(struct tree_leaf_h * tree) { unsigned char *p = tree->p+4; return get_u32(&p); } -static inline unsigned int tree_leaf_h_get_match(struct tree_leaf_h * tree) { unsigned char *p = tree->p+8; return get_u32(&p); } -static inline unsigned int tree_leaf_h_get_value(struct tree_leaf_h * tree) { unsigned char *p = tree->p+12; return get_u32(&p); } +static inline unsigned int tree_leaf_h_get_lower(struct tree_leaf_h * tree) { + unsigned char *p = tree->p; + return get_u32(&p); +} +static inline unsigned int tree_leaf_h_get_higher(struct tree_leaf_h * tree) { + unsigned char *p = tree->p+4; + return get_u32(&p); +} +static inline unsigned int tree_leaf_h_get_match(struct tree_leaf_h * tree) { + unsigned char *p = tree->p+8; + return get_u32(&p); +} +static inline unsigned int tree_leaf_h_get_value(struct tree_leaf_h * tree) { + unsigned char *p = tree->p+12; + return get_u32(&p); +} struct tree_hdr_v { - /*unsigned int count; - unsigned int next; - unsigned int unknown;*/ - unsigned char p[12]; + /*unsigned int count; + unsigned int next; + unsigned int unknown;*/ + unsigned char p[12]; }; -static inline unsigned int tree_hdr_v_get_count(struct tree_hdr_v * tree) { unsigned char *p = tree->p; return get_u32_unal(&p); } -static inline unsigned int tree_hdr_v_get_next(struct tree_hdr_v * tree) { unsigned char *p = tree->p+4; return get_u32_unal(&p); } -static inline unsigned int tree_hdr_v_get_unknown(struct tree_hdr_v * tree) { unsigned char *p = tree->p+8; return get_u32_unal(&p); } +static inline unsigned int tree_hdr_v_get_count(struct tree_hdr_v * tree) { + unsigned char *p = tree->p; + return get_u32_unal(&p); +} +static inline unsigned int tree_hdr_v_get_next(struct tree_hdr_v * tree) { + unsigned char *p = tree->p+4; + return get_u32_unal(&p); +} +static inline unsigned int tree_hdr_v_get_unknown(struct tree_hdr_v * tree) { + unsigned char *p = tree->p+8; + return get_u32_unal(&p); +} struct tree_leaf_v { - unsigned char key; - /*int value;*/ - unsigned char p[4]; + unsigned char key; + /*int value;*/ + unsigned char p[4]; } __attribute__((packed)); -static inline int tree_leaf_v_get_value(struct tree_leaf_v * tree) { unsigned char *p = tree->p; return get_u32_unal(&p); } +static inline int tree_leaf_v_get_value(struct tree_leaf_v * tree) { + unsigned char *p = tree->p; + return get_u32_unal(&p); +} -static int -tree_search_h(struct file *file, unsigned int search) -{ - unsigned char *p=file->begin,*end; - int last,i=0,value,lower; - struct tree_hdr_h *thdr; - struct tree_leaf_h *tleaf; +static int tree_search_h(struct file *file, unsigned int search) { + unsigned char *p=file->begin,*end; + int last,i=0,value,lower; + struct tree_hdr_h *thdr; + struct tree_leaf_h *tleaf; - dbg(lvl_debug,"enter\n"); - while (i++ < 1000) { - thdr=(struct tree_hdr_h *)p; - p+=sizeof(*thdr); - end=p+tree_hdr_h_get_size(thdr); - dbg(lvl_debug,"@%td\n", p-file->begin); - last=0; - while (p < end) { - tleaf=(struct tree_leaf_h *)p; - p+=sizeof(*tleaf); - dbg(lvl_debug,"low:0x%x high:0x%x match:0x%x val:0x%x search:0x%x\n", tree_leaf_h_get_lower(tleaf), tree_leaf_h_get_higher(tleaf), tree_leaf_h_get_match(tleaf), tree_leaf_h_get_value(tleaf), search); - value=tree_leaf_h_get_value(tleaf); - if (value == search) - return tree_leaf_h_get_match(tleaf); - if (value > search) { - dbg(lvl_debug,"lower\n"); - lower=tree_leaf_h_get_lower(tleaf); - if (lower) - last=lower; - break; - } - last=tree_leaf_h_get_higher(tleaf); - } - if (! last || last == -1) - return 0; - p=file->begin+last; - } - return 0; + dbg(lvl_debug,"enter"); + while (i++ < 1000) { + thdr=(struct tree_hdr_h *)p; + p+=sizeof(*thdr); + end=p+tree_hdr_h_get_size(thdr); + dbg(lvl_debug,"@%td", p-file->begin); + last=0; + while (p < end) { + tleaf=(struct tree_leaf_h *)p; + p+=sizeof(*tleaf); + dbg(lvl_debug,"low:0x%x high:0x%x match:0x%x val:0x%x search:0x%x", tree_leaf_h_get_lower(tleaf), + tree_leaf_h_get_higher(tleaf), tree_leaf_h_get_match(tleaf), tree_leaf_h_get_value(tleaf), search); + value=tree_leaf_h_get_value(tleaf); + if (value == search) + return tree_leaf_h_get_match(tleaf); + if (value > search) { + dbg(lvl_debug,"lower"); + lower=tree_leaf_h_get_lower(tleaf); + if (lower) + last=lower; + break; + } + last=tree_leaf_h_get_higher(tleaf); + } + if (! last || last == -1) + return 0; + p=file->begin+last; + } + return 0; } -static int -tree_search_v(struct file *file, int offset, int search) -{ - unsigned char *p=file->begin+offset; - int i=0,count,next; - struct tree_hdr_v *thdr; - struct tree_leaf_v *tleaf; - while (i++ < 1000) { - thdr=(struct tree_hdr_v *)p; - p+=sizeof(*thdr); - count=tree_hdr_v_get_count(thdr); - dbg(lvl_debug,"offset=%td count=0x%x\n", p-file->begin, count); - while (count--) { - tleaf=(struct tree_leaf_v *)p; - p+=sizeof(*tleaf); - dbg(lvl_debug,"0x%x 0x%x\n", tleaf->key, search); - if (tleaf->key == search) - return tree_leaf_v_get_value(tleaf); - } - next=tree_hdr_v_get_next(thdr); - if (! next) - break; - p=file->begin+next; - } - return 0; +static int tree_search_v(struct file *file, int offset, int search) { + unsigned char *p=file->begin+offset; + int i=0,count,next; + struct tree_hdr_v *thdr; + struct tree_leaf_v *tleaf; + while (i++ < 1000) { + thdr=(struct tree_hdr_v *)p; + p+=sizeof(*thdr); + count=tree_hdr_v_get_count(thdr); + dbg(lvl_debug,"offset=%td count=0x%x", p-file->begin, count); + while (count--) { + tleaf=(struct tree_leaf_v *)p; + p+=sizeof(*tleaf); + dbg(lvl_debug,"0x%x 0x%x", tleaf->key, search); + if (tleaf->key == search) + return tree_leaf_v_get_value(tleaf); + } + next=tree_hdr_v_get_next(thdr); + if (! next) + break; + p=file->begin+next; + } + return 0; } -int -tree_search_hv(char *dirname, char *filename, unsigned int search_h, unsigned int search_v, int *result) -{ - struct file *f_idx_h, *f_idx_v; - char buffer[4096]; - int h,v; +int tree_search_hv(char *dirname, char *filename, unsigned int search_h, unsigned int search_v, int *result) { + struct file *f_idx_h, *f_idx_v; + char buffer[4096]; + int h,v; - dbg(lvl_debug,"enter(%s, %s, 0x%x, 0x%x, %p)\n",dirname, filename, search_h, search_v, result); - sprintf(buffer, "%s/%s.h1", dirname, filename); - f_idx_h=file_create_caseinsensitive(buffer, 0); - if ((!f_idx_h) || (!file_mmap(f_idx_h))) - return 0; - sprintf(buffer, "%s/%s.v1", dirname, filename); - f_idx_v=file_create_caseinsensitive(buffer, 0); - dbg(lvl_debug,"%p %p\n", f_idx_h, f_idx_v); - if ((!f_idx_v) || (!file_mmap(f_idx_v))) { - file_destroy(f_idx_h); - return 0; - } - if ((h=tree_search_h(f_idx_h, search_h))) { - dbg(lvl_debug,"h=0x%x\n", h); - if ((v=tree_search_v(f_idx_v, h, search_v))) { - dbg(lvl_debug,"v=0x%x\n", v); - *result=v; - file_destroy(f_idx_v); - file_destroy(f_idx_h); - dbg(lvl_debug,"return 1\n"); - return 1; - } - } - file_destroy(f_idx_v); - file_destroy(f_idx_h); - dbg(lvl_debug,"return 0\n"); - return 0; + dbg(lvl_debug,"enter(%s, %s, 0x%x, 0x%x, %p)",dirname, filename, search_h, search_v, result); + sprintf(buffer, "%s/%s.h1", dirname, filename); + f_idx_h=file_create_caseinsensitive(buffer, 0); + if ((!f_idx_h) || (!file_mmap(f_idx_h))) + return 0; + sprintf(buffer, "%s/%s.v1", dirname, filename); + f_idx_v=file_create_caseinsensitive(buffer, 0); + dbg(lvl_debug,"%p %p", f_idx_h, f_idx_v); + if ((!f_idx_v) || (!file_mmap(f_idx_v))) { + file_destroy(f_idx_h); + return 0; + } + if ((h=tree_search_h(f_idx_h, search_h))) { + dbg(lvl_debug,"h=0x%x", h); + if ((v=tree_search_v(f_idx_v, h, search_v))) { + dbg(lvl_debug,"v=0x%x", v); + *result=v; + file_destroy(f_idx_v); + file_destroy(f_idx_h); + dbg(lvl_debug,"return 1"); + return 1; + } + } + file_destroy(f_idx_v); + file_destroy(f_idx_h); + dbg(lvl_debug,"return 0"); + return 0; } -static struct tree_search_node * -tree_search_enter(struct tree_search *ts, int offset) -{ - struct tree_search_node *tsn=&ts->nodes[++ts->curr_node]; - unsigned char *p; - p=ts->f->begin+offset; - tsn->hdr=(struct tree_hdr *)p; - tsn->p=p+sizeof(struct tree_hdr); - tsn->last=tsn->p; - tsn->end=p+tree_hdr_get_size(tsn->hdr); - tsn->low=tree_hdr_get_low(tsn->hdr); - tsn->high=tree_hdr_get_low(tsn->hdr); - dbg(lvl_debug,"pos %td addr 0x%ux size 0x%ux low 0x%ux end %tu\n", p-ts->f->begin, tree_hdr_get_addr(tsn->hdr), tree_hdr_get_size(tsn->hdr), tree_hdr_get_low(tsn->hdr), tsn->end-ts->f->begin); - return tsn; +static struct tree_search_node *tree_search_enter(struct tree_search *ts, int offset) { + struct tree_search_node *tsn=&ts->nodes[++ts->curr_node]; + unsigned char *p; + p=ts->f->begin+offset; + tsn->hdr=(struct tree_hdr *)p; + tsn->p=p+sizeof(struct tree_hdr); + tsn->last=tsn->p; + tsn->end=p+tree_hdr_get_size(tsn->hdr); + tsn->low=tree_hdr_get_low(tsn->hdr); + tsn->high=tree_hdr_get_low(tsn->hdr); + dbg(lvl_debug,"pos %td addr 0x%ux size 0x%ux low 0x%ux end %tu", p-ts->f->begin, tree_hdr_get_addr(tsn->hdr), + tree_hdr_get_size(tsn->hdr), tree_hdr_get_low(tsn->hdr), tsn->end-ts->f->begin); + return tsn; } -int tree_search_next(struct tree_search *ts, unsigned char **p, int dir) -{ - struct tree_search_node *tsn=&ts->nodes[ts->curr_node]; +int tree_search_next(struct tree_search *ts, unsigned char **p, int dir) { + struct tree_search_node *tsn=&ts->nodes[ts->curr_node]; - if (! *p) - *p=tsn->p; - dbg(lvl_debug,"next *p=%p dir=%d\n", *p, dir); - dbg(lvl_debug,"low1=0x%x high1=0x%x\n", tsn->low, tsn->high); - if (dir <= 0) { - dbg(lvl_debug,"down 0x%x\n", tsn->low); - if (tsn->low != 0xffffffff) { - tsn=tree_search_enter(ts, tsn->low); - *p=tsn->p; - tsn->high=get_u32(p); - ts->last_node=ts->curr_node; - dbg(lvl_debug,"saving last2 %d %td\n", ts->curr_node, tsn->last-ts->f->begin); - dbg(lvl_debug,"high2=0x%x\n", tsn->high); - return 0; - } - return -1; - } - tsn->low=tsn->high; - tsn->last=*p; - tsn->high=get_u32_unal(p); - dbg(lvl_debug,"saving last3 %d %p\n", ts->curr_node, tsn->last); - if (*p < tsn->end) - return (tsn->low == 0xffffffff ? 1 : 0); - dbg(lvl_debug,"end reached high=0x%x\n",tsn->high); - if (tsn->low != 0xffffffff) { - dbg(lvl_debug,"low 0x%x\n", tsn->low); - tsn=tree_search_enter(ts, tsn->low); - *p=tsn->p; - tsn->high=get_u32_unal(p); - ts->last_node=ts->curr_node; - dbg(lvl_debug,"saving last4 %d %td\n", ts->curr_node, tsn->last-ts->f->begin); - dbg(lvl_debug,"high4=0x%x\n", tsn->high); - return 0; - } - return -1; + if (! *p) + *p=tsn->p; + dbg(lvl_debug,"next *p=%p dir=%d", *p, dir); + dbg(lvl_debug,"low1=0x%x high1=0x%x", tsn->low, tsn->high); + if (dir <= 0) { + dbg(lvl_debug,"down 0x%x", tsn->low); + if (tsn->low != 0xffffffff) { + tsn=tree_search_enter(ts, tsn->low); + *p=tsn->p; + tsn->high=get_u32(p); + ts->last_node=ts->curr_node; + dbg(lvl_debug,"saving last2 %d %td", ts->curr_node, tsn->last-ts->f->begin); + dbg(lvl_debug,"high2=0x%x", tsn->high); + return 0; + } + return -1; + } + tsn->low=tsn->high; + tsn->last=*p; + tsn->high=get_u32_unal(p); + dbg(lvl_debug,"saving last3 %d %p", ts->curr_node, tsn->last); + if (*p < tsn->end) + return (tsn->low == 0xffffffff ? 1 : 0); + dbg(lvl_debug,"end reached high=0x%x",tsn->high); + if (tsn->low != 0xffffffff) { + dbg(lvl_debug,"low 0x%x", tsn->low); + tsn=tree_search_enter(ts, tsn->low); + *p=tsn->p; + tsn->high=get_u32_unal(p); + ts->last_node=ts->curr_node; + dbg(lvl_debug,"saving last4 %d %td", ts->curr_node, tsn->last-ts->f->begin); + dbg(lvl_debug,"high4=0x%x", tsn->high); + return 0; + } + return -1; } -int tree_search_next_lin(struct tree_search *ts, unsigned char **p) -{ - struct tree_search_node *tsn=&ts->nodes[ts->curr_node]; - int high; - - dbg(lvl_debug,"pos=%d %td\n", ts->curr_node, *p-ts->f->begin); - if (*p) - ts->nodes[ts->last_node].last=*p; - *p=tsn->last; - for (;;) { - high=get_u32_unal(p); - if (*p < tsn->end) { - ts->last_node=ts->curr_node; - while (high != 0xffffffff) { - tsn=tree_search_enter(ts, high); - dbg(lvl_debug,"reload %d\n",ts->curr_node); - high=tsn->low; - } - return 1; - } - dbg(lvl_debug,"eon %d %td %td\n", ts->curr_node, *p-ts->f->begin, tsn->end-ts->f->begin); - if (! ts->curr_node) - break; - ts->curr_node--; - tsn=&ts->nodes[ts->curr_node]; - *p=tsn->last; - } +int tree_search_next_lin(struct tree_search *ts, unsigned char **p) { + struct tree_search_node *tsn=&ts->nodes[ts->curr_node]; + int high; + + dbg(lvl_debug,"pos=%d %td", ts->curr_node, *p-ts->f->begin); + if (*p) + ts->nodes[ts->last_node].last=*p; + *p=tsn->last; + for (;;) { + high=get_u32_unal(p); + if (*p < tsn->end) { + ts->last_node=ts->curr_node; + while (high != 0xffffffff) { + tsn=tree_search_enter(ts, high); + dbg(lvl_debug,"reload %d",ts->curr_node); + high=tsn->low; + } + return 1; + } + dbg(lvl_debug,"eon %d %td %td", ts->curr_node, *p-ts->f->begin, tsn->end-ts->f->begin); + if (! ts->curr_node) + break; + ts->curr_node--; + tsn=&ts->nodes[ts->curr_node]; + *p=tsn->last; + } - return 0; + return 0; } -void -tree_search_init(char *dirname, char *filename, struct tree_search *ts, int offset) -{ - char buffer[4096]; - sprintf(buffer, "%s/%s", dirname, filename); - ts->f=file_create_caseinsensitive(buffer, 0); - ts->curr_node=-1; - if (ts->f) { - file_mmap(ts->f); - tree_search_enter(ts, offset); - } +void tree_search_init(char *dirname, char *filename, struct tree_search *ts, int offset) { + char buffer[4096]; + sprintf(buffer, "%s/%s", dirname, filename); + ts->f=file_create_caseinsensitive(buffer, 0); + ts->curr_node=-1; + if (ts->f) { + file_mmap(ts->f); + tree_search_enter(ts, offset); + } } -void -tree_search_free(struct tree_search *ts) -{ - if (ts->f) - file_destroy(ts->f); +void tree_search_free(struct tree_search *ts) { + if (ts->f) + file_destroy(ts->f); } |