Fix:Core:Renamed data to map to clean up things a bit
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Sat, 3 Jan 2009 19:11:30 +0000 (19:11 +0000)
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>
Sat, 3 Jan 2009 19:11:30 +0000 (19:11 +0000)
git-svn-id: https://navit.svn.sourceforge.net/svnroot/navit/trunk/navit@1884 ffa7fe5e-494d-0410-b361-a75ebd5db220

98 files changed:
Makefile.inc
configure.in
navit/Makefile.am
navit/data/Makefile.am [deleted file]
navit/data/binfile/Makefile.am [deleted file]
navit/data/binfile/binfile.c [deleted file]
navit/data/garmin/Makefile.am [deleted file]
navit/data/garmin/gar2navit.c [deleted file]
navit/data/garmin/gar2navit.h [deleted file]
navit/data/garmin/garmin.c [deleted file]
navit/data/garmin/garmin.h [deleted file]
navit/data/garmin/garmintypes.txt [deleted file]
navit/data/garmin/gentypes.c [deleted file]
navit/data/garmin_img/Makefile.am [deleted file]
navit/data/garmin_img/garmin_img.c [deleted file]
navit/data/mg/Makefile.am [deleted file]
navit/data/mg/block.c [deleted file]
navit/data/mg/map.c [deleted file]
navit/data/mg/mg.h [deleted file]
navit/data/mg/poly.c [deleted file]
navit/data/mg/street.c [deleted file]
navit/data/mg/town.c [deleted file]
navit/data/mg/tree.c [deleted file]
navit/data/poi_geodownload/Makefile.am [deleted file]
navit/data/poi_geodownload/libmdb/Makefile.am [deleted file]
navit/data/poi_geodownload/libmdb/backend.c [deleted file]
navit/data/poi_geodownload/libmdb/catalog.c [deleted file]
navit/data/poi_geodownload/libmdb/data.c [deleted file]
navit/data/poi_geodownload/libmdb/dump.c [deleted file]
navit/data/poi_geodownload/libmdb/file.c [deleted file]
navit/data/poi_geodownload/libmdb/iconv.c [deleted file]
navit/data/poi_geodownload/libmdb/include/Makefile.am [deleted file]
navit/data/poi_geodownload/libmdb/include/mdbtools.h [deleted file]
navit/data/poi_geodownload/libmdb/index.c [deleted file]
navit/data/poi_geodownload/libmdb/kkd.c [deleted file]
navit/data/poi_geodownload/libmdb/like.c [deleted file]
navit/data/poi_geodownload/libmdb/map.c [deleted file]
navit/data/poi_geodownload/libmdb/mem.c [deleted file]
navit/data/poi_geodownload/libmdb/money.c [deleted file]
navit/data/poi_geodownload/libmdb/options.c [deleted file]
navit/data/poi_geodownload/libmdb/props.c [deleted file]
navit/data/poi_geodownload/libmdb/sargs.c [deleted file]
navit/data/poi_geodownload/libmdb/stats.c [deleted file]
navit/data/poi_geodownload/libmdb/table.c [deleted file]
navit/data/poi_geodownload/libmdb/worktable.c [deleted file]
navit/data/poi_geodownload/libmdb/write.c [deleted file]
navit/data/poi_geodownload/poi_geodownload.c [deleted file]
navit/data/textfile/Makefile.am [deleted file]
navit/data/textfile/textfile.c [deleted file]
navit/data/textfile/textfile.h [deleted file]
navit/map/Makefile.am [new file with mode: 0644]
navit/map/binfile/Makefile.am [new file with mode: 0644]
navit/map/binfile/binfile.c [new file with mode: 0644]
navit/map/garmin/Makefile.am [new file with mode: 0644]
navit/map/garmin/gar2navit.c [new file with mode: 0644]
navit/map/garmin/gar2navit.h [new file with mode: 0644]
navit/map/garmin/garmin.c [new file with mode: 0644]
navit/map/garmin/garmin.h [new file with mode: 0644]
navit/map/garmin/garmintypes.txt [new file with mode: 0644]
navit/map/garmin/gentypes.c [new file with mode: 0644]
navit/map/garmin_img/Makefile.am [new file with mode: 0644]
navit/map/garmin_img/garmin_img.c [new file with mode: 0644]
navit/map/mg/Makefile.am [new file with mode: 0644]
navit/map/mg/block.c [new file with mode: 0644]
navit/map/mg/map.c [new file with mode: 0644]
navit/map/mg/mg.h [new file with mode: 0644]
navit/map/mg/poly.c [new file with mode: 0644]
navit/map/mg/street.c [new file with mode: 0644]
navit/map/mg/town.c [new file with mode: 0644]
navit/map/mg/tree.c [new file with mode: 0644]
navit/map/poi_geodownload/Makefile.am [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/Makefile.am [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/backend.c [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/catalog.c [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/data.c [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/dump.c [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/file.c [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/iconv.c [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/include/Makefile.am [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/include/mdbtools.h [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/index.c [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/kkd.c [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/like.c [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/map.c [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/mem.c [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/money.c [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/options.c [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/props.c [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/sargs.c [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/stats.c [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/table.c [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/worktable.c [new file with mode: 0644]
navit/map/poi_geodownload/libmdb/write.c [new file with mode: 0644]
navit/map/poi_geodownload/poi_geodownload.c [new file with mode: 0644]
navit/map/textfile/Makefile.am [new file with mode: 0644]
navit/map/textfile/textfile.c [new file with mode: 0644]
navit/map/textfile/textfile.h [new file with mode: 0644]
navit/plugin.c

index 5e5ff86..484d9b9 100644 (file)
@@ -1,5 +1,5 @@
 modulebindingdir=$(pkglibdir)/binding
-moduledatadir=$(pkglibdir)/data
+modulemapdir=$(pkglibdir)/map
 modulefontdir=$(pkglibdir)/font
 modulegraphicsdir=$(pkglibdir)/graphics
 moduleguidir=$(pkglibdir)/gui
index 813db68..fcd9d98 100644 (file)
@@ -171,7 +171,7 @@ AC_PROG_LIBTOOL
 AM_CONDITIONAL(EVENT_GLIB, [test "x$glib" = "xyes"])
 AM_CONDITIONAL(SUPPORT_GLIB, [test "x$glib" = "xno"])
 AM_CONDITIONAL(SUPPORT_EZXML, [test "x$glib" = "xno"])
-AM_CONDITIONAL(DATA_POI_GEODOWNLOAD, [test "x$glib" = "xyes"])
+AM_CONDITIONAL(MAP_POI_GEODOWNLOAD, [test "x$glib" = "xyes"])
 
 AC_CHECK_HEADER(
        zlib.h,
@@ -811,14 +811,14 @@ navit/Makefile
 navit/binding/Makefile
 navit/binding/python/Makefile
 navit/binding/dbus/Makefile
-navit/data/Makefile
-navit/data/mg/Makefile
-navit/data/textfile/Makefile
-navit/data/binfile/Makefile
-navit/data/garmin/Makefile
-navit/data/poi_geodownload/Makefile
-navit/data/poi_geodownload/libmdb/Makefile
-navit/data/poi_geodownload/libmdb/include/Makefile
+navit/map/Makefile
+navit/map/mg/Makefile
+navit/map/textfile/Makefile
+navit/map/binfile/Makefile
+navit/map/garmin/Makefile
+navit/map/poi_geodownload/Makefile
+navit/map/poi_geodownload/libmdb/Makefile
+navit/map/poi_geodownload/libmdb/include/Makefile
 navit/fib-1.1/Makefile
 navit/font/Makefile
 navit/font/freetype/Makefile
index ae1a339..1578442 100644 (file)
@@ -1,6 +1,6 @@
 include $(top_srcdir)/Makefile.inc
-DIST_SUBDIRS=binding data fib-1.1 font gui graphics osd speech support vehicle xpm maps
-SUBDIRS=binding data fib-1.1 font gui graphics osd speech support vehicle xpm
+DIST_SUBDIRS=binding map fib-1.1 font gui graphics osd speech support vehicle xpm maps
+SUBDIRS=binding map fib-1.1 font gui graphics osd speech support vehicle xpm
 if BUILD_SAMPLEMAP
   SUBDIRS += maps
 endif
diff --git a/navit/data/Makefile.am b/navit/data/Makefile.am
deleted file mode 100644 (file)
index f05aba1..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-SUBDIRS=mg textfile binfile
-#  garmin_img
-if HAVELIBGARMIN
-SUBDIRS+=garmin
-endif
-if DATA_POI_GEODOWNLOAD
-SUBDIRS+=poi_geodownload
-endif
-
-DIST_SUBDIRS=mg textfile poi_geodownload binfile garmin
-
diff --git a/navit/data/binfile/Makefile.am b/navit/data/binfile/Makefile.am
deleted file mode 100644 (file)
index 9f6426d..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-include $(top_srcdir)/Makefile.inc
-AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/navit -DMODULE=data_binfile
-if PLUGINS
-  moduledata_LTLIBRARIES = libdata_binfile.la
-else
-  noinst_LTLIBRARIES = libdata_binfile.la
-endif
-libdata_binfile_la_SOURCES = binfile.c
diff --git a/navit/data/binfile/binfile.c b/navit/data/binfile/binfile.c
deleted file mode 100644 (file)
index 7a91dcb..0000000
+++ /dev/null
@@ -1,907 +0,0 @@
-/**
- * Navit, a modular navigation system.
- * Copyright (C) 2005-2008 Navit Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA  02110-1301, USA.
- */
-
-#include <glib.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include "config.h"
-#include "debug.h"
-#include "plugin.h"
-#include "projection.h"
-#include "item.h"
-#include "map.h"
-#include "maptype.h"
-#include "attr.h"
-#include "coord.h"
-#include "transform.h"
-#include "file.h"
-#include "zipfile.h"
-#include "endianess.h"
-
-static int map_id;
-
-struct minmax {
-       short min;
-       short max;
-};
-
-struct tile {
-       int *start;
-       int *end;
-       int *pos;
-       int *pos_coord_start;
-       int *pos_coord;
-       int *pos_attr_start;
-       int *pos_attr;
-       int *pos_next;
-       int zipfile_num;
-};
-
-struct map_priv {
-       int id;
-       char *filename;
-       char *cachedir;
-       struct file *fi;
-       struct zip_cd *index_cd;
-       int index_offset;
-       int cde_size;
-       struct zip_eoc *eoc;
-       int zip_members;
-       unsigned char *search_data;
-       int search_offset;
-       int search_size;
-       int version;
-       int check_version;
-};
-
-struct map_rect_priv {
-       int *start;
-       int *end;
-       enum attr_type attr_last;
-       int label;
-       int *label_attr[4];
-        struct map_selection *sel;
-        struct map_priv *m;
-        struct item item;
-       int tile_depth;
-       struct tile tiles[8];
-       struct tile *t;
-       int country_id;
-       char *url;
-};
-
-struct map_search_priv {
-       struct map_rect_priv *mr;
-       struct attr *search;
-       struct map_selection *ms;
-       int partial;
-       GHashTable *search_results;
-};
-
-
-static void minmax_to_cpu(struct minmax * mima) {
-       dbg_assert(mima  != NULL);
-       mima->min = le16_to_cpu(mima->min);
-       mima->max = le16_to_cpu(mima->max);
-}
-
-static void lfh_to_cpu(struct zip_lfh *lfh) {
-       dbg_assert(lfh != NULL);
-       lfh->ziplocsig = le32_to_cpu(lfh->ziplocsig);
-       lfh->zipver    = le16_to_cpu(lfh->zipver);
-       lfh->zipgenfld = le16_to_cpu(lfh->zipgenfld);
-       lfh->zipmthd   = le16_to_cpu(lfh->zipmthd);
-       lfh->ziptime   = le16_to_cpu(lfh->ziptime);
-       lfh->zipdate   = le16_to_cpu(lfh->zipdate);
-       lfh->zipcrc    = le32_to_cpu(lfh->zipcrc);
-       lfh->zipsize   = le32_to_cpu(lfh->zipsize);
-       lfh->zipuncmp  = le32_to_cpu(lfh->zipuncmp);
-       lfh->zipfnln   = le16_to_cpu(lfh->zipfnln);
-       lfh->zipxtraln = le16_to_cpu(lfh->zipxtraln);
-}
-
-static void cd_to_cpu(struct zip_cd *zcd) {
-       dbg_assert(zcd != NULL);
-       zcd->zipcensig = le32_to_cpu(zcd->zipcensig);
-       zcd->zipccrc   = le32_to_cpu(zcd->zipccrc);
-       zcd->zipcsiz   = le32_to_cpu(zcd->zipcsiz);
-       zcd->zipcunc   = le32_to_cpu(zcd->zipcunc);
-       zcd->zipcfnl   = le16_to_cpu(zcd->zipcfnl);
-       zcd->zipcxtl   = le16_to_cpu(zcd->zipcxtl);
-       zcd->zipccml   = le16_to_cpu(zcd->zipccml);
-       zcd->zipdsk    = le16_to_cpu(zcd->zipdsk);
-       zcd->zipint    = le16_to_cpu(zcd->zipint);
-       zcd->zipext    = le32_to_cpu(zcd->zipext);
-       zcd->zipofst   = le32_to_cpu(zcd->zipofst);
-}
-
-static void eoc_to_cpu(struct zip_eoc *eoc) {
-       dbg_assert(eoc != NULL);
-       eoc->zipesig   = le32_to_cpu(eoc->zipesig);
-       eoc->zipedsk   = le16_to_cpu(eoc->zipedsk);
-       eoc->zipecen   = le16_to_cpu(eoc->zipecen);
-       eoc->zipenum   = le16_to_cpu(eoc->zipenum);
-       eoc->zipecenn  = le16_to_cpu(eoc->zipecenn);
-       eoc->zipecsz   = le32_to_cpu(eoc->zipecsz);
-       eoc->zipeofst  = le32_to_cpu(eoc->zipeofst);
-       eoc->zipecoml  = le16_to_cpu(eoc->zipecoml);
-}
-
-static void binfile_check_version(struct map_priv *m);
-
-static struct zip_eoc *
-binfile_read_eoc(struct file *fi)
-{
-       struct zip_eoc *eoc;
-       eoc=(struct zip_eoc *)file_data_read(fi,fi->size-sizeof(struct zip_eoc), sizeof(struct zip_eoc));
-       if (eoc) {
-               eoc_to_cpu(eoc);
-               dbg(1,"sig 0x%x\n", eoc->zipesig);
-               if (eoc->zipesig != zip_eoc_sig) {
-                       file_data_free(fi,(unsigned char *)eoc);
-                       eoc=NULL;
-               }
-       }
-       return eoc;
-}
-
-static struct zip_cd *
-binfile_read_cd(struct map_priv *m, int offset, int len)
-{
-       struct zip_cd *cd;
-       if (len == -1) {
-               cd=(struct zip_cd *)file_data_read(m->fi,m->eoc->zipeofst+offset, sizeof(*cd));
-               cd_to_cpu(m->index_cd);
-               len=cd->zipcfnl;
-               file_data_free(m->fi,(unsigned char *)cd);
-       }
-       cd=(struct zip_cd *)file_data_read(m->fi,m->eoc->zipeofst+offset, sizeof(*cd)+len);
-       if (cd) {
-               cd_to_cpu(cd);
-               dbg(1,"sig 0x%x\n", cd->zipcensig);
-               if (cd->zipcensig != zip_cd_sig) {
-                       file_data_free(m->fi,(unsigned char *)cd);
-                       cd=NULL;
-               }
-       }
-       return cd;
-}
-
-static struct zip_lfh *
-binfile_read_lfh(struct file *fi, int offset)
-{
-       struct zip_lfh *lfh;
-
-       lfh=(struct zip_lfh *)(file_data_read(fi,offset,sizeof(struct zip_lfh)));
-       if (lfh) {
-               lfh_to_cpu(lfh);
-               if (lfh->ziplocsig != zip_lfh_sig) {
-                       file_data_free(fi,(unsigned char *)lfh);
-                       lfh=NULL;
-               }
-       }
-       return lfh;
-}
-
-static unsigned char *
-binfile_read_content(struct file *fi, int offset, struct zip_lfh *lfh)
-{
-       offset+=sizeof(struct zip_lfh)+lfh->zipfnln+lfh->zipxtraln;
-       switch (lfh->zipmthd) {
-       case 0:
-               return file_data_read(fi,offset, lfh->zipuncmp);
-       case 8:
-               return file_data_read_compressed(fi,offset, lfh->zipsize, lfh->zipuncmp);
-       default:
-               dbg(0,"Unknown compression method %d\n", lfh->zipmthd);
-               return NULL;
-       }
-}
-
-static int
-binfile_search_cd(struct map_priv *m, int offset, char *name, int partial, int skip)
-{
-       int size=4096;
-       int end=m->eoc->zipecsz;
-       int len=strlen(name);
-       struct zip_cd *cd;
-#if 0
-       dbg(0,"end=%d\n",end);
-#endif
-       while (offset < end) {
-               cd=(struct zip_cd *)(m->search_data+offset-m->search_offset);
-               if (! m->search_data || 
-                     m->search_offset > offset || 
-                     offset-m->search_offset+sizeof(*cd) > m->search_size ||
-                     offset-m->search_offset+sizeof(*cd)+cd->zipcfnl > m->search_size
-                  ) {
-#if 0
-                       dbg(0,"reload %p %d %d\n", m->search_data, m->search_offset, offset);
-#endif
-                       if (m->search_data)
-                               file_data_free(m->fi,m->search_data);
-                       m->search_offset=offset;
-                       m->search_size=end-offset;
-                       if (m->search_size > size)
-                               m->search_size=size;
-                       m->search_data=file_data_read(m->fi,m->eoc->zipeofst+m->search_offset,m->search_size);
-                       cd=(struct zip_cd *)m->search_data;
-               }
-#if 0
-               dbg(0,"offset=%d search_offset=%d search_size=%d search_data=%p cd=%p\n", offset, m->search_offset, m->search_size, m->search_data, cd);
-               dbg(0,"offset=%d fn='%s'\n",offset,cd->zipcfn);
-#endif
-               if (!skip && 
-                   (partial || cd->zipcfnl == len) &&
-                   !strncmp(cd->zipcfn, name, len)) 
-                       return offset;
-               skip=0;
-               offset+=sizeof(*cd)+cd->zipcfnl+cd->zipcxtl+cd->zipccml;
-;
-       }
-       return -1;
-}
-
-static void
-map_destroy_binfile(struct map_priv *m)
-{
-       dbg(1,"map_destroy_binfile\n");
-       g_free(m);
-}
-
-static void
-binfile_coord_rewind(void *priv_data)
-{
-       struct map_rect_priv *mr=priv_data;
-       struct tile *t=mr->t;
-       t->pos_coord=t->pos_coord_start;
-}
-
-static int
-binfile_coord_get(void *priv_data, struct coord *c, int count)
-{
-       struct map_rect_priv *mr=priv_data;
-       struct tile *t=mr->t;
-       int ret=0;
-       dbg(2,"binfile_coord_get %d\n",count);
-       while (count--) {
-               dbg(2,"%p vs %p\n", t->pos_coord, t->pos_attr_start);
-               if (t->pos_coord >= t->pos_attr_start)
-                       break;
-               c->x=le32_to_cpu(*(t->pos_coord++));
-               c->y=le32_to_cpu(*(t->pos_coord++));
-               c++;
-               ret++;
-       }
-       return ret;
-}
-
-static void
-binfile_attr_rewind(void *priv_data)
-{
-       struct map_rect_priv *mr=priv_data;
-       struct tile *t=mr->t;
-       t->pos_attr=t->pos_attr_start;
-       
-}
-
-static char *
-binfile_extract(struct map_priv *m, char *dir, char *filename, int partial)
-{
-       char *full,*fulld,*sep;
-       unsigned char *start;
-       int len,offset=m->index_offset;
-       struct zip_cd *cd;
-       struct zip_lfh *lfh;
-       FILE *f;
-
-       for (;;) {
-               offset=binfile_search_cd(m, offset, filename, partial, 1);
-               if (offset == -1)
-                       break;
-               cd=binfile_read_cd(m, offset, -1);
-               len=strlen(dir)+1+cd->zipcfnl+1;
-               full=g_malloc(len);
-               strcpy(full,dir);
-               strcpy(full+strlen(full),"/");
-               strncpy(full+strlen(full),cd->zipcfn,cd->zipcfnl);
-               full[len-1]='\0';
-               fulld=g_strdup(full);
-               sep=strrchr(fulld, '/');
-               if (sep) {
-                       *sep='\0';
-                       file_mkdir(fulld, 1);
-               }
-               if (full[len-2] != '/') {
-                       lfh=binfile_read_lfh(m->fi, cd->zipofst);
-                       start=binfile_read_content(m->fi, cd->zipofst, lfh);
-                       dbg(0,"fopen '%s'\n", full);
-                       f=fopen(full,"w");
-                       fwrite(start, lfh->zipuncmp, 1, f);
-                       fclose(f);
-                       file_data_free(m->fi, start);
-                       file_data_free(m->fi, (unsigned char *)lfh);
-               }
-               file_data_free(m->fi, (unsigned char *)cd);
-               g_free(fulld);
-               g_free(full);
-               if (! partial)
-                       break;
-       }
-       
-       return g_strdup_printf("%s/%s",dir,filename);
-}
-
-static int
-binfile_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
-{      
-       struct map_rect_priv *mr=priv_data;
-       struct tile *t=mr->t;
-       enum attr_type type;
-       int i,size;
-
-       if (attr_type != mr->attr_last) {
-               t->pos_attr=t->pos_attr_start;
-               mr->attr_last=attr_type;
-       }
-       while (t->pos_attr < t->pos_next) {
-               size=le32_to_cpu(*(t->pos_attr++));
-               type=le32_to_cpu(t->pos_attr[0]);
-               if (type == attr_label) 
-                       mr->label=1;
-               if (type == attr_house_number)
-                       mr->label_attr[0]=t->pos_attr;
-               if (type == attr_street_name)
-                       mr->label_attr[1]=t->pos_attr;
-               if (type == attr_street_name_systematic)
-                       mr->label_attr[2]=t->pos_attr;
-               if (type == attr_town_name)
-                       mr->label_attr[3]=t->pos_attr;
-               if (type == attr_type || attr_type == attr_any) {
-                       if (attr_type == attr_any) {
-                               dbg(1,"pos %p attr %s size %d\n", t->pos_attr-1, attr_to_name(type), size);
-                       }
-                       attr->type=type;
-                       attr_data_set(attr, t->pos_attr+1);
-                       if (type == attr_url_local) {
-                               g_free(mr->url);
-                               mr->url=binfile_extract(mr->m, mr->m->cachedir, attr->u.str, 1);
-                               attr->u.str=mr->url;
-                       }
-                       t->pos_attr+=size;
-                       return 1;
-               } else {
-                       t->pos_attr+=size;
-               }
-       }
-       if (!mr->label && (attr_type == attr_any || attr_type == attr_label)) {
-               for (i = 0 ; i < sizeof(mr->label_attr)/sizeof(int *) ; i++) {
-                       if (mr->label_attr[i]) {
-                               mr->label=1;
-                               attr->type=attr_label;
-                               attr_data_set(attr, mr->label_attr[i]+1);
-                               return 1;
-                       }
-               }
-       }
-       return 0;
-}
-
-static struct item_methods methods_binfile = {
-        binfile_coord_rewind,
-        binfile_coord_get,
-        binfile_attr_rewind,
-        binfile_attr_get,
-};
-
-static void
-push_tile(struct map_rect_priv *mr, struct tile *t)
-{
-       dbg_assert(mr->tile_depth < 8);
-       mr->t=&mr->tiles[mr->tile_depth++];
-       *(mr->t)=*t;
-       mr->t->pos=mr->t->pos_next=mr->t->start;
-}
-
-static int
-pop_tile(struct map_rect_priv *mr)
-{
-       if (mr->tile_depth <= 1)
-               return 0;
-       file_data_free(mr->m->fi, (unsigned char *)(mr->t->start));
-       mr->t=&mr->tiles[--mr->tile_depth-1];
-       return 1;
-}
-
-
-static int
-zipfile_to_tile(struct file *f, struct zip_cd *cd, struct tile *t)
-{
-       char buffer[1024];
-       struct zip_lfh *lfh;
-       char *zipfn;
-       dbg(1,"enter %p %p %p\n", f, cd, t);
-       dbg(1,"cd->zipofst=0x%x\n", cd->zipofst);
-       t->start=NULL;
-       lfh=binfile_read_lfh(f, cd->zipofst);
-       zipfn=(char *)(file_data_read(f,cd->zipofst+sizeof(struct zip_lfh), lfh->zipfnln));
-       strncpy(buffer, zipfn, lfh->zipfnln);
-       buffer[lfh->zipfnln]='\0';
-       t->start=(int *)binfile_read_content(f, cd->zipofst, lfh);
-       t->end=t->start+lfh->zipuncmp/4;
-       dbg(1,"0x%x '%s' %d %d,%d\n", lfh->ziplocsig, buffer, sizeof(*cd)+cd->zipcfnl, lfh->zipsize, lfh->zipuncmp);
-       file_data_free(f, (unsigned char *)zipfn);
-       file_data_free(f, (unsigned char *)lfh);
-       return t->start != NULL;
-}
-
-static void
-push_zipfile_tile(struct map_rect_priv *mr, int zipfile)
-{
-        struct map_priv *m=mr->m;
-       struct file *f=m->fi;
-       struct tile t;
-       struct zip_cd *cd=(struct zip_cd *)(file_data_read(f, m->eoc->zipeofst + zipfile*m->cde_size, sizeof(struct zip_cd)));
-       cd_to_cpu(cd);
-       dbg(1,"enter %p %d\n", mr, zipfile);
-       t.zipfile_num=zipfile;
-       if (zipfile_to_tile(f, cd, &t))
-               push_tile(mr, &t);
-       file_data_free(f, (unsigned char *)cd);
-}
-
-static struct map_rect_priv *
-map_rect_new_binfile(struct map_priv *map, struct map_selection *sel)
-{
-       struct map_rect_priv *mr;
-       struct tile t={};
-
-       binfile_check_version(map);
-       dbg(1,"map_rect_new_binfile\n");
-       mr=g_new0(struct map_rect_priv, 1);
-       mr->m=map;
-       mr->sel=sel;
-       mr->item.id_hi=0;
-       mr->item.id_lo=0;
-       dbg(1,"zip_members=%d\n", map->zip_members);
-       if (map->eoc) 
-               push_zipfile_tile(mr, map->zip_members-1);
-       else {
-               unsigned char *d=file_data_read(map->fi, 0, map->fi->size);
-               t.start=(int *)d;
-               t.end=(int *)(d+map->fi->size);
-               t.zipfile_num=0;
-               push_tile(mr, &t);
-       }
-       mr->item.meth=&methods_binfile;
-       mr->item.priv_data=mr;
-       return mr;
-}
-
-
-static void
-map_rect_destroy_binfile(struct map_rect_priv *mr)
-{
-       while (pop_tile(mr));
-       file_data_free(mr->m->fi, (unsigned char *)(mr->tiles[0].start));
-       g_free(mr->url);
-        g_free(mr);
-}
-
-static void
-setup_pos(struct map_rect_priv *mr)
-{
-       int size,coord_size;
-       struct tile *t=mr->t;
-       size=le32_to_cpu(*(t->pos++));
-       if (size > 1024*1024 || size < 0) {
-               dbg(0,"size=0x%x\n", size);
-#if 0
-               fprintf(stderr,"offset=%d\n", (unsigned char *)(mr->pos)-mr->m->f->begin);
-#endif
-               dbg(0,"size error");
-       }
-       t->pos_next=t->pos+size;
-       mr->item.type=le32_to_cpu(*(t->pos++));
-       coord_size=le32_to_cpu(*(t->pos++));
-       t->pos_coord_start=t->pos_coord=t->pos;
-       t->pos_attr_start=t->pos_attr=t->pos_coord+coord_size;
-}
-
-static int
-selection_contains(struct map_selection *sel, struct coord_rect *r, struct minmax *mima)
-{
-       int order;
-       if (! sel)
-               return 1;
-       while (sel) {
-               if (coord_rect_overlap(r, &sel->u.c_rect)) {
-                       order=sel->order;
-                       dbg(1,"min %d max %d order %d\n", mima->min, mima->max, order);
-                       if (!mima->min && !mima->max)
-                               return 1;
-                       if (order >= mima->min && order <= mima->max)
-                               return 1;
-               }
-               sel=sel->next;
-       }
-       return 0;
-}
-
-static void
-map_parse_country_binfile(struct map_rect_priv *mr)
-{
-       struct attr at;
-       if (binfile_attr_get(mr->item.priv_data, attr_country_id, &at)) {
-               if (at.u.num == mr->country_id)
-               {
-                       if (binfile_attr_get(mr->item.priv_data, attr_zipfile_ref, &at))
-                       {
-                               push_zipfile_tile(mr, at.u.num);
-                       }
-               }
-       }
-}
-
-static struct item *
-map_rect_get_item_binfile(struct map_rect_priv *mr)
-{
-       struct tile *t;
-       struct minmax *mima;
-       for (;;) {
-               t=mr->t;
-               if (! t)
-                       return NULL;
-               t->pos=t->pos_next;
-               if (t->pos >= t->end) {
-                       if (pop_tile(mr))
-                               continue;
-                       return NULL;
-               }
-               mr->item.id_hi=t->zipfile_num;
-               mr->item.id_lo=t->pos-t->start;
-               mr->label=0;
-               memset(mr->label_attr, 0, sizeof(mr->label_attr));
-               setup_pos(mr);
-               if ((mr->item.type == type_submap) && (!mr->country_id)) {
-                       struct coord_rect r;
-                       r.lu.x=le32_to_cpu(t->pos_coord[0]);
-                       r.lu.y=le32_to_cpu(t->pos_coord[3]);
-                       r.rl.x=le32_to_cpu(t->pos_coord[2]);
-                       r.rl.y=le32_to_cpu(t->pos_coord[1]);
-                       mima=(struct minmax *)(t->pos_attr+2);
-                       minmax_to_cpu(mima);
-                       if (!mr->m->eoc || !selection_contains(mr->sel, &r, mima)) {
-                               continue;
-                       }
-                       dbg(1,"pushing zipfile %d from %d\n", le32_to_cpu(t->pos_attr[5]), t->zipfile_num);
-                       push_zipfile_tile(mr, le32_to_cpu(t->pos_attr[5]));
-                       continue;
-                               
-               }
-               if (mr->country_id)
-               {
-                       if (mr->item.type == type_countryindex) {
-                               map_parse_country_binfile(mr);
-                       }
-                       if (item_is_town(mr->item))
-                       {
-                               return &mr->item;
-                       } else {
-                               continue;
-                       }
-               }
-               return &mr->item;
-       }
-}
-
-static struct item *
-map_rect_get_item_byid_binfile(struct map_rect_priv *mr, int id_hi, int id_lo)
-{
-       struct tile *t;
-       if (mr->m->eoc) 
-               push_zipfile_tile(mr, id_hi);
-       t=mr->t;
-       t->pos=t->start+id_lo;
-       mr->item.id_hi=id_hi;
-       mr->item.id_lo=id_lo;
-       mr->label=0;
-       memset(mr->label_attr, 0, sizeof(mr->label_attr));
-       setup_pos(mr);
-       return &mr->item;
-}
-
-static struct map_search_priv *
-binmap_search_new(struct map_priv *map, struct item *item, struct attr *search, int partial)
-{
-       struct map_rect_priv *map_rec;
-       struct map_search_priv *msp;
-       struct map_selection *ms;
-       struct item *town;
-       
-       /*
-     * NOTE: If you implement search for other attributes than attr_town_name and attr_street_name,
-     * please update this comment and the documentation for map_search_new() in map.c
-     */
-       switch (search->type) {
-               case attr_country_name:
-                       break;
-               case attr_town_name:
-                       msp = g_new(struct map_search_priv, 1);
-                       msp->search_results = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
-                       map_rec = map_rect_new_binfile(map, NULL);
-                       map_rec->country_id = item->id_lo;
-                       msp->mr = map_rec;
-                       msp->search = search;
-                       msp->partial = partial;
-                       return msp;
-                       break;
-               case attr_town_postal:
-                       break;
-               case attr_street_name:
-                       if (! item->map)
-                               break;
-                       if (!map_priv_is(item->map, map))
-                               break;
-                       ms = g_new(struct map_selection, 1);
-                       ms->next = NULL;
-                       ms->range = item_range_all; /* FIXME */
-                       ms->order = 18;
-                       map_rec = map_rect_new_binfile(map, ms);
-                       town = map_rect_get_item_byid_binfile(map_rec, item->id_hi, item->id_lo);
-                       if (town) {
-                               struct map_search_priv *msp = g_new(struct map_search_priv, 1);
-                               struct coord *c = g_new(struct coord, 1);
-                               int size = 10000;
-                               switch (town->type) {
-                                       case type_town_label_2e5:
-                                               size = 10000;
-                                               break;
-                                       case type_town_label_2e4:
-                                               size = 5000;
-                                               break;
-                                       case type_town_label_2e3:
-                                               size = 2500;
-                                               break;
-                                       case type_town_label_2e2:
-                                               size = 1000;
-                                               break;
-                                       default:
-                                               break;
-                               }
-                               item_coord_get(town, c, 1);
-                               ms->u.c_rect.lu.x = c->x-size;
-                               ms->u.c_rect.lu.y = c->y+size;
-                               ms->u.c_rect.rl.x = c->x+size;
-                               ms->u.c_rect.rl.y = c->y-size;
-                               
-                               map_rect_destroy_binfile(map_rec);
-                               map_rec = map_rect_new_binfile(map, ms);
-                               msp->mr = map_rec;
-                               msp->search = search;
-                               msp->partial = partial;
-                               msp->search_results = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
-                               return msp;
-                       }
-                       map_rect_destroy_binfile(map_rec);
-                       g_free(ms);
-                       break;
-               default:
-                       break;
-       }
-       return NULL;
-}
-static int
-ascii_cmp(char *name, char *match, int partial)
-{
-       if (partial)
-               return g_ascii_strncasecmp(name, match, strlen(match));
-       else
-               return g_ascii_strcasecmp(name, match);
-}
-
-static struct item *
-binmap_search_get_item(struct map_search_priv *map_search)
-{
-       struct item* it;
-       while ((it  = map_rect_get_item_binfile(map_search->mr))) {
-               if (map_search->search->type == attr_town_name) {
-                       if (item_is_town(*it)) {
-                               struct attr at;
-                               if (binfile_attr_get(it->priv_data, attr_label, &at)) {
-                                       if (!ascii_cmp(at.u.str, map_search->search->u.str, map_search->partial)) {
-                                               return it;
-                                       }
-                               }
-                       }
-               } else if (map_search->search->type == attr_street_name) {
-                       if ((it->type == type_street_3_city) || (it->type == type_street_2_city) || (it->type == type_street_1_city)) {
-                               struct attr at;
-                               if (map_selection_contains_item_rect(map_search->mr->sel, it) && binfile_attr_get(it->priv_data, attr_label, &at)) {
-                                       if (!ascii_cmp(at.u.str, map_search->search->u.str, map_search->partial)) {
-                                               if (!g_hash_table_lookup(map_search->search_results, at.u.str)) {
-                                                       item_coord_rewind(it);
-                                                       item_attr_rewind(it);
-                                                       g_hash_table_insert(map_search->search_results, g_strdup(at.u.str), "");
-                                                       return it;
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-       return NULL;
-}
-
-static void
-binmap_search_destroy(struct map_search_priv *ms)
-{
-       g_hash_table_destroy(ms->search_results);
-       g_free(ms->mr->sel);
-       map_rect_destroy_binfile(ms->mr);
-       g_free(ms);
-}
-
-static struct map_methods map_methods_binfile = {
-       projection_mg,
-       "utf-8",
-       map_destroy_binfile,
-       map_rect_new_binfile,
-       map_rect_destroy_binfile,
-       map_rect_get_item_binfile,
-       map_rect_get_item_byid_binfile,
-       binmap_search_new,
-       binmap_search_destroy,
-       binmap_search_get_item
-};
-
-static int
-binfile_get_index(struct map_priv *m)
-{
-       int len;
-       int cde_index_size;
-       int offset;
-       struct zip_cd *cd;
-
-       len = strlen("index");
-       cde_index_size = sizeof(struct zip_cd)+len;
-       offset = m->eoc->zipecsz-cde_index_size;
-       cd = binfile_read_cd(m, offset, len);
-
-       if (cd) {
-               if (cd->zipcfnl == len && !strncmp(cd->zipcfn, "index", len)) {
-                       m->index_offset=offset;
-                       m->index_cd=cd;
-                       return 1;
-               }
-       }
-       offset=binfile_search_cd(m, 0, "index", 0, 0);
-       if (offset == -1)
-               return 0;
-       cd=binfile_read_cd(m, offset, len);
-       if (!cd)
-               return 0;
-       m->index_offset=offset;
-       m->index_cd=cd;
-       return 1;
-}
-
-static int
-map_binfile_open(struct map_priv *m)
-{
-       int *magic;
-       struct zip_cd *first_cd;
-
-       dbg(1,"file_create %s\n", m->filename);
-       m->fi=file_create(m->filename);
-       if (! m->fi) {
-               dbg(0,"Failed to load '%s'\n", m->filename);
-               return 0;
-       }
-       if (m->check_version)
-               m->version=file_version(m->fi, m->check_version == 2);
-       magic=(int *)file_data_read(m->fi, 0, 4);
-       *magic = le32_to_cpu(*magic);
-       if (*magic == zip_lfh_sig) {
-               if ((m->eoc=binfile_read_eoc(m->fi)) && binfile_get_index(m) && (first_cd=binfile_read_cd(m, 0, 0))) {
-                       m->cde_size=sizeof(struct zip_cd)+first_cd->zipcfnl;
-                       m->zip_members=m->index_offset/m->cde_size+1;
-                       dbg(1,"cde_size %d\n", m->cde_size);
-                       dbg(1,"members %d\n",m->zip_members);
-                       file_data_free(m->fi, (unsigned char *)first_cd);
-               } else {
-                       dbg(0,"invalid file format for '%s'\n", m->filename);
-                       return 0;
-               }
-       } else 
-               file_mmap(m->fi);
-       file_data_free(m->fi, (unsigned char *)magic);
-       m->cachedir="/tmp/navit";
-       return 1;
-}
-
-static void
-map_binfile_close(struct map_priv *m)
-{
-       file_data_free(m->fi, (unsigned char *)m->index_cd);
-       file_data_free(m->fi, (unsigned char *)m->eoc);
-       file_destroy(m->fi);
-}
-
-static void
-map_binfile_destroy(struct map_priv *m)
-{
-       g_free(m->filename);
-       g_free(m);
-}
-
-
-static void
-binfile_check_version(struct map_priv *m)
-{
-       int version;
-       if (!m->check_version)
-               return;
-       version=file_version(m->fi, m->check_version == 2);
-       if (version != m->version) {
-               map_binfile_close(m);
-               map_binfile_open(m);
-       }
-}
-
-
-static struct map_priv *
-map_new_binfile(struct map_methods *meth, struct attr **attrs)
-{
-       struct map_priv *m;
-       struct attr *data=attr_search(attrs, NULL, attr_data);
-       struct attr *check_version;
-       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);
-       dbg(1,"map_new_binfile %s\n", data->u.str);     
-       *meth=map_methods_binfile;
-
-       m=g_new0(struct map_priv, 1);
-       m->id=++map_id;
-       m->filename=g_strdup(wexp_data[0]);
-       file_wordexp_destroy(wexp);
-       check_version=attr_search(attrs, NULL, attr_check_version);
-       if (check_version) 
-               m->check_version=check_version->u.num;
-       if (!map_binfile_open(m)) {
-               map_binfile_destroy(m);
-               m=NULL;
-       }
-       return m;
-}
-
-void
-plugin_init(void)
-{
-       dbg(1,"binfile: plugin_init\n");
-       plugin_register_map_type("binfile", map_new_binfile);
-}
-
diff --git a/navit/data/garmin/Makefile.am b/navit/data/garmin/Makefile.am
deleted file mode 100644 (file)
index 42f2824..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-include $(top_srcdir)/Makefile.inc
-AM_CPPFLAGS = @NAVIT_CFLAGS@   -I$(top_srcdir)/navit -DMODULE=data_garmin
-AM_CPPFLAGS+= @LIBGARMIN_CFLAGS@
-INCLUDES=-I$(top_srcdir)/navit/data/garmin/libgarmin
-AM_CPPFLAGS+=-I$(top_srcdir)/navit/data/garmin/libgarmin
-AM_CPPFLAGS+=-I$(srcdir)
-
-moduledata_LTLIBRARIES = libdata_garmin.la
-libdata_garmin_la_SOURCES = garmin.c garmin.h gar2navit.c gar2navit.h
-libdata_garmin_la_LIBADD = @LIBGARMIN_LIBS@
-nodist_libdata_garmin_la_SOURCES = g2nbuiltin.h
-builddir = @builddir@
-
-gar2navit.l$(OBJEXT): g2nbuiltin.h
-
-CLEANFILES = g2nbuiltin.h
-
-noinst_PROGRAMS=gentypes$(EXEEXT)
-gentypes_SOURCES=gentypes.c
-
-gentypes.$(OBJEXT): gentypes.c
-       $(CC_FOR_BUILD) -I$(top_srcdir)/navit -c -o $@ $<
-
-gentypes$(EXEEXT): $(gentypes_OBJECTS) $(gentypes_DEPENDENCIES) 
-       @rm -f gentypes$(EXEEXT)
-       $(CCLD_FOR_BUILD) -o $@ $(gentypes_OBJECTS)
-
-g2nbuiltin.h: gentypes$(EXEEXT) garmintypes.txt
-       ./gentypes$(EXEEXT) $(top_srcdir)/navit/data/garmin/garmintypes.txt $@
-
-EXTRA_DIST = garmintypes.txt
-
diff --git a/navit/data/garmin/gar2navit.c b/navit/data/garmin/gar2navit.c
deleted file mode 100644 (file)
index 7c44504..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
-       Copyright (C) 2007  Alexander Atanasov      <aatanasov@gmail.com>
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; version 2 of the License.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-       MA  02110-1301  USA
-    
-       Garmin and MapSource are registered trademarks or trademarks
-       of Garmin Ltd. or one of its subsidiaries.
-
-*/
-
-/*
-File format is:
-
-POINT
-GROUP,0x0100 = town_label_1e5, Megapolis (10M +)
-GROUP,0x0200 = town_label_5e4, Megapolis (5-10M)
-...
-GROUP,0x1e00-0x1e3f = district_label, District, Province, State Name
-...
-POLYLINE
-GROUP,0x00 = ALL, street_1_land, Road
-GROUP,0x01 = MCTL, highway_land, Major HWY thick
-GROUP,0x02 = MCTL, street_4_land, Principal HWY-thick
-GROUP,0x03 = MCTL, street_2_land, Principal HWY-medium
-....
-POLYGONE
-GROUP,0x01 = town_poly, City (>200k)
-GROUP,0x02 = town_poly, City (<200k)
-GROUP,0x03 = town_poly, Village
-
-GROUP is
-0 - RGN1
-1 - RGN2-4
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <malloc.h>
-#include "item.h"
-#include "attr.h"
-#include "garmin.h"
-#include "gar2navit.h"
-
-static int add_def(struct gar2nav_conv *conv, int type, unsigned short minid,
-               unsigned short maxid, unsigned int group, char *ntype,
-               char *descr)
-{
-       enum item_type it;
-       struct gar2navit *g2n;
-       dlog(11, "group=%d type=%d routable=%u min=%04X max=%04X ntype=%s descr=%s\n",
-               group, type,  minid, maxid, ntype, descr);
-       it = item_from_name(ntype);
-       if (it==type_none) {
-               dlog(1, "Please define: %s\n", ntype);
-       } 
-       g2n = calloc(1, sizeof(*g2n));
-       if (!g2n)
-               return -1;
-       g2n->id = minid;
-       g2n->maxid = maxid;
-       g2n->ntype = it;
-       g2n->descr = strdup(descr);
-       g2n->group = group;
-       if (type == 1) {
-               g2n->next = conv->points;
-               conv->points = g2n;
-       } else if (type == 2) {
-               g2n->next = conv->polylines;
-               conv->polylines = g2n;
-       } else if (type == 3) {
-               g2n->next = conv->polygons;
-               conv->polygons = g2n;
-       }
-       return 0;
-}
-
-static int load_types_file(char *file, struct gar2nav_conv *conv)
-{
-       char buf[4096];
-       char descr[4096];
-       char ntype[4096];
-       FILE *fp;
-       unsigned int minid, maxid, group;
-       int rc;
-       int type = -1;
-
-       fp = fopen(file, "r");
-       if (!fp)
-               return -1;
-       while (fgets(buf, sizeof(buf), fp)) {
-               if (*buf == '#' || *buf == '\n')
-                       continue;
-               if (!strncasecmp(buf, "POINT", 5)) {
-                       type = 1;
-                       continue;
-               } else if (!strncasecmp(buf, "POI", 3)) {
-                       type = 1;
-                       continue;
-               } else if (!strncasecmp(buf, "POLYLINE", 8)) {
-                       type = 2;
-                       continue;
-               } else if (!strncasecmp(buf, "POLYGONE", 8)) {
-                       type = 3;
-                       continue;
-               }
-               // assume only lines are routable
-               rc = sscanf(buf, "%d, 0x%04X - 0x%04X = %[^\t , ] , %[^\n]",
-                       &group, &minid, &maxid, ntype, descr);
-               if (rc != 5) { 
-                       maxid = 0;
-                       rc = sscanf(buf, "%d,0x%04X = %[^\t, ], %[^\n]",
-                               &group, &minid, ntype, descr);
-                       if (rc != 4) {
-                               dlog(1, "Invalid line rc=%d:[%s]\n",rc, buf);
-                               dlog(1, "minid=%04X ntype=[%s] des=[%s]\n",
-                                       minid, ntype, descr);
-                               continue;
-                       }
-               }
-               add_def(conv, type, minid, maxid, group, ntype, descr);
-       }
-       fclose(fp);
-       return 1;
-}
-
-struct gar2nav_conv *g2n_conv_load(char *file)
-{
-       struct gar2nav_conv *c;
-       int rc;
-
-       c = calloc(1, sizeof(*c));
-       if (!c)
-               return c;
-       rc = load_types_file(file, c);
-       if (rc < 0) {
-               dlog(1, "Failed to load: [%s]\n", file);
-               free(c);
-               return NULL;
-       }
-       return c;
-}
-
-enum item_type g2n_get_type(struct gar2nav_conv *c, unsigned int type, unsigned short id)
-{
-       struct gar2navit *def = NULL;
-       int group;
-       group = (type >> G2N_KIND_SHIFT);
-       type &= ~G2N_KIND_MASK;
-       if (type == G2N_POINT)
-               def = c->points;
-       else if (type == G2N_POLYLINE)
-               def = c->polylines;
-       else if (type == G2N_POLYGONE)
-               def = c->polygons;
-       else {
-               dlog(1, "Unknown conversion type:%d\n", type);
-               return type_none;
-       }
-
-       if (!def) {
-               dlog(5, "No conversion data for %d\n", type);
-               return type_none;
-       }
-
-       while (def) {
-               if (def->group == group &&
-                       ((!def->maxid && def->id == id) || 
-                       (def->id <= id && id <= def->maxid)))
-                       return def->ntype;
-               def = def->next;
-       }
-       dlog(5, "Type[%d]:ID:[%04X] unknown\n", type, id);
-       return type == G2N_POINT ? type_point_unkn : type_street_unkn;
-}
-
-char *g2n_get_descr(struct gar2nav_conv *c, int type, unsigned short id)
-{
-       struct gar2navit *def = NULL;
-       if (type == G2N_POINT)
-               def = c->points;
-       else if (type == G2N_POLYLINE)
-               def = c->polylines;
-       else if (type == G2N_POLYGONE)
-               def = c->polygons;
-       else {
-               dlog(1, "Unknown conversion type:%d\n", type);
-               return NULL;
-       }
-       while (def) {
-               if ((!def->maxid && def->id == id) || 
-                               (def->id <= id && id <= def->maxid))
-                       return def->descr;
-               def = def->next;
-       }
-       dlog(5, "Type[%d]:ID:[%04X] unknown\n", type, id);
-       return NULL;
-}
-
-#if 0
-int main(int argc, char **argv)
-{
-       load_types_file(argv[1], NULL);
-       return 0;
-}
-#endif
-
-#include "g2nbuiltin.h"
diff --git a/navit/data/garmin/gar2navit.h b/navit/data/garmin/gar2navit.h
deleted file mode 100644 (file)
index 46b6885..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-#define GROUP_RGN1     0
-#define GROUP_RGN2     1
-
-struct gar2navit {
-       unsigned short id;
-       unsigned short maxid;
-       enum item_type ntype;
-       unsigned group;
-       char *descr;
-       struct gar2navit *next;
-};
-
-#define G2N_POINT              1
-#define G2N_POLYLINE           2
-#define G2N_POLYGONE           3
-#define G2N_KIND_MASK          0xF0000000
-#define G2N_KIND_SHIFT         28
-#define G2N_RGN1               (GROUP_RGN1<<29)
-#define G2N_RGN2               (GROUP_RGN2<<29)
-
-struct gar2nav_conv {
-       struct gar2navit *points;
-       struct gar2navit *polylines;
-       struct gar2navit *polygons;
-};
-
-struct gar2nav_conv *g2n_conv_load(char *file);
-enum item_type g2n_get_type(struct gar2nav_conv *c, unsigned int type, unsigned short id);
-char *g2n_get_descr(struct gar2nav_conv *c, int type, unsigned short id);
-struct gar2nav_conv *g2n_default_conv(void);
diff --git a/navit/data/garmin/garmin.c b/navit/data/garmin/garmin.c
deleted file mode 100644 (file)
index da0f580..0000000
+++ /dev/null
@@ -1,997 +0,0 @@
-/*
-       Copyright (C) 2007  Alexander Atanasov      <aatanasov@gmail.com>
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; version 2 of the License.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-       MA  02110-1301  USA
-    
-       Garmin and MapSource are registered trademarks or trademarks
-       of Garmin Ltd. or one of its subsidiaries.
-
-*/
-
-#include <glib.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include "config.h"
-#include "plugin.h"
-#include "data.h"
-#include "projection.h"
-#include "item.h"
-#include "debug.h"
-#include "map.h"
-#include "maptype.h"
-#include "attr.h"
-#include "coord.h"
-#include "transform.h"
-#include <stdio.h>
-#include "attr.h"
-#include "coord.h"
-#include <libgarmin.h>
-#include "garmin.h"
-#include "gar2navit.h"
-
-
-static int map_id;
-
-struct map_priv {
-       int id;
-       char *filename;
-       struct gar2nav_conv *conv;
-       struct gar *g;
-};
-
-struct map_rect_priv {
-       int id;
-       struct coord_rect r;
-       char *label;            // FIXME: Register all strings for searches
-       int limit;
-       struct map_priv *mpriv;
-       struct gmap *gmap;
-       struct gobject *cobj;
-       struct gobject *objs;
-       struct item item;
-       unsigned int last_coord;
-       void *last_itterated;
-       struct coord last_c;
-       void *last_oattr;
-       unsigned int last_attr;
-       struct gar_search *search;
-};
-
-int garmin_debug = 10;
-
-void 
-logfn(char *file, int line, int level, char *fmt, ...)
-{
-       va_list ap;
-       char fileline[256];
-       int sz;
-       if (level > garmin_debug)
-               return;
-       va_start(ap, fmt);
-       sz = sprintf(fileline, "%s:%d:%d|", file, line, level);
-       debug_vprintf(0, "", strlen(""), fileline, sz,
-               1, fmt, ap);
-       va_end(ap);
-}
-// need a base map and a map
-struct gscale {
-       char *label;
-       float scale;
-       int bits;
-};
-
-static struct gscale mapscales[] = {
-       {"7000 km", 70000.0, 8}
-       ,{"5000 km", 50000.0, 8}
-       ,{"3000 km", 30000.0, 9}
-       ,{"2000 km", 20000.0, 9}
-       ,{"1500 km", 15000.0, 10}
-       ,{"1000 km", 10000.0, 10}
-       ,{"700 km", 7000.0, 11}
-       ,{"500 km", 5000.0, 11}
-       ,{"300 km", 3000.0, 13}
-       ,{"200 km", 2000.0, 13}
-       ,{"150 km", 1500.0, 13}
-       ,{"100 km", 1000.0, 14}
-       ,{"70 km", 700.0, 15}
-       ,{"50 km", 500.0, 16}
-       ,{"30 km", 300.0, 16}
-       ,{"20 km", 200.0, 17}
-       ,{"15 km", 150.0, 17}
-       ,{"10 km", 100.0, 18}
-       ,{"7 km", 70.0, 18}
-       ,{"5 km", 50.0, 19}
-       ,{"3 km", 30.0, 19}
-       ,{"2 km", 20.0, 20}
-       ,{"1.5 km", 15.0, 22}
-       ,{"1 km", 10.0, 24}
-       ,{"700 m", 7.0, 24}
-       ,{"500 m", 5.0, 24}
-       ,{"300 m", 3.0, 24}
-       ,{"200 m", 2.0, 24}
-       ,{"150 m", 1.5, 24}
-       ,{"100 m", 1.0, 24}
-       ,{"70 m", 0.7, 24}
-       ,{"50 m", 0.5, 24}
-       ,{"30 m", 0.3, 24}
-       ,{"20 m", 0.2, 24}
-       ,{"15 m", 0.1, 24}
-       ,{"10 m", 0.15, 24}
-};
-
-
-static int 
-garmin_object_label(struct gobject *o, struct attr *attr)
-{
-       struct map_rect_priv *mr = o->priv_data;
-       char *codepage;
-       char *label;
-       if (!mr) {
-               dlog(1, "Error object do not have priv_data!!\n");
-               return 0;
-       }
-       if (mr->label) {
-               free(mr->label);
-       }
-       label = gar_get_object_lbl(o);
-       if (label) {
-               codepage = gar_obj_codepage(o);
-               if (*codepage != 'a') {
-                       mr->label = g_convert(label, -1,"utf-8",codepage,NULL,NULL,NULL);
-                       free(label);
-               } else
-                       mr->label = label;
-       } else {
-               mr->label = NULL;
-               return 0;
-       }
-       if (mr->label) {
-               char *cp = mr->label;
-#warning FIXME Process label and give only the visible part
-               if (*mr->label == '@' || *mr->label == '^')
-                       cp++; 
-               /* FIXME: If zoomlevel is high convert ^ in the string to spaces */
-               attr->u.str = cp;
-               return 1;
-       }
-       return 0;
-}
-
-static int 
-garmin_object_debug(struct gobject *o, struct attr *attr)
-{
-       struct map_rect_priv *mr = o->priv_data;
-       if (!mr) {
-               dlog(1, "Error object do not have priv_data!!\n");
-               return 0;
-       }
-       if (mr->label)
-               free(mr->label);
-       mr->label = gar_object_debug_str(o);
-       if (mr->label) {
-               attr->u.str = mr->label;
-               return 1;
-       }
-       return 0;
-}
-
-
-static struct map_search_priv *
-gmap_search_new(struct map_priv *map, struct item *item, struct attr *search, int partial)
-{
-       struct map_rect_priv *mr=g_new0(struct map_rect_priv, 1);
-       struct gar_search *gs;
-       int rc;
-
-       dlog(1, "Called!\n");
-       mr->mpriv=map;
-       gs = g_new0(struct gar_search,1);
-       if (!gs) {
-               dlog(1, "Can not init search \n");
-               free(mr);
-               return NULL;
-       }
-       mr->search = gs;
-       switch (search->type) {
-               case attr_country_name:
-                       gs->type = GS_COUNTRY;
-                               break;
-               case attr_town_name:
-                       gs->type = GS_CITY;
-                               break;
-               case attr_town_postal:
-                       gs->type = GS_ZIP;
-                               break;
-               case attr_street_name:
-                       gs->type = GS_ROAD;
-                               break;
-#if someday
-               case attr_region_name:
-               case attr_intersection:
-               case attr_housenumber:
-#endif
-               default:
-                       dlog(1, "Don't know how to search for %d\n", search->type);
-                       goto out_err;
-       }
-       gs->match = partial ? GM_START : GM_EXACT;
-       gs->needle = strdup(search->u.str);
-       dlog(5, "Needle: %s\n", gs->needle);
-
-       mr->gmap = gar_find_subfiles(mr->mpriv->g, gs, GO_GET_SEARCH);
-       if (!mr->gmap) {
-               dlog(1, "Can not init search \n");
-               goto out_err;
-       }
-       rc = gar_get_objects(mr->gmap, 0, gs, &mr->objs, GO_GET_SEARCH);
-       if (rc < 0) {
-               dlog(1, "Error loading objects\n");
-               goto out_err;
-       }
-       mr->cobj = mr->objs;
-       dlog(4, "Loaded %d objects\n", rc);
-       return (struct map_search_priv *)mr;
-
-out_err:
-       free(gs);
-       free(mr);
-       return NULL;
-}
-
-/* Assumes that only one item will be itterated at time! */
-static void 
-coord_rewind(void *priv_data)
-{
-       struct gobject *g = priv_data;
-       struct map_rect_priv *mr = g->priv_data;
-       mr->last_coord = 0;
-};
-
-static void 
-attr_rewind(void *priv_data)
-{
-       struct gobject *g = priv_data;
-       struct map_rect_priv *mr = g->priv_data;
-       mr->last_attr = 0;
-};
-
-static int 
-point_coord_get(void *priv_data, struct coord *c, int count)
-{
-       struct gobject *g = priv_data;
-       struct map_rect_priv *mr = g->priv_data;
-       struct gcoord gc;
-       if (!count)
-               return 0;
-       if (g != mr->last_itterated) {
-               mr->last_itterated = g;
-               mr->last_coord = 0;
-       }
-
-       if (mr->last_coord > 0)
-               return 0;
-
-       gar_get_object_coord(mr->gmap, g, &gc);
-       c->x = gc.x;
-       c->y = gc.y;
-       mr->last_coord++;
-//     dlog(1,"point: x=%d y=%d\n", c->x, c->y);
-       // dlog(1, "point: x=%f y=%f\n", GARDEG(c->x), GARDEG(c->y));
-       return 1;
-}
-
-static int
-coord_is_node(void *priv_data)
-{
-       struct gobject *g = priv_data;
-       struct map_rect_priv *mr = g->priv_data;
-
-       return gar_is_object_dcoord_node(mr->gmap, g, mr->last_coord);
-}
-
-static int 
-poly_coord_get(void *priv_data, struct coord *c, int count)
-{
-       struct gobject *g = priv_data;
-       struct map_rect_priv *mr = g->priv_data;
-       int ndeltas = 0, total = 0;
-       struct gcoord dc;
-
-       if (!count)
-               return 0;
-
-       if (g != mr->last_itterated) {
-               mr->last_itterated = g;
-               mr->last_coord = 0;
-       }
-       ndeltas = gar_get_object_deltas(g);
-       if (mr->last_coord > ndeltas + 1)
-               return 0;
-       while (count --) {
-               if (mr->last_coord == 0) {
-                       gar_get_object_coord(mr->gmap, g, &dc);
-                       mr->last_c.x = dc.x;
-                       mr->last_c.y = dc.y;
-               } else {
-                       if (!gar_get_object_dcoord(mr->gmap, g, mr->last_coord - 1, &dc)) {
-                               mr->last_coord = ndeltas + 2;
-                               return total;
-                       }
-                       mr->last_c.x += dc.x;
-                       mr->last_c.y += dc.y;
-               }
-               c->x = mr->last_c.x;
-               c->y = mr->last_c.y;
-               ddlog(1, "poly: x=%f y=%f\n", GARDEG(c->x), GARDEG(c->y));
-//             dlog(1,"poly: x=%d y=%d\n", c->x, c->y);
-               c++;
-               total++;
-               mr->last_coord ++;
-       }
-       return total;
-}
-
-// for _any we must return one by one 
-static int 
-point_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
-{
-       struct gobject *g = priv_data;
-       struct map_rect_priv *mr = g->priv_data;
-       int rc;
-       switch (attr_type) {
-       case attr_any:
-                       if (g != mr->last_oattr) {
-                               mr->last_oattr = g;
-                               mr->last_attr = 0;
-                       }
-                       switch(mr->last_attr) {
-                               case 0:
-                                       mr->last_attr++;
-                                       attr->type = attr_label;
-                                       rc = garmin_object_label(g, attr);
-                                       if (rc)
-                                               return rc;
-                               case 1:
-                                       mr->last_attr++;
-                                       attr->type = attr_debug;
-                                       rc = garmin_object_debug(g, attr);
-                                       if (rc)
-                                               return rc;
-                               case 2:
-                                       mr->last_attr++;
-                                       if (g->type == GO_POLYLINE) {
-                                               attr->type = attr_street_name;
-                                               rc = garmin_object_label(g, attr);
-                                               if (rc)
-                                                       return rc;
-                                       }
-                               case 3:
-                                       mr->last_attr++;
-                                       attr->type = attr_flags;
-                                       attr->u.num = 0;
-                                       rc = gar_object_flags(g);
-                                       if (rc & F_ONEWAY)
-                                               attr->u.num |= AF_ONEWAY;
-                                       if (rc & F_SEGMENTED)
-                                               attr->u.num |= AF_SEGMENTED;
-                                       return 1;
-                               default:
-                                       return 0;
-                       }
-                       break;
-       case attr_label:
-               attr->type = attr_label;
-               return garmin_object_label(g, attr);
-       case attr_town_name:
-               attr->type = attr_town_name;
-               return garmin_object_label(g, attr);
-       case attr_street_name:
-               attr->type = attr_type;
-               return garmin_object_label(g, attr);
-       case attr_street_name_systematic:
-               /* TODO: Get secondary labels of roads */
-               return 0;
-       case attr_flags:
-               attr->type = attr_flags;
-               attr->u.num = 0;
-               rc = gar_object_flags(g);
-               if (rc & F_ONEWAY)
-                       attr->u.num |= AF_ONEWAY;
-               if (rc & F_SEGMENTED)
-                       attr->u.num |= AF_SEGMENTED;
-               return 1;
-       default:
-               dlog(1, "Dont know about attribute %d[%04X]=%s yet\n", attr_type,attr_type, attr_to_name(attr_type));
-       }
-
-       return 0;
-}
-
-static struct item_methods methods_garmin_point = {
-       coord_rewind,
-       point_coord_get,
-       attr_rewind,
-       point_attr_get,
-};
-
-static struct item_methods methods_garmin_poly = {
-       coord_rewind,
-       poly_coord_get,
-       attr_rewind,    // point_attr_rewind,
-       point_attr_get, // poly_attr_get,
-       coord_is_node,
-};
-
-static int
-search_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
-{
-       struct gobject *g = priv_data;
-       struct map_rect_priv *mr = g->priv_data;
-       int rc;
-       switch (attr_type) {
-       case attr_any:
-                       if (g != mr->last_oattr) {
-                               mr->last_oattr = g;
-                               mr->last_attr = 0;
-                       }
-                       switch(mr->last_attr) {
-                               case 0:
-                                       mr->last_attr++;
-                                       attr->type = attr_label;
-                                       rc = garmin_object_label(g, attr);
-                                       if (rc)
-                                               return rc;
-                               case 1:
-                                       mr->last_attr++;
-                                       attr->type = attr_debug;
-                                       rc = garmin_object_debug(g, attr);
-                                       if (rc)
-                                               return rc;
-                               case 2:
-                                       mr->last_attr++;
-                                       if (g->type == GO_POLYLINE) {
-                                               attr->type = attr_street_name;
-                                               rc = garmin_object_label(g, attr);
-                                               if (rc)
-                                                       return rc;
-                                       }
-                               case 3:
-                                       mr->last_attr++;
-                                       attr->type = attr_flags;
-                                       attr->u.num = 0;
-                                       rc = gar_object_flags(g);
-                                       if (rc & F_ONEWAY)
-                                               attr->u.num |= AF_ONEWAY;
-                                       if (rc & F_SEGMENTED)
-                                               attr->u.num |= AF_SEGMENTED;
-                                       return 1;
-                               default:
-                                       return 0;
-                       }
-                       break;
-       case attr_label:
-               attr->type = attr_label;
-               return garmin_object_label(g, attr);
-       case attr_town_name:
-               attr->type = attr_town_name;
-               if (mr->label)
-                       free(mr->label);
-               mr->label = gar_srch_get_city(g);
-               attr->u.str = mr->label;
-               if (attr->u.str)
-                       return 1;
-               return 0;
-       case attr_town_id:
-               rc = gar_srch_get_cityid(g);
-               if (rc) {
-                       attr->type = attr_town_id;
-                       attr->u.num = rc;
-                       return 1;
-               }
-               return 0;
-       case attr_town_postal:
-               attr->type = attr_town_postal;
-               attr->u.str = gar_srch_get_zip(g);
-               if (attr->u.str)
-                       return 1;
-               return 0;
-       case attr_street_name:
-               attr->type = attr_street_name;
-               if (mr->label)
-                       free(mr->label);
-               mr->label = gar_srch_get_roadname(g);
-               attr->u.str = mr->label;
-               if (attr->u.str)
-                       return 1;
-               return 0;
-       case attr_street_id:
-               attr->type = attr_street_id;
-               attr->u.num = gar_srch_get_roadid(g);
-               if (attr->u.num)
-                       return 1;
-               return 0;
-       case attr_flags:
-               attr->type = attr_flags;
-               attr->u.num = 0;
-               rc = gar_object_flags(g);
-               if (rc & F_ONEWAY)
-                       attr->u.num |= AF_ONEWAY;
-               if (rc & F_SEGMENTED)
-                       attr->u.num |= AF_SEGMENTED;
-               return 1;
-       case attr_country_id:
-               rc = gar_srch_get_countryid(g);
-               if (rc) {
-                       attr->type = attr_country_id;
-                       attr->u.num = rc;
-                       return 1;
-               }
-               return 0;
-       case attr_country_name:
-               attr->type = attr_country_name;
-               attr->u.str = gar_srch_get_country(g);
-               if (attr->u.str)
-                       return 1;
-               return 0;
-       case attr_district_id:
-               rc = gar_srch_get_regionid(g);
-               if (rc) {
-                       attr->type = attr_district_id;
-                       attr->u.num = rc;
-                       return 1;
-               }
-               return 0;
-       case attr_district_name:
-               attr->type = attr_district_name;
-               attr->u.str = gar_srch_get_region(g);
-               if (attr->u.str)
-                       return 1;
-               return 0;
-       case attr_town_streets_item:
-               return 0;
-       default:
-               dlog(1, "Dont know about attribute %d[%04X]=%s yet\n",
-                               attr_type,attr_type, attr_to_name(attr_type));
-       }
-
-       return 0;
-}
-
-static int
-search_coord_get(void *priv_data, struct coord *c, int count)
-{
-       struct gobject *g = priv_data;
-       struct map_rect_priv *mr = g->priv_data;
-       struct gcoord gc;
-       if (!count)
-               return 0;
-       if (g != mr->last_itterated) {
-               mr->last_itterated = g;
-               mr->last_coord = 0;
-       }
-
-       if (mr->last_coord > 0)
-               return 0;
-
-       if (gar_get_object_coord(mr->gmap, g, &gc)) {
-               c->x = gc.x;
-               c->y = gc.y;
-               mr->last_coord++;
-               return 1;
-       }
-       return 0;
-}
-
-static struct item_methods methods_garmin_search = {
-       coord_rewind,
-       search_coord_get,
-       attr_rewind,
-       search_attr_get,
-};
-
-
-static struct item *
-garmin_poi2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype)
-{
-       if (mr->mpriv->conv) {
-               int mask = gar_object_group(o) << G2N_KIND_SHIFT;
-               mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POINT|mask, otype);
-       }
-       mr->item.meth = &methods_garmin_point;
-       return &mr->item;
-}
-
-static struct item *
-garmin_pl2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype)
-{
-       if (mr->mpriv->conv) {
-               int mask = gar_object_group(o) << G2N_KIND_SHIFT;
-               mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POLYLINE|mask, otype);
-       }
-       mr->item.meth = &methods_garmin_poly;
-       return &mr->item;
-}
-
-static struct item *
-garmin_pg2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype)
-{
-       if (mr->mpriv->conv) {
-               int mask = gar_object_group(o) << G2N_KIND_SHIFT;
-               mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POLYGONE|mask, otype);
-       }
-       mr->item.meth = &methods_garmin_poly;
-       return &mr->item;
-}
-
-static struct item *
-garmin_srch2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype)
-{
-       mr->item.type = type_country_label;
-       mr->item.meth = &methods_garmin_search;
-       return &mr->item;
-}
-
-static struct item *
-garmin_obj2item(struct map_rect_priv *mr, struct gobject *o)
-{
-       unsigned short otype;
-       otype = gar_obj_type(o);
-       mr->item.type = type_none;
-       switch (o->type) {
-               case GO_POINT:
-                       return garmin_poi2item(mr, o, otype);
-               case GO_POLYLINE:
-                       return garmin_pl2item(mr, o, otype);
-               case GO_POLYGON:
-                       return garmin_pg2item(mr, o, otype);
-               case GO_ROAD:
-                       return garmin_pl2item(mr, o, otype);
-#if 0
-               case GO_SEARCH:
-                       return garmin_srch2item(mr, o, otype);
-#endif
-               default:
-                       dlog(1, "Unknown garmin object type:%d\n",
-                               o->type);
-       }
-       return NULL;
-}
-
-static struct item *
-gmap_rect_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo)
-{
-       struct gobject *o;
-       o = mr->objs = gar_get_object_by_id(mr->mpriv->g, id_hi, id_lo);
-       if (!o) {
-               dlog(1, "Can not find object\n");
-               return NULL;
-       }
-
-       mr->item.id_hi = id_hi;
-       mr->item.id_lo = id_lo;
-       mr->item.priv_data = o;
-       mr->item.type = type_none;
-       o->priv_data = mr;
-       if (!garmin_obj2item(mr, o))
-               return NULL;
-       return &mr->item;
-}
-
-static struct item *
-gmap_rect_get_item(struct map_rect_priv *mr)
-{
-       struct gobject *o;
-       if (!mr->objs)
-               return NULL;
-       if (!mr->cobj)
-               return NULL;
-               // mr->cobj = mr->objs;
-       o = mr->cobj;
-//     dlog(1, "gi:o=%p\n", o);
-       mr->cobj = mr->cobj->next;
-       if (o) {
-               mr->item.id_hi = gar_object_mapid(o);
-               mr->item.id_lo = gar_object_index(o);
-               mr->item.priv_data = o;
-               mr->item.type = type_none;
-               o->priv_data = mr;
-               if (!garmin_obj2item(mr, o))
-                       return NULL;
-               return &mr->item;
-       }
-       return NULL;
-}
-
-#define max(a,b) ((a) > (b) ? (a) : (b))
-struct nl2gl_t {
-       int g;
-       int bits;
-       char *descr;
-};
-
-struct nl2gl_t nl2gl_1[] = { 
-       { /* 0 */  .g = 12, .descr = "0-120m", },
-       { /* 1 */  .g = 11, .descr = "0-120m", },
-       { /* 2 */  .g = 10, .descr = "0-120m", },
-       { /* 3 */  .g = 9, .descr = "0-120m", },
-       { /* 4 */  .g = 8, .descr = "0-120m", },
-       { /* 5 */  .g = 7, .descr = "0-120m", },
-       { /* 6 */  .g = 6, .descr = "0-120m", },
-       { /* 7 */  .g = 5, .descr = "0-120m", },
-       { /* 8 */  .g = 4, .descr = "0-120m", },
-       { /* 9 */  .g = 4, .descr = "0-120m", },
-       { /* 10 */ .g = 3, .descr = "0-120m", },
-       { /* 11 */ .g = 3, .descr = "0-120m", },
-       { /* 12 */ .g = 2, .descr = "0-120m", },
-       { /* 13 */ .g = 2, .descr = "0-120m", },
-       { /* 14 */ .g = 2, .descr = "0-120m", },
-       { /* 15 */ .g = 1, .descr = "0-120m", },
-       { /* 16 */ .g = 1, .descr = "0-120m", },
-       { /* 17 */ .g = 1, .descr = "0-120m", },
-       { /* 18 */ .g = 0, .descr = "0-120m", },
-};
-
-struct nl2gl_t nl2gl[] = { 
-       { /* 0 */  .g = 9, .descr = "0-120m", },
-       { /* 1 */  .g = 9, .descr = "0-120m", },
-       { /* 2 */  .g = 8, .descr = "0-120m", },
-       { /* 3 */  .g = 8, .descr = "0-120m", },
-       { /* 4 */  .g = 7, .descr = "0-120m", },
-       { /* 5 */  .g = 7, .descr = "0-120m", },
-       { /* 6 */  .g = 6, .descr = "0-120m", },
-       { /* 7 */  .g = 6, .descr = "0-120m", },
-       { /* 8 */  .g = 5, .descr = "0-120m", },
-       { /* 9 */  .g = 5, .descr = "0-120m", },
-       { /* 10 */ .g = 4, .descr = "0-120m", },
-       { /* 11 */ .g = 4, .descr = "0-120m", },
-       { /* 12 */ .g = 3, .descr = "0-120m", },
-       { /* 13 */ .g = 3, .descr = "0-120m", },
-       { /* 14 */ .g = 2, .descr = "0-120m", },
-       { /* 15 */ .g = 2, .descr = "0-120m", },
-       { /* 16 */ .g = 1, .descr = "0-120m", },
-       { /* 17 */ .g = 1, .descr = "0-120m", },
-       { /* 18 */ .g = 0, .descr = "0-120m", },
-};
-
-static int 
-get_level(struct map_selection *sel)
-{
-       return sel->order;
-}
-
-static int
-garmin_get_selection(struct map_rect_priv *map, struct map_selection *sel)
-{
-       struct gar_rect r;
-       struct gmap *gm;
-       struct gobject **glast = NULL;
-       int rc;
-       int sl, el;
-       int level = 0; // 18;   /* max level for maps, overview maps can have bigger
-                          /* levels we do not deal w/ them
-                       */
-       int flags = 0;
-       if (sel && sel->range.min == type_street_0 && sel->range.max == type_ferry) {
-               // Get all roads 
-               flags = GO_GET_ROUTABLE;
-       } else if (sel)
-               flags = GO_GET_SORTED;
-
-       if (sel) {
-               r.lulat = sel->u.c_rect.lu.y;
-               r.lulong = sel->u.c_rect.lu.x;
-               r.rllat = sel->u.c_rect.rl.y;
-               r.rllong = sel->u.c_rect.rl.x;
-               level = get_level(sel);
-//             level = nl2gl[level].g;
-               dlog(2, "Looking level=%d for %f %f %f %f\n",
-                       level, r.lulat, r.lulong, r.rllat, r.rllong);
-       }
-       gm = gar_find_subfiles(map->mpriv->g, sel ? &r : NULL, flags);
-       if (!gm) {
-               if (sel) {
-                       dlog(1, "Can not find map data for the area: %f %f %f %f\n",
-                               r.lulat, r.lulong, r.rllat, r.rllong);
-               } else {
-                       dlog(1, "Can not find map data\n");
-               }
-               return -1;
-       }
-#if 0
-       sl = (18-(gm->maxlevel - gm->minlevel))/2;
-       el = sl + (gm->maxlevel - gm->minlevel);
-       if (level < sl)
-               level = sl;
-       if (level > el)
-               level = el;
-       level = level - sl;
-       level = (gm->maxlevel - gm->minlevel) - level;
-       dlog(3, "sl=%d el=%d level=%d\n", sl, el, level);
-#endif
-       sl = (18-gm->zoomlevels)/2;
-       el = sl + gm->zoomlevels;
-       if (level < sl)
-               level = sl;
-       if (level > el)
-               level = el;
-       level = level - sl;
-       level = gm->basebits + level;
-       dlog(3, "sl=%d el=%d level=%d\n", sl, el, level);
-       map->gmap = gm;
-       glast = &map->objs;
-       while (*glast) {
-               if ((*glast)->next) {
-                       *glast = (*glast)->next;
-               } else
-                       break;
-       }
-       rc = gar_get_objects(gm, level, sel ? &r : NULL, glast, flags);
-       if (rc < 0) {
-               dlog(1, "Error loading objects\n");
-               return -1;
-       }
-       map->cobj = map->objs;
-       dlog(2, "Loaded %d objects\n", rc);
-       return rc;
-}
-// Can not return NULL, navit segfaults
-static struct map_rect_priv *
-gmap_rect_new(struct map_priv *map, struct map_selection *sel)
-{
-       struct map_selection *ms = sel;
-       struct map_rect_priv *mr;
-
-       if (!map)
-               return NULL;
-       mr = calloc(1, sizeof(*mr));
-       if (!mr)
-               return mr;
-       mr->mpriv = map;
-       if (!sel) {
-               return mr;
-       } else {
-               while (ms) {
-                       dlog(2, "order %d\n", ms->order); 
-                       if (garmin_get_selection(mr, ms) < 0) {
-                       //      free(mr);
-                       //      return NULL;
-                       }
-                       ms = ms->next;
-               }
-       }
-       return mr;
-}
-
-static void
-gmap_rect_destroy(struct map_rect_priv *mr)
-{
-       dlog(11,"destroy maprect\n");
-       if (mr->gmap)
-               gar_free_gmap(mr->gmap);
-       if (mr->objs)
-               gar_free_objects(mr->objs);
-       if (mr->label)
-               free(mr->label);
-       free(mr);
-}
-
-static void 
-gmap_search_destroy(struct map_search_priv *ms)
-{
-       gmap_rect_destroy((struct map_rect_priv *)ms);
-}
-
-static void
-gmap_destroy(struct map_priv *m)
-{
-       dlog(5, "garmin_map_destroy\n");
-       if (m->g)
-               gar_free(m->g);
-       if (m->filename)
-               free(m->filename);
-       free(m);
-}
-
-static struct map_methods map_methods = {
-       projection_garmin,
-       "utf-8",
-       gmap_destroy,
-       gmap_rect_new,
-       gmap_rect_destroy,
-       gmap_rect_get_item,
-       gmap_rect_get_item_byid,
-       gmap_search_new,
-       gmap_search_destroy,
-       gmap_rect_get_item,
-};
-
-static struct map_priv *
-gmap_new(struct map_methods *meth, struct attr **attrs)
-{
-       struct map_priv *m;
-       struct attr *data;
-       struct attr *debug;
-       struct attr *flags;
-       char buf[PATH_MAX];
-       struct stat st;
-       int dl = 1;
-       struct gar_config cfg;
-       int debugmask = 0;
-
-       data=attr_search(attrs, NULL, attr_data);
-       if (! data)
-               return NULL;
-       debug=attr_search(attrs, NULL, attr_debug);
-       if (debug) {
-               dl = atoi(debug->u.str);
-               if (!dl)
-                       dl = 1;
-       }
-       flags=attr_search(attrs, NULL, attr_flags);
-       if (flags) {
-               debugmask = flags->u.num;
-       }
-       m=g_new(struct map_priv, 1);
-       m->id=++map_id;
-       m->filename = strdup(data->u.str);
-       if (!m->filename) {
-               g_free(m);
-               return NULL;
-       }
-       memset(&cfg, 0, sizeof(struct gar_config));
-       cfg.opm = OPM_GPS;
-       cfg.debuglevel = dl;
-       cfg.debugmask = debugmask;
-       garmin_debug = dl;
-       m->g = gar_init_cfg(NULL, logfn, &cfg);
-       if (!m->g) {
-               g_free(m->filename);
-               g_free(m);
-               return NULL;
-       }
-       // we want the data now, later we can load only what's necessery
-       if (gar_img_load(m->g, m->filename, 1) < 0) {
-               gar_free(m->g);
-               g_free(m->filename);
-               g_free(m);
-               return NULL;
-       }
-       m->conv = NULL;
-       snprintf(buf, sizeof(buf), "%s.types", m->filename);
-       if (!stat(buf, &st)) {
-               dlog(1, "Loading custom types from %s\n", buf);
-               m->conv = g2n_conv_load(buf);
-       }
-       if (!m->conv) {
-               dlog(1, "Using builtin types\n");
-               m->conv = g2n_default_conv();
-       }
-       if (!m->conv) {
-               dlog(1, "Failed to load map types\n");
-       }
-       *meth=map_methods;
-       return m;
-}
-
-void
-plugin_init(void)
-{
-       plugin_register_map_type("garmin", gmap_new);
-}
diff --git a/navit/data/garmin/garmin.h b/navit/data/garmin/garmin.h
deleted file mode 100644 (file)
index 50935b0..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-#define dlog(x,y ...) logfn(__FILE__,__LINE__,x, ##y)
-#ifdef HARDDEBUG
-#define ddlog(x,y ...) logfn(__FILE__,__LINE__,x, ##y)
-#else
-#define ddlog(x,y ...)
-#endif
-
-extern int garmin_debug;
-void logfn(char *file, int line, int level, char *fmt, ...);
-
diff --git a/navit/data/garmin/garmintypes.txt b/navit/data/garmin/garmintypes.txt
deleted file mode 100644 (file)
index 7df6831..0000000
+++ /dev/null
@@ -1,707 +0,0 @@
-#
-#
-#
-POINT
-0, 0x0000 = label_unkn, Unknown label
-0, 0x0100 = town_label_1e5, Megapolis (10M +)
-0, 0x0200 = town_label_5e4, Megapolis (5-10M)
-0, 0x0300 = town_label_2e4, Big City (2-5M)
-0, 0x0400 = town_label_1e4, Big City (1-2M)
-0, 0x0500 = town_label_5e3, Big City (0.5-1M)
-0, 0x0600 = town_label_2e3, City (200-500k)
-0, 0x0700 = town_label_1e3, City (100-200k)
-0, 0x0800 = town_label_5e2, City (50-100k)
-0, 0x0900 = town_label_2e2, City (20-50k)
-0, 0x0a00 = town_label_1e2, City (10-20k)
-0, 0x0b00 = town_label_5e1, Small City (5-10k)
-0, 0x0c00 = town_label_2e1, Small City (2-5k)
-0, 0x0d00 = town_label_1e1, Village (1-2k)
-0, 0x0e00 = town_label_5e0, Village (500-1000)
-0, 0x0f00 = town_label_2e0, Village (200-500)
-0, 0x1000 = town_label_1e0, Village (100-200)
-0, 0x1100 = town_label_0e0, Village (0-100)
-
-0, 0x1200 = port_label, Port with services
-0, 0x1300 = label_unkn, Unknown label2
-0, 0x1400-0x14FF = country_label, Large Country Name
-0, 0x1500-0x15FF = country_label, Country Name
-0, 0x1c00 = poi_wreck, Unclassified Obstruction
-0, 0x1c01 = poi_wreck, Wreck
-0, 0x1c02 = poi_dangerous, submerged wreck, dangerous
-0, 0x1c03 = poi_nondangerous,  submerged wreck, non-dangerous
-0, 0x1c04 = poi_wreck, Wreck, cleared by wire drag
-0, 0x1c05 = poi_rock, Obstruction, visible at high water
-0, 0x1c06 = poi_rock, Obstruction, awash
-0, 0x1c07 = poi_rock, Obstruction, submerged
-0, 0x1c08 = poi_rock, Obstruction, cleared by wire drag
-0, 0x1c09 = poi_rock, Rock, awash
-0, 0x1c0a = poi_rock, Rock, submerged at low Water
-0, 0x1c0b = poi_sounding, Sounding
-0, 0x1d00 = poi_tide, Tide Prediction
-
-0, 0x1e00-0x1e3f = district_label, District, Province, State Name
-0, 0x1f00 = district_label_0e0, Region, District Name
-
-# Fixme if it has label how to change to highway_exit_with_label ??
-0, 0x2000-0x203F = highway_exit, Exit
-0, 0x2100-0x213F = highway_exit, Exit with Services
-0, 0x2200-0x223F = highway_exit, Exit with Restroom
-0, 0x2300-0x233F = highway_exit, Exit with Convinience Store
-0, 0x2400-0x243F = highway_exit, Exit with Weight Station
-0, 0x2500-0x253F = highway_exit, Exit with Toolbooth Booth
-0, 0x2600-0x263F = highway_exit, Exit with Information
-0, 0x2700-0x273F = highway_exit, Exit
-
-0, 0x2800-0x283F = district_label_1e0, Region Name
-
-0, 0x2900 = poi_public_utilities, Services
-
-0, 0x2A00 = poi_dining, Dining(Other)
-0, 0x2A01 = poi_dining, Dining(American)
-0, 0x2A02 = poi_dining, Dining(Asian)
-0, 0x2A03 = poi_dining, Dining(Barbecue)
-0, 0x2A04 = poi_dining, Dining(Chinese)
-0, 0x2A05 = poi_dining, Dining(Deli/Bakery)
-0, 0x2A06 = poi_dining, Dining(International)
-0, 0x2A07 = poi_fastfood, Fast Food
-0, 0x2A08 = poi_dining, Dining(Italian)
-0, 0x2A09 = poi_dining, Dining(Mexican)
-0, 0x2A0A = poi_dining, Dining(Pizza)
-0, 0x2A0B = poi_dining, Dining(Sea Food)
-0, 0x2A0C = poi_dining, Dining(Steak/Grill)
-0, 0x2A0D = poi_dining, Dining(Bagel/Donut)
-0, 0x2A0E = poi_dining, Dining(Cafe/Diner)
-0, 0x2A0F = poi_dining, Dining(French)
-0, 0x2A10 = poi_dining, Dining(German)
-0, 0x2A11 = poi_dining, Dining(British Isles)
-0, 0x2A12 = poi_dining, Dining(Special Foods)
-
-0, 0x2B00 = poi_hotel, Hotel(Other)
-0, 0x2B01 = poi_hotel, Hotel/Motel
-0, 0x2B02 = poi_hotel, Bed & Breakfast inn
-0, 0x2B03 = poi_camp_rv, Camping/RV-Park
-0, 0x2B04 = poi_resort, Resort
-
-0, 0x2C00 = poi_attraction, Amusement Park
-0, 0x2C01 = poi_attraction, Amusement Park
-0, 0x2C02 = poi_museum_history, Museum/History
-0, 0x2C03 = poi_library, Libraries
-0, 0x2C04 = poi_landmark, Land Mark
-0, 0x2C05 = poi_school, School
-0, 0x2C06 = poi_park, Park
-0, 0x2C07 = poi_zoo, Zoo
-0, 0x2C08 = poi_stadium, Sportpark, Stadium,(point)
-0, 0x2C09 = poi_fair, Fair, Conference(point)
-0, 0x2C0A = poi_wine, Wine restaurant(point)
-0, 0x2C0B = poi_worship, Place of Worship
-0, 0x2C0C = poi_hotspring, Hot Spring
-
-0, 0x2D00 = poi_theater, Theater
-0, 0x2D01 = poi_theater, Theater
-0, 0x2D02 = poi_bar, Bar
-0, 0x2D03 = poi_cinema, Cinema
-0, 0x2D04 = poi_casino, Casino
-0, 0x2D05 = poi_golf, Golf
-0, 0x2D06 = poi_skiing, Skiing Center
-0, 0x2D07 = poi_bowling, Bowling
-0, 0x2D08 = poi_icesport, Ice/Sporting
-0, 0x2D09 = poi_swimming, Swimming
-0, 0x2D0A = poi_sport, Sports(point)
-0, 0x2D0B = poi_sailing, Sailing Airport
-
-0, 0x2E00 = poi_shopping, Shoping general
-0, 0x2E01 = poi_shop_department, Department Store
-0, 0x2E02 = poi_shop_grocery, Grocery
-0, 0x2E03 = poi_shop_merchandise, General Merchandiser
-0, 0x2E04 = poi_mall, Shopping Center
-0, 0x2E05 = poi_pharmacy, Pharmacy
-0, 0x2E06 = poi_shopping, Convenience
-0, 0x2E07 = poi_shop_apparel, Apparel
-0, 0x2E08 = poi_shop_handg, House and Garden
-0, 0x2E09 = poi_shop_furnish, Home Furnishing
-0, 0x2E0a = poi_shop_retail, Special Retail
-0, 0x2E0b = poi_shop_computer, Computer/Software
-0, 0x2E0c = poi_shop_computer, Mobile Communications
-
-0, 0x2F00 = poi_service, generic service
-0, 0x2F01 = poi_fuel, Fuel/Gas
-0, 0x2F02 = poi_car_rent, Car Rental
-0, 0x2F03 = poi_autoservice, Car Repair
-0, 0x2F04 = poi_airport, Airport
-0, 0x2F05 = poi_post, Post Office
-0, 0x2F06 = poi_bank, Bank
-0, 0x2F07 = poi_car_dealer_parts, Car Dealer(point)
-0, 0x2F08 = poi_bus_station, Bus Station
-0, 0x2F09 = poi_marina, Marina
-0, 0x2F0A = poi_wrecker, Wrecker Service
-0, 0x2F0B = poi_car_parking, Parking
-0, 0x2F0C = poi_rest_room, Restroom
-0, 0x2F0D = poi_auto_club, Automobile Club
-0, 0x2F0E = poi_car_wash, Car Wash
-0, 0x2F0F = poi_garmin, Garmin Dealer
-0, 0x2F10 = poi_personal_service, Personal Service
-0, 0x2F11 = poi_bussines_service, Business Service
-0, 0x2F12 = poi_communication, Communication
-0, 0x2F13 = poi_repair_service, Repair Service
-0, 0x2F14 = poi_social_service, Social Service
-0, 0x2F15 = poi_public_utilities, Utility
-0, 0x2F16 = poi_truck_stop, Truck Stop
-0, 0x2F17 = poi_bus_stop, Bus Stop
-
-0, 0x3000 = poi_emergency, generic emergency/government
-0, 0x3001 = poi_police, Police Station
-0, 0x3002 = poi_hospital, Hospital
-0, 0x3003 = poi_public_office, Public Office
-0, 0x3004 = poi_justice, Justice
-0, 0x3005 = poi_concert, Concert hall(point)
-0, 0x3006 = poi_border_station, Border Station(point)
-0, 0x3007 = poi_goverment_building, Goverment Building
-0, 0x3008 = poi_firebrigade, FireFighters Station
-
-0, 0x4000-0x403F = poi_golf, Golf
-0, 0x4100-0x413F = poi_fish, Fish
-0, 0x4200-0x423F = poi_wreck, Wreck
-0, 0x4300-0x433F = poi_marina, Marina
-0, 0x4400-0x443F = poi_fuel, Gas
-0, 0x4500-0x453F = poi_restaurant, Restaurant
-0, 0x4600-0x463F = poi_bar, Bar
-0, 0x4700-0x473F = poi_boat_ramp, Boat Ramp
-0, 0x4800-0x483F = poi_camping, Camping
-0, 0x4900-0x493F = poi_park, Park
-0, 0x4A00-0x4A3F = poi_picnic, Picnic Area
-0, 0x4B00-0x4B3F = poi_hospital, Hospital
-0, 0x4C00-0x4C3F = poi_information, Information
-0, 0x4D00-0x4D3F = poi_car_parking, Parking
-0, 0x4E00-0x4E3F = poi_restroom, Restroom
-0, 0x4F00-0x4F3F = poi_shower, Shower
-0, 0x5000-0x503F = poi_drinking_water, Drinking Water
-0, 0x5100-0x513F = poi_telephone, Telephone
-0, 0x5200-0x523F = poi_scenic_area, Scenic Area
-0, 0x5300-0x533F = poi_skiing, Skiing
-0, 0x5400-0x543F = poi_swimming, Swimming
-0, 0x5500-0x553F = poi_dam, Dam
-
-0, 0x5600-0x563F = poi_forbiden_area, Forbiden Area
-0, 0x5700-0x573F = poi_danger_area, Danger Area
-0, 0x5800-0x583F = poi_restricted_area, Restricted Area
-
-0, 0x5900 = poi_airport, Generic Airport
-0, 0x5901 = poi_airport, Large Airport
-0, 0x5902 = poi_airport, Medium Airport
-0, 0x5903 = poi_airport, Small Airport
-0, 0x5904 = poi_heliport, Heliport
-0, 0x5905-0x593F = poi_airport, Airport
-
-0, 0x5a00 = poi_mark, Kilometer Pole
-0, 0x5b00 = poi_mark, Kolokol
-0, 0x5c00 = poi_diving, Diving Place
-
-0, 0x5D00-0x5D3F = poi_daymark, Daymark,Green Square
-0, 0x5E00-0x5E3F = poi_daymark, Daymark,Red Triangle
-
-0, 0x6000 = poi_loudspeaker, LoudSpeaker
-0, 0x6100 = poi_building, House
-
-0, 0x6200 = poi_height, Height with point in feet one decimal place
-0, 0x6300 = poi_height, Height without point in feet no decimal place
-0, 0x6400 = poi_manmade_feature, Manmade Feature
-0, 0x6401 = poi_bridge, Bridge
-0, 0x6402 = poi_building, Building
-0, 0x6403 = poi_cemetery, Cemetery
-0, 0x6404 = poi_church, Church
-0, 0x6405 = poi_civil, Civil
-0, 0x6406 = poi_crossing, Crossing
-0, 0x6407 = poi_dam, Dam
-0, 0x6408 = poi_hospital, Hospital
-0, 0x6409 = poi_levee, Levee
-0, 0x640A = poi_locale, Locale
-0, 0x640B = poi_military, Military
-0, 0x640C = poi_mine, Mine
-0, 0x640D = poi_oil_field, Oil Field
-0, 0x640E = poi_park, Park
-0, 0x640F = poi_post, Post
-0, 0x6410 = poi_school, School
-0, 0x6411 = poi_tower, Tower
-0, 0x6412 = poi_trail, Trail
-0, 0x6413 = poi_tunnel, Tunnel
-0, 0x6414 = poi_drinking_water, Drink water
-0, 0x6415 = town_ghost, Ghost Town
-0, 0x6416 = poi_subdivision, Subdivision
-
-0, 0x6500 = poi_water_feature, Water Feature
-0, 0x6501 = poi_water_feature, Arroyo
-0, 0x6502 = poi_water_feature, Sand Bar
-0, 0x6503 = poi_bay, Bay
-0, 0x6504 = poi_bend, Bend
-0, 0x6505 = poi_water_feature, Canal
-0, 0x6506 = poi_water_feature, Channel
-0, 0x6507 = poi_cove, Cove
-0, 0x6508 = poi_water_feature, Falls
-0, 0x6509 = poi_water_feature, Geyser
-0, 0x650A = poi_water_feature, Glacier
-0, 0x650B = poi_marine, Harbour
-0, 0x650C = poi_island, Island
-0, 0x650D = poi_water_feature, Lake
-0, 0x650E = poi_water_feature, Rapids
-0, 0x650F = poi_water_feature, Reservoir
-0, 0x6510 = poi_water_feature, Sea
-0, 0x6511 = poi_water_feature, Spring
-0, 0x6512 = poi_water_feature, Stream
-0, 0x6513 = poi_water_feature, Swamp
-
-0, 0x6600 = poi_land_feature, Land Feature
-0, 0x6601 = poi_land_feature, Arch
-0, 0x6602 = poi_land_feature, Area
-0, 0x6603 = poi_land_feature, Basin
-0, 0x6604 = poi_land_feature, Beach
-0, 0x6605 = poi_land_feature, Bench
-0, 0x6606 = poi_land_feature, Cape
-0, 0x6607 = poi_land_feature, Cliff
-0, 0x6608 = poi_land_feature, Crater
-0, 0x6609 = poi_land_feature, Flat
-0, 0x660A = poi_land_feature, Forest
-0, 0x660B = poi_land_feature, Gap
-0, 0x660C = poi_land_feature, Gut
-0, 0x660D = poi_land_feature, Isthmus
-0, 0x660E = poi_land_feature, Lava
-0, 0x660F = poi_land_feature, Pillar
-0, 0x6610 = poi_land_feature, Plain
-0, 0x6611 = poi_land_feature, Range
-0, 0x6612 = poi_land_feature, Reserve
-0, 0x6613 = poi_land_feature, Ridge
-0, 0x6614 = poi_land_feature, Rock
-0, 0x6615 = poi_land_feature, Slope
-0, 0x6616 = poi_land_feature, Summit
-0, 0x6617 = poi_land_feature, Valley
-0, 0x6618 = poi_land_feature, Woods
-
-# This are dublicated to 0x1700, 0x1800, 0x1900, 0x1A00, 0x1B00
-# fix them if you need them
-0, 0x1600 = poi_marine_type, Beakon
-0, 0x1601 = poi_marine_type, Fog Horn
-0, 0x1602 = poi_marine_type, Radio Beacon
-0, 0x1603 = poi_marine_type, Racon
-0, 0x1604 = poi_marine_type, Day Beacon, red triangle
-0, 0x1605 = poi_marine_type, Day Beacon, green square
-0, 0x1606 = poi_marine_type, Day Beacon, white diamond
-0, 0x1607 = poi_marine_type, unlit Navaid, white
-0, 0x1608 = poi_marine_type, unlit Navaid, red
-0, 0x1609 = poi_marine_type, unlit Navaid, green
-0, 0x160a = poi_marine_type, unlit Navaid, black
-0, 0x160b = poi_marine_type, unlit Navaid, yellow or amber
-0, 0x160c = poi_marine_type, unlit Navaid, orange
-0, 0x160d = poi_marine_type, unlit Navaid, multi colored
-0, 0x160e = poi_marine_type, Navaid, unknown
-0, 0x160f = poi_marine_type, lighted Navaid, white
-0, 0x1610 = poi_marine_type, lighted Navaid, red
-0, 0x1611 = poi_marine_type, lighted Navaid, green
-0, 0x1612 = poi_marine_type, lighted Navaid, yellow or amber
-0, 0x1613 = poi_marine_type, lighted Navaid, orange
-0, 0x1614 = poi_marine_type, lighted Navaid, violet
-0, 0x1615 = poi_marine_type, lighted Navaid, blue
-0, 0x1616 = poi_marine_type, lighted Navaid, multi colored
-# RGN2-4 types 
-# Marine types start
-1, 0x0100 = point_unkn, Light
-1, 0x0102 = point_unkn, Light with north topmark
-1, 0x0103 = point_unkn, Light with south topmark
-1, 0x0104 = point_unkn, Light with east topmark
-1, 0x0105 = point_unkn, Light with west topmark
-1, 0x0106 = point_unkn, Isolated danger light
-1, 0x0107 = point_unkn, Port hand light
-1, 0x0108 = point_unkn, Starboard hand light
-1, 0x0109 = point_unkn, Special purpose light
-1, 0x010a = point_unkn, Safe water light
-1, 0x0200 = point_unkn, Buoy
-1, 0x0201 = point_unkn, Buoy
-1, 0x0202 = point_unkn, Buoy with north topmark
-1, 0x0203 = point_unkn, Buoy with south topmark
-1, 0x0204 = point_unkn, Buoy with east topmark
-1, 0x0205 = point_unkn, Buoy with west topmark
-1, 0x0206 = point_unkn, Beacon
-1, 0x0207 = point_unkn, Spar buoy
-1, 0x0208 = point_unkn, Isolated danger buoy
-1, 0x0209 = point_unkn, Port hand buoy
-1, 0x020a = point_unkn, Starboard hand buoy
-1, 0x020b = point_unkn, Special purpose buoy
-1, 0x020c = point_unkn, Safe water buoy
-1, 0x020d = point_unkn, Platform buoy
-1, 0x020e = point_unkn, Beacon with north topmark
-1, 0x020f = point_unkn, Beacon with south north topmark
-1, 0x0210 = point_unkn, Beacon with east topmark
-1, 0x0211 = point_unkn, Beacon with west topmark
-1, 0x0212 = point_unkn, Isolated danger beacon
-1, 0x0213 = point_unkn, Port hand beacon
-1, 0x0214 = point_unkn, Starboard hand beacon
-1, 0x0215 = point_unkn, Special purpose beacon
-1, 0x0216 = point_unkn, Mooring buoy
-1, 0x0217 = point_unkn, Fixed point
-1, 0x0218 = point_unkn, Pole
-1, 0x0300 = point_unkn, Depth point
-1, 0x0301 = point_unkn, Depth point invisible
-1, 0x0302 = point_unkn, Depth point underscore
-1, 0x0303 = point_unkn, Spot height
-1, 0x0304 = point_unkn, Building
-1, 0x0305 = point_unkn, Chimney
-1, 0x0306 = point_unkn, Church
-1, 0x0307 = point_unkn, Tanks
-1, 0x0308 = point_unkn, Tower
-1, 0x0309 = point_unkn, Rock
-1, 0x030a = point_unkn, Triangulation point
-1, 0x030b = point_unkn, Radio mast
-1, 0x0400 = point_unkn, Isolated danger
-1, 0x0401 = point_unkn, Obstruction
-1, 0x0402 = point_unkn, Wreck
-1, 0x0403 = point_unkn, Exposed wreck
-1, 0x0404 = point_unkn, Well
-1, 0x0405 = point_unkn, Foul
-1, 0x0406 = point_unkn, Explosive
-1, 0x0407 = point_unkn, Fish haven
-1, 0x0408 = point_unkn, Obstruction that covers
-1, 0x0409 = point_unkn, Marine farm
-1, 0x040a = point_unkn, Dangerous rock
-1, 0x040b = point_unkn, No bottom found
-1, 0x040c = point_unkn, Exposed rock
-1, 0x040d = point_unkn, Dangerous rock
-1, 0x040e = point_unkn, Underwater rock (non-dangerous rock)
-1, 0x040f = point_unkn, Shoal
-1, 0x0500 = point_unkn, Label point
-1, 0x0600 = point_unkn, Centered label
-1, 0x0700 = point_unkn, Miscellaneous point
-1, 0x0701 = point_unkn, Recommended anchorage
-1, 0x0702 = point_unkn, Pilot boarding place
-1, 0x0703 = point_unkn, Yacht harbour
-1, 0x0704 = point_unkn, Pile
-1, 0x0705 = point_unkn, Anchoring prohibited
-1, 0x0706 = point_unkn, Fishing prohibited
-1, 0x0707 = point_unkn, Precautionary area
-1, 0x0708 = point_unkn, Radio report point
-1, 0x0709 = point_unkn, Anchorage berths
-1, 0x070a = point_unkn, Rescue station
-1, 0x070b = point_unkn, Fishing harbour
-1, 0x070c = point_unkn, Airport
-1, 0x0800 = point_unkn, Information
-1, 0x0901 = point_unkn, Bottom conditions
-1, 0x0902 = point_unkn, Fishing information
-1, 0x0903 = point_unkn, Facility
-# NT types start
-1, 0x0b00 = poi_dining, Dining(Other)
-1, 0x0b04 = poi_dining, Dining(Chinese)
-1, 0x0b05 = poi_dining, Dining (Deli/Bakery)
-1, 0x0b06 = poi_dining, Dining (International)
-1, 0x0b07 = poi_fastfood, Fast Food
-1, 0x0b09 = poi_dining, Dining(Mexican)
-1, 0x0b0a = poi_dining, Dining(Pizza)
-1, 0x0b0b = poi_dining, Dining (Sea Food)
-1, 0x0b0c = poi_dining, Dining (Steak/Grill)
-1, 0x0b0d = poi_dining, Dining(Bagel/Donut)
-1, 0x0b0e = poi_dining, Dining(Cafe/Diner)
-1, 0x0c01 = poi_hotel, Hotel/Motel
-1, 0x0c02 = poi_hotel, Bed & Breakfast inn
-1, 0x0c03 = poi_camp_rv, Camping/RV-Park
-1, 0x0c04 = poi_resort, Resort
-1, 0x0d01 = poi_attraction, Amusement Park
-1, 0x0d02 = poi_museum_history, Museum/History
-1, 0x0d03 = poi_fair, Fair, Conference(point)
-1, 0x0d04 = poi_scenic_area, Scenic Area
-1, 0x0d05 = poi_school, School
-1, 0x0d06 = poi_park, Park
-1, 0x0d07 = poi_zoo, Zoo
-1, 0x0d08 = poi_stadium, Sportpark, Stadium
-1, 0x0d0a = poi_bar, Wine Bar
-1, 0x0d14 = poi_hospital, Hospital 
-1, 0x0e01 = poi_theater, Theater
-1, 0x0e02 = poi_bar, Bar
-1, 0x0e03 = poi_cinema, Cinema
-1, 0x0e04 = poi_casino, Casino
-1, 0x0e05 = poi_golf, Golf
-1, 0x0e06 = poi_skiing, Skiing Center/Lift
-1, 0x0e07 = poi_bar, Night Bar/Piano
-1, 0x0e08 = poi_icesport, Ice/Sporting
-1, 0x0e09 = poi_swimming, Swimming
-1, 0x0e0a = poi_sport, Sports(point)
-1, 0x0f00 = poi_hotel, Hotel(Other)
-1, 0x0f01 = poi_shop_department, Department Store
-1, 0x0f02 = poi_shop_grocery, Grocery
-1, 0x0f03 = poi_hotel, Hotel/Motel
-1, 0x0f04 = poi_resort, Resort
-1, 0x0f05 = poi_pharmacy, Pharmacy
-1, 0x1001 = poi_fuel, Fuel/Gas
-1, 0x1002 = poly_car_parking, Parking Lot
-1, 0x1003 = poi_autoservice, Car Repair
-1, 0x1004 = poi_airport, Airport
-1, 0x1005 = poi_post, Post Office
-1, 0x1006 = poi_bank, Bank
-1, 0x1008 = poi_bus_station, Bus station
-1, 0x1009 = poi_marina, SeaPort
-1, 0x100a = poi_wrecker, Wrecker Service
-1, 0x100b = poi_car_parking, Parking
-1, 0x100d = poi_car_dealer_parts, Car Dealer(point)
-1, 0x100e = poi_car_wash, Car Wash
-1, 0x1011 = poi_bussines_service, Business Service
-1, 0x1012 = poi_communication, Communication
-1, 0x1013 = poi_repair_service, Repair Service 
-1, 0x1014 = poi_social_service, Social Service
-1, 0x1015 = poi_public_utilities, Utility
-1, 0x1101 = poi_police, Police Station
-1, 0x1102 = poi_hospital, Hospital
-1, 0x1104 = poi_justice, Justice
-1, 0x1107 = poi_public_office, Public Office
-1, 0x1400 = town_label_1e5, Megapolis (10M +)
-1, 0x1401 = town_label_5e4, Megapolis (5-10M)
-1, 0x1402 = town_label_2e4, Big City (2-5M)
-1, 0x1403 = town_label_5e3, Big City (0.5-1M)
-1, 0x1404 = town_label_2e3, City (200-500k)
-1, 0x1405 = town_label_1e3, City (100-200k)
-1, 0x1406 = town_label_5e2, City (50-100k)
-1, 0x1405 = town_label_2e2, City (20-50k)
-1, 0x1406 = town_label_1e2, City (10-20k)
-1, 0x1407 = town_label_5e1, Small City (5-10k)
-1, 0x1408 = town_label_2e1, Small City (2-5k)
-1, 0x1409 = town_label_1e1, Village (1-2k)
-1, 0x140a = town_label_5e0, Village (500-1000)
-1, 0x140b = town_label_2e0, Village (200-500)
-1, 0x140c = town_label_1e0, Village (100-200)
-1, 0x140d = town_label_0e0, Village (0-100)
-1, 0x1500 = poi_personal_service, Personal Service
-1, 0x1501 = poi_bussines_service, Bussines Service
-
-
-POLYLINE
-0, 0x00 = street_1_land, Road
-0, 0x01 = highway_land, Major HWY thick
-0, 0x02 = street_4_land, Principal HWY-thick
-0, 0x03 = street_2_land, Principal HWY-medium
-0, 0x04 = street_3_city, Arterial Road-medium
-0, 0x05 = street_4_city, Arterial Road-thick
-0, 0x06 = street_2_city, Road-thin
-0, 0x07 = street_1_city, Alley-thick
-0, 0x08 = ramp, Ramp
-0, 0x09 = ramp, Ramp highspeed
-0, 0x0a = street_0, Unpaved Road-thin
-0, 0x0b = ramp, Major HWY Connector-thick
-0, 0x0c = roundabout, Roundabout
-0, 0x0d = street_unkn, Custom defined street 1
-0, 0x0e = street_unkn, Custom defined street 2
-0, 0x0f = street_unkn, Custom defined street 3
-0, 0x10 = street_unkn, Custom defined street 4
-0, 0x11 = street_unkn, Custom defined street 5
-0, 0x12 = street_unkn, Custom defined street 6
-0, 0x13 = street_unkn, Custom defined street 7
-0, 0x14 = rail, Railroad
-0, 0x15 = water_line, Shoreline
-0, 0x16 = street_nopass, Trail
-0, 0x18 = water_line, Stream-thin
-0, 0x19 = time_zone, Time-Zone
-0, 0x1a = ferry, Ferry
-0, 0x1b = ferry, Ferry
-0, 0x1c = border_country, Political Boundary
-0, 0x1d = border_country, County Boundary
-0, 0x1e = border_country, Intl. Boundary
-0, 0x1f = water_line, River
-0, 0x20 = height_line_1, Land Contour (thin) Height in feet
-0, 0x21 = height_line_2, Land Contour (medium) Height in feet
-0, 0x22 = height_line_3, Land Contour (thick) Height in feet
-0, 0x23 = depth_line_1, Depth Contour (thin) Depth in feet
-0, 0x24 = depth_line_2, Depth Contour (medium) Depth in feet
-0, 0x25 = depth_line_3, Depth Contour (thick) Depth in feet
-0, 0x26 = water_line, Intermittent River
-0, 0x27 = street_nopass, Airport Runway
-0, 0x28 = pipeline, Pipeline
-0, 0x29 = powerline, Powerline
-0, 0x2a = marine_boundary, Marine Boundary (no line)
-0, 0x2b = marine_hazard, Marine Hazard (no line)
-# RGN2-4
-# Marine
-1, 0x0100 = street_unkn, Miscellaneous line
-1, 0x0101 = street_unkn, Line
-1, 0x0102 = street_unkn, Cartographic line
-1, 0x0103 = street_unkn, Road
-1, 0x0104 = street_unkn, Clearing line
-1, 0x0105 = street_unkn, Contour line
-1, 0x0106 = street_unkn, Overhead cable
-1, 0x0107 = street_unkn, Bridge
-1, 0x0108 = street_unkn, Recommended route
-1, 0x0109 = street_unkn, Chart border
-1, 0x0300 = street_unkn, Depth contour
-1, 0x0301 = street_unkn, Depth contour value
-1, 0x0307 = street_unkn, Intertidal zone border
-1, 0x0400 = street_unkn, Obstruction line
-1, 0x0401 = street_unkn, Submarine cable
-1, 0x0402 = street_unkn, Submarine pipeline
-1, 0x0403 = street_unkn, Pile barrier
-1, 0x0404 = street_unkn, Fishing stakes
-1, 0x0405 = street_unkn, Supply pipeline area
-1, 0x0406 = street_unkn, Submarine cable area
-1, 0x0407 = street_unkn, Dumping ground
-1, 0x0408 = street_unkn, Explosive dumping ground
-1, 0x0409 = street_unkn, Danger line
-1, 0x040a = street_unkn, Overhead cable
-1, 0x040b = street_unkn, Submerged construction
-1, 0x040c = street_unkn, Pier/jetty
-1, 0x0500 = street_unkn, Restriction
-1, 0x0501 = street_unkn, Anchoring prohibited
-1, 0x0502 = street_unkn, Fishing prohibited
-1, 0x0503 = street_unkn, Prohibited area
-1, 0x0504 = street_unkn, Military practice area
-1, 0x0505 = street_unkn, Anchoring and fishing prohibited
-1, 0x0506 = street_unkn, Limit of nature reservation
-1, 0x0507 = street_unkn, Restricted area
-1, 0x0508 = street_unkn, Minefield
-1, 0x0600 = street_unkn, Miscellaneous line
-1, 0x0601 = street_unkn, Cartographic line
-1, 0x0602 = street_unkn, Traffic separation line
-1, 0x0603 = street_unkn, International maritime boundary
-1, 0x0604 = street_unkn, Straight territorial sea baseline
-1, 0x0605 = street_unkn, Seaward limit of territorial sea
-1, 0x0606 = street_unkn, Anchorage area
-1, 0x0607 = street_unkn, Quarantine anchorage area
-1, 0x0608 = street_unkn, Fishery zone
-1, 0x0609 = street_unkn, Swept area
-1, 0x060a = street_unkn, Traffic separation zone
-1, 0x060b = street_unkn, Limit of exclusive economic zone
-1, 0x060c = street_unkn, Established direction of traffic flow
-1, 0x060d = street_unkn, Recommended direction of traffic flow
-1, 0x060e = street_unkn, Harbour limit
-1, 0x060f = street_unkn, Inadequately surveyed area
-1, 0x0610 = street_unkn, Inshore traffic zone
-1, 0x0611 = street_unkn, Limit of traffic lane
-1, 0x0701 = street_unkn, River channel
-1, 0x0702 = street_unkn, Submerged object
-1, 0x0703 = street_unkn, Submerged object
-1, 0x0704 = street_unkn, Submerged object
-1, 0x0705 = street_unkn, Submerged object
-1, 0x0706 = street_unkn, Chart boundary
-# NT types
-1, 0x0a00 = water_line, River
-1, 0x0a01 = water_line, Small River
-1, 0x0a19 = street_unkn, Dry Creek
-1, 0x0b04 = border_country, Country Border
-
-
-POLYGONE
-0, 0x01 = poly_town, City (>200k)
-0, 0x02 = poly_town, City (<200k)
-0, 0x03 = poly_town, Village
-0, 0x04 = poly_military_zone, Military
-0, 0x05 = poly_car_parking, Parking Lot
-0, 0x06 = poly_car_parking, Parking Garage
-0, 0x07 = poly_airport, Airport
-0, 0x08 = poly_commercial_center, Shopping Center
-0, 0x09 = poly_marine, Marina
-0, 0x0a = poly_university, University/College
-0, 0x0b = poly_hospital, Hospital
-0, 0x0c = poly_industry, Industrial
-0, 0x0d = area, Reservation
-0, 0x0e = poly_airport, Airport Runway
-0, 0x13 = area_unspecified, Man made area
-0, 0x14 = poly_national_park, National park
-0, 0x15 = poly_national_park, National park
-0, 0x16 = poly_nature_park, National park
-0, 0x17 = poly_park, City Park
-0, 0x18 = poly_golf_course, Golf
-0, 0x19 = poly_sport, Sport
-0, 0x1a = poly_cemetery, Cemetery
-0, 0x1e = poly_nature_park, State Park
-0, 0x1f = poly_park, State Park
-0, 0x20 = poly_park, State Park
-0, 0x28 = poly_water, Ocean
-0, 0x29 = poly_water, Water Reservour
-0, 0x32 = poly_water, Sea
-0, 0x3b = poly_water, Water Reservour
-0, 0x3c = poly_water, Lake (250-600 km2)
-0, 0x3d = poly_water, Lake (77-250 km2)
-0, 0x3e = poly_water, Lake (25-77 km2)
-0, 0x3f = poly_water, Lake (11-25 km2)
-0, 0x40 = poly_water, Lake (0.25-11 km2)
-0, 0x41 = poly_water, Lake (<0.25 km2)
-0, 0x42 = poly_water, Lake (>3.3k km2)
-0, 0x43 = poly_water, Lake (1.1-3.3k km2)
-0, 0x44 = poly_water, Lake (0.6-1.1k km2)
-0, 0x45 = poly_water, Water Reservour
-0, 0x46 = poly_water, River (>1km)
-0, 0x47 = poly_water, River (200m-1km)
-0, 0x48 = poly_water, River (40-200m)
-0, 0x49 = poly_water, River (<40m)
-0, 0x4a = area, Definition Area
-0, 0x4b = area, Background
-0, 0x4c = poly_water, Intermittent River/Lake
-0, 0x4d = poly_glacier, Glaciers
-0, 0x4e = plantation, Orchard or plantation
-0, 0x4f = poly_scrub, Scrub
-0, 0x50 = poly_wood, Woods
-0, 0x51 = poly_wetland, Wetland
-0, 0x52 = tundra, Tundra
-0, 0x53 = poly_flats, Flats
-# RGN2-4 
-# Marine
-1, 0x0100 = street_unkn, Land - white
-1, 0x0101 = street_unkn, Land - non-urban
-1, 0x0102 = street_unkn, Land - urban
-1, 0x0103 = street_unkn, Chart exclusion area
-1, 0x0104 = street_unkn, Chart background
-1, 0x0105 = street_unkn, Bridge
-1, 0x0300 = street_unkn, Depth area - white 1
-1, 0x0301 = street_unkn, Intertidal zone
-1, 0x0302 = street_unkn, Depth area - blue 1
-1, 0x0303 = street_unkn, Depth area - blue 2
-1, 0x0304 = street_unkn, Depth area - blue 3
-1, 0x0305 = street_unkn, Depth area - blue 4
-1, 0x0306 = street_unkn, Depth area - blue 5
-1, 0x0307 = street_unkn, Depth area - white
-1, 0x0400 = street_unkn, Obstruction (invisible)
-1, 0x0401 = street_unkn, Submarine cable (invisible)
-1, 0x0402 = street_unkn, Submarine pipeline (invisible)
-1, 0x0403 = street_unkn, Pile barrier (invisible)
-1, 0x0404 = street_unkn, Fishing stakes (invisible)
-1, 0x0405 = street_unkn, Supply pipeline area/line (invisible)
-1, 0x0406 = street_unkn, Submarine cable area/line (invisible)
-1, 0x0407 = street_unkn, Dumping ground (invisible)
-1, 0x0408 = street_unkn, Explosive dumping ground (invisible)
-1, 0x0409 = street_unkn, Danger line (invisible)
-1, 0x040a = street_unkn, Overhead cable (invisible)
-1, 0x040b = street_unkn, Submerged construction (invisible)
-1, 0x040c = street_unkn, Pier/jetty (invisible)
-1, 0x0500 = street_unkn, Restriction area/line (invisible)
-1, 0x0501 = street_unkn, Anchoring prohibited (invisible)
-1, 0x0502 = street_unkn, Fishing prohibited (invisible)
-1, 0x0503 = street_unkn, Prohibited area (invisible)
-1, 0x0504 = street_unkn, Military practice area (invisible)
-1, 0x0505 = street_unkn, Anchoring and fishing prohibited (invisible)
-1, 0x0506 = street_unkn, Limit of nature reservation (invisible)
-1, 0x0507 = street_unkn, Restricted area (invisible)
-1, 0x0508 = street_unkn, Minefield (invisible)
-1, 0x0600 = street_unkn, Miscellaneous area
-1, 0x0601 = street_unkn, Cartographic area
-1, 0x0602 = street_unkn, Traffic separation area
-1, 0x0603 = street_unkn, International maritime boundary
-1, 0x0604 = street_unkn, Straight territorial sea baseline
-1, 0x0605 = street_unkn, Seaward limit of territorial sea
-1, 0x0606 = street_unkn, Anchorage area
-1, 0x0607 = street_unkn, Quarantine anchorage area
-1, 0x0608 = street_unkn, Fishery zone
-1, 0x0609 = street_unkn, Swept area
-1, 0x060a = street_unkn, Traffic separation zone
-1, 0x060b = street_unkn, Limit of exclusive economic zone
-1, 0x060c = street_unkn, Established direction of traffic flow
-1, 0x0701 = street_unkn, Fishing area
-1, 0x0702 = street_unkn, Restricted area
-1, 0x0703 = street_unkn, Anchorage area
-1, 0x0704 = street_unkn, Fishing Hot Spots chart
-# NT types
-1, 0x0800 = poly_town, Large City
-1, 0x0801 = poly_town, City
-1, 0x0900 = poly_plaza, Square/Place
-1, 0x0902 = poly_car_parking, Car Park (Parking Lot)
-1, 0x0904 = poly_airport, Airport
-1, 0x090d = poly_sports_stadium, Stage like circus/sport/stadium
-1, 0x090e = poly_cemetery, Graveyard/Cemetery
-1, 0x0a01 = poly_national_park, National Park
-1, 0x0a04 = poly_park, City Park
-1, 0x0a05 = poly_nature_park, Nature Park
-1, 0x0a06 = street_unkn, Dam/Man made/ ??
-1, 0x0b02 = poly_water, Sea
-1, 0x0b03 = poly_water, Water Reservour
-1, 0x0b07 = poly_water, Dam/Lake
-1, 0x0b08 = poly_water, Dam/Lake
-1, 0x0b0c = poly_water, River
diff --git a/navit/data/garmin/gentypes.c b/navit/data/garmin/gentypes.c
deleted file mode 100644 (file)
index 16682a5..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
-       Copyright (C) 2007  Alexander Atanasov      <aatanasov@gmail.com>
-
-       This program is free software; you can redistribute it and/or modify
-       it under the terms of the GNU General Public License as published by
-       the Free Software Foundation; version 2 of the License.
-
-       This program is distributed in the hope that it will be useful,
-       but WITHOUT ANY WARRANTY; without even the implied warranty of
-       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-       GNU General Public License for more details.
-
-       You should have received a copy of the GNU General Public License
-       along with this program; if not, write to the Free Software
-       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
-       MA  02110-1301  USA
-    
-       Garmin and MapSource are registered trademarks or trademarks
-       of Garmin Ltd. or one of its subsidiaries.
-
-*/
-
-/*
-File format is:
-
-POINT
-GROUP,0x0100 = town_label_1e5, Megapolis (10M +)
-GROUP,0x0200 = town_label_5e4, Megapolis (5-10M)
-...
-GROUP,0x1e00-0x1e3f = district_label, District, Province, State Name
-...
-POLYLINE
-GROUP,0x00 = street_1_land, Road
-GROUP,0x01 = highway_land, Major HWY thick
-GROUP,0x02 = street_4_land, Principal HWY-thick
-GROUP,0x03 = street_2_land, Principal HWY-medium
-....
-POLYGONE
-GROUP,0x01 = town_poly, City (>200k)
-GROUP,0x02 = town_poly, City (<200k)
-GROUP,0x03 = town_poly, Village
-
-GROUP is
-0 - good old garmin types in RGN1
-1 - NT types in RGN2-4 5 is completely unknown yet
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <malloc.h>
-#include <unistd.h>
-#include "item.h"
-#include "gar2navit.h"
-
-#define dlog(x, y...) fprintf(stderr, ## y)
-/*
-static int add_def(struct gar2nav_conv *conv, int type, unsigned short minid,
-               unsigned short maxid, unsigned int routable, char *ntype,
-               char *descr)
-*/
-
-static void print_header(FILE *fp)
-{
-       fprintf(fp, "// This is autogenerated file -- DO NOT EDIT\n");
-       fprintf(fp, "struct gar2nav_conv *g2n_default_conv(void)\n"
-                       "{\n"
-                       "\tstruct gar2nav_conv *conv;\n"
-                       "\n"
-                       "\tconv = calloc(1, sizeof(*conv));\n"
-                       "\tif (!conv)\n"
-                       "\t\treturn conv;\n");
-}
-
-static int load_types_file(char *file, char *out)
-{
-       char buf[4096];
-       char descr[4096];
-       char ntype[4096];
-       FILE *fp;
-       unsigned int minid, maxid, group;
-       int rc;
-       int type = -1;
-       FILE *fpout = stdout;
-
-       fp = fopen(file, "r");
-       if (!fp)
-               return -1;
-       if (out) {
-               fpout = fopen(out, "w");
-               if (!fpout)
-                       return -1;
-       }
-       print_header(fpout);
-       while (fgets(buf, sizeof(buf), fp)) {
-               if (*buf == '#' || *buf == '\n')
-                       continue;
-               if (!strncasecmp(buf, "POINT", 5)) {
-                       type = 1;
-                       continue;
-               } else if (!strncasecmp(buf, "POI", 3)) {
-                       type = 1;
-                       continue;
-               } else if (!strncasecmp(buf, "POLYLINE", 8)) {
-                       type = 2;
-                       continue;
-               } else if (!strncasecmp(buf, "POLYGONE", 8)) {
-                       type = 3;
-                       continue;
-               }
-
-               rc = sscanf(buf, "%d, 0x%04X - 0x%04X = %[^\t , ] , %[^\n]",
-                       &group, &minid, &maxid, ntype, descr);
-               if (rc != 5) { 
-                       maxid = 0;
-                       rc = sscanf(buf, "%d, 0x%04X = %[^\t, ], %[^\n]",
-                               &group,&minid, ntype, descr);
-                       if (rc != 4) {
-                               dlog(1, "Invalid line rc=%d:[%s]\n",rc, buf);
-                               dlog(1, "minid=%04X ntype=[%s] des=[%s]\n",
-                                       minid, ntype, descr);
-                               continue;
-                       }
-               }
-
-               fprintf(fpout, "\tadd_def(conv, %d, %#.04x, %#.04x, %d, \"%s\", \"%s\");\n",
-                               type, minid, maxid, group, ntype, descr);
-       }
-       fprintf(fpout, "\treturn conv;\n");
-       fprintf(fpout, "}\n");
-       fclose(fp);
-       if (out)
-               fclose(fpout);
-       return 1;
-}
-
-int main(int argc, char **argv)
-{
-       if (argc!=3) {
-               fprintf(stderr, "Usage: %s garmintypes.txt outfile.c\n",
-                       argv[0]);
-               return -1;
-       }
-       if (load_types_file(argv[1], argv[2]) < 0) {
-               unlink(argv[2]);
-               return -1;
-       }
-       return 0;
-}
diff --git a/navit/data/garmin_img/Makefile.am b/navit/data/garmin_img/Makefile.am
deleted file mode 100644 (file)
index 9e50c62..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-include $(top_srcdir)/Makefile.inc
-AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/navit -DMODULE=data_garmin_img
-moduledata_LTLIBRARIES = libdata_garmin_img.la
-libdata_garmin_img_la_SOURCES = garmin_img.c
diff --git a/navit/data/garmin_img/garmin_img.c b/navit/data/garmin_img/garmin_img.c
deleted file mode 100644 (file)
index 58fe489..0000000
+++ /dev/null
@@ -1,1513 +0,0 @@
-/**
- * Navit, a modular navigation system.
- * Copyright (C) 2005-2008 Navit Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA  02110-1301, USA.
- */
-
-#include <glib.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include "config.h"
-#include "plugin.h"
-#include "data.h"
-#include "projection.h"
-#include "map.h"
-#include "maptype.h"
-#include "item.h"
-#include "attr.h"
-#include "coord.h"
-#include "transform.h"
-#include <stdio.h>
-#include "attr.h"
-#include "coord.h"
-
-struct file {
-       FILE *f;
-       int offset;
-};
-
-
-int shift=5;
-int subdiv_next=0x10;
-
-
-static void *
-file_read(struct file *f, int offset, int size)
-{
-       void *ptr;
-       int ret;
-
-       ptr=calloc(size, 1);
-       if (! ptr)
-               return ptr;
-       fseek(f->f, f->offset+offset, SEEK_SET);
-       ret=fread(ptr, size, 1, f->f);
-       if (ret != 1) {
-               printf("fread %d vs %d offset %d+%d(0x%x)\n", ret, size, f->offset, offset,offset);
-               g_assert(1==0);
-       }
-       return ptr;
-}
-
-static void
-file_free(void *ptr)
-{
-       free(ptr);
-}
-
-struct offset_len {
-       int offset;
-       int length;
-} __attribute ((packed));
-
-static void
-dump_offset_len(struct offset_len *off_len)
-{
-       printf("offset: 0x%x(%d) length 0x%x(%d)\n", off_len->offset, off_len->offset, off_len->length, off_len->length);
-}
-
-struct timestamp {
-       short creation_year;
-       char creation_month;
-       char creation_day;
-       char creation_hour;
-       char creation_minute;
-       char creation_second;
-} __attribute__((packed));
-
-struct img_header {
-       char xor;
-       char zero1[9];
-       char update_month;
-       char update_year;
-       char zero2[3];
-       char checksum[1];
-       char signature[7];
-       char unknown1[1];
-       char unknown2[2];
-       char unknown3[2];
-       char unknown4[2];
-       char unknown5[2];
-       char zero3[25];
-       struct timestamp ts;
-       char unknown6;
-       char map_file_identifier[7];
-       char unknown12;
-       char map_description1[20];
-       short unknown13;
-       short unknown14;
-       char e1;
-       char e2;
-       char other[413];
-       char zero4[512];
-       char unknown7;
-       char unknown8[11];
-       int file_offset;
-       char unknown9;
-       char unknown10[15];
-       char unknown11[480];
-} __attribute__((packed));
-
-static void
-dump_ts(struct timestamp *ts)
-{
-       printf("%d-%02d-%02d %02d:%02d:%02d\n", ts->creation_year, ts->creation_month, ts->creation_day, ts->creation_hour, ts->creation_minute, ts->creation_second);
-}
-
-#if 0
-static void
-dump_img(struct img_header *img_hdr)
-{
-       printf("signature: '%s'\n", img_hdr->signature);
-       printf("creation: ");
-       dump_ts(&img_hdr->ts);
-       printf("map_file_identifier: '%s'\n", img_hdr->map_file_identifier);
-       printf("file_offset: 0x%x\n", img_hdr->file_offset);
-       printf("e1: 0x%x(%d)\n", img_hdr->e1, img_hdr->e1);
-       printf("e2: 0x%x(%d)\n", img_hdr->e2, img_hdr->e2);
-       printf("offset 0x%x\n", (int) &img_hdr->e1 - (int) img_hdr);
-       printf("size %d\n", sizeof(*img_hdr));
-}
-#endif
-
-struct fat_block {
-       char flag;
-       char filename[8];
-       char type[3];
-       int size;
-       char zero1;
-       char part;
-       char zero[14];
-       unsigned short blocks[240];
-} __attribute__((packed));
-
-#if 0
-static void
-dump_fat_block(struct fat_block *fat_blk)
-{
-       int i=0;
-       char name[9];
-       char type[4];
-       printf("flag: 0x%x(%d)\n", fat_blk->flag, fat_blk->flag);
-       strcpy(name, fat_blk->filename);
-       name[8]='\0';
-       strcpy(type, fat_blk->type);
-       type[3]='\0';
-       printf("name: '%s.%s'\n", name, type);
-       printf("size: 0x%x(%d)\n", fat_blk->size, fat_blk->size);
-       printf("part: 0x%x(%d)\n", fat_blk->part, fat_blk->part);
-       printf("blocks: ");
-       while (i < 240) {
-               printf("0x%x(%d) ",fat_blk->blocks[i], fat_blk->blocks[i]);
-               if (fat_blk->blocks[i] == 0xffff)
-                       break;
-               i++;
-       }
-       printf("size: %d\n", sizeof(*fat_blk));
-       
-}
-#endif
-
-struct file_header {
-       short header_len;
-       char type[10];
-       char unknown1;
-       char unknown2;
-       struct timestamp ts;
-} __attribute__((packed));
-
-static void
-dump_file(struct file_header *fil_hdr)
-{
-       printf("header_len: %d\n", fil_hdr->header_len);
-       printf("type: '%s'\n", fil_hdr->type);
-       printf("unknown1: 0x%x(%d)\n", fil_hdr->unknown1, fil_hdr->unknown1);
-       printf("unknown2: 0x%x(%d)\n", fil_hdr->unknown2, fil_hdr->unknown2);
-       printf("creation: ");
-       dump_ts(&fil_hdr->ts);
-       printf("size %d\n", sizeof(*fil_hdr));
-}
-
-struct region_header {
-       struct file_header fil_hdr;
-       struct offset_len offset_len;
-} __attribute__((packed));
-
-#if 0
-static void
-dump_region(struct region_header *rgn_hdr)
-{
-       dump_offset_len(&rgn_hdr->offset_len);
-}
-#endif
-
-struct map_priv {
-       int id;
-       char *filename;
-};
-
-struct map_rect_priv {
-       struct coord_rect r;
-       int limit;
-
-       struct file tre;
-       struct tree_header *tre_hdr;
-       struct file rgn;
-       struct region_header *rgn_hdr;
-       struct file lbl;
-       struct label_header *lbl_hdr;
-       char *label;
-
-       int subdiv_level_count;
-       int subdiv_pos;
-       char *subdiv;
-
-       int rgn_offset;
-       int rgn_end;
-       struct rgn_point *pnt;
-       struct rgn_poly *ply;
-       unsigned char *ply_data;
-       int ply_bitpos;
-       int ply_bitcount;
-       int ply_lngbits;
-       int ply_latbits;
-       int ply_lng;
-       int ply_lat;
-       int ply_lnglimit;
-       int ply_latlimit;
-       int ply_lngsign;
-       int ply_latsign;
-       struct offset_len rgn_items[4];
-       int rgn_type;
-
-       int count;
-
-       FILE *f;
-       long pos;
-       char line[256];
-       int attr_pos;
-       enum attr_type attr_last;
-       char attrs[256];
-       char attr[256];
-       double lat,lng;
-       char lat_c,lng_c;
-       int eoc;
-       struct map_priv *m;
-       struct item item;
-};
-
-static int map_id;
-
-static int
-contains_coord(char *line)
-{
-       return g_ascii_isdigit(line[0]);
-}
-
-static int debug=1;
-
-static int
-get_tag(char *line, char *name, int *pos, char *ret)
-{
-       int len,quoted;
-       char *p,*e,*n;
-
-       if (debug)
-               printf("get_tag %s from %s\n", name, line); 
-       if (! name)
-               return 0;
-       len=strlen(name);
-       if (pos) 
-               p=line+*pos;
-       else
-               p=line;
-       for(;;) {
-               while (*p == ' ') {
-                       p++;
-               }
-               if (! *p)
-                       return 0;
-               n=p;
-               e=index(p,'=');
-               if (! e)
-                       return 0;
-               p=e+1;
-               quoted=0;
-               while (*p) {
-                       if (*p == ' ' && !quoted)
-                               break;
-                       if (*p == '"')
-                               quoted=1-quoted;
-                       p++;
-               }
-               if (e-n == len && !strncmp(n, name, len)) {
-                       e++;
-                       len=p-e;
-                       if (e[0] == '"') {
-                               e++;
-                               len-=2;
-                       }
-                       strncpy(ret, e, len);
-                       ret[len]='\0';
-                       if (pos)
-                               *pos=p-line;
-                       return 1;
-               }
-       }       
-       return 0;
-}
-
-static void
-get_line(struct map_rect_priv *mr)
-{
-       mr->pos=ftell(mr->f);
-       fgets(mr->line, 256, mr->f);
-}
-
-static void
-map_destroy_garmin_img(struct map_priv *m)
-{
-       if (debug)
-               printf("map_destroy_garmin_img\n");
-       g_free(m);
-}
-
-static char *
-map_charset_garmin_img(struct map_priv *m)
-{
-       return "iso8859-1";
-}
-
-static enum projection
-map_projection_garmin_img(struct map_priv *m)
-{
-       return projection_garmin;
-}
-
-struct label_data_offset {
-       struct offset_len offset_len;
-       char multiplier;
-       char data;
-} __attribute ((packed));
-
-#if 0
-static void
-dump_label_data_offset(struct label_data_offset *lbl_dat)
-{
-       dump_offset_len(&lbl_dat->offset_len);
-       printf("multiplier 0x%x(%d)\n", lbl_dat->multiplier, lbl_dat->multiplier);
-       printf("data 0x%x(%d)\n", lbl_dat->data, lbl_dat->data);
-}
-#endif
-
-struct label_data {
-       struct offset_len offset_len;
-       short size;
-       int zero;
-} __attribute ((packed));
-
-static void
-dump_label_data(struct label_data *lbl_dat)
-{
-       dump_offset_len(&lbl_dat->offset_len);
-       printf("size 0x%x(%d)\n", lbl_dat->size, lbl_dat->size);
-}
-
-struct tree_header {
-       struct file_header fil_hdr;
-       char boundary[12];
-       struct offset_len level;
-       struct offset_len subdivision;
-       struct label_data copyright;
-       struct offset_len tre7;
-       short unknown1;
-       char zero1;
-       struct label_data polyline;
-       struct label_data polygon;
-       struct label_data point;
-       int mapid;
-};
-
-static void
-dump_tree_header(struct tree_header *tre_hdr)
-{
-       printf("tree_header:\n");
-       dump_file(&tre_hdr->fil_hdr);
-       printf("level: "); dump_offset_len(&tre_hdr->level);
-       printf("subdivision: "); dump_offset_len(&tre_hdr->subdivision);
-       printf("copyright: "); dump_label_data(&tre_hdr->copyright);
-       printf("polyline: "); dump_label_data(&tre_hdr->polyline);
-       printf("polygon: "); dump_label_data(&tre_hdr->polygon);
-       printf("point: "); dump_label_data(&tre_hdr->point);
-       printf("len: 0x%x(%d)\n", sizeof(*tre_hdr), sizeof(*tre_hdr));
-}
-
-struct label_header {
-       struct file_header fil_hdr;
-       struct label_data_offset label;
-       struct label_data country;
-       struct label_data region;
-       struct label_data city;
-       struct label_data poi_index;
-       struct label_data_offset poi_properties;
-       short zero1;
-       char zero2;
-       struct label_data poi_types;
-       struct label_data zip;
-       struct label_data hway;
-       struct label_data exit;
-       struct label_data hway_data;
-       int unknown1;
-       short unknown2;
-       struct offset_len sort_descriptor;
-       struct label_data lbl13;
-       struct label_data lbl14;
-} __attribute((packed));
-
-#if 0
-static void
-dump_label(struct label_header *lbl_hdr)
-{
-       dump_file(&lbl_hdr->fil_hdr);
-       printf("label:\n");
-       dump_label_data_offset(&lbl_hdr->label);
-       printf("country:\n");
-       dump_label_data(&lbl_hdr->country);
-       printf("region:\n");
-       dump_label_data(&lbl_hdr->region);
-       printf("city:\n");
-       dump_label_data(&lbl_hdr->city);
-       printf("poi_index:\n");
-       dump_label_data(&lbl_hdr->poi_index);
-       printf("poi_properties:\n");
-       dump_label_data_offset(&lbl_hdr->poi_properties);
-       printf("poi_types:\n");
-       dump_label_data(&lbl_hdr->poi_types);
-       printf("zip:\n");
-       dump_label_data(&lbl_hdr->zip);
-       printf("hway:\n");
-       dump_label_data(&lbl_hdr->hway);
-       printf("exit:\n");
-       dump_label_data(&lbl_hdr->exit);
-       printf("hway_data:\n");
-       dump_label_data(&lbl_hdr->hway_data);
-       printf("lbl13:\n");
-       dump_label_data(&lbl_hdr->lbl13);
-       printf("lbl14:\n");
-       dump_label_data(&lbl_hdr->lbl14);
-       printf("len: 0x%x(%d)\n", sizeof(*lbl_hdr), sizeof(*lbl_hdr));
-}
-#endif
-
-struct triple {
-       unsigned char data[3];
-} __attribute((packed));
-
-static unsigned int
-triple_u(struct triple *t)
-{
-       return t->data[0] | (t->data[1] << 8)  | (t->data[2] << 16);
-}
-
-static int
-triple(struct triple *t)
-{
-       int ret=t->data[0] | (t->data[1] << 8)  | (t->data[2] << 16);
-       if (ret > 1<<23)
-               ret=ret-(1<<24);
-       return ret;
-}
-
-static void
-dump_triple_u(struct triple *t)
-{
-       int val=triple_u(t);
-       printf("0x%x(%d)\n", val, val);
-}
-
-struct tcoord {
-       struct triple lng,lat;
-} __attribute((packed));
-
-static void
-dump_tcoord(struct tcoord *t)
-{
-       printf ("0x%x(%d),0x%x(%d)\n", triple_u(&t->lng), triple_u(&t->lng), triple_u(&t->lat), triple_u(&t->lat));
-}
-
-struct level {
-       unsigned char zoom;
-       unsigned char bits_per_coord;
-       unsigned short subdivisions;
-} __attribute((packed));
-
-static void
-dump_level(struct level *lvl)
-{
-       printf("level:\n");
-       printf("\tzoom 0x%x(%d)\n", lvl->zoom, lvl->zoom);
-       printf("\tbits_per_coord 0x%x(%d)\n", lvl->bits_per_coord, lvl->bits_per_coord);
-       printf("\tsubdivisions 0x%x(%d)\n", lvl->subdivisions, lvl->subdivisions);
-}
-
-struct subdivision {
-       struct triple rgn_offset;
-       unsigned char types;
-       struct tcoord center;
-       unsigned short width;
-       unsigned short height;
-       unsigned short next; 
-} __attribute((packed));
-
-static void
-dump_subdivision(struct subdivision *sub)
-{
-       printf("subdivision:\n");
-       printf("\trgn_offset: "); dump_triple_u(&sub->rgn_offset);
-       printf("\ttypes: 0x%x(%d)\n", sub->types, sub->types);
-       printf("\tcenter: "); dump_tcoord(&sub->center);
-       printf("\tsize: 0x%x(%d)x0x%x(%d) %s\n",sub->width & 0x7fff, sub->width & 0x7fff, sub->height, sub->height, sub->width & 0x8000 ? "Terminating" : "");
-       printf("\tnext: 0x%x(%d)\n",sub->next, sub->next);
-       
-       printf("\tlen: 0x%x(%d)\n", sizeof(*sub), sizeof(*sub));
-}
-
-struct rgn_point {
-       unsigned char info;
-       struct triple lbl_offset;
-       short lng_delta;
-       short lat_delta;
-       unsigned char subtype;
-} __attribute((packed));
-
-static void
-dump_point(struct rgn_point *pnt)
-{
-       printf("point:\n");
-       printf("\tinfo 0x%x(%d)\n", pnt->info, pnt->info);
-       printf("\tlbl_offset 0x%x(%d)\n", triple_u(&pnt->lbl_offset), triple_u(&pnt->lbl_offset));
-       printf("\tlng_delta 0x%x(%d)\n", pnt->lng_delta, pnt->lng_delta);
-       printf("\tlat_delta 0x%x(%d)\n", pnt->lat_delta, pnt->lat_delta);
-       printf("\tsubtype 0x%x(%d)\n", pnt->subtype, pnt->subtype);
-       printf("\tlen: 0x%x(%d)\n", sizeof(*pnt), sizeof(*pnt));
-}
-
-struct rgn_poly {
-       unsigned char info;
-       struct triple lbl_offset;
-       short lng_delta;
-       short lat_delta;
-       union {
-               struct {
-                       unsigned char bitstream_len;
-                       unsigned char bitstream_info;
-               } __attribute((packed)) p1;
-               struct {
-                       unsigned short bitstream_len;
-                       unsigned char bitstream_info;
-               } __attribute((packed)) p2;
-       } __attribute((packed)) u;
-} __attribute((packed));
-
-static void
-dump_poly(struct rgn_poly *ply)
-{
-       printf("poly:\n");
-       printf("\tinfo 0x%x(%d)\n", ply->info, ply->info);
-       printf("\tlbl_offset 0x%x(%d)\n", triple_u(&ply->lbl_offset), triple_u(&ply->lbl_offset));
-       printf("\tlng_delta 0x%x(%d)\n", ply->lng_delta, ply->lng_delta);
-       printf("\tlat_delta 0x%x(%d)\n", ply->lat_delta, ply->lat_delta);
-       if (ply->info & 0x80) {
-               printf("\tbitstream_len 0x%x(%d)\n", ply->u.p2.bitstream_len, ply->u.p2.bitstream_len);
-               printf("\tbitstream_info 0x%x(%d)\n", ply->u.p2.bitstream_info, ply->u.p2.bitstream_info);
-       } else {
-               printf("\tbitstream_len 0x%x(%d)\n", ply->u.p1.bitstream_len, ply->u.p1.bitstream_len);
-               printf("\tbitstream_info 0x%x(%d)\n", ply->u.p1.bitstream_info, ply->u.p1.bitstream_info);
-       }
-       printf("\tlen: 0x%x(%d)\n", sizeof(*ply), sizeof(*ply));
-}
-
-static void
-dump_hex(void *ptr, int len)
-{
-       unsigned char *c=ptr;
-       while (len--) {
-               printf("%02x ", *c++);
-       }
-       printf("\n");
-}
-
-static void
-dump_hex_r(void *ptr, int len, int rec)
-{
-       unsigned char *c=ptr;
-       int l=rec;
-       while (len--) {
-               printf("%02x ", *c++);
-               if (! --l) {
-                       printf("\n");
-                       l=rec;
-               }
-       }
-       printf("\n");
-}
-
-#if 0
-static void
-dump_label_offset(struct map_rect_priv *mr, int offset)
-{
-       void *p;
-       p=file_read(&mr->lbl, mr->lbl_hdr->label.offset_len.offset+offset, 128);
-       printf("%s\n", (char *)p);
-}
-#endif
-
-
-#if 0
-static void
-dump_region_item(struct subdivision *sub, struct file *rgn, struct map_rect_priv *mr)
-{
-       int offset,item_offset,i,j;
-       unsigned short count=0;
-       unsigned short *offsets[4];
-       unsigned short *file_offsets;
-       struct rgn_point *pnt;
-
-       offset=triple_u(&sub->rgn_offset)+mr->rgn_hdr->offset_len.offset;
-       file_offsets=file_read(rgn, offset, 90*sizeof(unsigned short));
-       printf("0x%x ", offset); dump_hex(file_offsets, 90);
-       for (i=0 ; i < 4 ; i++) {
-               printf("i=%d\n", i);
-               if (sub->types & (0x10 << i)) {
-                       if (count) {    
-                               offsets[i]=&file_offsets[count-1];
-                       } else
-                               offsets[i]=&count;
-                       count++;
-               } else
-                       offsets[i]=NULL;
-               
-       }
-       count--;
-       count*=2;
-       for (i=0 ; i < 4 ; i++) {
-               printf("i=%d\n", i);
-               if (offsets[i]) {
-                       printf("offset[%d]=0x%x(%d)\n", i, *offsets[i], *offsets[i]);
-                       switch (i) {
-                       case 0:
-                               printf("point\n");
-                               break;
-                       case 1:
-                               printf("indexed point\n");
-                               break;
-                       case 2:
-                               printf("polyline\n");
-                               break;
-                       case 3:
-                               printf("polygon\n");
-                               break;
-                       }
-                       item_offset=offset+*offsets[i];
-                       switch (i) {
-                       case 0:
-                       case 1:
-                               for (j = 0 ; j < 10 ; j++) {
-                                       struct coord_geo g;
-                                       char buffer[1024];
-                                       double conv=180.0/(1UL<<23);
-                                       pnt=file_read(rgn, item_offset, sizeof(*pnt)*20);
-                                       // printf("0x%x ", item_offset); dump_hex(pnt, 32);
-                                       dump_point(pnt);
-                                       g.lng=(triple(&sub->center.lng)+(pnt->lng_delta << shift))*conv;
-                                       g.lat=(triple(&sub->center.lat)+(pnt->lat_delta << shift))*conv;
-                                       printf("%f %f\n", g.lng, g.lat);
-                                       coord_format(g.lat,g.lng,DEGREES_MINUTES_SECONDS,
-                                                    buffer,sizeof(buffer));
-                                       printf("%s\n", buffer);
-                                       dump_label_offset(mr, triple_u(&pnt->lbl_offset));
-                                       if (pnt->info & 0x80) 
-                                               item_offset+=sizeof(*pnt);
-                                       else
-                                               item_offset+=sizeof(*pnt)-1;
-                               }
-                       }
-               } else {
-                       printf("offset[%d] doesn't exist\n", i);
-               }
-       }
-       file_free(file_offsets);
-}
-
-#endif
-
-static void
-dump_levels(struct map_rect_priv *mr)
-{
-       int i,offset;
-       struct level *lvl;
-
-       offset=mr->tre_hdr->level.offset;
-       for (i = 0 ; i < mr->tre_hdr->level.length/sizeof(*lvl) ; i++) {
-               lvl=file_read(&mr->tre, offset, sizeof(*lvl));
-               dump_level(lvl);
-               offset+=sizeof(*lvl);
-       }
-}
-
-#if 0
-static void
-dump_tree(struct file *f, struct file *rgn, struct map_rect_priv *mr)
-{
-       struct tree_header *tre_hdr;
-       struct subdivision *sub;
-       int i,offset;
-
-       tre_hdr=file_read(f, 0, sizeof(*tre_hdr));
-       dump_tree_header(tre_hdr);
-       offset=tre_hdr->subdivision.offset;
-       sub=file_read(f, offset, sizeof(*sub));
-       dump_subdivision(sub);
-       offset+=sizeof(*sub);
-       for (i = 1 ; i < tre_hdr->subdivision.length/sizeof(*sub) ; i++) {
-               printf("i=%d\n", i);
-               sub=file_read(f, offset, sizeof(*sub));
-               dump_subdivision(sub);
-               dump_region_item(sub, rgn, mr);
-               if (sub->width & 0x8000)
-                       break;          
-               offset+=sizeof(*sub);
-       }
-       file_free(tre_hdr);
-}
-#endif
-
-#if 0
-static void
-dump_labels(struct file *f)
-{
-       struct label_header *lbl_hdr;
-       
-       lbl_hdr=file_read(f, 0, sizeof(*lbl_hdr));
-       printf("**labels**\n");
-       dump_label(lbl_hdr);
-       file_free(lbl_hdr);
-#if 0
-       labels=alloca(lbl_hdr.label_length);
-       file_read(f, lbl_hdr.label_offset, labels, lbl_hdr.label_length);
-       l=labels;
-       while (l < labels+lbl_hdr.label_length) {
-               printf("'%s'(%d)\n", l, strlen(l));
-               l+=strlen(l)+1;
-       }
-#endif
-       
-}
-#endif
-
-static void
-garmin_img_coord_rewind(void *priv_data)
-{
-}
-
-static void
-parse_line(struct map_rect_priv *mr)
-{
-       int pos=0;
-       sscanf(mr->line,"%lf %c %lf %c %n",&mr->lat,&mr->lat_c,&mr->lng,&mr->lng_c,&pos);
-       if (pos < strlen(mr->line)) {
-               strcpy(mr->attrs, mr->line+pos);
-       }
-}
-
-static int
-get_bits(struct map_rect_priv *mr, int bits)
-{
-       unsigned long ret;
-       ret=L(*((unsigned long *)(mr->ply_data+mr->ply_bitpos/8)));
-       ret >>= (mr->ply_bitpos & 7);
-       ret &= (1 << bits)-1;
-       mr->ply_bitpos+=bits;
-       return ret;
-}
-
-static int
-garmin_img_coord_get(void *priv_data, struct coord *c, int count)
-{
-       struct map_rect_priv *mr=priv_data;
-       struct subdivision *sub=(struct subdivision *)(mr->subdiv+mr->subdiv_pos);
-       int ret=0;
-       int debug=0;
-       if (debug)
-               printf("garmin_img_coord_get %d\n",count);
-       if (debug)
-               dump_subdivision(sub);
-       while (count--) {
-               if (mr->rgn_type < 2) {
-                       c->x=triple(&sub->center.lng)+(mr->pnt->lng_delta << shift);
-                       c->y=triple(&sub->center.lat)+(mr->pnt->lat_delta << shift);
-               } else {
-                       if (! mr->ply_bitpos) {
-                               if (mr->ply->info & 0x80) {
-                                       mr->ply_bitcount=mr->ply->u.p2.bitstream_len*8;
-                                       mr->ply_lngbits=mr->ply->u.p2.bitstream_info & 0xf;
-                                       mr->ply_latbits=mr->ply->u.p2.bitstream_info >> 4;
-                               } else {
-                                       mr->ply_bitcount=mr->ply->u.p1.bitstream_len*8;
-                                       mr->ply_lngbits=mr->ply->u.p1.bitstream_info & 0xf;
-                                       mr->ply_latbits=mr->ply->u.p1.bitstream_info >> 4;
-                               }
-                               if (mr->ply_lngbits <= 9)
-                                       mr->ply_lngbits+=2;
-                               if (mr->ply_latbits <= 9)
-                                       mr->ply_latbits+=2;
-                               if (! get_bits(mr,1)) {
-                                       mr->ply_lngbits+=1;
-                                       mr->ply_lngsign=0;
-                               } else  
-                                       if (get_bits(mr, 1))
-                                               mr->ply_lngsign=-1;
-                                       else
-                                               mr->ply_lngsign=1;
-                               if (! get_bits(mr,1)) {
-                                       mr->ply_latbits+=1;
-                                       mr->ply_latsign=0;
-                               } else
-                                       if (get_bits(mr, 1))
-                                               mr->ply_latsign=-1;
-                                       else
-                                               mr->ply_latsign=1;
-                               mr->ply_lnglimit=1 << (mr->ply_lngbits-1);
-                               mr->ply_latlimit=1 << (mr->ply_latbits-1);
-                               mr->ply_lng=mr->ply->lng_delta;
-                               mr->ply_lat=mr->ply->lat_delta;
-                               if (debug)
-                                       printf("lngbits %d latbits %d bitcount %d\n", mr->ply_lngbits, mr->ply_latbits, mr->ply_bitcount);
-                               c->x=0;
-                               c->y=0;
-                       } else {
-                       if (mr->ply_bitpos + mr->ply_lngbits + mr->ply_latbits > mr->ply_bitcount) {
-                               if (debug)
-                                       printf("out of bits %d + %d + %d >= %d\n", mr->ply_bitpos, mr->ply_lngbits, mr->ply_latbits, mr->ply_bitcount);
-                               return ret;
-                       }
-                       c->x=0;
-                       c->y=0;
-                       int x,y;
-                       for (;;) {
-                               x=get_bits(mr,mr->ply_lngbits);
-                               if (debug)
-                                       printf("x %d ", x);
-                               if (mr->ply_lngsign || x != mr->ply_lnglimit)
-                                       break;
-                               c->x += x-1;
-                       }
-                       if (mr->ply_lngsign) {
-                               c->x=x*mr->ply_lngsign;
-                       } else {
-                               if (x >= mr->ply_lnglimit) 
-                                       c->x = x - (mr->ply_lnglimit << 1) - c->x;
-                               else
-                                       c->x +=x;
-                       }
-                       for (;;) {
-                               y=get_bits(mr,mr->ply_latbits);
-                               if (debug)
-                                       printf("y %d ", y);
-                               if (mr->ply_latsign || y != mr->ply_latlimit)
-                                       break;
-                               c->y += y-1;
-                       }
-                       if (mr->ply_latsign) {
-                               c->y=y*mr->ply_latsign;
-                       } else {
-                               if (y >= mr->ply_latlimit) 
-                                       c->y = y - (mr->ply_latlimit << 1) - c->y;
-                               else
-                                       c->y +=y;
-                       }
-                       mr->ply_lng += c->x;
-                       mr->ply_lat += c->y;
-                       }
-                       if (debug)
-                               printf(": x %d y %d\n", c->x, c->y);
-               
-                       c->x=triple(&sub->center.lng)+(mr->ply_lng << shift);
-                       c->y=triple(&sub->center.lat)+(mr->ply_lat << shift);
-               }
-#if 0
-               c->x-=0x6f160;
-                c->y-=0x181f59;
-               c->x+=0x168ca1;
-               c->y+=0x68d815;
-#endif
-               c++;
-               ret++;          
-               if (mr->rgn_type < 2)
-                       return ret;
-       }
-       return ret;
-}
-
-static char * 
-get_label_offset(struct map_rect_priv *mr, int offset)
-{
-       g_assert(offset < mr->lbl_hdr->label.offset_len.length);
-       return file_read(&mr->lbl, mr->lbl_hdr->label.offset_len.offset+offset, 128);
-}
-
-static void
-garmin_img_attr_rewind(void *priv_data)
-{
-}
-
-static int
-garmin_img_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
-{      
-       struct map_rect_priv *mr=priv_data;
-       int debug=0;
-
-       if (debug)
-               printf("garmin_img_attr_get\n");
-       if (attr_type == attr_label) {
-               if (debug)
-                       printf("garmin_img_attr_get label\n");
-               attr->type=attr_type;
-               if (mr->rgn_type < 2) {
-                       if (mr->label) 
-                               file_free(mr->label);
-                       mr->label=get_label_offset(mr, triple_u(&mr->pnt->lbl_offset) & 0x3fffff);
-                       attr->u.str=mr->label;
-               } else {
-                       attr->u.str="";
-               }
-               return 1;
-       }
-       return 0;
-}
-
-static struct item_methods methods_garmin_img = {
-        garmin_img_coord_rewind,
-        garmin_img_coord_get,
-        garmin_img_attr_rewind,
-        garmin_img_attr_get,
-};
-
-static int rgn_next_type(struct map_rect_priv *mr)
-{
-       while (mr->rgn_type < 3) {
-               mr->rgn_type++;
-               if (mr->rgn_items[mr->rgn_type].offset && mr->rgn_items[mr->rgn_type].length != 0) {
-                       mr->rgn_offset=mr->rgn_items[mr->rgn_type].offset;
-                       mr->rgn_end=mr->rgn_offset+mr->rgn_items[mr->rgn_type].length;
-                       return 0;
-               }
-       }
-       return 1;
-}
-
-static int
-sub_next(struct map_rect_priv *mr, int next)
-{
-       int i,offset,first=-1,last=-1,count=-1;
-       int end;
-       unsigned short *offsets;
-       int debug=0;
-
-       if (mr->subdiv_level_count <= 0)
-               return 1;
-       if (debug)
-               printf("%d left\n", mr->subdiv_level_count);
-       mr->subdiv_level_count--;
-               
-#if 0
-       if (next && mr->subdiv[mr->subdiv_current].width & 0x8000)
-               return 1;
-#endif
-       if (debug) 
-               dump_hex_r(mr->subdiv+mr->subdiv_pos, 64, 14);
-       mr->subdiv_pos+=next;
-       if (debug)
-               printf("subdiv_pos 0x%x\n", mr->subdiv_pos);
-       if (mr->subdiv_pos > mr->tre_hdr->subdivision.length)
-               return 1;
-       struct subdivision *sub=(struct subdivision *)(mr->subdiv+mr->subdiv_pos);
-       offset=triple_u(&sub->rgn_offset)+mr->rgn_hdr->offset_len.offset;
-       if (debug) {
-               printf("offset=0x%x\n", offset);
-               dump_subdivision(sub);
-       }
-       offsets=file_read(&mr->rgn, offset, 3*sizeof(unsigned short));
-
-       if (! next)
-               next=subdiv_next;
-       if (mr->subdiv_pos+next < mr->tre_hdr->subdivision.length) 
-               end=triple_u(&((struct subdivision *)(mr->subdiv+mr->subdiv_pos+next))->rgn_offset)+mr->rgn_hdr->offset_len.offset;
-       else
-               end=mr->rgn_hdr->offset_len.offset+mr->rgn_hdr->offset_len.length;
-       if (debug) {
-               dump_subdivision(sub);
-               dump_hex(offsets, 6);
-       }
-       for (i=0 ; i < 4 ; i++) {
-               if (debug)
-                       printf("i=%d ", i);
-               if (sub->types & (0x10 << i)) {
-                       if (debug)
-                               printf("+ ");
-                       if (first == -1) {
-                               first=i;
-                               mr->rgn_items[i].offset=offset;
-                               if (debug)
-                                       printf("\n");
-                       } else {
-                               mr->rgn_items[i].offset=offset+offsets[count];
-                               if (debug)
-                                       printf("0x%x\n", offsets[count]);
-                               mr->rgn_items[last].length=mr->rgn_items[i].offset-mr->rgn_items[last].offset;
-                       }
-                       last=i;
-                       count++;
-               } else {
-                       if (debug)
-                               printf("-\n");
-                       mr->rgn_items[i].offset=0;
-                       mr->rgn_items[i].length=0;
-               }
-               
-       }
-       if (first != -1) {
-               mr->rgn_items[first].offset+=count*2;
-               mr->rgn_items[first].length-=count*2;
-               mr->rgn_items[last].length=end-mr->rgn_items[last].offset;
-       }
-       if (debug) {
-               for (i=0 ; i < 4 ; i++) {
-                       printf("%d 0x%x 0x%x\n", i, mr->rgn_items[i].offset, mr->rgn_items[i].length);
-               }
-       }
-       mr->rgn_type=-1;
-       rgn_next_type(mr);
-       if (debug)
-               printf("*** offset 0x%x\n", mr->rgn_offset);
-       file_free(offsets);
-       return 0;               
-}
-
-int item_count;
-
-static struct map_rect_priv *
-map_rect_new_garmin_img(struct map_priv *map, struct coord_rect *r, struct layer *layers, int limit)
-{
-       struct map_rect_priv *mr;
-       struct img_header img;
-
-       if (debug)
-               printf("map_rect_new_garmin_img\n");
-       mr=g_new0(struct map_rect_priv, 1);
-       mr->m=map;
-       if (r) 
-               mr->r=*r;
-       mr->limit=limit;
-       mr->item.id_hi=0;
-       mr->item.id_lo=0;
-       mr->item.meth=&methods_garmin_img;
-       mr->item.priv_data=mr;
-       mr->f=fopen(map->filename, "r");
-       
-       fread(&img, sizeof(img), 1, mr->f);
-#if 0
-       dump_img(&img);
-       for (i = 0 ; i < (img.file_offset-sizeof(img))/sizeof(fat_blk) ; i++) {
-               fread(&fat_blk, sizeof(fat_blk), 1, mr->f);
-               if (!fat_blk.flag)
-                       break;
-               dump_fat_block(&fat_blk);
-       }
-#endif
-       mr->rgn.offset=0xa*2048;
-       mr->rgn.f=mr->f;
-       mr->rgn_hdr=file_read(&mr->rgn, 0, sizeof(*mr->rgn_hdr));
-
-       mr->tre.offset=0x62b*2048;
-       mr->tre.f=mr->f;
-       mr->tre_hdr=file_read(&mr->tre, 0, sizeof(*mr->tre_hdr));
-
-       mr->lbl.offset=0x64a*2048;
-       mr->lbl.f=mr->f;
-       mr->lbl_hdr=file_read(&mr->lbl, 0, sizeof(*mr->lbl_hdr));
-
-       mr->subdiv=file_read(&mr->tre, mr->tre_hdr->subdivision.offset, mr->tre_hdr->subdivision.length);
-#if 0
-       dump_hex_r(mr->subdiv, mr->tre_hdr->subdivision.length, 16);
-#endif
-       dump_tree_header(mr->tre_hdr);
-
-       dump_levels(mr);
-
-
-       printf("limit=%d\n", limit);
-       if (limit < 3) {
-               mr->subdiv_pos=0; 
-               mr->subdiv_level_count=1;
-               shift=11;
-       } else if (limit < 6) {
-               mr->subdiv_pos=1*sizeof(struct subdivision); 
-               mr->subdiv_level_count=5;
-               shift=9;
-       } else if (limit < 8) {
-               mr->subdiv_pos=6*sizeof(struct subdivision); 
-               mr->subdiv_level_count=9;
-               shift=7;
-       } else if (limit < 10) {
-               mr->subdiv_pos=15*sizeof(struct subdivision); 
-               mr->subdiv_level_count=143;
-               shift=5;
-       } else {
-               mr->subdiv_pos=158*sizeof(struct subdivision); 
-               mr->subdiv_level_count=4190;
-               shift=2;
-               subdiv_next=14;
-       }
-
-#if 0
-       mr->rgn_offset=triple_u(&mr->subdiv[mr->subdiv_current].rgn_offset)+mr->rgn_hdr->offset_len.offset+4;
-       mr->rgn_type=1;
-       mr->rgn_end=mr->rgn_offset+20*8;
-#endif
-       mr->count=0;
-       item_count=0;
-
-#if 0
-       printf("*** offset 0x%x\n", 0x656c-mr->rgn.offset);
-       printf("*** offset 0x%x\n", mr->rgn_offset);
-#endif
-#if 1
-       sub_next(mr, 0);
-#endif
-#if 0
-       {
-               struct rgn_point *pnt;
-               int i;
-               int offset=0x65cc;
-               for (i = 0 ; i < 26 ; i++) {
-                       pnt=file_read(&mr->rgn, 0x656c+8*i-mr->rgn.offset, sizeof(*pnt));
-                       // dump_hex(pnt, sizeof(*pnt));
-                       dump_point(pnt);
-                       dump_label_offset(mr, triple_u(&pnt->lbl_offset));
-               }
-       }
-       exit(0);
-#endif
-#if 0
-       dump_tree(&mr->tre,&mr->rgn,mr);
-#endif
-
-#if 0
-       f.offset=0x64a*2048;
-       f.f=mr->f;
-       dump_labels(&f);
-#endif
-#if 0
-       fseek(mr->f, img.file_offset, SEEK_SET);
-       fread(&fil, sizeof(fil), 1, mr->f);
-       dump_file(&fil);
-       fread(&rgn, sizeof(rgn), 1, mr->f);
-       dump_region(&rgn);
-       fseek(mr->f, rgn.data_length, SEEK_CUR);
-       fread(&fil, sizeof(fil), 1, mr->f);
-       dump_file(&fil);
-#endif
-       return mr;
-}
-
-
-static void
-map_rect_destroy_garmin_img(struct map_rect_priv *mr)
-{
-       fclose(mr->f);
-        g_free(mr);
-}
-
-
-static struct item *
-map_rect_get_item_garmin_img(struct map_rect_priv *mr)
-{
-       char *p,type[256];
-       int ptype;
-       int debug=0;
-
-       item_count++;
-
-       if (debug)
-               printf("map_rect_get_item_garmin_img\n");
-       for (;;) {
-               if (mr->rgn_offset < mr->rgn_end) {
-                       if (debug)
-                               printf("data available\n");
-                       if (mr->rgn_type >= 2) {
-                               int len;
-                               if (debug)
-                                       printf("polyline %d\n", mr->count);
-                               if (mr->ply)
-                                       file_free(mr->ply);
-                               mr->ply=file_read(&mr->rgn, mr->rgn_offset, sizeof(*mr->ply)*3);
-                               if(triple_u(&mr->ply->lbl_offset) >= mr->lbl_hdr->label.offset_len.length) {
-                                       printf("item_count %d\n", item_count);
-                                       dump_poly(mr->ply);
-                                       dump_hex(mr->ply, 32);
-                                       printf("%d vs %d\n", triple_u(&mr->ply->lbl_offset), mr->lbl_hdr->label.offset_len.length);
-                               }
-                               g_assert(triple_u(&mr->ply->lbl_offset) < mr->lbl_hdr->label.offset_len.length);
-                               if (debug) {
-                                       dump_hex(mr->ply, 16);
-                                       dump_poly(mr->ply);
-                               }
-                               if (mr->ply_data)
-                                       file_free(mr->ply_data);
-                               mr->rgn_offset+=10;
-                               if (mr->ply->info & 0x80) {
-                                       mr->rgn_offset++;
-                                       len=mr->ply->u.p2.bitstream_len;
-                               } else
-                                       len=mr->ply->u.p1.bitstream_len;
-               
-                               mr->ply_data=file_read(&mr->rgn, mr->rgn_offset, len);
-                               mr->rgn_offset += len;
-                               mr->ply_bitpos=0;
-                               // dump_hex(mr->ply_data, 32);
-                               if (mr->rgn_type == 3) {
-                                       switch(mr->ply->info & 0x7f) {
-                                       case 0x1:       /* large urban area (>200k) */
-                                               mr->item.type=type_town_poly;
-                                               break;
-                                       case 0xd:       /* reservation */
-                                               mr->item.type=type_park_poly;
-                                               break;
-                                       case 0xe:       /* airport runway */
-                                               mr->item.type=type_airport_poly;
-                                               break;
-                                       case 0x14:      /* national park */
-                                               mr->item.type=type_park_poly;
-                                               break;
-                                       case 0x32:      /* sea */
-                                       case 0x3d:      /* large lake (77-250km2) */
-                                       case 0x4c:      /* intermittend water */
-                                               mr->item.type=type_water_poly;
-                                               break;
-                                       case 0x4b:      /* background */
-                                               continue;
-                                       default:
-                                               printf("unknown polygon: 0x%x\n", mr->ply->info);
-                                               mr->item.type=type_street_3_city;
-                                       }
-                               } else {
-                                       switch(mr->ply->info & 0x3f) {
-                                       case 0x1:       /* major highway */
-                                               mr->item.type=type_highway_land;
-                                               break;
-                                       case 0x2:       /* principal highway */
-                                               mr->item.type=type_street_3_land;
-                                               break;
-                                       case 0x6:       /* residental street */
-                                               mr->item.type=type_street_2_land;
-                                               break;
-                                       case 0x16:      /* walkway/trail */
-                                               mr->item.type=type_street_1_land;
-                                               break;
-                                       case 0x1e:      /* international boundary */
-                                               mr->item.type=type_border_country;
-                                               break;
-                                       case 0x20:      /* minor land contour 1/10 */
-                                               mr->item.type=type_height_line_1;
-                                               break;
-                                       case 0x21:      /* major land contour 1/2 */
-                                               mr->item.type=type_height_line_2;
-                                               break;
-                                       default:
-                                               printf("unknown polyline: 0x%x\n", mr->ply->info);
-                                               mr->item.type=type_street_3_city;
-                                       }
-                               }
-                               return &mr->item;
-                       } 
-                       if (mr->pnt)
-                               file_free(mr->pnt);
-                       mr->pnt=file_read(&mr->rgn, mr->rgn_offset, sizeof(*mr->pnt));
-                       mr->item.type=type_none;
-                       int subtype=mr->pnt->subtype;
-                       if (mr->pnt->lbl_offset.data[2] & 0x80) 
-                               mr->rgn_offset+=9;
-                       else {
-                               mr->rgn_offset+=8;
-                               subtype=0;
-                       }
-                       switch(mr->pnt->info) {
-                       case 0x3:       /* large city 2-5M */
-                               mr->item.type=type_town_label_2e6;
-                               break;
-                       case 0xa:       /* small city/town 10-20k */
-                               mr->item.type=type_town_label_1e4;
-                               break;
-                       case 0xd:       /* settlement 1-2K  */
-                               mr->item.type=type_town_label_1e3;
-                               break;
-                       case 0x11:      /* settlement less 100 */
-                               mr->item.type=type_town_label_5e1;
-                               break;
-                       case 0x1c:
-                               switch(subtype) {
-                               case 0x01:
-                                       mr->item.type=type_poi_wreck;
-                                       break;
-                               }
-                               break;
-                       case 0x20:
-                               mr->item.type=type_highway_exit;
-                               break;
-                       case 0x25:
-                               mr->item.type=type_poi_toll_booth;
-                               break;
-                       case 0x2b:
-                               switch(subtype) {
-                               case 0x01:
-                                       mr->item.type=type_poi_hotel;
-                                       break;
-                               case 0x03:
-                                       mr->item.type=type_poi_camp_rv;
-                                       break;
-                               }
-                               break;
-                       case 0x2c:
-                               switch(subtype) {
-                               case 0x00:
-                                       mr->item.type=type_poi_attraction;
-                                       break;
-                               case 0x02:
-                                       mr->item.type=type_poi_museum_history;
-                                       break;
-                               }
-                               break;
-                       case 0x2e:
-                               mr->item.type=type_poi_shopping;
-                               break;
-                       case 0x2f:
-                               switch(subtype) {
-                               case 0x01:
-                                       mr->item.type=type_poi_fuel;
-                                       break;
-                               case 0x07:
-                                       mr->item.type=type_poi_car_dealer_parts;
-                                       break;
-                               case 0x0b:
-                                       mr->item.type=type_poi_car_parking;
-                                       break;
-                               case 0x15:
-                                       mr->item.type=type_poi_public_utilities;
-                                       break;
-                               }
-                               break;
-                       case 0x30:
-                               switch(subtype) {
-                               case 0x02:
-                                       mr->item.type=type_poi_hospital;
-                                       break;
-                               }
-                               break;
-                       case 0x43:
-                               mr->item.type=type_poi_marina;
-                               break;
-                       case 0x46:
-                               mr->item.type=type_poi_bar;
-                               break;
-                       case 0x48:
-                               mr->item.type=type_poi_camping;
-                               break;
-                       case 0x49:
-                               mr->item.type=type_poi_park;
-                               break;
-                       case 0x4a:
-                               mr->item.type=type_poi_picnic;
-                               break;
-                       case 0x59:      /* airport */
-                               mr->item.type=type_poi_airport;
-                               break;
-                       case 0x64:
-                               switch(subtype) {
-                               case 0x1:
-                                       mr->item.type=type_poi_bridge;
-                                       break;
-                               case 0x2:
-                                       mr->item.type=type_poi_building;
-                                       break;
-                               case 0x15:
-                                       mr->item.type=type_town_ghost;
-                                       break;
-                               }
-                               break;
-                       case 0x65:
-                               switch(subtype) {
-                               case 0x0:
-                                       mr->item.type=type_poi_water_feature;
-                                       break;
-                               case 0xc:
-                                       mr->item.type=type_poi_island;
-                                       break;
-                               case 0xd:
-                                       mr->item.type=type_poi_lake;
-                                       break;
-                               }
-                               break;
-                       case 0x66:
-                               switch(subtype) {
-                               case 0x0:
-                                       mr->item.type=type_poi_land_feature;
-                                       break;
-                               case 0x6:
-                                       mr->item.type=type_poi_cape;
-                                       break;
-                               case 0x14:
-                                       mr->item.type=type_poi_rock;
-                                       break;
-                               }
-                               break;
-                       }
-                       if (mr->item.type == type_none) {
-                               printf("unknown point: 0x%x 0x%x\n", mr->pnt->info, mr->pnt->subtype);
-                               dump_point(mr->pnt);
-                               printf("label: %s\n", get_label_offset(mr, triple_u(&mr->pnt->lbl_offset) & 0x3fffff));
-                               mr->item.type=type_town_label;
-                       }
-                       return &mr->item;
-               }
-               if (debug)
-                       printf("out of data for type\n");
-               if (rgn_next_type(mr)) {
-                       if (debug)
-                               printf("out of data for region\n");
-                       if (sub_next(mr, subdiv_next)) {
-                               if (debug)
-                                       printf("out of data for subdivision\n");
-                               return NULL;
-                       }
-               }
-       }
-}
-
-static struct item *
-map_rect_get_item_byid_garmin_img(struct map_rect_priv *mr, int id_hi, int id_lo)
-{
-       fseek(mr->f, id_lo, SEEK_SET);
-       get_line(mr);
-       mr->item.id_hi=id_hi;
-       return map_rect_get_item_garmin_img(mr);
-}
-
-static struct map_methods map_methods_garmin_img = {
-       projection_garmin,
-       "iso8859-1",
-       map_destroy_garmin_img,
-       map_charset_garmin_img,
-       map_projection_garmin_img,
-       map_rect_new_garmin_img,
-       map_rect_destroy_garmin_img,
-       map_rect_get_item_garmin_img,
-       map_rect_get_item_byid_garmin_img,
-};
-
-static struct map_priv *
-map_new_garmin_img(struct map_methods *meth, struct attr **attrs)
-{
-       struct map_priv *m;
-       struct attr *data=attr_search(attrs, NULL, attr_data);
-       if (! data)
-               return NULL;
-
-       *meth=map_methods_garmin_img;
-       m=g_new(struct map_priv, 1);
-       m->id=++map_id;
-       m->filename=g_strdup(data->u.str);
-       return m;
-}
-
-void
-plugin_init(void)
-{
-       plugin_register_map_type("garmin_img", map_new_garmin_img);
-}
-
diff --git a/navit/data/mg/Makefile.am b/navit/data/mg/Makefile.am
deleted file mode 100644 (file)
index a32fc38..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-include $(top_srcdir)/Makefile.inc
-AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/navit -DMODULE=data_mg
-if PLUGINS
-  moduledata_LTLIBRARIES = libdata_mg.la
-else
-  noinst_LTLIBRARIES = libdata_mg.la
-endif
-libdata_mg_la_SOURCES = map.c block.c town.c tree.c poly.c street.c mg.h
diff --git a/navit/data/mg/block.c b/navit/data/mg/block.c
deleted file mode 100644 (file)
index e22440a..0000000
+++ /dev/null
@@ -1,286 +0,0 @@
-/**
- * Navit, a modular navigation system.
- * Copyright (C) 2005-2008 Navit Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA  02110-1301, USA.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "debug.h"
-#include "mg.h"
-
-
-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;
-};
-
-struct block_index {
-       unsigned int blocks;
-        unsigned int size;
-        unsigned int next;      
-       struct block_index_item list[0];
-};
-
-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;
-
-
-       blk_idx=(struct block_index *)(file->begin+0x1000);
-       max=(blk_idx->size-sizeof(struct block_index))/sizeof(struct block_index_item);
-       block_mem+=24;
-       while (id >= max) {
-               blk_idx=(struct block_index *)(file->begin+blk_idx->next*512);
-               id-=max;
-       }
-       blk_num=blk_idx->list[id].blocknum;
-
-       *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(1,"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+blk->b->size;
-
-       return 1;
-}
-
-static void
-block_setup_tags(struct map_rect_priv *mr)
-{
-       int len;
-       unsigned char *p,*t;
-       char *str;
-
-       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;
-       }
-}
-
-#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);
-}
-#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);
-}
-
-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)
-{
-       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+mr->b.b->blocks*512;
-               if (mr->b.p >= mr->file->end) {
-                       dbg(1,"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+mr->b.b->size;
-               if (mr->b.b->count == -1) {
-                       dbg(1,"empty blocks\n");
-                       return 0;
-               }
-               if (!mr->cur_sel || coord_rect_overlap(&mr->cur_sel->u.c_rect, &mr->b.b->r)) {
-                       block_active_count++;
-                       block_active_mem+=mr->b.b->blocks*512-sizeof(struct block *);
-                       dbg(1,"block ok\n");
-                       return 1;
-               }
-               dbg(2,"block not in cur_sel\n");
-       }
-}
-
-int
-block_next(struct map_rect_priv *mr)
-{
-       int blk_num,coord,r_h,r_w;
-       struct block_bt_priv *bt=&mr->b.bt;
-
-       if (!mr->b.binarytree || ! mr->cur_sel)
-               return block_next_lin(mr);
-       for (;;) {
-               if (! bt->p) {
-                       dbg(1,"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+mr->b.bt.b->size;
-                       bt->next=bt->b->next;
-                       bt->order=0;
-                       dbg(1,"size 0x%x next 0x%x\n", bt->b->size, bt->b->next);
-                       if (! mr->b.bt.block_count) {
-#if 0
-                               if (debug) {
-                                       printf("idx rect ");
-                                       block_rect_print(&mr->b.bt.b->r);
-                               }
-#endif
-                               bt->r=bt->b->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(1,"%p vs %p coord 0x%x ", mr->b.bt.end, mr->b.bt.p, coord);
-                       dbg(1,"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+mr->b.b->size;
-                                       block_rect_same(&mr->b.b->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+=mr->b.b->blocks*512;
-                               return 1;
-                       }
-               }
-               bt->p=NULL;
-       }       
-       return 0;
-}
diff --git a/navit/data/mg/map.c b/navit/data/mg/map.c
deleted file mode 100644 (file)
index 7e5f895..0000000
+++ /dev/null
@@ -1,514 +0,0 @@
-/**
- * Navit, a modular navigation system.
- * Copyright (C) 2005-2008 Navit Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA  02110-1301, USA.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "config.h"
-#include "debug.h"
-#include "plugin.h"
-#include "maptype.h"
-#include "mg.h"
-
-
-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},
-};
-
-struct map_priv * map_new_mg(struct map_methods *meth, struct attr **attrs);
-
-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",
-};
-
-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_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;
-}
-
-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 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 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]);
-       }
-}
-
-extern int block_lin_count,block_idx_count,block_active_count,block_mem,block_active_mem;
-
-static 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;
-}
-
-
-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(1,"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_byid_mg(struct map_rect_priv *mr, int id_hi, int id_lo)
-{
-       mr->current_file = id_hi >> 16;
-       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;
-       default:        
-               if (poly_get_byid(mr, &mr->poly, id_hi, id_lo, &mr->item))
-                       return &mr->item;
-               break;
-       }
-       return NULL;
-}
-
-
-static 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(1,"0x%x\n", *str);
-                       *c++=*str;
-                       break;
-               }
-               if (! *str)
-                       return ret;
-               str++;
-       }
-}
-
-
-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);
-       char *prefix;
-       dbg(1,"id_lo=0x%x\n", item->id_lo);
-       dbg(1,"search=%s\n", search->u.str);
-       mr->m=map;
-       mr->search_type=search->type;
-
-       /*
-     * NOTE: If you implement search for other attributes than attr_town_postal, attr_town_name and attr_street_name,
-     * please update this comment and the documentation for map_search_new() in map.c
-     */
-
-       switch (search->type) {
-       case attr_town_postal:
-               if (item->type != type_country_label)
-                       return NULL;
-               prefix=mg_country_postal_prefix(item->id_lo);
-               if (! prefix)
-                       return NULL;
-               tree_search_init(map->dirname, "town.b1", &mr->ts, 0);
-               mr->current_file=file_town_twn;
-               mr->search_str=g_strdup_printf("%s%s",prefix,search->u.str);
-               dbg(0,"search_str='%s'\n",mr->search_str);
-               mr->search_country=mg_country_from_isonum(item->id_lo);
-               break;
-       case attr_town_name:
-               if (item->type != type_country_label)
-                       return NULL;
-               tree_search_init(map->dirname, "town.b2", &mr->ts, 0x1000);
-               mr->current_file=file_town_twn;
-               mr->search_str=map_search_mg_convert_special(search->u.str);
-               mr->search_country=mg_country_from_isonum(item->id_lo);
-               break;
-       case attr_street_name:
-               if (item->type != type_town_streets)
-                       return NULL;
-               dbg(1,"street_assoc=0x%x\n", item->id_lo);
-               tree_search_init(map->dirname, "strname.b1", &mr->ts, 0);
-               mr->current_file=file_strname_stn;
-               mr->search_str=g_strdup(search->u.str);
-               break;
-       default:
-               dbg(0,"unknown search\n");
-               g_free(mr);
-               return NULL;
-       }
-       mr->search_item=*item;
-       mr->search_partial=partial;
-       mr->file=mr->m->file[mr->current_file];
-       block_init(mr);
-       return (struct map_search_priv *)mr;
-}
-
-static void
-map_search_destroy_mg(struct map_search_priv *ms)
-{
-       struct map_rect_priv *mr=(struct map_rect_priv *)ms;
-
-       dbg(1,"mr=%p\n", mr);
-       if (! mr)
-               return;
-       g_free(mr->search_str);
-       tree_search_free(&mr->ts);
-       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;
-
-       if (! mr)
-               return NULL;
-       switch (mr->search_type) {
-       case attr_town_postal:
-       case attr_town_name:
-               return town_search_get_item(mr);
-       case attr_street_name:
-               return street_search_get_item(mr);
-       default:
-               return NULL;
-       }
-}
-
-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,
-};
-
-struct map_priv *
-map_new_mg(struct map_methods *meth, struct attr **attrs)
-{
-       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);
-                       if (! m->file[i]) {
-                               maybe_missing=(i == file_border_ply || i == file_height_ply || i == file_sea_ply);
-                               if (! maybe_missing)
-                                       dbg(0,"Failed to load %s\n", filename);
-                       } else
-                               file_mmap(m->file[i]);
-                       g_free(filename);
-               }
-       }
-
-       return m;
-}
-
-void
-plugin_init(void)
-{
-       plugin_register_map_type("mg", map_new_mg);
-}
diff --git a/navit/data/mg/mg.h b/navit/data/mg/mg.h
deleted file mode 100644 (file)
index 302b65f..0000000
+++ /dev/null
@@ -1,314 +0,0 @@
-/**
- * Navit, a modular navigation system.
- * Copyright (C) 2005-2008 Navit Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA  02110-1301, USA.
- */
-
-#include <glib.h>
-#include "item.h"
-#include "attr.h"
-#include "coord.h"
-#include "data.h"
-#include "projection.h"
-#include "map.h"
-#include "file.h"
-
-struct block_data {
-       struct file *file;
-};
-
-struct block {
-       int blocks;
-       int size;
-       int next;
-       struct coord_rect r;
-       int count;
-};
-
-struct item_priv {
-       int cidx;
-       int aidx;
-       unsigned char *cstart,*cp,*cend;
-       unsigned char *astart,*ap,*aend;
-       enum attr_type attr_last;
-       enum attr_type attr_next;
-       struct item item;
-};
-
-struct town_priv {
-       unsigned int id; /*!< Identifier */
-       struct coord c; /*!< Coordinates */
-       char *name; /*!< Name */
-       char *district; /*!< District */
-       char *postal_code1; /*!< Postal code */
-       unsigned char order; /*!< Order (Importance) */
-       unsigned char type; /*!< Type */
-       unsigned short country; /*!< Country */
-       unsigned int unknown2; /*!< Unknown */
-       unsigned char size; /*!< Size of town */
-       unsigned int street_assoc; /*!< Association to streets */
-       unsigned char unknown3; /*!< Unknown */
-       char *postal_code2; /*!< 2nd postal code */
-       unsigned int unknown4; /*!< Unknown */
-
-       int cidx;
-       int aidx;
-       enum attr_type attr_next;
-       char debug[256];
-       char postal[32];
-       struct item town_attr_item;
-};
-
-struct poly_priv {
-       int poly_num;
-       unsigned char *poly_next;
-       int subpoly_num;
-       int subpoly_num_all;
-       unsigned char *subpoly_next;
-       unsigned char *subpoly_start;
-       unsigned char *p;
-       struct coord c[2];
-       char *name;
-       unsigned char order;
-       unsigned char type;
-       unsigned int polys;
-       unsigned int *count;
-       unsigned int count_sum;
-
-       int aidx;
-       enum attr_type attr_next;
-};
-
-struct street_header {
-        unsigned char order;
-        int count;
-} __attribute__((packed));
-
-struct street_type {
-        unsigned char order;
-        unsigned short country;
-} __attribute__((packed));
-
-struct street_header_type {
-       struct street_header *header;
-       int type_count;
-       struct street_type *type;
-};
-
-struct street_str {
-        int segid;
-        unsigned char limit;            /* 0x03,0x30=One Way,0x33=No Passing */
-        unsigned char unknown2;
-        unsigned char unknown3;
-        unsigned char type;
-        unsigned int nameid;
-};
-
-struct street_name_segment {
-       int segid;
-       int country;
-};
-
-struct street_name {
-       int len;
-       int country;
-       int townassoc;
-       char *name1;
-       char *name2;
-       int segment_count;
-       struct street_name_segment *segments;
-       int aux_len;
-       unsigned char *aux_data;
-       int tmp_len;
-       unsigned char *tmp_data;
-};
-
-struct street_name_numbers {
-       int len;
-       int tag;
-       int dist;
-       int country;
-       struct coord *c;
-       int first;
-       int last;
-       int segment_count;
-       struct street_name_segment *segments;
-       int aux_len;
-       unsigned char *aux_data;
-       int tmp_len;
-       unsigned char *tmp_data;
-};
-
-struct street_name_number {
-        int len;
-        int tag;
-        struct coord *c;
-        int first;
-        int last;
-        struct street_name_segment *segment;
-};
-
-
-
-struct street_priv {
-       struct file *name_file;
-       struct street_header *header;
-       int type_count;
-       struct street_type *type;
-       struct street_str *str;
-       struct street_str *str_start;
-       unsigned char *coord_begin;
-       unsigned char *p;
-       unsigned char *p_rewind;
-       unsigned char *end;
-       unsigned char *next;
-       int status;
-       int status_rewind;
-       struct coord *ref;
-       int bytes;
-       int more;
-       struct street_name name;
-       enum attr_type attr_next;
-       char debug[256];
-};
-
-enum file_index {
-        file_border_ply=0,
-        file_bridge_ply,
-       file_build_ply,
-       file_golf_ply,
-        file_height_ply,
-       file_natpark_ply,
-       file_nature_ply,
-        file_other_ply,
-        file_rail_ply,
-        file_sea_ply,
-        file_street_bti,
-        file_street_str,
-        file_strname_stn,
-        file_town_twn,
-        file_tunnel_ply,
-        file_water_ply,
-        file_woodland_ply,
-        file_end
-};
-
-struct map_priv {
-       int id;
-       struct file *file[file_end];
-       char *dirname;
-};
-
-#define BT_STACK_SIZE 32
-
-struct block_bt_priv {
-       struct block *b;
-       struct coord_rect r, r_curr;
-       int next;
-       int block_count;
-       struct coord_rect stack[BT_STACK_SIZE];
-       int stackp;
-       int order;
-       unsigned char *p;
-       unsigned char *end;
-};
-
-struct block_priv {
-       int block_num;
-       struct coord_rect b_rect;
-       unsigned char *block_start;
-       struct block *b;
-       unsigned char *p;
-       unsigned char *end;
-       unsigned char *p_start;
-       int binarytree;
-       struct block_bt_priv bt;
-};
-
-struct block_offset {
-       unsigned short offset;
-       unsigned short block;
-};
-
-
-struct tree_search_node {
-       struct tree_hdr *hdr;
-       unsigned char *p;
-       unsigned char *last;
-       unsigned char *end;
-       int low;
-       int high;
-       int last_low;
-       int last_high;
-       };
-
-struct tree_search {
-       struct file *f;
-       int last_node;
-       int curr_node;
-       struct tree_search_node nodes[5];
-};
-
-
-struct map_rect_priv {
-       struct map_selection *xsel;
-       struct map_selection *cur_sel;
-
-       struct map_priv *m;
-       enum file_index current_file;
-       struct file *file;
-       struct block_priv b;
-       struct item item;
-       struct town_priv town;
-       struct poly_priv poly;
-       struct street_priv street;
-       struct tree_search ts;
-       int search_country;
-       struct item search_item;
-       char *search_str;
-       int search_partial;
-       int search_linear;
-       unsigned char *search_p;
-       int search_blk_count;
-       enum attr_type search_type;
-       struct block_offset *search_blk_off;
-       int search_block;
-       GHashTable *block_hash[file_end];
-       struct item_priv item3;
-};
-
-int mg_country_from_isonum(int isonum);
-int mg_country_to_isonum(int country);
-int mg_country_postal_len(int country);
-
-int block_init(struct map_rect_priv *mr);
-int block_next(struct map_rect_priv *mr);
-int block_get_byindex(struct file *file, int idx, struct block_priv *blk);
-int block_next_lin(struct map_rect_priv *mr);
-
-int tree_search_hv(char *dirname, char *filename, unsigned int search1, unsigned int search2, int *result);
-int town_get(struct map_rect_priv *mr, struct town_priv *poly, struct item *item);
-int town_get_byid(struct map_rect_priv *mr, struct town_priv *twn, int id_hi, int id_lo, struct item *item);
-struct item * town_search_get_item(struct map_rect_priv *mr);
-int poly_get(struct map_rect_priv *mr, struct poly_priv *poly, struct item *item);
-int poly_get_byid(struct map_rect_priv *mr, struct poly_priv *poly, int id_hi, int id_lo, struct item *item);
-int street_get(struct map_rect_priv *mr, struct street_priv *street, struct item *item);
-int street_get_byid(struct map_rect_priv *mr, struct street_priv *street, int id_hi, int id_lo, struct item *item);
-struct item * street_search_get_item(struct map_rect_priv *mr);
-void tree_search_init(char *dirname, char *filename, struct tree_search *ts, int offset);
-void tree_search_free(struct tree_search *ts);
-int tree_search_next(struct tree_search *ts, unsigned char **p, int dir);
-int tree_search_next_lin(struct tree_search *ts, unsigned char **p);
diff --git a/navit/data/mg/poly.c b/navit/data/mg/poly.c
deleted file mode 100644 (file)
index 2618a89..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-/**
- * Navit, a modular navigation system.
- * Copyright (C) 2005-2008 Navit Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA  02110-1301, USA.
- */
-
-#include <string.h>
-#include "debug.h"
-#include "mg.h"
-
-static void
-poly_coord_rewind(void *priv_data)
-{
-       struct poly_priv *poly=priv_data;
-
-       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 void 
-poly_attr_rewind(void *priv_data)
-{
-       struct poly_priv *poly=priv_data;
-
-       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;
-
-       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,
-};
-
-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 >= mr->b.b->count)
-                       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(0,"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(1,"%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(1,"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_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/data/mg/street.c b/navit/data/mg/street.c
deleted file mode 100644 (file)
index 284ad6f..0000000
+++ /dev/null
@@ -1,775 +0,0 @@
-/**
- * Navit, a modular navigation system.
- * Copyright (C) 2005-2008 Navit Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA  02110-1301, USA.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "debug.h"
-#include "mg.h"
-
-int coord_debug;
-
-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 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=get_u24(p);
-       name_numbers->last=get_u24(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 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=get_u24(p);
-        name_number->last=get_u24(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 *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[0].x+x;
-               f->y=ref[1].y+y;
-       }
-       dbg(1,"0x%x,0x%x + 0x%x,0x%x = 0x%x,0x%x\n", x, y, ref[0].x, ref[1].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 (L(str->segid)) {
-               str++;
-       }
-       (*p)=(unsigned char *)str;
-       (*p)+=4;
-}
-
-
-static void
-street_coord_rewind(void *priv_data)
-{
-       /* struct street_priv *street=priv_data; */
-
-}
-
-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;
-
-       if (! street->p && count) {
-               street->p=street->coord_begin;
-               scount=street->str-street->str_start;
-               for (i = 0 ; i < scount ; i++) {
-                       street->status=L(street->str[i+1].segid) >= 0 ? 0:1;
-                       while (street_coord_get_helper(street, c));
-                       street->p=street->next;
-               }
-               street->status_rewind=street->status=L(street->str[1].segid) >= 0 ? 0:1;
-       }
-       while (count > 0) {
-               if (street_coord_get_helper(street, c)) {
-                       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(1,"segid 0x%x\n", L(street->str->segid));
-       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=L(street->str->nameid);
-               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=L(street->str->nameid);
-               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=L(street->str->nameid);
-               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:
-               if (street->str->type & 0x40) {
-                       attr->u.num=(street->str->limit & 0x30) ? AF_ONEWAYREV:0;
-                       attr->u.num|=(street->str->limit & 0x03) ? AF_ONEWAY:0;
-               } else {
-                       attr->u.num=(street->str->limit & 0x30) ? AF_ONEWAY:0;
-                       attr->u.num|=(street->str->limit & 0x03) ? AF_ONEWAYREV:0;
-               }
-               street->attr_next=attr_country_id;
-               return 1;
-       case attr_country_id:
-               street->attr_next=attr_debug;
-               nameid=L(street->str->nameid);
-               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->order,str->segid,str->limit,str->unknown2,str->unknown3,str->type,str->nameid, 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,
-};
-
-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->count;
-       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)
-{      
-       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->order > limit[mr->cur_sel->order])
-                               return 0;
-                       street->end=mr->b.end;
-                       street->ref=&mr->b.b->r.lu;
-                       street->bytes=street_get_bytes(&mr->b.b->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 (! L(street->str->segid))
-                       return 0;
-               if (L(street->str->segid) < 0)
-                       street->type++;
-#if 0
-               dbg_assert(street->p != NULL);
-#endif
-               street->next=NULL;
-               street->status_rewind=street->status=L(street->str[1].segid) >= 0 ? 0:1;
-#if 0
-               if (street->type->country != 0x31) {
-                       printf("country=0x%x\n", street->type->country);
-               }
-#endif
-               item->id_hi=street->type->country | (mr->current_file << 16);
-               item->id_lo=L(street->str->segid) > 0 ? L(street->str->segid) : -L(street->str->segid);
-               switch(street->str->type & 0x1f) {
-               case 0xf: /* very small street */
-                       if (street->str->limit == 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->limit == 0x03 || street->str->limit == 0x30) && street->header->order < 4)
-                               item->type=type_street_4_city;
-                       else    
-                               item->type=type_street_3_city;
-                       break;
-               case 0x9:
-                       if (street->header->order < 5)
-                               item->type=type_street_4_city;
-                       else if (street->header->order < 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->limit == 0x03 || street->str->limit == 0x30) && street->header->order < 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(0,"unknown type 0x%x\n",street->str->type);
-               }
-#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;
-               if (!map_selection_contains_item(mr->cur_sel, 0, item->type)) 
-                       continue;
-               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;
-       dbg(1,"enter(%p,%p,0x%x,0x%x,%p)\n", mr, street, id_hi, id_lo, item);
-       if (! country)
-               return 0;
-        tree_search_hv(mr->m->dirname, "street", (id_lo >> 8) | (country << 24), id_lo & 0xff, &res);
-       dbg(1,"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;
-       street->ref=&mr->b.b->r.lu;
-       street->bytes=street_get_bytes(&mr->b.b->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(1,"segid 0x%x\n", L(street->str[1].segid));
-       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;
-}
-     
-
-struct street_name_index {
-       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 == 0xd6 || c == 0xdc)
-               return c+0x20;
-       return c;
-}
-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
-street_search_compare_do(struct map_rect_priv *mr, int country, int town_assoc, char *name)
-{
-        int d;
-
-       dbg(1,"enter");
-       dbg(1,"country 0x%x town_assoc 0x%x name '%s'\n", country, town_assoc, name);
-       d=(mr->search_item.id_hi & 0xffff)-country;
-       dbg(1,"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(1,"town_assoc match (0x%x)\n", town_assoc);
-                       if (mr->search_partial)
-                               d=strncasecmp_latin1(mr->search_str, name, strlen(mr->search_str));
-                       else
-                               d=strncasecmp_latin1(mr->search_str, name, INT_MAX);
-                       dbg(1,"string %d\n", d);
-               } else {
-                       if (town_assoc < mr->search_item.id_lo)
-                               d=1;
-                       else
-                               d=-1;
-                       dbg(1,"assoc %d 0x%x-0x%x\n",d, mr->search_item.id_lo, town_assoc);
-               }
-       }
-       dbg(1,"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(1,"enter\n");
-       i=(struct street_name_index *)(*p);
-       *p+=sizeof(*i)+strlen(i->name)+1;
-
-       dbg(1,"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_numbers_coord_rewind(void *priv_data)
-{
-       /* struct street_priv *street=priv_data; */
-
-}
-
-static void
-street_name_numbers_attr_rewind(void *priv_data)
-{
-       /* struct street_priv *street=priv_data; */
-
-}
-
-static int
-street_name_numbers_coord_get(void *priv_data, struct coord *c, int count)
-{
-       return 0;
-}
-
-static int
-street_name_numbers_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
-{
-       attr->type=attr_type;
-       switch (attr_type) {
-       default:
-               dbg(0,"unknown item\n");
-               return 0;
-       }
-}
-
-
-
-
-
-static struct item_methods street_name_numbers_meth = {
-       street_name_numbers_coord_rewind,
-       street_name_numbers_coord_get,
-       street_name_numbers_attr_rewind,
-       street_name_numbers_attr_get,
-};
-
-
-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(1,"aux_data=%p\n", p);
-       if (count) {
-               street_name_numbers_get(&snns, &p);
-               *c=*(snns.c);
-               return 1;
-       }
-       
-       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;
-       struct item *item;
-
-       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_street_name_numbers_item:
-               item=&mr->item3.item;
-               attr->u.item=item;
-               item->type=type_street_name_numbers;
-               item->id_hi=0;
-               item->id_lo=1;
-               item->meth=&street_name_numbers_meth;
-               item->map=NULL;
-               item->priv_data=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);
-                                       printf("  last %d\n", nns.last);
-                                       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);
-                                               printf("    last %d\n", nn.last);
-                                       }
-                               }
-                       }
-               }
-               return 1;
-       default:
-               dbg(0,"unknown item\n");
-               return 0;
-       }
-}
-
-
-
-
-
-static struct item_methods street_name_meth = {
-       street_name_coord_rewind,
-       street_name_coord_get,
-       street_name_attr_rewind,
-       street_name_attr_get,
-};
-
-
-struct item *
-street_search_get_item(struct map_rect_priv *mr)
-{
-       int dir=1,leaf;
-       unsigned char *last;
-
-       dbg(1,"enter\n");
-       if (! mr->search_blk_count) {
-               dbg(1,"partial 0x%x '%s' ***\n", mr->town.street_assoc, mr->search_str);
-               if (mr->search_linear)
-                       return NULL;
-               dbg(1,"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(1,"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(1,"name id 0x%x\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(1,"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(1,"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(1,"end of data\n");
-                               mr->search_blk_count=0;
-                               return NULL;
-                       }
-                       if (!dir) {
-                               dbg(1,"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=mr->street.name.country | (mr->current_file << 16) | 0x10000000;
-                               mr->item.id_lo=last-mr->m->file[mr->current_file]->begin;
-                               mr->item.meth=&street_name_meth;
-                               mr->item.map=NULL;
-                               mr->item.priv_data=mr;
-                               return &mr->item;
-                       }
-               }
-       }
-}
diff --git a/navit/data/mg/town.c b/navit/data/mg/town.c
deleted file mode 100644 (file)
index aedf34a..0000000
+++ /dev/null
@@ -1,285 +0,0 @@
-/**
- * Navit, a modular navigation system.
- * Copyright (C) 2005-2008 Navit Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA  02110-1301, USA.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "debug.h"
-#include "mg.h"
-
-
-
-static void
-town_coord_rewind(void *priv_data)
-{
-       struct town_priv *twn=priv_data;
-
-       twn->cidx=0;
-}
-
-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;
-}
-
-static void
-town_attr_rewind(void *priv_data)
-{
-       struct town_priv *twn=priv_data;
-
-       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;
-
-       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:
-               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_assert(1==0);
-               return 0;
-       }
-       return 1;
-}
-
-static struct item_methods town_meth = {
-       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
-}
-                            /*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;
-                       }
-               }
-       }
-}
-
-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;
-
-       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(1,"country 0x%x ", country);
-               name=get_string(p);
-               dbg(1,"name '%s' ",name);
-               mr->search_blk_count=get_u32_unal(p);
-               mr->search_blk_off=(struct block_offset *)(*p);
-               dbg(1,"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(1,"%d \n",d);
-       return d;
-
-}
-
-
-
-struct item *
-town_search_get_item(struct map_rect_priv *mr)
-{
-       int dir=1,leaf;
-
-       if (! mr->search_blk_count) {
-               dbg(1,"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 && leaf) {
-                                       mr->search_linear=1;
-                                       mr->search_p=NULL;
-                                       break;
-                               }
-                       }
-                       if (! mr->search_linear) {
-                               dbg(1,"not found\n");
-                               return NULL;
-                       }
-               }
-               if (! tree_search_next_lin(&mr->ts, &mr->search_p)) {
-                       dbg(1,"linear not found\n");
-                       return NULL;
-               }
-               if (town_search_compare(&mr->search_p, mr)) {
-                       dbg(1,"no match\n");
-                       return NULL;
-               }
-               dbg(1,"found %d blocks\n",mr->search_blk_count);
-       }
-       if (! mr->search_blk_count)
-               return NULL;
-       dbg(1,"block 0x%x offset 0x%x\n", mr->search_blk_off->block, mr->search_blk_off->offset);
-       block_get_byindex(mr->m->file[mr->current_file], mr->search_blk_off->block, &mr->b);
-       mr->b.p=mr->b.block_start+mr->search_blk_off->offset;
-       town_get(mr, &mr->town, &mr->item);
-       mr->search_blk_off++;
-       mr->search_blk_count--;
-       return &mr->item;
-}
diff --git a/navit/data/mg/tree.c b/navit/data/mg/tree.c
deleted file mode 100644 (file)
index 695b401..0000000
+++ /dev/null
@@ -1,263 +0,0 @@
-/**
- * Navit, a modular navigation system.
- * Copyright (C) 2005-2008 Navit Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA  02110-1301, USA.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include "debug.h"
-#include "mg.h"
-
-struct tree_hdr {
-       unsigned int addr;
-       unsigned int size;
-       unsigned int low;
-};
-
-struct tree_hdr_h {
-       unsigned int addr;
-       unsigned int size;
-};
-
-struct tree_leaf_h {
-       unsigned int lower;
-       unsigned int higher;
-       unsigned int match;
-       unsigned int value;
-};
-
-
-struct tree_hdr_v {
-       unsigned int count;
-       unsigned int next;
-       unsigned int unknown;
-};
-
-struct tree_leaf_v {
-       unsigned char key;
-       int value;
-} __attribute__((packed));
-
-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(1,"enter\n");
-       while (i++ < 1000) {
-               thdr=(struct tree_hdr_h *)p;
-               p+=sizeof(*thdr);
-               end=p+thdr->size;
-               dbg(1,"@0x%x\n", p-file->begin);
-               last=0;
-               while (p < end) {
-                       tleaf=(struct tree_leaf_h *)p;
-                       p+=sizeof(*tleaf);
-                       dbg(1,"low:0x%x high:0x%x match:0x%x val:0x%x search:0x%x\n", tleaf->lower, tleaf->higher, tleaf->match, tleaf->value, search);
-                       value=tleaf->value;
-                       if (value == search)
-                               return tleaf->match;
-                       if (value > search) {
-                               dbg(1,"lower\n");
-                               lower=tleaf->lower;
-                               if (lower)
-                                       last=lower;
-                               break;
-                       }
-                       last=tleaf->higher;
-               }
-               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=L(thdr->count);
-               dbg(1,"offset=0x%x count=0x%x\n", p-file->begin, count);
-               while (count--) {
-                       tleaf=(struct tree_leaf_v *)p;
-                       p+=sizeof(*tleaf);
-                       dbg(1,"0x%x 0x%x\n", tleaf->key, search);
-                       if (tleaf->key == search)
-                               return L(tleaf->value);
-               }
-               next=L(thdr->next);
-               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;
-
-       dbg(1,"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);
-       if (! f_idx_h)
-               return 0;
-       file_mmap(f_idx_h);     
-       sprintf(buffer, "%s/%s.v1", dirname, filename);
-       f_idx_v=file_create_caseinsensitive(buffer);
-       dbg(1,"%p %p\n", f_idx_h, f_idx_v);
-       if (! f_idx_v) {
-               file_destroy(f_idx_h);
-               return 0;
-       }
-       file_mmap(f_idx_v);
-       if ((h=tree_search_h(f_idx_h, search_h))) {
-               dbg(1,"h=0x%x\n", h);
-               if ((v=tree_search_v(f_idx_v, h, search_v))) {
-                       dbg(1,"v=0x%x\n", v);
-                       *result=v;
-                       file_destroy(f_idx_v);
-                       file_destroy(f_idx_h);
-                       dbg(1,"return 1\n");
-                       return 1;
-               }
-       }
-       file_destroy(f_idx_v);
-       file_destroy(f_idx_h);
-       dbg(1,"return 0\n");
-       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+tsn->hdr->size;
-       tsn->low=tsn->hdr->low;
-       tsn->high=tsn->hdr->low;
-       dbg(1,"pos 0x%x addr 0x%x size 0x%x low 0x%x end 0x%x\n", p-ts->f->begin, tsn->hdr->addr, tsn->hdr->size, tsn->hdr->low, 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];
-
-       if (! *p) 
-               *p=tsn->p;
-       dbg(1,"next *p=%p dir=%d\n", *p, dir);
-       dbg(1,"low1=0x%x high1=0x%x\n", tsn->low, tsn->high);
-       if (dir <= 0) {
-               dbg(1,"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(1,"saving last2 %d 0x%x\n", ts->curr_node, tsn->last-ts->f->begin);
-                       dbg(1,"high2=0x%x\n", tsn->high);
-                       return 0;
-               }
-               return -1;
-       }
-       tsn->low=tsn->high;
-       tsn->last=*p;
-       tsn->high=get_u32_unal(p);
-       dbg(1,"saving last3 %d %p\n", ts->curr_node, tsn->last);
-       if (*p < tsn->end)
-               return (tsn->low == 0xffffffff ? 1 : 0);
-       dbg(1,"end reached high=0x%x\n",tsn->high);
-       if (tsn->low != 0xffffffff) {
-               dbg(1,"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(1,"saving last4 %d 0x%x\n", ts->curr_node, tsn->last-ts->f->begin);
-               dbg(1,"high4=0x%x\n", 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(1,"pos=%d 0x%x\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(1,"reload %d\n",ts->curr_node);
-                               high=tsn->low;
-                       }
-                       return 1;
-               }
-               dbg(1,"eon %d 0x%x 0x%x\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;
-       }
-
-       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);
-       ts->curr_node=-1;
-       if (ts->f) {
-               file_mmap(ts->f);
-               tree_search_enter(ts, offset);
-       }
-}
-
-void
-tree_search_free(struct tree_search *ts)
-{
-       file_destroy(ts->f);
-}
diff --git a/navit/data/poi_geodownload/Makefile.am b/navit/data/poi_geodownload/Makefile.am
deleted file mode 100644 (file)
index 41f25d5..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-SUBDIRS=libmdb
-include $(top_srcdir)/Makefile.inc
-AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/navit -I$(srcdir)/libmdb/include -DMODULE=data_poi_geodownload
-moduledata_LTLIBRARIES = libdata_poi_geodownload.la
-libdata_poi_geodownload_la_SOURCES = poi_geodownload.c
-libdata_poi_geodownload_la_LIBADD = -Llibmdb -lmdb
diff --git a/navit/data/poi_geodownload/libmdb/Makefile.am b/navit/data/poi_geodownload/libmdb/Makefile.am
deleted file mode 100644 (file)
index e2e440b..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-SUBDIRS=include
-AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(srcdir)/include
-noinst_LTLIBRARIES = libmdb.la
-libmdb_la_SOURCES=backend.c catalog.c data.c dump.c file.c iconv.c index.c kkd.c like.c map.c mem.c money.c options.c props.c sargs.c stats.c table.c worktable.c write.c
diff --git a/navit/data/poi_geodownload/libmdb/backend.c b/navit/data/poi_geodownload/libmdb/backend.c
deleted file mode 100644 (file)
index 902805c..0000000
+++ /dev/null
@@ -1,301 +0,0 @@
-/* MDB Tools - A library for reading MS Access database files
- * Copyright (C) 2000 Brian Bruns
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/*
-** functions to deal with different backend database engines
-*/
-
-#include "mdbtools.h"
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-static int is_init;
-static GHashTable *mdb_backends;
-
-   /*    Access data types */
-static MdbBackendType mdb_access_types[] = {
-               {"Unknown 0x00", 0,0,0 },
-               {"Boolean", 0,0,0},
-               {"Byte", 0,0,0},
-               {"Integer", 0,0,0},
-               {"Long Integer", 0,0,0},
-               {"Currency", 0,0,0},
-               {"Single", 0,0,0},
-               {"Double", 0,0,0},
-               {"DateTime (Short)", 0,0,1},
-               {"Unknown 0x09", 0,0,0},
-               {"Text", 1,0,1},
-               {"OLE", 1,0,1},
-               {"Memo/Hyperlink",1,0,1},
-               {"Unknown 0x0d",0,0,0},
-               {"Unknown 0x0e",0,0,0},
-               {"Replication ID",0,0,0},
-               {"Numeric",1,1,0}
-};
-
-/*    Oracle data types */
-static MdbBackendType mdb_oracle_types[] = {
-               {"Oracle_Unknown 0x00",0,0,0},
-               {"NUMBER",1,0,0},
-               {"NUMBER",1,0,0},
-               {"NUMBER",1,0,0},
-               {"NUMBER",1,0,0},
-               {"NUMBER",1,0,0},
-               {"FLOAT",0,0,0},
-               {"FLOAT",0,0,0},
-               {"DATE",0,0,0},
-               {"Oracle_Unknown 0x09",0,0,0},
-               {"VARCHAR2",1,0,1},
-               {"BLOB",1,0,1},
-               {"CLOB",1,0,1},
-               {"Oracle_Unknown 0x0d",0,0,0},
-               {"Oracle_Unknown 0x0e",0,0,0},
-               {"NUMBER",1,0,0},
-               {"NUMBER",1,0,0},
-};
-
-/*    Sybase/MSSQL data types */
-static MdbBackendType mdb_sybase_types[] = {
-               {"Sybase_Unknown 0x00",0,0,0},
-               {"bit",0,0,0},
-               {"char",1,0,1},
-               {"smallint",0,0,0},
-               {"int",0,0,0},
-               {"money",0,0,0},
-               {"real",0,0,0},
-               {"float",0,0,0},
-               {"smalldatetime",0,0,0},
-               {"Sybase_Unknown 0x09",0,0,0},
-               {"varchar",1,0,1},
-               {"varbinary",1,0,1},
-               {"text",1,0,1},
-               {"Sybase_Unknown 0x0d",0,0,0},
-               {"Sybase_Unknown 0x0e",0,0,0},
-               {"Sybase_Replication ID",0,0,0},
-               {"numeric",1,1,0},
-};
-
-/*    Postgres data types */
-static MdbBackendType mdb_postgres_types[] = {
-               {"Postgres_Unknown 0x00",0,0,0},
-               {"Bool",0,0,0},
-               {"Int2",0,0,0},
-               {"Int4",0,0,0},
-               {"Int8",0,0,0},
-               {"Money",0,0,0},
-               {"Float4",0,0,0},
-               {"Float8",0,0,0},
-               {"Timestamp",0,0,0},
-               {"Postgres_Unknown 0x09",0,0,0},
-               {"Char",1,0,1},
-               {"Postgres_Unknown 0x0b",0,0,0},
-               {"Postgres_Unknown 0x0c",0,0,0},
-               {"Postgres_Unknown 0x0d",0,0,0},
-               {"Postgres_Unknown 0x0e",0,0,0},
-               {"Serial",0,0,0},
-               {"Postgres_Unknown 0x10",0,0,0},
-};
-/*    MySQL data types */
-static MdbBackendType mdb_mysql_types[] = {
-               {"Text",1,0,1},
-               {"char",0,0,0},
-               {"int",0,0,0},
-               {"int",0,0,0},
-               {"int",0,0,0},
-               {"float",0,0,0},
-               {"float",0,0,0},
-               {"float",0,0,0},
-               {"date",0,0,1},
-               {"varchar",1,0,1},
-               {"varchar",1,0,1},
-               {"varchar",1,0,1},
-               {"text",1,0,1},
-               {"blob",0,0,0},
-               {"text",1,0,1},
-               {"numeric",1,1,0},
-               {"numeric",1,1,0},
-};
-
-static gboolean mdb_drop_backend(gpointer key, gpointer value, gpointer data);
-
-char *mdb_get_coltype_string(MdbBackend *backend, int col_type)
-{
-       static char buf[16];
-
-       if (col_type > 0x10 ) {
-               // return NULL;
-               snprintf(buf,sizeof(buf), "type %04x", col_type);
-               return buf;
-       } else {
-               return backend->types_table[col_type].name;
-       }
-}
-
-int mdb_coltype_takes_length(MdbBackend *backend, int col_type)
-{
-       return backend->types_table[col_type].needs_length;
-}
-
-/**
- * mdb_init_backends
- *
- * Initializes the mdb_backends hash and loads the builtin backends.
- * Use mdb_remove_backends() to destroy this hash when done.
- */
-void mdb_init_backends(void)
-{
-       mdb_backends = g_hash_table_new(g_str_hash, g_str_equal);
-
-       mdb_register_backend(mdb_access_types, "access");
-       mdb_register_backend(mdb_sybase_types, "sybase");
-       mdb_register_backend(mdb_oracle_types, "oracle");
-       mdb_register_backend(mdb_postgres_types, "postgres");
-       mdb_register_backend(mdb_mysql_types, "mysql");
-}
-void mdb_register_backend(MdbBackendType *backend_type, char *backend_name)
-{
-       MdbBackend *backend = (MdbBackend *) g_malloc0(sizeof(MdbBackend));
-       backend->types_table = backend_type;
-       g_hash_table_insert(mdb_backends, backend_name, backend);
-}
-
-/**
- * mdb_remove_backends
- *
- * Removes all entries from and destroys the mdb_backends hash.
- */
-void mdb_remove_backends(void)
-{
-       g_hash_table_foreach_remove(mdb_backends, mdb_drop_backend, NULL);
-       g_hash_table_destroy(mdb_backends);
-}
-static gboolean mdb_drop_backend(gpointer key, gpointer value, gpointer data)
-{
-       MdbBackend *backend = (MdbBackend *)value;
-       g_free (backend);
-       return TRUE;
-}
-
-/**
- * mdb_set_default_backend
- * @mdb: Handle to open MDB database file
- * @backend_name: Name of the backend to set as default
- *
- * Sets the default backend of the handle @mdb to @backend_name.
- *
- * Returns: 1 if successful, 0 if unsuccessful.
- */
-int mdb_set_default_backend(MdbHandle *mdb, char *backend_name)
-{
-       MdbBackend *backend;
-
-       backend = (MdbBackend *) g_hash_table_lookup(mdb_backends, backend_name);
-       if (backend) {
-               mdb->default_backend = backend;
-               mdb->backend_name = (char *) g_strdup(backend_name);
-               is_init = 0;
-               return 1;
-       } else {
-               return 0;
-       }
-}
-
-/**
- * mdb_get_relationships
- * @mdb: Handle to open MDB database file
- *
- * Generates relationships by reading the MSysRelationships table.
- *   'szColumn' contains the column name of the child table.
- *   'szObject' contains the table name of the child table.
- *   'szReferencedColumn' contains the column name of the parent table.
- *   'szReferencedObject' contains the table name of the parent table.
- *
- * Returns: a string stating that relationships are not supported for the
- *   selected backend, or a string containing SQL commands for setting up
- *   the relationship, tailored for the selected backend.  The caller is
- *   responsible for freeing this string.
- */
-char *mdb_get_relationships(MdbHandle *mdb)
-{
-       unsigned int i;
-       gchar *text = NULL;  /* String to be returned */
-       static char *bound[4];  /* Bound values */
-       static MdbTableDef *table;  /* Relationships table */
-       int backend = 0;  /* Backends: 1=oracle */
-
-       if (strncmp(mdb->backend_name,"oracle",6) == 0) {
-               backend = 1;
-       } else {
-               if (is_init == 0) { /* the first time through */
-                       is_init = 1;
-                       return (char *) g_strconcat(
-                               "-- relationships are not supported for ",
-                               mdb->backend_name, NULL);
-               } else { /* the second time through */
-                       is_init = 0;
-                       return NULL;
-               }
-       }
-
-       if (is_init == 0) {
-               table = mdb_read_table_by_name(mdb, "MSysRelationships", MDB_TABLE);
-               if ((!table) || (table->num_rows == 0)) {
-                       return NULL;
-               }
-
-               mdb_read_columns(table);
-               for (i=0;i<4;i++) {
-                       bound[i] = (char *) g_malloc0(MDB_BIND_SIZE);
-               }
-               mdb_bind_column_by_name(table, "szColumn", bound[0]);
-               mdb_bind_column_by_name(table, "szObject", bound[1]);
-               mdb_bind_column_by_name(table, "szReferencedColumn", bound[2]);
-               mdb_bind_column_by_name(table, "szReferencedObject", bound[3]);
-               mdb_rewind_table(table);
-
-               is_init = 1;
-       }
-       else if (table->cur_row >= table->num_rows) {  /* past the last row */
-               for (i=0;i<4;i++)
-                       g_free(bound[i]);
-               is_init = 0;
-               return NULL;
-       }
-
-       if (!mdb_fetch_row(table)) {
-               for (i=0;i<4;i++)
-                       g_free(bound[i]);
-               is_init = 0;
-               return NULL;
-       }
-
-       switch (backend) {
-         case 1:  /* oracle */
-               text = g_strconcat("alter table ", bound[1],
-                       " add constraint ", bound[3], "_", bound[1],
-                       " foreign key (", bound[0], ")"
-                       " references ", bound[3], "(", bound[2], ")", NULL);
-               break;
-       }
-
-       return (char *)text;
-}
-
diff --git a/navit/data/poi_geodownload/libmdb/catalog.c b/navit/data/poi_geodownload/libmdb/catalog.c
deleted file mode 100644 (file)
index dc08abd..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-/* MDB Tools - A library for reading MS Access database file
- * Copyright (C) 2000 Brian Bruns
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "mdbtools.h"
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-char *
-mdb_get_objtype_string(int obj_type)
-{
-static char *type_name[] = {"Form",
-                       "Table",
-                       "Macro",
-                       "System Table",
-                       "Report",
-                       "Query",
-                       "Linked Table",
-                       "Module",
-                       "Relationship",
-                       "Unknown 0x09",
-                       "Unknown 0x0a",
-                       "Database"
-               };
-
-       if (obj_type > 11) {
-               return NULL;
-       } else {
-               return type_name[obj_type]; 
-       }
-}
-
-void mdb_free_catalog(MdbHandle *mdb)
-{
-       unsigned int i;
-
-       if (!mdb->catalog) return;
-       for (i=0; i<mdb->catalog->len; i++)
-               g_free (g_ptr_array_index(mdb->catalog, i));
-       g_ptr_array_free(mdb->catalog, TRUE);
-       mdb->catalog = NULL;
-}
-
-GPtrArray *mdb_read_catalog (MdbHandle *mdb, int objtype)
-{
-       MdbCatalogEntry *entry, msysobj;
-       MdbTableDef *table;
-       char obj_id[256];
-       char obj_name[256];
-       char obj_type[256];
-       char obj_flags[256];
-       int type;
-
-       if (mdb->catalog) mdb_free_catalog(mdb);
-       mdb->catalog = g_ptr_array_new();
-       mdb->num_catalog = 0;
-
-       /* dummy up a catalog entry so we may read the table def */
-       memset(&msysobj, 0, sizeof(MdbCatalogEntry));
-       msysobj.mdb = mdb;
-       msysobj.object_type = MDB_TABLE;
-       msysobj.table_pg = 2;
-       strcpy(msysobj.object_name, "MSysObjects");
-
-       /* mdb_table_dump(&msysobj); */
-
-       table = mdb_read_table(&msysobj);
-       if (!table) return NULL;
-
-       mdb_read_columns(table);
-
-       mdb_bind_column_by_name(table, "Id", obj_id);
-       mdb_bind_column_by_name(table, "Name", obj_name);
-       mdb_bind_column_by_name(table, "Type", obj_type);
-       mdb_bind_column_by_name(table, "Flags", obj_flags);
-
-       mdb_rewind_table(table);
-
-       while (mdb_fetch_row(table)) {
-               type = atoi(obj_type);
-               if (objtype==MDB_ANY || type == objtype) {
-                       // fprintf(stdout, "obj_id: %10ld objtype: %-3d obj_name: %s\n", 
-                       // (atol(obj_id) & 0x00FFFFFF), type, obj_name); 
-                       entry = (MdbCatalogEntry *) g_malloc0(sizeof(MdbCatalogEntry));
-                       entry->mdb = mdb;
-                       strcpy(entry->object_name, obj_name);
-                       entry->object_type = (type & 0x7F);
-                       entry->table_pg = atol(obj_id) & 0x00FFFFFF;
-                       entry->flags = atol(obj_flags);
-                       mdb->num_catalog++;
-                       g_ptr_array_add(mdb->catalog, entry); 
-               }
-       }
-       //mdb_dump_catalog(mdb, MDB_TABLE);
-       mdb_free_tabledef(table);
-
-       return mdb->catalog;
-}
-
-void 
-mdb_dump_catalog(MdbHandle *mdb, int obj_type)
-{
-       unsigned int i;
-       MdbCatalogEntry *entry;
-
-       mdb_read_catalog(mdb, obj_type);
-       for (i=0;i<mdb->num_catalog;i++) {
-                entry = g_ptr_array_index(mdb->catalog,i);
-               if (obj_type==MDB_ANY || entry->object_type==obj_type) {
-                       fprintf(stdout,"Type: %-10s Name: %-18s T pg: %04x KKD pg: %04x row: %2d\n",
-                       mdb_get_objtype_string(entry->object_type),
-                       entry->object_name,
-                       (unsigned int) entry->table_pg,
-                       (unsigned int) entry->kkd_pg,
-                       entry->kkd_rowid);
-               }
-        }
-       return;
-}
-
diff --git a/navit/data/poi_geodownload/libmdb/data.c b/navit/data/poi_geodownload/libmdb/data.c
deleted file mode 100644 (file)
index e50e57d..0000000
+++ /dev/null
@@ -1,856 +0,0 @@
-/* MDB Tools - A library for reading MS Access database file
- * Copyright (C) 2000 Brian Bruns
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "mdbtools.h"
-#include "time.h"
-#include "math.h"
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-#define OFFSET_MASK 0x1fff
-
-char *mdb_money_to_string(MdbHandle *mdb, int start, char *s);
-static int _mdb_attempt_bind(MdbHandle *mdb, 
-       MdbColumn *col, unsigned char isnull, int offset, int len);
-static char *mdb_num_to_string(MdbHandle *mdb, int start, int datatype, int prec, int scale);
-int mdb_copy_ole(MdbHandle *mdb, char *dest, int start, int size);
-
-static char date_fmt[64] = "%x %X";
-
-void mdb_set_date_fmt(const char *fmt)
-{
-               date_fmt[63] = 0; 
-               strncpy(date_fmt, fmt, 63);
-}
-
-void mdb_bind_column(MdbTableDef *table, int col_num, void *bind_ptr)
-{
-MdbColumn *col;
-
-       /* 
-       ** the column arrary is 0 based, so decrement to get 1 based parameter 
-       */
-       col=g_ptr_array_index(table->columns, col_num - 1);
-       col->bind_ptr = bind_ptr;
-}
-int
-mdb_bind_column_by_name(MdbTableDef *table, gchar *col_name, void *bind_ptr)
-{
-       unsigned int i;
-       int col_num = -1;
-       MdbColumn *col;
-       
-       for (i=0;i<table->num_cols;i++) {
-               col=g_ptr_array_index(table->columns,i);
-               if (!strcmp(col->name,col_name)) {
-                       col_num = col->col_num + 1;
-                       mdb_bind_column(table, col_num, bind_ptr);
-                       break;
-               }
-       }
-
-       return col_num;
-}
-void mdb_bind_len(MdbTableDef *table, int col_num, int *len_ptr)
-{
-MdbColumn *col;
-
-       col=g_ptr_array_index(table->columns, col_num - 1);
-       col->len_ptr = len_ptr;
-}
-
-/**
- * mdb_find_pg_row
- * @mdb: Database file handle
- * @pg_row: Lower byte contains the row number, the upper three contain page
- * @buf: Pointer for returning a pointer to the page
- * @off: Pointer for returning an offset to the row
- * @len: Pointer for returning the length of the row
- * 
- * Returns: 0 on success.  1 on failure.
- */
-int mdb_find_pg_row(MdbHandle *mdb, int pg_row, char **buf, int *off, int *len)
-{
-       unsigned int pg = pg_row >> 8;
-       unsigned int row = pg_row & 0xff;
-
-       if (mdb_read_alt_pg(mdb, pg) != mdb->fmt->pg_size)
-               return 1;
-       mdb_swap_pgbuf(mdb);
-       *off = mdb_pg_get_int16(mdb, mdb->fmt->row_count_offset + 2 + (row*2));
-       *len = mdb_find_end_of_row(mdb, row) - *off + 1;
-       mdb_swap_pgbuf(mdb);
-       *buf = mdb->alt_pg_buf;
-       return 0;
-}
-
-int 
-mdb_find_end_of_row(MdbHandle *mdb, int row)
-{
-       MdbFormatConstants *fmt = mdb->fmt;
-       int row_end;
-
-       /* Search the previous "row start" values for the first non-'lookupflag' one.
-       * If we don't find one, then the end of the page is the correct value.
-       */
-#if 1
-       if (row==0) {
-               row_end = fmt->pg_size - 1;
-       } else {
-               row_end = (mdb_pg_get_int16(mdb, ((fmt->row_count_offset + 2) + (row - 1) * 2)) & OFFSET_MASK) - 1;
-       }
-       return row_end;
-#else
-               int i, row_start;
-
-               /* if lookupflag is     not set, it's good (deleteflag is ok) */
-        for (i = row - 1; i >= 0; i--) {
-                row_start = mdb_pg_get_int16(mdb, ((fmt->row_count_offset + 2) + i * 2));
-                if (!(row_start & 0x8000)) {
-                        break;
-                }
-        }
-
-        if (i == -1) {
-                row_end = fmt->pg_size - 1;
-        } else {
-                row_end = (row_start & OFFSET_MASK) - 1;
-        }
-       return row_end;
-#endif
-}
-int mdb_is_null(unsigned char *null_mask, int col_num)
-{
-int byte_num = (col_num - 1) / 8;
-int bit_num = (col_num - 1) % 8;
-
-       if ((1 << bit_num) & null_mask[byte_num]) {
-               return 0;
-       } else {
-               return 1;
-       }
-}
-/* bool has to be handled specially because it uses the null bit to store its 
-** value*/
-static int 
-mdb_xfer_bound_bool(MdbHandle *mdb, MdbColumn *col, int value)
-{
-       
-       col->cur_value_len = value;
-       if (col->bind_ptr) {
-               strcpy(col->bind_ptr,  value ? "0" : "1");
-       }
-
-       return 0;
-}
-static int mdb_xfer_bound_ole(MdbHandle *mdb, int start, MdbColumn *col, int len)
-{
-       int ret = 0;
-       if (len) {
-               col->cur_value_start = start;
-               col->cur_value_len = len;
-       } else {
-               col->cur_value_start = 0;
-               col->cur_value_len = 0;
-       }
-       if (col->bind_ptr || col->len_ptr) {
-               //ret = mdb_copy_ole(mdb, col->bind_ptr, start, len);
-               memcpy(col->bind_ptr, &mdb->pg_buf[start], MDB_MEMO_OVERHEAD);
-       }
-       if (col->len_ptr) {
-               *col->len_ptr = MDB_MEMO_OVERHEAD;
-       }
-       return ret;
-}
-static int mdb_xfer_bound_data(MdbHandle *mdb, int start, MdbColumn *col, int len)
-{
-int ret;
-       //if (!strcmp("Name",col->name)) {
-               //printf("start %d %d\n",start, len);
-       //}
-       if (len) {
-               col->cur_value_start = start;
-               col->cur_value_len = len;
-       } else {
-               col->cur_value_start = 0;
-               col->cur_value_len = 0;
-       }
-       if (col->bind_ptr) {
-               if (!len) {
-                       strcpy(col->bind_ptr, "");
-               } else if (col->col_type == MDB_NUMERIC) {
-                       //fprintf(stdout,"len %d size %d\n",len, col->col_size);
-                       char *str = mdb_num_to_string(mdb, start, col->col_type,
-                               col->col_prec, col->col_scale);
-                       strcpy(col->bind_ptr, str);
-                       g_free(str);
-               } else {
-                       //fprintf(stdout,"len %d size %d\n",len, col->col_size);
-                       char *str = mdb_col_to_string(mdb, mdb->pg_buf, start,
-                               col->col_type, len);
-                       strcpy(col->bind_ptr, str);
-                       
-               }
-               ret = strlen(col->bind_ptr);
-               if (col->len_ptr) {
-                       *col->len_ptr = ret;
-               }
-               return ret;
-       }
-       return 0;
-}
-int mdb_read_row(MdbTableDef *table, unsigned int row)
-{
-       MdbHandle *mdb = table->entry->mdb;
-       MdbFormatConstants *fmt = mdb->fmt;
-       MdbColumn *col;
-       unsigned int i;
-       int rc;
-       int row_start, row_end;
-       int delflag, lookupflag;
-       MdbField fields[256];
-       int num_fields;
-
-       if (table->num_rows <= row) 
-               return 0;
-
-       row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (row*2)); 
-       row_end = mdb_find_end_of_row(mdb, row);
-
-       delflag = lookupflag = 0;
-       if (row_start & 0x8000) lookupflag++;
-       if (row_start & 0x4000) delflag++;
-       row_start &= OFFSET_MASK; /* remove flags */
-#if MDB_DEBUG
-       fprintf(stdout,"Row %d bytes %d to %d %s %s\n", 
-               row, row_start, row_end,
-               lookupflag ? "[lookup]" : "",
-               delflag ? "[delflag]" : "");
-#endif 
-
-       if (!table->noskip_del && delflag) {
-               row_end = row_start-1;
-               return 0;
-       }
-
-       num_fields = mdb_crack_row(table, row_start, row_end, fields);
-       if (!mdb_test_sargs(table, fields, num_fields)) return 0;
-       
-#if MDB_DEBUG
-       fprintf(stdout,"sarg test passed row %d \n", row);
-#endif 
-
-#if MDB_DEBUG
-       buffer_dump(mdb->pg_buf, row_start, row_end);
-#endif
-
-       /* take advantage of mdb_crack_row() to clean up binding */
-       /* use num_cols instead of num_fields -- bsb 03/04/02 */
-       for (i = 0; i < table->num_cols; i++) {
-               col = g_ptr_array_index(table->columns,fields[i].colnum);
-               rc = _mdb_attempt_bind(mdb, col, fields[i].is_null,
-                       fields[i].start, fields[i].siz);
-       }
-
-       return 1;
-}
-static int _mdb_attempt_bind(MdbHandle *mdb, 
-       MdbColumn *col, 
-       unsigned char isnull, 
-       int offset, 
-       int len)
-{
-       if (col->col_type == MDB_BOOL) {
-               mdb_xfer_bound_bool(mdb, col, isnull);
-       } else if (isnull) {
-               mdb_xfer_bound_data(mdb, 0, col, 0);
-       } else if (col->col_type == MDB_OLE) {
-               mdb_xfer_bound_ole(mdb, offset, col, len);
-       } else {
-               //if (!mdb_test_sargs(mdb, col, offset, len)) {
-                       //return 0;
-               //}
-               mdb_xfer_bound_data(mdb, offset, col, len);
-       }
-       return 1;
-}
-int mdb_read_next_dpg(MdbTableDef *table)
-{
-       MdbCatalogEntry *entry = table->entry;
-       MdbHandle *mdb = entry->mdb;
-       int next_pg;
-
-#ifndef SLOW_READ
-       next_pg = mdb_map_find_next(mdb, table->usage_map,
-               table->map_sz, table->cur_phys_pg);
-
-       if (next_pg >= 0) {
-               if (mdb_read_pg(mdb, next_pg)) {
-                       table->cur_phys_pg = next_pg;
-                       return table->cur_phys_pg;
-               } else {
-                       return 0;
-               }
-       }
-       fprintf(stderr, "Warning: defaulting to brute force read\n");
-#endif 
-       /* can't do a fast read, go back to the old way */
-       do {
-               if (!mdb_read_pg(mdb, table->cur_phys_pg++))
-                       return 0;
-       } while (mdb->pg_buf[0]!=0x01 || mdb_pg_get_int32(mdb, 4)!=entry->table_pg);
-       /* fprintf(stderr,"returning new page %ld\n", table->cur_phys_pg); */
-       return table->cur_phys_pg;
-}
-int mdb_rewind_table(MdbTableDef *table)
-{
-       table->cur_pg_num=0;
-       table->cur_phys_pg=0;
-       table->cur_row=0;
-
-       return 0;
-}
-int 
-mdb_fetch_row(MdbTableDef *table)
-{
-       MdbHandle *mdb = table->entry->mdb;
-       MdbFormatConstants *fmt = mdb->fmt;
-       unsigned int rows;
-       int rc;
-       guint32 pg;
-
-       if (table->num_rows==0)
-               return 0;
-
-       /* initialize */
-       if (!table->cur_pg_num) {
-               table->cur_pg_num=1;
-               table->cur_row=0;
-               if ((!table->is_temp_table)&&(table->strategy!=MDB_INDEX_SCAN))
-                       if (!mdb_read_next_dpg(table)) return 0;
-       }
-
-       do {
-               if (table->is_temp_table) {
-                       GPtrArray *pages = table->temp_table_pages;
-                       rows = mdb_get_int16(
-                               g_ptr_array_index(pages, table->cur_pg_num-1),
-                               fmt->row_count_offset);
-                       if (table->cur_row >= rows) {
-                               table->cur_row = 0;
-                               table->cur_pg_num++;
-                               if (table->cur_pg_num > pages->len)
-                                       return 0;
-                       }
-                       memcpy(mdb->pg_buf,
-                               g_ptr_array_index(pages, table->cur_pg_num-1),
-                               fmt->pg_size);
-               } else if (table->strategy==MDB_INDEX_SCAN) {
-               
-                       if (!mdb_index_find_next(table->mdbidx, table->scan_idx, table->chain, &pg, (guint16 *) &(table->cur_row))) {
-                               mdb_index_scan_free(table);
-                               return 0;
-                       }
-                       mdb_read_pg(mdb, pg);
-               } else {
-                       rows = mdb_pg_get_int16(mdb,fmt->row_count_offset);
-
-                       /* if at end of page, find a new page */
-                       if (table->cur_row >= rows) {
-                               table->cur_row=0;
-       
-                               if (!mdb_read_next_dpg(table)) {
-                                       return 0;
-                               }
-                       }
-               }
-
-               /* printf("page %d row %d\n",table->cur_phys_pg, table->cur_row); */
-               rc = mdb_read_row(table, table->cur_row);
-               table->cur_row++;
-       } while (!rc);
-
-       return 1;
-}
-void mdb_data_dump(MdbTableDef *table)
-{
-       unsigned int i;
-       char *bound_values[MDB_MAX_COLS]; 
-
-       for (i=0;i<table->num_cols;i++) {
-               bound_values[i] = (char *) g_malloc(256);
-               mdb_bind_column(table, i+1, bound_values[i]);
-       }
-       mdb_rewind_table(table);
-       while (mdb_fetch_row(table)) {
-               for (i=0;i<table->num_cols;i++) {
-                       fprintf(stdout, "column %d is %s\n", i+1, bound_values[i]);
-               }
-       }
-       for (i=0;i<table->num_cols;i++) {
-               g_free(bound_values[i]);
-       }
-}
-
-int mdb_is_fixed_col(MdbColumn *col)
-{
-       return col->is_fixed;
-}
-#if 0
-static char *mdb_data_to_hex(MdbHandle *mdb, char *text, int start, int size) 
-{
-int i;
-
-       for (i=start; i<start+size; i++) {
-               sprintf(&text[(i-start)*2],"%02x", mdb->pg_buf[i]);
-       }
-       text[(i-start)*2]='\0';
-
-       return text;
-}
-#endif
-int 
-mdb_ole_read_next(MdbHandle *mdb, MdbColumn *col, void *ole_ptr)
-{
-       guint16 ole_len;
-       guint16 ole_flags;
-       char *buf;
-       int pg_row, row_start;
-       int len;
-
-       ole_len = mdb_get_int16(ole_ptr, 0);
-       ole_flags = mdb_get_int16(ole_ptr, 2);
-
-       if (ole_flags == 0x8000) {
-               /* inline fields don't have a next */
-               return 0;
-       } else if (ole_flags == 0x4000) {
-               /* 0x4000 flagged ole's are contained on one page and thus 
-                * should be handled entirely with mdb_ole_read() */
-               return 0;
-       } else if (ole_flags == 0x0000) {
-               pg_row = (col->cur_blob_pg << 8) & col->cur_blob_row;
-               if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) {
-                       return 0;
-               }
-               if (col->bind_ptr)
-                       memcpy(col->bind_ptr, buf + row_start, len);
-               pg_row = mdb_get_int32(buf, row_start);
-               col->cur_blob_pg = pg_row >> 8;
-               col->cur_blob_row = pg_row & 0xff;
-
-               return len;
-       }
-       return 0;
-}
-int 
-mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, int chunk_size)
-{
-       guint16 ole_len;
-       guint16 ole_flags;
-       char *buf;
-       int pg_row, row_start;
-       int len;
-
-       ole_len = mdb_get_int16(ole_ptr, 0);
-       ole_flags = mdb_get_int16(ole_ptr, 2);
-       mdb_debug(MDB_DEBUG_OLE,"ole len = %d ole flags = %08x",
-               ole_len, ole_flags);
-
-       col->chunk_size = chunk_size;
-
-       if (ole_flags == 0x8000) {
-               /* inline ole field, if we can satisfy it, then do it */
-               len = col->cur_value_len - MDB_MEMO_OVERHEAD;
-               if (chunk_size >= len) {
-                       if (col->bind_ptr) 
-                               memcpy(col->bind_ptr, 
-                                       &mdb->pg_buf[col->cur_value_start + 
-                                               MDB_MEMO_OVERHEAD],
-                                       len);
-                       return len;
-               } else {
-                       return 0;
-               }
-       } else if (ole_flags == 0x4000) {
-               pg_row = mdb_get_int32(ole_ptr, 4);
-               col->cur_blob_pg = pg_row >> 8;
-               col->cur_blob_row = pg_row & 0xff;
-               mdb_debug(MDB_DEBUG_OLE,"ole row = %d ole pg = %ld",
-                       col->cur_blob_row, col->cur_blob_pg);
-
-               if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) {
-                       return 0;
-               }
-               mdb_debug(MDB_DEBUG_OLE,"start %d len %d", row_start, len);
-
-               if (col->bind_ptr) {
-                       memcpy(col->bind_ptr, buf + row_start, len);
-                       if (mdb_get_option(MDB_DEBUG_OLE))
-                               buffer_dump(col->bind_ptr, 0, 16);
-               }
-               return len;
-       } else if (ole_flags == 0x0000) {
-               pg_row = mdb_get_int32(ole_ptr, 4);
-               col->cur_blob_pg = pg_row >> 8;
-               col->cur_blob_row = pg_row & 0xff;
-
-               if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) {
-                       return 0;
-               }
-
-               if (col->bind_ptr) 
-                       memcpy(col->bind_ptr, buf + row_start, len);
-
-               pg_row = mdb_get_int32(buf, row_start);
-               col->cur_blob_pg = pg_row >> 8;
-               col->cur_blob_row = pg_row & 0xff;
-
-               return len;
-       } else {
-               fprintf(stderr,"Unhandled ole field flags = %04x\n", ole_flags);
-               return 0;
-       }
-}
-int mdb_copy_ole(MdbHandle *mdb, char *dest, int start, int size)
-{
-       guint16 ole_len;
-       guint16 ole_flags;
-       guint32 row_start, pg_row;
-       guint32 len;
-       char *buf;
-
-       if (size<MDB_MEMO_OVERHEAD) {
-               return 0;
-       } 
-
-       /* The 16 bit integer at offset 0 is the length of the memo field.
-        * The 32 bit integer at offset 4 contains page and row information.
-        */
-       ole_len = mdb_pg_get_int16(mdb, start);
-       ole_flags = mdb_pg_get_int16(mdb, start+2);
-
-       if (ole_flags == 0x8000) {
-               len = size - MDB_MEMO_OVERHEAD;
-               /* inline ole field */
-               if (dest) memcpy(dest, &mdb->pg_buf[start + MDB_MEMO_OVERHEAD],
-                       size - MDB_MEMO_OVERHEAD);
-               return len;
-       } else if (ole_flags == 0x4000) {
-               pg_row = mdb_get_int32(mdb->pg_buf, start+4);
-               mdb_debug(MDB_DEBUG_OLE,"Reading LVAL page %06x", pg_row >> 8);
-
-               if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) {
-                       return 0;
-               }
-               mdb_debug(MDB_DEBUG_OLE,"row num %d start %d len %d",
-                       pg_row & 0xff, row_start, len);
-
-               if (dest)
-                       memcpy(dest, buf + row_start, len);
-               return len;
-       } else if (ole_flags == 0x0000) {
-               int cur = 0;
-               pg_row = mdb_get_int32(mdb->pg_buf, start+4);
-               mdb_debug(MDB_DEBUG_OLE,"Reading LVAL page %06x", pg_row >> 8);
-               do {
-                       if (mdb_find_pg_row(mdb,pg_row,&buf,&row_start,&len)) {
-                               return 0;
-                       }
-
-                       mdb_debug(MDB_DEBUG_OLE,"row num %d start %d len %d",
-                               pg_row & 0xff, row_start, len);
-
-                       if (dest) 
-                               memcpy(dest+cur, buf + row_start + 4, len - 4);
-                       cur += len - 4;
-
-                       /* find next lval page */
-                       pg_row = mdb_get_int32(buf, row_start);
-               } while ((pg_row >> 8));
-               return cur;
-       } else {
-               fprintf(stderr,"Unhandled ole field flags = %04x\n", ole_flags);
-               return 0;
-       }
-}
-static char *mdb_memo_to_string(MdbHandle *mdb, int start, int size)
-{
-       guint16 memo_len;
-       static char text[MDB_BIND_SIZE];
-       guint16 memo_flags;
-       guint32 row_start, pg_row;
-       guint32 len;
-       char *buf;
-
-       if (size<MDB_MEMO_OVERHEAD) {
-               return "";
-       } 
-
-#if MDB_DEBUG
-       buffer_dump(mdb->pg_buf, start, start + 12);
-#endif
-
-       /* The 16 bit integer at offset 0 is the length of the memo field.
-        * The 32 bit integer at offset 4 contains page and row information.
-        */
-       memo_len = mdb_pg_get_int16(mdb, start);
-       memo_flags = mdb_pg_get_int16(mdb, start+2);
-
-       if (memo_flags & 0x8000) {
-               /* inline memo field */
-               strncpy(text, &mdb->pg_buf[start + MDB_MEMO_OVERHEAD],
-                       size - MDB_MEMO_OVERHEAD);
-               text[size - MDB_MEMO_OVERHEAD]='\0';
-               return text;
-       } else if (memo_flags & 0x4000) {
-               pg_row = mdb_get_int32(mdb->pg_buf, start+4);
-#if MDB_DEBUG
-               printf("Reading LVAL page %06x\n", pg_row >> 8);
-#endif
-               if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) {
-                       return "";
-               }
-#if MDB_DEBUG
-               printf("row num %d start %d len %d\n",
-                       pg_row & 0xff, row_start, len);
-               buffer_dump(mdb->pg_buf, row_start, row_start + len);
-#endif
-               if (IS_JET3(mdb)) {
-                       strncpy(text, buf + row_start, len);
-                       text[len]='\0';
-               } else {
-                       mdb_unicode2ascii(mdb, buf, row_start, len, text);
-               }
-               return text;
-       } else { /* if (memo_flags == 0x0000) { */
-               pg_row = mdb_get_int32(mdb->pg_buf, start+4);
-#if MDB_DEBUG
-               printf("Reading LVAL page %06x\n", pg_row >> 8);
-#endif
-               text[0]='\0';
-               do {
-                       if (mdb_find_pg_row(mdb,pg_row,&buf,&row_start,&len)) {
-                               return "";
-                       }
-#if MDB_DEBUG
-                       printf("row num %d start %d len %d\n",
-                               pg_row & 0xff, row_start, len);
-#endif
-                       strncat(text, buf + row_start + 4, 
-                               strlen(text) + len - 4 > MDB_BIND_SIZE ?
-                               MDB_BIND_SIZE - strlen(text) : len - 4);
-
-                       /* find next lval page */
-                       pg_row = mdb_get_int32(mdb->pg_buf, row_start);
-               } while ((pg_row >> 8));
-               return text;
-/*
-       } else {
-               fprintf(stderr,"Unhandled memo field flags = %04x\n", memo_flags);
-               return "";
-*/
-       }
-}
-static char *
-mdb_num_to_string(MdbHandle *mdb, int start, int datatype, int prec, int scale)
-{
-       char *text;
-       gint32 l;
-
-       memcpy(&l, mdb->pg_buf+start+13, 4);
-
-       text = (char *) g_malloc(prec+2);
-       sprintf(text, "%0*" G_GINT32_FORMAT, prec, GINT32_FROM_LE(l));
-       if (scale) {
-               memmove(text+prec-scale, text+prec-scale+1, scale+1);
-               text[prec-scale] = '.';
-       }
-       return text;
-}
-
-static int trim_trailing_zeros(char * buff, int n)
-{
-       char * p = buff + n - 1;
-
-       while (p >= buff && *p == '0')
-               *p-- = '\0';
-
-       if (*p == '.')
-               *p = '\0';
-
-       return 0;
-}
-                               
-char *mdb_col_to_string(MdbHandle *mdb, unsigned char *buf, int start, int datatype, int size)
-{
-       /* FIX ME -- not thread safe */
-       static char text[MDB_BIND_SIZE];
-       time_t t;
-       int n;
-       float tf;
-       double td;
-
-       switch (datatype) {
-               case MDB_BOOL:
-                       /* shouldn't happen.  bools are handled specially
-                       ** by mdb_xfer_bound_bool() */
-               break;
-               case MDB_BYTE:
-                       sprintf(text,"%d",mdb_get_byte(buf, start));
-                       return text;
-               break;
-               case MDB_INT:
-                       sprintf(text,"%ld",(long)mdb_get_int16(buf, start));
-                       return text;
-               break;
-               case MDB_LONGINT:
-                       sprintf(text,"%ld",mdb_get_int32(buf, start));
-                       return text;
-               break;
-               case MDB_FLOAT:
-                       tf = mdb_get_single(mdb->pg_buf, start);
-                       n = sprintf(text,"%.*f",FLT_DIG - (int)ceil(log10(tf)), tf);
-                       trim_trailing_zeros(text, n);
-                       return text;
-               break;
-               case MDB_DOUBLE:
-                       td = mdb_get_double(mdb->pg_buf, start);
-                       n = sprintf(text,"%.*f",DBL_DIG - (int)ceil(log10(td)), td);
-                       trim_trailing_zeros(text, n);
-                       return text;
-               break;
-               case MDB_TEXT:
-                       if (size<0) {
-                               return "";
-                       }
-                       if (IS_JET4(mdb)) {
-/*
-                               int i;
-                               for (i=0;i<size;i++) {
-                                       fprintf(stdout, "%c %02x ", mdb->pg_buf[start+i], mdb->pg_buf[start+i]);
-                               } 
-                               fprintf(stdout, "\n");
-*/
-                               mdb_unicode2ascii(mdb, mdb->pg_buf, start, size, text);
-                       } else {
-                               strncpy(text, &buf[start], size);
-                               text[size]='\0';
-                       }
-                       return text;
-               break;
-               case MDB_SDATETIME:
-                       td = mdb_get_double(mdb->pg_buf, start);
-                       if (td > 1) {
-                               t = (long int)((td - 25569.0) * 86400.0);
-                       } else {
-                               t = (long int)(td * 86400.0);
-                       }
-                       strftime(text, MDB_BIND_SIZE, date_fmt, (struct tm*)gmtime(&t));
-                       return text;
-
-               break;
-               case MDB_MEMO:
-                       return mdb_memo_to_string(mdb, start, size);
-               break;
-               case MDB_MONEY:
-                       mdb_money_to_string(mdb, start, text);
-                       return text;
-               case MDB_NUMERIC:
-               break;
-               default:
-                       return "";
-               break;
-       }
-       return NULL;
-}
-int mdb_col_disp_size(MdbColumn *col)
-{
-       switch (col->col_type) {
-               case MDB_BOOL:
-                       return 1;
-               break;
-               case MDB_BYTE:
-                       return 4;
-               break;
-               case MDB_INT:
-                       return 6;
-               break;
-               case MDB_LONGINT:
-                       return 11;
-               break;
-               case MDB_FLOAT:
-                       return 10;
-               break;
-               case MDB_DOUBLE:
-                       return 10;
-               break;
-               case MDB_TEXT:
-                       return col->col_size;
-               break;
-               case MDB_SDATETIME:
-                       return 20;
-               break;
-               case MDB_MEMO:
-                       return 255; 
-               break;
-               case MDB_MONEY:
-                       return 21;
-               break;
-       }
-       return 0;
-}
-int mdb_col_fixed_size(MdbColumn *col)
-{
-       switch (col->col_type) {
-               case MDB_BOOL:
-                       return 1;
-               break;
-               case MDB_BYTE:
-                       return -1;
-               break;
-               case MDB_INT:
-                       return 2;
-               break;
-               case MDB_LONGINT:
-                       return 4;
-               break;
-               case MDB_FLOAT:
-                       return 4;
-               break;
-               case MDB_DOUBLE:
-                       return 8;
-               break;
-               case MDB_TEXT:
-                       return -1;
-               break;
-               case MDB_SDATETIME:
-                       return 4;
-               break;
-               case MDB_MEMO:
-                       return -1; 
-               break;
-               case MDB_MONEY:
-                       return 8;
-               break;
-       }
-       return 0;
-}
diff --git a/navit/data/poi_geodownload/libmdb/dump.c b/navit/data/poi_geodownload/libmdb/dump.c
deleted file mode 100644 (file)
index 7ee17f9..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-#include <ctype.h>
-#include <string.h>
-#include <stdio.h>
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-void buffer_dump(const unsigned char* buf, int start, int end)
-{
-       char asc[20];
-       int j, k;
-
-       memset(asc, 0, sizeof(asc));
-       k = 0;
-       for (j=start; j<=end; j++) {
-               if (k == 0) {
-                       fprintf(stdout, "%04x  ", j);
-               }
-               fprintf(stdout, "%02x ", buf[j]);
-               asc[k] = isprint(buf[j]) ? buf[j] : '.';
-               k++;
-               if (k == 8) {
-                       fprintf(stdout, " ");
-               }
-               if (k == 16) {
-                       fprintf(stdout, "  %s\n", asc);
-                       memset(asc, 0, sizeof(asc));
-                       k = 0;
-               }
-       }
-       for (j=k; j<16; j++) {
-               fprintf(stdout, "   ");
-       }
-       if (k < 8) {
-               fprintf(stdout, " ");
-       }
-       fprintf(stdout, "  %s\n", asc);
-}
diff --git a/navit/data/poi_geodownload/libmdb/file.c b/navit/data/poi_geodownload/libmdb/file.c
deleted file mode 100644 (file)
index 941830c..0000000
+++ /dev/null
@@ -1,376 +0,0 @@
-/* MDB Tools - A library for reading MS Access database files
- * Copyright (C) 2000 Brian Bruns
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "mdbtools.h"
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-/*
-typedef struct {
-       int             pg_size;
-       guint16         row_count_offset; 
-       guint16         tab_num_rows_offset;
-       guint16         tab_num_cols_offset;
-       guint16         tab_num_idxs_offset;
-       guint16         tab_num_ridxs_offset;
-       guint16         tab_usage_map_offset;
-       guint16         tab_first_dpg_offset;
-       guint16         tab_cols_start_offset;
-       guint16         tab_ridx_entry_size;
-       guint16         col_fixed_offset;
-       guint16         col_size_offset;
-       guint16         col_num_offset;
-       guint16         tab_col_entry_size;
-       guint16         tab_free_map_offset;
-       guint16         tab_col_offset_var;
-       guint16         tab_col_offset_fixed;
-       guint16         tab_row_col_num_offset;
-} MdbFormatConstants; 
-*/
-MdbFormatConstants MdbJet4Constants = {
-       4096, 0x0c, 16, 45, 47, 51, 55, 56, 63, 12, 15, 23, 5, 25, 59, 7, 21, 9
-};
-MdbFormatConstants MdbJet3Constants = {
-       2048, 0x08, 12, 25, 27, 31, 35, 36, 43, 8, 13, 16, 1, 18, 39, 3, 14, 5 /* not sure on 5, need to check */
-};
-
-static ssize_t _mdb_read_pg(MdbHandle *mdb, unsigned char *pg_buf, unsigned long pg);
-
-/**
- * mdb_find_file:
- * @filename: path to MDB (database) file
- *
- * Finds and returns the absolute path to an MDB file.  Function will first try
- * to fstat file as passed, then search through the $MDBPATH if not found.
- *
- * Return value: gchar pointer to absolute path. Caller is responsible for
- * freeing.
- **/
-
-static gchar *mdb_find_file(char *file_name)
-{
-       struct stat status;
-       gchar *mdbpath, **dir, *tmpfname;
-       unsigned int i = 0;
-
-       /* try the provided file name first */
-       if (!stat(file_name, &status)) {
-               return g_strdup(file_name);
-       }
-       
-       /* Now pull apart $MDBPATH and try those */
-       mdbpath = (gchar *) getenv("MDBPATH");
-       /* no path, can't find file */
-       if (!mdbpath || !strlen(mdbpath)) return NULL;
-
-       dir = g_strsplit(mdbpath, ":", 0); 
-       while (dir[i]) {
-               if (!strlen(dir[i])) continue;
-               tmpfname = g_strconcat(dir[i++], "/", file_name, NULL);
-               if (!stat(tmpfname, &status)) {
-                       g_strfreev(dir);
-                       return tmpfname;
-               }
-               g_free(tmpfname);
-       }
-       g_strfreev(dir);
-       return NULL;
-}
-/**
- * mdb_open:
- * @filename: path to MDB (database) file
- * @flags: MDB_NOFLAGS for read-only, MDB_WRITABLE for read/write
- *
- * Opens an MDB file and returns an MdbHandle to it.  MDB File may be relative
- * to the current directory, a full path to the file, or relative to a 
- * component of $MDBPATH.
- *
- * Return value: pointer to MdbHandle structure.
- **/
-MdbHandle *mdb_open(char *filename, MdbFileFlags flags)
-{
-       MdbHandle *mdb;
-
-       mdb = (MdbHandle *) g_malloc0(sizeof(MdbHandle));
-       mdb_set_default_backend(mdb, "access");
-       /* need something to bootstrap with, reassign after page 0 is read */
-       mdb->fmt = &MdbJet3Constants;
-       mdb->f = (MdbFile *) g_malloc0(sizeof(MdbFile));
-       mdb->f->refs = 1;
-       mdb->f->fd = -1;
-       mdb->f->filename = (char *) mdb_find_file(filename);
-       if (!mdb->f->filename) { 
-               fprintf(stderr, "Can't alloc filename\n");
-               mdb_close(mdb);
-               return NULL; 
-       }
-       if (flags & MDB_WRITABLE) {
-               mdb->f->writable = TRUE;
-               mdb->f->fd = open(mdb->f->filename,O_RDWR);
-       } else {
-               mdb->f->fd = open(mdb->f->filename,O_RDONLY);
-       }
-
-       if (mdb->f->fd==-1) {
-               fprintf(stderr,"Couldn't open file %s\n",mdb->f->filename); 
-               mdb_close(mdb);
-               return NULL;
-       }
-       if (!mdb_read_pg(mdb, 0)) {
-               fprintf(stderr,"Couldn't read first page.\n");
-               mdb_close(mdb);
-               return NULL;
-       }
-       if (mdb->pg_buf[0] != 0) {
-               mdb_close(mdb);
-               return NULL; 
-       }
-       mdb->f->jet_version = mdb_pg_get_int32(mdb, 0x14);
-       if (IS_JET4(mdb)) {
-               mdb->fmt = &MdbJet4Constants;
-       } else if (IS_JET3(mdb)) {
-               mdb->fmt = &MdbJet3Constants;
-       } else {
-               fprintf(stderr,"Unknown Jet version.\n");
-               mdb_close(mdb);
-               return NULL; 
-       }
-
-       return mdb;
-}
-
-/**
- * mdb_close:
- * @mdb: Handle to open MDB database file
- *
- * Dereferences MDB file, closes if reference count is 0, and destroys handle.
- *
- **/
-void 
-mdb_close(MdbHandle *mdb)
-{
-       if (!mdb) return;       
-       mdb_free_catalog(mdb);
-       g_free(mdb->stats);
-       g_free(mdb->backend_name);
-
-       if (mdb->f) {
-               if (mdb->f->refs > 1) {
-                       mdb->f->refs--;
-               } else {
-                       if (mdb->f->fd != -1) close(mdb->f->fd);
-                       g_free(mdb->f->filename);
-                       g_free(mdb->f);
-               }
-       }
-
-       g_free(mdb);
-}
-/**
- * mdb_clone_handle:
- * @mdb: Handle to open MDB database file
- *
- * Clones an existing database handle.  Cloned handle shares the file descriptor
- * but has its own page buffer, page position, and similar internal variables.
- *
- * Return value: new handle to the database.
- */
-MdbHandle *mdb_clone_handle(MdbHandle *mdb)
-{
-       MdbHandle *newmdb;
-       MdbCatalogEntry *entry, *data;
-       unsigned int i;
-
-       newmdb = (MdbHandle *) g_memdup(mdb, sizeof(MdbHandle));
-       newmdb->stats = NULL;
-       newmdb->catalog = g_ptr_array_new();
-       for (i=0;i<mdb->num_catalog;i++) {
-               entry = g_ptr_array_index(mdb->catalog,i);
-               data = g_memdup(entry,sizeof(MdbCatalogEntry));
-               g_ptr_array_add(newmdb->catalog, data);
-       }
-       mdb->backend_name = NULL;
-       if (mdb->f) {
-               mdb->f->refs++;
-       }
-       return newmdb;
-}
-
-/* 
-** mdb_read a wrapper for read that bails if anything is wrong 
-*/
-ssize_t mdb_read_pg(MdbHandle *mdb, unsigned long pg)
-{
-       ssize_t len;
-
-       if (pg && mdb->cur_pg == pg) return mdb->fmt->pg_size;
-
-       len = _mdb_read_pg(mdb, mdb->pg_buf, pg);
-       //fprintf(stderr, "read page %d type %02x\n", pg, mdb->pg_buf[0]);
-       mdb->cur_pg = pg;
-       /* kan - reset the cur_pos on a new page read */
-       mdb->cur_pos = 0; /* kan */
-       return len;
-}
-ssize_t mdb_read_alt_pg(MdbHandle *mdb, unsigned long pg)
-{
-       ssize_t len;
-
-       len = _mdb_read_pg(mdb, mdb->alt_pg_buf, pg);
-       return len;
-}
-static ssize_t _mdb_read_pg(MdbHandle *mdb, unsigned char *pg_buf, unsigned long pg)
-{
-       ssize_t len;
-       struct stat status;
-       off_t offset = pg * mdb->fmt->pg_size;
-
-        fstat(mdb->f->fd, &status);
-        if (status.st_size < offset) { 
-                fprintf(stderr,"offset %lu is beyond EOF\n",offset);
-                return 0;
-        }
-       if (mdb->stats && mdb->stats->collect) 
-               mdb->stats->pg_reads++;
-
-       lseek(mdb->f->fd, offset, SEEK_SET);
-       len = read(mdb->f->fd,pg_buf,mdb->fmt->pg_size);
-       if (len==-1) {
-               perror("read");
-               return 0;
-       }
-       else if (len<mdb->fmt->pg_size) {
-               /* fprintf(stderr,"EOF reached %d bytes returned.\n",len, mdb->fmt->pg_size); */
-               return 0;
-       } 
-       return len;
-}
-void mdb_swap_pgbuf(MdbHandle *mdb)
-{
-char tmpbuf[MDB_PGSIZE];
-
-       memcpy(tmpbuf,mdb->pg_buf, MDB_PGSIZE);
-       memcpy(mdb->pg_buf,mdb->alt_pg_buf, MDB_PGSIZE);
-       memcpy(mdb->alt_pg_buf,tmpbuf,MDB_PGSIZE);
-}
-
-
-/* really stupid, just here for consistancy */
-unsigned char mdb_get_byte(unsigned char *buf, int offset)
-{
-       return buf[offset];
-}
-unsigned char mdb_pg_get_byte(MdbHandle *mdb, int offset)
-{
-       if (offset < 0 || offset+1 > mdb->fmt->pg_size) return -1;
-       mdb->cur_pos++;
-       return mdb->pg_buf[offset];
-}
-
-int mdb_get_int16(unsigned char *buf, int offset)
-{
-       return buf[offset+1]*256+buf[offset];
-}
-int mdb_pg_get_int16(MdbHandle *mdb, int offset)
-{
-       if (offset < 0 || offset+2 > mdb->fmt->pg_size) return -1;
-       mdb->cur_pos+=2;
-       return mdb_get_int16(mdb->pg_buf, offset);
-}
-
-gint32 mdb_pg_get_int24_msb(MdbHandle *mdb, int offset)
-{
-       gint32 l = 0;
-       if (offset <0 || offset+3 > mdb->fmt->pg_size) return -1;
-       mdb->cur_pos+=3;
-       memcpy((char *)&l+1, &(mdb->pg_buf[offset]), 3);
-#if 0
-       printf("l=0x%08x 0x%08x\n",l,GINT32_FROM_BE(l));
-#endif
-       return GINT32_FROM_BE(l);
-}
-gint32 mdb_get_int24(unsigned char *buf, int offset)
-{
-       gint32 l = 0;
-       memcpy(&l, &buf[offset], 3);
-       return GINT32_FROM_LE(l);
-}
-gint32 mdb_pg_get_int24(MdbHandle *mdb, int offset)
-{
-       if (offset <0 || offset+3 > mdb->fmt->pg_size) return -1;
-       mdb->cur_pos+=3;
-       return mdb_get_int24(mdb->pg_buf, offset);
-}
-
-long mdb_get_int32(unsigned char *buf, int offset)
-{
-       guint32 l;
-       memcpy(&l, &buf[offset], 4);
-       return (long)GINT32_FROM_LE(l);
-}
-long mdb_pg_get_int32(MdbHandle *mdb, int offset)
-{
-       if (offset <0 || offset+4 > mdb->fmt->pg_size) return -1;
-       mdb->cur_pos+=4;
-       return mdb_get_int32(mdb->pg_buf, offset);
-}
-
-float mdb_get_single(unsigned char *buf, int offset)
-{
-       union {guint32 g; float f;} f;
-       memcpy(&f, &buf[offset], 4);
-       f.g = GUINT32_FROM_LE(f.g);
-       return f.f;
-}
-float mdb_pg_get_single(MdbHandle *mdb, int offset)
-{
-       if (offset <0 || offset+4 > mdb->fmt->pg_size) return -1;
-       mdb->cur_pos+=4;
-       return mdb_get_single(mdb->pg_buf, offset);
-}
-
-double mdb_get_double(unsigned char *buf, int offset)
-{
-       union {guint64 g; double d;} d;
-       memcpy(&d, &buf[offset], 8);
-       d.g = GUINT64_FROM_LE(d.g);
-       return d.d;
-}
-double mdb_pg_get_double(MdbHandle *mdb, int offset)
-{
-       if (offset <0 || offset+8 > mdb->fmt->pg_size) return -1;
-       mdb->cur_pos+=8;
-       return mdb_get_double(mdb->pg_buf, offset);
-}
-
-
-int 
-mdb_set_pos(MdbHandle *mdb, int pos)
-{
-       if (pos<0 || pos >= mdb->fmt->pg_size) return 0;
-
-       mdb->cur_pos=pos;
-       return pos;
-}
-int mdb_get_pos(MdbHandle *mdb)
-{
-       return mdb->cur_pos;
-}
diff --git a/navit/data/poi_geodownload/libmdb/iconv.c b/navit/data/poi_geodownload/libmdb/iconv.c
deleted file mode 100644 (file)
index 9f41afe..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/* MDB Tools - A library for reading MS Access database files
- * Copyright (C) 2000 Brian Bruns
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "mdbtools.h"
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-int
-mdb_unicode2ascii(MdbHandle *mdb, unsigned char *buf, int offset, unsigned int len, char *dest)
-{
-       unsigned int i;
-
-       if (buf[offset]==0xff && buf[offset+1]==0xfe) {
-               strncpy(dest, &buf[offset+2], len-2);
-               dest[len-2]='\0';
-       } else {
-               /* convert unicode to ascii, rather sloppily */
-               for (i=0;i<len;i+=2)
-                       dest[i/2] = buf[offset + i];
-               dest[len/2]='\0';
-       }
-       return len;
-}
-
-int
-mdb_ascii2unicode(MdbHandle *mdb, unsigned char *buf, int offset, unsigned int len, char *dest)
-{
-       unsigned int i = 0;
-
-       if (!buf) return 0;
-
-       if (IS_JET3(mdb)) {
-               strncpy(dest, &buf[offset], len);
-               dest[len]='\0';
-               return strlen(dest);
-       }
-
-       while (i<strlen(&buf[offset]) && (i*2+2)<len) {
-               dest[i*2] = buf[offset+i];
-               dest[i*2+1] = 0;
-               i++;
-       }
-
-       return (i*2);
-}
diff --git a/navit/data/poi_geodownload/libmdb/include/Makefile.am b/navit/data/poi_geodownload/libmdb/include/Makefile.am
deleted file mode 100644 (file)
index 084a754..0000000
+++ /dev/null
@@ -1 +0,0 @@
-EXTRA_DIST = mdbtools.h
diff --git a/navit/data/poi_geodownload/libmdb/include/mdbtools.h b/navit/data/poi_geodownload/libmdb/include/mdbtools.h
deleted file mode 100644 (file)
index b17df28..0000000
+++ /dev/null
@@ -1,536 +0,0 @@
-/* MDB Tools - A library for reading MS Access database files
- * Copyright (C) 2000 Brian Bruns
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef _mdbtools_h_
-#define _mdbtools_h_
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <string.h>
-#include <glib.h>
-
-#ifdef HAVE_ICONV
-#include <iconv.h>
-#endif
-
-#define MDB_DEBUG 0
-
-#define MDB_PGSIZE 4096
-#define MDB_MAX_OBJ_NAME 256
-#define MDB_MAX_COLS 256
-#define MDB_MAX_IDX_COLS 10
-#define MDB_CATALOG_PG 18
-#define MDB_MEMO_OVERHEAD 12
-#define MDB_BIND_SIZE 16384
-
-enum {
-       MDB_PAGE_DB = 0,
-       MDB_PAGE_DATA,
-       MDB_PAGE_TABLE,
-       MDB_PAGE_INDEX,
-       MDB_PAGE_LEAF,
-       MDB_PAGE_MAP
-};
-enum {
-       MDB_VER_JET3 = 0,
-       MDB_VER_JET4 = 1
-};
-enum {
-       MDB_FORM = 0,
-       MDB_TABLE,
-       MDB_MACRO,
-       MDB_SYSTEM_TABLE,
-       MDB_REPORT,
-       MDB_QUERY,
-       MDB_LINKED_TABLE,
-       MDB_MODULE,
-       MDB_RELATIONSHIP,
-       MDB_UNKNOWN_09,
-       MDB_UNKNOWN_0A,
-       MDB_DATABASE_PROPERTY,
-       MDB_ANY = -1
-};
-enum {
-       MDB_BOOL = 0x01,
-       MDB_BYTE = 0x02,
-       MDB_INT = 0x03,
-       MDB_LONGINT = 0x04,
-       MDB_MONEY = 0x05,
-       MDB_FLOAT = 0x06,
-       MDB_DOUBLE = 0x07,
-       MDB_SDATETIME = 0x08,
-       MDB_TEXT = 0x0a,
-       MDB_OLE = 0x0b,
-       MDB_MEMO = 0x0c,
-       MDB_REPID = 0x0f,
-       MDB_NUMERIC = 0x10
-};
-
-/* SARG operators */
-enum {
-       MDB_OR = 1,
-       MDB_AND,
-       MDB_NOT,
-       MDB_EQUAL,
-       MDB_GT,
-       MDB_LT,
-       MDB_GTEQ,
-       MDB_LTEQ,
-       MDB_LIKE,
-       MDB_ISNULL,
-       MDB_NOTNULL
-};
-
-typedef enum {
-       MDB_TABLE_SCAN,
-       MDB_LEAF_SCAN,
-       MDB_INDEX_SCAN
-} MdbStrategy;
-
-typedef enum {
-       MDB_NOFLAGS = 0x00,
-       MDB_WRITABLE = 0x01
-} MdbFileFlags;
-
-enum {
-       MDB_DEBUG_LIKE = 0x0001,
-       MDB_DEBUG_WRITE = 0x0002,
-       MDB_DEBUG_USAGE = 0x0004,
-       MDB_DEBUG_OLE = 0x0008,
-       MDB_DEBUG_ROW = 0x0010,
-       MDB_USE_INDEX = 0x0020
-};
-
-#define mdb_is_logical_op(x) (x == MDB_OR || \
-                               x == MDB_AND || \
-                               x == MDB_NOT )
-
-#define mdb_is_relational_op(x) (x == MDB_EQUAL || \
-                               x == MDB_GT || \
-                               x == MDB_LT || \
-                               x == MDB_GTEQ || \
-                               x == MDB_LTEQ || \
-                               x == MDB_LIKE || \
-                               x == MDB_ISNULL || \
-                               x == MDB_NOTNULL )
-
-enum {
-       MDB_ASC,
-       MDB_DESC
-};
-
-enum {
-       MDB_IDX_UNIQUE = 0x01,
-       MDB_IDX_IGNORENULLS = 0x02,
-       MDB_IDX_REQUIRED = 0x08 
-};
-
-#define IS_JET4(mdb) (mdb->f->jet_version==MDB_VER_JET4)
-#define IS_JET3(mdb) (mdb->f->jet_version==MDB_VER_JET3)
-
-/* hash to store registered backends */
-/* extern GHashTable   *mdb_backends; */
-
-/* forward declarations */
-typedef struct mdbindex MdbIndex;
-typedef struct mdbsargtree MdbSargNode;
-
-typedef struct {
-       char *name;
-       unsigned char needs_length; /* or precision */
-       unsigned char needs_scale;
-       unsigned char needs_quotes;
-} MdbBackendType;
-               
-typedef struct {
-        MdbBackendType *types_table;
-} MdbBackend;
-
-typedef struct {
-       gboolean collect;
-       unsigned long pg_reads;
-} MdbStatistics;
-
-typedef struct {
-       int           fd;
-       gboolean      writable;
-       char          *filename;
-       guint32         jet_version;
-       guint32         db_key;
-       char            db_passwd[14];
-       MdbBackend      *default_backend;
-       char                    *backend_name;
-       MdbStatistics   *stats;
-       /* free map */
-       int  map_sz;
-       unsigned char *free_map;
-       /* reference count */
-       int refs;
-} MdbFile; 
-
-/* offset to row count on data pages...version dependant */
-typedef struct {
-       int             pg_size;
-       guint16         row_count_offset; 
-       guint16         tab_num_rows_offset;
-       guint16         tab_num_cols_offset;
-       guint16         tab_num_idxs_offset;
-       guint16         tab_num_ridxs_offset;
-       guint16         tab_usage_map_offset;
-       guint16         tab_first_dpg_offset;
-       guint16         tab_cols_start_offset;
-       guint16         tab_ridx_entry_size;
-       guint16         col_fixed_offset;
-       guint16         col_size_offset;
-       guint16         col_num_offset;
-       guint16         tab_col_entry_size;
-       guint16         tab_free_map_offset;
-       guint16         tab_col_offset_var;
-       guint16         tab_col_offset_fixed;
-       guint16         tab_row_col_num_offset;
-} MdbFormatConstants; 
-
-typedef struct {
-       MdbFile       *f;
-       guint32       cur_pg;
-       guint16       row_num;
-       unsigned int  cur_pos;
-       unsigned char pg_buf[MDB_PGSIZE];
-       unsigned char alt_pg_buf[MDB_PGSIZE];
-       unsigned int  num_catalog;
-       GPtrArray       *catalog;
-       MdbBackend      *default_backend;
-       char            *backend_name;
-       MdbFormatConstants *fmt;
-       MdbStatistics *stats;
-#ifdef HAVE_ICONV
-       iconv_t iconv_out;
-#endif
-} MdbHandle; 
-
-typedef struct {
-       MdbHandle       *mdb;
-       char           object_name[MDB_MAX_OBJ_NAME+1];
-       int            object_type;
-       unsigned long  table_pg; /* misnomer since object may not be a table */
-       unsigned long  kkd_pg;
-       unsigned int   kkd_rowid;
-       int                     num_props;
-       GArray          *props;
-       GArray          *columns;
-       int             flags;
-} MdbCatalogEntry;
-
-typedef struct {
-       gchar *name;
-       GHashTable      *hash;
-} MdbProperties;
-
-typedef union {
-       int     i;
-       double  d;
-       char    s[256];
-} MdbAny;
-
-typedef struct {
-       char            name[MDB_MAX_OBJ_NAME+1];
-       int             col_type;
-       int             col_size;
-       void    *bind_ptr;
-       int             *len_ptr;
-       GHashTable      *properties;
-       unsigned int    num_sargs;
-       GPtrArray       *sargs;
-       GPtrArray       *idx_sarg_cache;
-       unsigned char   is_fixed;
-       int             query_order;
-       /* col_num is the current column order, 
-        * does not include deletes */
-       int             col_num;        
-       int             cur_value_start;
-       int             cur_value_len;
-       /* MEMO/OLE readers */
-       guint32         cur_blob_pg;
-       int             cur_blob_row;
-       int             chunk_size;
-       /* numerics only */
-       int             col_prec;
-       int             col_scale;
-       MdbProperties   *props;
-       /* info needed for handling deleted/added columns */
-       int             fixed_offset;
-       int             var_col_num;
-       /* row_col_num is the row column number order, 
-        * including deleted columns */
-       int             row_col_num;
-} MdbColumn;
-
-struct mdbsargtree {
-       int       op;
-       MdbColumn *col;
-       MdbAny    value;
-       void      *parent;
-       MdbSargNode *left;
-       MdbSargNode *right;
-};
-
-typedef struct {
-       guint32 pg;
-       int start_pos;
-       int offset;
-       int len;
-       guint16 idx_starts[2000];       
-       unsigned char cache_value[256];
-} MdbIndexPage;
-
-typedef int (*MdbSargTreeFunc)(MdbSargNode *, gpointer *data);
-
-#define MDB_MAX_INDEX_DEPTH 10
-
-typedef struct {
-       int cur_depth;
-       guint32 last_leaf_found;
-       int clean_up_mode;
-       MdbIndexPage pages[MDB_MAX_INDEX_DEPTH];
-} MdbIndexChain;
-
-typedef struct {
-       MdbCatalogEntry *entry;
-       char    name[MDB_MAX_OBJ_NAME+1];
-       unsigned int    num_cols;
-       GPtrArray       *columns;
-       unsigned int    num_rows;
-       int     index_start;
-       unsigned int    num_real_idxs;
-       unsigned int    num_idxs;
-       GPtrArray       *indices;
-       guint32 first_data_pg;
-       guint32 cur_pg_num;
-       guint32 cur_phys_pg;
-       unsigned int    cur_row;
-       int  noskip_del;  /* don't skip deleted rows */
-       /* object allocation map */
-       guint32  map_base_pg;
-       unsigned int  map_sz;
-       unsigned char *usage_map;
-       /* pages with free space left */
-       guint32  freemap_base_pg;
-       unsigned int  freemap_sz;
-       unsigned char *free_usage_map;
-       /* query planner */
-       MdbSargNode *sarg_tree;
-       MdbStrategy strategy;
-       MdbIndex *scan_idx;
-       MdbHandle *mdbidx;
-       MdbIndexChain *chain;
-       MdbProperties   *props;
-       unsigned int num_var_cols;  /* to know if row has variable columns */
-       /* temp table */
-       unsigned int  is_temp_table;
-       GPtrArray     *temp_table_pages;
-} MdbTableDef;
-
-struct mdbindex {
-       int             index_num;
-       char            name[MDB_MAX_OBJ_NAME+1];
-       unsigned char   index_type;
-       guint32         first_pg;
-       int             num_rows;  /* number rows in index */
-       unsigned int    num_keys;
-       short   key_col_num[MDB_MAX_IDX_COLS];
-       unsigned char   key_col_order[MDB_MAX_IDX_COLS];
-       unsigned char   flags;
-       MdbTableDef     *table;
-};
-
-typedef struct {
-       char            name[MDB_MAX_OBJ_NAME+1];
-} MdbColumnProp;
-
-typedef struct {
-       void *value;
-       int siz;
-       int start;
-       unsigned char is_null;
-       unsigned char is_fixed;
-       int colnum;
-       int offset;
-} MdbField;
-
-typedef struct {
-       int     op;
-       MdbAny  value;
-} MdbSarg;
-
-/* mem.c */
-extern void mdb_init(void);
-extern void mdb_exit(void);
-
-/* file.c */
-extern ssize_t mdb_read_pg(MdbHandle *mdb, unsigned long pg);
-extern ssize_t mdb_read_alt_pg(MdbHandle *mdb, unsigned long pg);
-extern unsigned char mdb_get_byte(unsigned char *buf, int offset);
-extern int    mdb_get_int16(unsigned char *buf, int offset);
-extern gint32   mdb_get_int24(unsigned char *buf, int offset);
-extern long   mdb_get_int32(unsigned char *buf, int offset);
-extern float  mdb_get_single(unsigned char *buf, int offset);
-extern double mdb_get_double(unsigned char *buf, int offset);
-extern unsigned char mdb_pg_get_byte(MdbHandle *mdb, int offset);
-extern int    mdb_pg_get_int16(MdbHandle *mdb, int offset);
-extern gint32   mdb_pg_get_int24(MdbHandle *mdb, int offset);
-extern long   mdb_pg_get_int32(MdbHandle *mdb, int offset);
-extern float  mdb_pg_get_single(MdbHandle *mdb, int offset);
-extern double mdb_pg_get_double(MdbHandle *mdb, int offset);
-extern gint32 mdb_pg_get_int24_msb(MdbHandle *mdb, int offset);
-extern MdbHandle *mdb_open(char *filename, MdbFileFlags flags);
-extern void mdb_close(MdbHandle *mdb);
-extern MdbHandle *mdb_clone_handle(MdbHandle *mdb);
-extern void mdb_swap_pgbuf(MdbHandle *mdb);
-extern long _mdb_get_int32(unsigned char *buf, int offset);
-
-/* catalog.c */
-extern void mdb_free_catalog(MdbHandle *mdb);
-extern GPtrArray *mdb_read_catalog(MdbHandle *mdb, int obj_type);
-extern void mdb_dump_catalog(MdbHandle *mdb, int obj_type);
-extern char *mdb_get_objtype_string(int obj_type);
-
-/* table.c */
-extern MdbTableDef *mdb_alloc_tabledef(MdbCatalogEntry *entry);
-extern void mdb_free_tabledef(MdbTableDef *table);
-extern MdbTableDef *mdb_read_table(MdbCatalogEntry *entry);
-extern MdbTableDef *mdb_read_table_by_name(MdbHandle *mdb, gchar *table_name, int obj_type);
-extern void mdb_append_column(GPtrArray *columns, MdbColumn *in_col);
-extern void mdb_free_columns(GPtrArray *columns);
-extern GPtrArray *mdb_read_columns(MdbTableDef *table);
-extern void mdb_table_dump(MdbCatalogEntry *entry);
-extern guint16 read_pg_if_16(MdbHandle *mdb, int *cur_pos);
-extern guint32 read_pg_if_32(MdbHandle *mdb, int *cur_pos);
-extern int read_pg_if(MdbHandle *mdb, int *cur_pos, int offset);
-extern guint16 read_pg_if_n(MdbHandle *mdb, unsigned char *buf, int *cur_pos, int len);
-extern int mdb_is_user_table(MdbCatalogEntry *entry);
-extern int mdb_is_system_table(MdbCatalogEntry *entry);
-
-/* data.c */
-extern int mdb_bind_column_by_name(MdbTableDef *table, gchar *col_name, void *bind_ptr);
-extern void mdb_data_dump(MdbTableDef *table);
-extern void mdb_bind_column(MdbTableDef *table, int col_num, void *bind_ptr);
-extern int mdb_rewind_table(MdbTableDef *table);
-extern int mdb_fetch_row(MdbTableDef *table);
-extern int mdb_is_fixed_col(MdbColumn *col);
-extern char *mdb_col_to_string(MdbHandle *mdb, unsigned char *buf, int start, int datatype, int size);
-extern int mdb_find_pg_row(MdbHandle *mdb, int pg_row, char **buf, int *off, int *len);
-extern int mdb_find_end_of_row(MdbHandle *mdb, int row);
-extern int mdb_col_fixed_size(MdbColumn *col);
-extern int mdb_col_disp_size(MdbColumn *col);
-extern void mdb_bind_len(MdbTableDef *table, int col_num, int *len_ptr);
-extern int mdb_ole_read_next(MdbHandle *mdb, MdbColumn *col, void *ole_ptr);
-extern int mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, int chunk_size);
-extern void mdb_set_date_fmt(const char *);
-extern int mdb_read_row(MdbTableDef *table, unsigned int row);
-
-/* dump.c */
-extern void buffer_dump(const unsigned char* buf, int start, int end);
-
-/* backend.c */
-extern char *mdb_get_coltype_string(MdbBackend *backend, int col_type);
-extern int  mdb_coltype_takes_length(MdbBackend *backend, int col_type);
-extern void mdb_init_backends(void);
-extern void mdb_register_backend(MdbBackendType *backend, char *backend_name);
-extern void mdb_remove_backends(void);
-extern int  mdb_set_default_backend(MdbHandle *mdb, char *backend_name);
-extern char *mdb_get_relationships(MdbHandle *mdb);
-
-/* sargs.c */
-extern int mdb_test_sargs(MdbTableDef *table, MdbField *fields, int num_fields);
-extern int mdb_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSargNode *node, MdbField *field);
-extern void mdb_sql_walk_tree(MdbSargNode *node, MdbSargTreeFunc func, gpointer data);
-extern int mdb_find_indexable_sargs(MdbSargNode *node, gpointer data);
-extern int mdb_add_sarg_by_name(MdbTableDef *table, char *colname, MdbSarg *in_sarg);
-extern int mdb_test_string(MdbSargNode *node, char *s);
-extern int mdb_test_int(MdbSargNode *node, gint32 i);
-extern int mdb_add_sarg(MdbColumn *col, MdbSarg *in_sarg);
-
-
-
-/* index.c */
-extern GPtrArray *mdb_read_indices(MdbTableDef *table);
-extern void mdb_index_dump(MdbTableDef *table, MdbIndex *idx);
-extern void mdb_index_scan_free(MdbTableDef *table);
-extern int mdb_index_find_next_on_page(MdbHandle *mdb, MdbIndexPage *ipg);
-extern int mdb_index_find_next(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 *pg, guint16 *row);
-extern void mdb_index_hash_text(guchar *text, guchar *hash);
-extern void mdb_index_scan_init(MdbHandle *mdb, MdbTableDef *table);
-extern int mdb_index_find_row(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 pg, guint16 row);
-extern void mdb_index_swap_n(unsigned char *src, int sz, unsigned char *dest);
-extern void mdb_free_indices(GPtrArray *indices);
-void mdb_index_page_reset(MdbIndexPage *ipg);
-extern MdbIndexPage *mdb_index_read_bottom_pg(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain);
-extern MdbIndexPage *mdb_index_unwind(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain);
-extern void mdb_index_page_init(MdbIndexPage *ipg);
-
-
-/* stats.c */
-extern void mdb_stats_on(MdbHandle *mdb);
-extern void mdb_stats_off(MdbHandle *mdb);
-extern void mdb_dump_stats(MdbHandle *mdb);
-
-/* like.c */
-extern int mdb_like_cmp(char *s, char *r);
-
-/* write.c */
-extern int mdb_crack_row(MdbTableDef *table, int row_start, int row_end, MdbField *fields);
-extern guint16 mdb_add_row_to_pg(MdbTableDef *table, unsigned char *row_buffer, int new_row_size);
-extern int mdb_update_index(MdbTableDef *table, MdbIndex *idx, unsigned int num_fields, MdbField *fields, guint32 pgnum, guint16 rownum);
-extern int mdb_pack_row(MdbTableDef *table, unsigned char *row_buffer, unsigned int num_fields, MdbField *fields);
-extern int mdb_replace_row(MdbTableDef *table, int row, unsigned char *new_row, int new_row_size);
-extern int mdb_pg_get_freespace(MdbHandle *mdb);
-extern int mdb_update_row(MdbTableDef *table);
-extern unsigned char *mdb_new_data_pg(MdbCatalogEntry *entry);
-
-/* map.c */
-extern guint32 mdb_map_find_next_freepage(MdbTableDef *table, int row_size);
-guint32 mdb_map_find_next(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg);
-
-/* props.c */
-extern GPtrArray *mdb_read_props_list(gchar *kkd, int len);
-extern void mdb_free_props(MdbProperties *props);
-extern MdbProperties *mdb_read_props(MdbHandle *mdb, GPtrArray *names, gchar *kkd, int len);
-
-/* worktable.c */
-extern MdbTableDef *mdb_create_temp_table(MdbHandle *mdb, char *name);
-extern void mdb_temp_table_add_col(MdbTableDef *table, MdbColumn *col);
-extern void mdb_fill_temp_col(MdbColumn *tcol, char *col_name, int col_size, int col_type, int is_fixed);
-extern void mdb_fill_temp_field(MdbField *field, void *value, int siz, int is_fixed, int is_null, int start, int column);
-extern void mdb_temp_columns_end(MdbTableDef *table);
-
-/* options.c */
-extern int mdb_get_option(unsigned long optnum);
-extern void mdb_debug(int klass, char *fmt, ...);
-
-/* iconv.c */
-extern int mdb_unicode2ascii(MdbHandle *mdb, unsigned char *buf, int offset, unsigned int len, char *dest);
-extern int mdb_ascii2unicode(MdbHandle *mdb, unsigned char *buf, int offset, unsigned int len, char *dest);
-
-#endif /* _mdbtools_h_ */
diff --git a/navit/data/poi_geodownload/libmdb/index.c b/navit/data/poi_geodownload/libmdb/index.c
deleted file mode 100644 (file)
index e840536..0000000
+++ /dev/null
@@ -1,905 +0,0 @@
-/* MDB Tools - A library for reading MS Access database file
- * Copyright (C) 2000-2004 Brian Bruns
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "mdbtools.h"
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-MdbIndexPage *mdb_index_read_bottom_pg(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain);
-MdbIndexPage *mdb_chain_add_page(MdbHandle *mdb, MdbIndexChain *chain, guint32 pg);
-
-char idx_to_text[] = {
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0-7     0x00-0x07 */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8-15    0x09-0x0f */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 16-23   0x10-0x17 */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 24-31   0x19-0x1f */
-' ',  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 32-39   0x20-0x27 */
-0x00, 0x00, 0x00, 0x00, 0x00, ' ',  ' ',  0x00, /* 40-47   0x29-0x2f */
-'V',  'W',  'X',  'Y',  'Z',  '[',  '\\', ']',  /* 48-55   0x30-0x37 */
-'^',  '_',  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 56-63   0x39-0x3f */
-0x00, '`',  'a',  'b',  'd',  'f',  'g',  'h',  /* 64-71   0x40-0x47 */
-'i',  'j',  'k',  'l',  'm',  'o',  'p',  'r',  /* 72-79   0x49-0x4f  H */
-'s',  't',  'u',  'v',  'w',  'x',  'z',  '{',  /* 80-87   0x50-0x57  P */
-'|',  '}',  '~',  '5',  '6',  '7',  '8',  '9',  /* 88-95   0x59-0x5f */
-0x00, '`',  'a',  'b',  'd',  'f',  'g',  'h',  /* 96-103  0x60-0x67 */
-'i',  'j',  'k',  'l',  'm',  'o',  'p',  'r',  /* 014-111 0x69-0x6f  h */
-'s',  't',  'u',  'v',  'w',  'x',  'z',  '{',  /* 112-119 0x70-0x77  p */
-'|',  '}',  '~',  0x00, 0x00, 0x00, 0x00, 0x00, /* 120-127 0x78-0x7f */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128-135 0x80-0x87 */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */
-0x00, 0x00, 0x00, 0x00, 0x00, '`',  0x00, 0x00, /* 0xc0-0xc7 */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */
-0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */
-0x00, '`',  0x00, '`',  '`',  '`',  0x00, 0x00, /* 0xe0-0xe7 */
-'f',  'f',  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */
-0x00, 0x00, 0x00, 'r',  0x00, 0x00, 'r',  0x00, /* 0xf0-0xf7 */
-0x81, 0x00, 0x00, 0x00, 'x',  0x00, 0x00, 0x00, /* 0xf8-0xff */
-};
-
-
-GPtrArray *
-mdb_read_indices(MdbTableDef *table)
-{
-       MdbCatalogEntry *entry = table->entry;
-       MdbHandle *mdb = entry->mdb;
-       MdbFormatConstants *fmt = mdb->fmt;
-       MdbIndex *pidx;
-       unsigned int i, j;
-       int idx_num, key_num, col_num;
-       int cur_pos, name_sz, idx2_sz, type_offset;
-       int index_start_pg = mdb->cur_pg;
-       gchar *tmpbuf;
-
-        table->indices = g_ptr_array_new();
-
-        if (IS_JET4(mdb)) {
-               cur_pos = table->index_start + 52 * table->num_real_idxs;
-               idx2_sz = 28;
-               type_offset = 23;
-       } else {
-               cur_pos = table->index_start + 39 * table->num_real_idxs;
-               idx2_sz = 20;
-               type_offset = 19;
-       }
-
-       tmpbuf = (gchar *) g_malloc(idx2_sz);
-       for (i=0;i<table->num_idxs;i++) {
-               read_pg_if_n(mdb, tmpbuf, &cur_pos, idx2_sz);
-               cur_pos += idx2_sz;
-               pidx = (MdbIndex *) g_malloc0(sizeof(MdbIndex));
-               pidx->table = table;
-               pidx->index_num = mdb_get_int16(tmpbuf, 4);
-               pidx->index_type = tmpbuf[type_offset]; 
-               g_ptr_array_add(table->indices, pidx);
-       }
-       g_free(tmpbuf);
-
-       for (i=0;i<table->num_idxs;i++) {
-               pidx = g_ptr_array_index (table->indices, i);
-               if (IS_JET4(mdb)) {
-                       name_sz=read_pg_if_16(mdb, &cur_pos);
-                       cur_pos += 2;
-                       tmpbuf = g_malloc(name_sz);
-                       read_pg_if_n(mdb, tmpbuf, &cur_pos, name_sz);
-                       cur_pos += name_sz;
-                       mdb_unicode2ascii(mdb, tmpbuf, 0, name_sz, pidx->name); 
-                       g_free(tmpbuf);
-               } else {
-                       read_pg_if(mdb, &cur_pos, 0);
-                       name_sz=mdb->pg_buf[cur_pos++];
-                       read_pg_if_n(mdb, pidx->name, &cur_pos, name_sz);
-                       cur_pos += name_sz;
-                       pidx->name[name_sz]='\0';               
-               }
-               //fprintf(stderr, "index name %s\n", pidx->name);
-       }
-
-       mdb_read_alt_pg(mdb, entry->table_pg);
-       mdb_read_pg(mdb, index_start_pg);
-       cur_pos = table->index_start;
-       idx_num=0;
-       for (i=0;i<table->num_real_idxs;i++) {
-               if (IS_JET4(mdb)) cur_pos += 4;
-               do {
-                       pidx = g_ptr_array_index (table->indices, idx_num++);
-               } while (pidx && pidx->index_type==2);
-
-               /* if there are more real indexes than index entries left after
-                  removing type 2's decrement real indexes and continue.  Happens
-                  on Northwind Orders table.
-               */
-               if (!pidx) {
-                       table->num_real_idxs--;
-                       continue;
-               }
-
-               pidx->num_rows = mdb_get_int32(mdb->alt_pg_buf, 
-                               fmt->tab_cols_start_offset +
-                               (i*fmt->tab_ridx_entry_size));
-
-               key_num=0;
-               for (j=0;j<MDB_MAX_IDX_COLS;j++) {
-                       col_num=read_pg_if_16(mdb,&cur_pos);
-                       cur_pos += 2;
-                       read_pg_if(mdb, &cur_pos, 0);
-                       cur_pos++;
-                       if (col_num == 0xFFFF)
-                               continue;
-                       /* set column number to a 1 based column number and store */
-                       pidx->key_col_num[key_num] = col_num + 1;
-                       pidx->key_col_order[key_num] =
-                               (mdb->pg_buf[cur_pos-1]) ? MDB_ASC : MDB_DESC;
-                       key_num++;
-               }
-               pidx->num_keys = key_num;
-
-               cur_pos += 4;
-               pidx->first_pg = read_pg_if_32(mdb, &cur_pos);
-               cur_pos += 4;
-               read_pg_if(mdb, &cur_pos, 0);
-               pidx->flags = mdb->pg_buf[cur_pos++];
-               if (IS_JET4(mdb)) cur_pos += 9;
-       }
-       return NULL;
-}
-void
-mdb_index_hash_text(guchar *text, guchar *hash)
-{
-       unsigned int k;
-
-       for (k=0;k<strlen(text);k++) {
-               hash[k] = idx_to_text[text[k]];
-               if (!(hash[k])) fprintf(stderr, 
-                               "No translation available for %02x %d\n", 
-                               text[k],text[k]);
-       }
-       hash[strlen(text)]=0;
-}
-void
-mdb_index_swap_n(unsigned char *src, int sz, unsigned char *dest)
-{
-       int i, j = 0;
-
-       for (i = sz; i > 0; i--) {
-               dest[j++] = src[i];
-       }
-}
-void 
-mdb_index_cache_sarg(MdbColumn *col, MdbSarg *sarg, MdbSarg *idx_sarg)
-{
-       //guint32 cache_int;
-       unsigned char *c;
-
-       switch (col->col_type) {
-               case MDB_TEXT:
-               mdb_index_hash_text(sarg->value.s, idx_sarg->value.s);
-               break;
-
-               case MDB_LONGINT:
-               idx_sarg->value.i = GUINT32_SWAP_LE_BE(sarg->value.i);
-               //cache_int = sarg->value.i * -1;
-               c = (unsigned char *) &(idx_sarg->value.i);
-               c[0] |= 0x80;
-               //printf("int %08x %02x %02x %02x %02x\n", sarg->value.i, c[0], c[1], c[2], c[3]);
-               break;  
-
-               case MDB_INT:
-               break;  
-
-               default:
-               break;  
-       }
-}
-#if 0
-int 
-mdb_index_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSarg *sarg, int offset, int len)
-{
-char tmpbuf[256];
-int lastchar;
-
-       switch (col->col_type) {
-               case MDB_BYTE:
-                       return mdb_test_int(sarg, mdb_pg_get_byte(mdb, offset));
-                       break;
-               case MDB_INT:
-                       return mdb_test_int(sarg, mdb_pg_get_int16(mdb, offset));
-                       break;
-               case MDB_LONGINT:
-                       return mdb_test_int(sarg, mdb_pg_get_int32(mdb, offset));
-                       break;
-               case MDB_TEXT:
-                       strncpy(tmpbuf, &mdb->pg_buf[offset],255);
-                       lastchar = len > 255 ? 255 : len;
-                       tmpbuf[lastchar]='\0';
-                       return mdb_test_string(sarg, tmpbuf);
-               default:
-                       fprintf(stderr, "Calling mdb_test_sarg on unknown type.  Add code to mdb_test_sarg() for type %d\n",col->col_type);
-                       break;
-       }
-       return 1;
-}
-#endif
-int
-mdb_index_test_sargs(MdbHandle *mdb, MdbIndex *idx, unsigned char *buf, int len)
-{
-       unsigned int i, j;
-       MdbColumn *col;
-       MdbTableDef *table = idx->table;
-       MdbSarg *idx_sarg;
-       MdbSarg *sarg;
-       MdbField field;
-       MdbSargNode node;
-       //int c_offset = 0, 
-       int c_len;
-
-#if 0
-       fprintf(stderr,"mdb_index_test_sargs called on ");
-       for (i=0;i<len;i++)
-               fprintf(stderr,"%02x ",buf[i]); //mdb->pg_buf[offset+i]);
-       fprintf(stderr,"\n");
-#endif
-       for (i=0;i<idx->num_keys;i++) {
-               //c_offset++; /* the per column null indicator/flags */
-               col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
-               /*
-                * This will go away eventually
-                */
-               if (col->col_type==MDB_TEXT) {
-                       //c_len = strlen(&mdb->pg_buf[offset + c_offset]);
-                       c_len = strlen(buf);
-               } else {
-                       c_len = col->col_size;
-                       //fprintf(stderr,"Only text types currently supported.  How did we get here?\n");
-               }
-               /*
-                * If we have no cached index values for this column, 
-                * create them.
-                */
-               if (col->num_sargs && !col->idx_sarg_cache) {
-                       col->idx_sarg_cache = g_ptr_array_new();
-                       for (j=0;j<col->num_sargs;j++) {
-                               sarg = g_ptr_array_index (col->sargs, j);
-                               idx_sarg = g_memdup(sarg,sizeof(MdbSarg));
-                               //printf("calling mdb_index_cache_sarg\n");
-                               mdb_index_cache_sarg(col, sarg, idx_sarg);
-                               g_ptr_array_add(col->idx_sarg_cache, idx_sarg);
-                       }
-               }
-
-               for (j=0;j<col->num_sargs;j++) {
-                       sarg = g_ptr_array_index (col->idx_sarg_cache, j);
-                       /* XXX - kludge */
-                       node.op = sarg->op;
-                       node.value = sarg->value;
-                       //field.value = &mdb->pg_buf[offset + c_offset];
-                       field.value = buf;
-                       field.siz = c_len;
-                       field.is_null = FALSE;
-                       if (!mdb_test_sarg(mdb, col, &node, &field)) {
-                               /* sarg didn't match, no sense going on */
-                               return 0;
-                       }
-               }
-       }
-       return 1;
-}
-/*
- * pack the pages bitmap
- */
-int
-mdb_index_pack_bitmap(MdbHandle *mdb, MdbIndexPage *ipg)
-{
-       int mask_bit = 0;
-       int mask_pos = 0x16;
-       int mask_byte = 0;
-       int elem = 0;
-       int len, start, i;
-
-       start = ipg->idx_starts[elem++];
-
-       while (start) {
-               len = ipg->idx_starts[elem] - start;
-               fprintf(stdout, "len is %d\n", len);
-               for (i=0; i < len; i++) {
-                       mask_bit++;
-                       if (mask_bit==8) {
-                               mask_bit=0;
-                               mdb->pg_buf[mask_pos++] = mask_byte;
-                               mask_byte = 0;
-                       }
-                       /* upon reaching the len, set the bit */
-               }
-               mask_byte = (1 << mask_bit) | mask_byte;
-               fprintf(stdout, "mask byte is %02x at %d\n", mask_byte, mask_pos);
-               start = ipg->idx_starts[elem++];
-       }
-       /* flush the last byte if any */
-       mdb->pg_buf[mask_pos++] = mask_byte;
-       /* remember to zero the rest of the bitmap */
-       for (i = mask_pos; i < 0xf8; i++) {
-               mdb->pg_buf[mask_pos++] = 0;
-       }
-       return 0;
-}
-/*
- * unpack the pages bitmap
- */
-int
-mdb_index_unpack_bitmap(MdbHandle *mdb, MdbIndexPage *ipg)
-{
-       int mask_bit = 0;
-       int mask_pos = 0x16;
-       int mask_byte;
-       int start = 0xf8;
-       int elem = 0;
-       int len = 0;
-
-       ipg->idx_starts[elem++]=start;
-
-#if 0
-       fprintf(stdout, "Unpacking index page %u\n", ipg->pg);
-#endif
-       do {
-               len = 0;
-               do {
-                       mask_bit++;
-                       if (mask_bit==8) {
-                               mask_bit=0;
-                               mask_pos++;
-                       }
-                       mask_byte = mdb->pg_buf[mask_pos];
-                       len++;
-               } while (mask_pos <= 0xf8 && !((1 << mask_bit) & mask_byte));
-               //fprintf(stdout, "%d %d %d %d\n", mask_pos, mask_bit, mask_byte, len);
-
-               start += len;
-               if (mask_pos < 0xf8) ipg->idx_starts[elem++]=start;
-
-       } while (mask_pos < 0xf8);
-
-       /* if we zero the next element, so we don't pick up the last pages starts*/
-       ipg->idx_starts[elem]=0;
-
-       return elem;
-}
-/*
- * find the next entry on a page (either index or leaf). Uses state information
- * stored in the MdbIndexPage across calls.
- */
-int
-mdb_index_find_next_on_page(MdbHandle *mdb, MdbIndexPage *ipg)
-{
-       if (!ipg->pg) return 0;
-
-       /* if this page has not been unpacked to it */
-       if (!ipg->idx_starts[0]){
-               //fprintf(stdout, "Unpacking page %d\n", ipg->pg);
-               mdb_index_unpack_bitmap(mdb, ipg);
-       }
-
-       
-       if (ipg->idx_starts[ipg->start_pos + 1]==0) return 0; 
-       ipg->len = ipg->idx_starts[ipg->start_pos+1] - ipg->idx_starts[ipg->start_pos];
-       ipg->start_pos++;
-       //fprintf(stdout, "Start pos %d\n", ipg->start_pos);
-
-       return ipg->len;
-}
-void mdb_index_page_reset(MdbIndexPage *ipg)
-{
-       ipg->offset = 0xf8; /* start byte of the index entries */
-       ipg->start_pos=0;
-       ipg->len = 0; 
-       ipg->idx_starts[0]=0;
-}
-void mdb_index_page_init(MdbIndexPage *ipg)
-{
-       memset(ipg, 0, sizeof(MdbIndexPage));
-       mdb_index_page_reset(ipg);
-}
-/*
- * find the next leaf page if any given a chain. Assumes any exhausted leaf 
- * pages at the end of the chain have been peeled off before the call.
- */
-MdbIndexPage *
-mdb_find_next_leaf(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
-{
-       MdbIndexPage *ipg, *newipg;
-       guint32 pg;
-       guint passed = 0;
-
-       ipg = mdb_index_read_bottom_pg(mdb, idx, chain);
-
-       /*
-        * If we are at the first page deep and it's not an index page then
-        * we are simply done. (there is no page to find
-        */
-
-       if (mdb->pg_buf[0]==MDB_PAGE_LEAF) {
-               /* Indexes can have leaves at the end that don't appear
-                * in the upper tree, stash the last index found so
-                * we can follow it at the end.  */
-               chain->last_leaf_found = ipg->pg;
-               return ipg;
-       }
-
-       /*
-        * apply sargs here, currently we don't
-        */
-       do {
-               ipg->len = 0;
-               //printf("finding next on pg %lu\n", ipg->pg);
-               if (!mdb_index_find_next_on_page(mdb, ipg)) {
-                       //printf("find_next_on_page returned 0\n");
-                       return 0;
-               }
-               pg = mdb_pg_get_int24_msb(mdb, ipg->offset + ipg->len - 3);
-               //printf("Looking at pg %lu at %lu %d\n", pg, ipg->offset, ipg->len);
-               ipg->offset += ipg->len;
-
-               /*
-                * add to the chain and call this function
-                * recursively.
-                */
-               newipg = mdb_chain_add_page(mdb, chain, pg);
-               newipg = mdb_find_next_leaf(mdb, idx, chain);
-               //printf("returning pg %lu\n",newipg->pg);
-               return newipg;
-       } while (!passed);
-       /* no more pages */
-       return NULL;
-
-}
-MdbIndexPage *
-mdb_chain_add_page(MdbHandle *mdb, MdbIndexChain *chain, guint32 pg)
-{
-       MdbIndexPage *ipg;
-
-       chain->cur_depth++;
-       if (chain->cur_depth > MDB_MAX_INDEX_DEPTH) {
-               fprintf(stderr,"Error! maximum index depth of %d exceeded.  This is probably due to a programming bug, If you are confident that your indexes really are this deep, adjust MDB_MAX_INDEX_DEPTH in mdbtools.h and recompile.\n", MDB_MAX_INDEX_DEPTH);
-               exit(1);
-       }
-       ipg = &(chain->pages[chain->cur_depth - 1]);
-       mdb_index_page_init(ipg);
-       ipg->pg = pg;
-
-       return ipg;
-}
-/*
- * returns the bottom page of the IndexChain, if IndexChain is empty it 
- * initializes it by reading idx->first_pg (the root page)
- */
-MdbIndexPage *
-mdb_index_read_bottom_pg(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
-{
-       MdbIndexPage *ipg;
-
-       /*
-        * if it's new use the root index page (idx->first_pg)
-        */
-       if (!chain->cur_depth) {
-               ipg = &(chain->pages[0]);
-               mdb_index_page_init(ipg);
-               chain->cur_depth = 1;
-               ipg->pg = idx->first_pg;
-               if (!(ipg = mdb_find_next_leaf(mdb, idx, chain)))
-                       return 0;
-       } else {
-               ipg = &(chain->pages[chain->cur_depth - 1]);
-               ipg->len = 0; 
-       }
-
-       mdb_read_pg(mdb, ipg->pg);
-
-       return ipg;
-}
-/*
- * unwind the stack and search for new leaf node
- */
-MdbIndexPage *
-mdb_index_unwind(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
-{
-       MdbIndexPage *ipg;
-
-       //printf("page %lu finished\n",ipg->pg);
-       if (chain->cur_depth==1) {
-               //printf("cur_depth == 1 we're out\n");
-               return NULL;
-       }
-       /* 
-       * unwind the stack until we find something or reach 
-       * the top.
-       */
-       ipg = NULL;
-       while (chain->cur_depth>1 && ipg==NULL) {
-               //printf("chain depth %d\n", chain->cur_depth);
-               chain->cur_depth--;
-               ipg = mdb_find_next_leaf(mdb, idx, chain);
-               if (ipg) mdb_index_find_next_on_page(mdb, ipg);
-       }
-       if (chain->cur_depth==1) {
-               //printf("last leaf %lu\n", chain->last_leaf_found);
-               return NULL;
-       }
-       return ipg;
-}
-/*
- * the main index function.
- * caller provides an index chain which is the current traversal of index
- * pages from the root page to the leaf.  Initially passed as blank, 
- * mdb_index_find_next will store it's state information here. Each invocation
- * then picks up where the last one left off, allowing us to scroll through
- * the index one by one.
- *
- * Sargs are applied here but also need to be applied on the whole row b/c
- * text columns may return false positives due to hashing and non-index
- * columns with sarg values can't be tested here.
- */
-int
-mdb_index_find_next(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 *pg, guint16 *row)
-{
-       MdbIndexPage *ipg;
-       int passed = 0;
-       int idx_sz;
-       int idx_start = 0;
-       MdbColumn *col;
-
-       ipg = mdb_index_read_bottom_pg(mdb, idx, chain);
-
-       /*
-        * loop while the sargs don't match
-        */
-       do {
-               ipg->len = 0;
-               /*
-                * if no more rows on this leaf, try to find a new leaf
-                */
-               if (!mdb_index_find_next_on_page(mdb, ipg)) {
-                       if (!chain->clean_up_mode) {
-                               if (!(ipg = mdb_index_unwind(mdb, idx, chain)))
-                                       chain->clean_up_mode = 1;
-                       }
-                       if (chain->clean_up_mode) {
-                               //fprintf(stdout,"in cleanup mode\n");
-
-                               if (!chain->last_leaf_found) return 0;
-                               mdb_read_pg(mdb, chain->last_leaf_found);
-                               chain->last_leaf_found = mdb_pg_get_int24(mdb, 0x0c);
-                               //printf("next leaf %lu\n", chain->last_leaf_found);
-                               mdb_read_pg(mdb, chain->last_leaf_found);
-                               /* reuse the chain for cleanup mode */
-                               chain->cur_depth = 1;
-                               ipg = &chain->pages[0];
-                               mdb_index_page_init(ipg);
-                               ipg->pg = chain->last_leaf_found;
-                               //printf("next on page %d\n",
-                               if (!mdb_index_find_next_on_page(mdb, ipg))
-                                       return 0;
-                       }
-               }
-               *row = mdb->pg_buf[ipg->offset + ipg->len - 1];
-#if 0
-               printf("page: ");
-               buffer_dump(mdb->pg_buf, ipg->offset+ipg->len-4, ipg->offset+ipg->len-2);
-#endif
-               *pg = mdb_pg_get_int24_msb(mdb, ipg->offset + ipg->len - 4);
-#if 0
-               printf("row = %d pg = %lu ipg->pg = %lu offset = %lu len = %d\n", *row, *pg, ipg->pg, ipg->offset, ipg->len);
-#endif
-               col=g_ptr_array_index(idx->table->columns,idx->key_col_num[0]-1);
-               idx_sz = mdb_col_fixed_size(col);
-               /* handle compressed indexes, single key indexes only? */
-               if (idx->num_keys==1 && idx_sz>0 && ipg->len - 4 < idx_sz) {
-#if 0
-                       printf("short index found\n");
-                       buffer_dump(ipg->cache_value, 0, idx_sz);
-#endif
-                       memcpy(&ipg->cache_value[idx_sz - (ipg->len - 4)], &mdb->pg_buf[ipg->offset], ipg->len);
-#if 0
-                       buffer_dump(ipg->cache_value, 0, idx_sz);
-#endif
-               } else {
-                       idx_start = ipg->offset + (ipg->len - 4 - idx_sz);
-                       memcpy(ipg->cache_value, &mdb->pg_buf[idx_start], idx_sz);
-               }
-
-               //idx_start = ipg->offset + (ipg->len - 4 - idx_sz);
-               passed = mdb_index_test_sargs(mdb, idx, ipg->cache_value, idx_sz);
-
-//             printf("passed=%d\n", passed);
-
-               buffer_dump(mdb->pg_buf, ipg->offset, ipg->offset+ipg->len-1);
-               ipg->offset += ipg->len;
-
-       } while (!passed);
-
-#if 0
-       fprintf(stdout,"len = %d pos %d\n", ipg->len, ipg->len);
-       buffer_dump(mdb->pg_buf, ipg->offset, ipg->offset+ipg->len-1);
-#endif
-
-       return ipg->len;
-}
-/*
- * XXX - FIX ME
- * This function is grossly inefficient.  It scans the entire index building 
- * an IndexChain to a specific row.  We should be checking the index pages 
- * for matches against the indexed fields to find the proper leaf page, but
- * getting it working first and then make it fast!
- */
-int 
-mdb_index_find_row(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 pg, guint16 row)
-{
-       MdbIndexPage *ipg;
-       int passed = 0;
-       guint32 datapg;
-       guint16 datarow;
-
-       ipg = mdb_index_read_bottom_pg(mdb, idx, chain);
-
-       do {
-               ipg->len = 0;
-               /*
-                * if no more rows on this leaf, try to find a new leaf
-                */
-               if (!mdb_index_find_next_on_page(mdb, ipg)) {
-                       /* back to top? We're done */
-                       if (chain->cur_depth==1)
-                               return 0;
-
-                       /* 
-                        * unwind the stack until we find something or reach 
-                        * the top.
-                        */
-                       while (chain->cur_depth>1) {
-                               chain->cur_depth--;
-                               if (!(ipg = mdb_find_next_leaf(mdb, idx, chain)))
-                                       return 0;
-                               mdb_index_find_next_on_page(mdb, ipg);
-                       }
-                       if (chain->cur_depth==1)
-                               return 0;
-               }
-               /* test row and pg */
-               datarow = mdb->pg_buf[ipg->offset + ipg->len - 1];
-               datapg = mdb_pg_get_int24_msb(mdb, ipg->offset + ipg->len - 4);
-
-               if (datapg == pg && datarow == row) {
-                       passed = 1;
-               }
-               ipg->offset += ipg->len;
-       } while (!passed);
-
-       /* index chain from root to leaf should now be in "chain" */
-       return 1;
-}
-
-void mdb_index_walk(MdbTableDef *table, MdbIndex *idx)
-{
-MdbHandle *mdb = table->entry->mdb;
-int cur_pos = 0;
-unsigned char marker;
-MdbColumn *col;
-unsigned int i;
-
-       if (idx->num_keys!=1) return;
-
-       mdb_read_pg(mdb, idx->first_pg);
-       cur_pos = 0xf8;
-       
-       for (i=0;i<idx->num_keys;i++) {
-               marker = mdb->pg_buf[cur_pos++];
-               col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
-               //printf("column %d coltype %d col_size %d (%d)\n",i,col->col_type, mdb_col_fixed_size(col), col->col_size);
-       }
-}
-void 
-mdb_index_dump(MdbTableDef *table, MdbIndex *idx)
-{
-       unsigned int i;
-       MdbColumn *col;
-
-       fprintf(stdout,"index number     %d\n", idx->index_num);
-       fprintf(stdout,"index name       %s\n", idx->name);
-       fprintf(stdout,"index first page %d\n", idx->first_pg);
-       fprintf(stdout,"index rows       %d\n", idx->num_rows);
-       if (idx->index_type==1) fprintf(stdout,"index is a primary key\n");
-       for (i=0;i<idx->num_keys;i++) {
-               col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
-               fprintf(stdout,"Column %s(%d) Sorted %s Unique: %s\n", 
-                       col->name,
-                       idx->key_col_num[i], 
-                       idx->key_col_order[i]==MDB_ASC ? "ascending" : "descending",
-                       idx->flags & MDB_IDX_UNIQUE ? "Yes" : "No"
-                       );
-       }
-       mdb_index_walk(table, idx);
-}
-/*
- * compute_cost tries to assign a cost to a given index using the sargs 
- * available in this query.
- *
- * Indexes with no matching sargs are assigned 0
- * Unique indexes are preferred over non-uniques
- * Operator preference is equal, like, isnull, others 
- */
-int mdb_index_compute_cost(MdbTableDef *table, MdbIndex *idx)
-{
-       unsigned int i;
-       MdbColumn *col;
-       MdbSarg *sarg = NULL;
-       int not_all_equal = 0;
-
-       if (!idx->num_keys) return 0;
-       if (idx->num_keys > 1) {
-               for (i=0;i<idx->num_keys;i++) {
-                       col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
-                       if (col->sargs) sarg = g_ptr_array_index (col->sargs, 0);
-                       if (!sarg || sarg->op != MDB_EQUAL) not_all_equal++;
-               }
-       }
-
-       col=g_ptr_array_index(table->columns,idx->key_col_num[0]-1);
-       /* 
-        * if this is the first key column and there are no sargs,
-        * then this index is useless.
-        */
-       if (!col->num_sargs) return 0;
-
-       sarg = g_ptr_array_index (col->sargs, 0);
-
-       /*
-        * a like with a wild card first is useless as a sarg */
-       if (sarg->op == MDB_LIKE && sarg->value.s[0]=='%')
-               return 0;
-
-       /*
-        * this needs a lot of tweaking.
-        */
-       if (idx->flags & MDB_IDX_UNIQUE) {
-               if (idx->num_keys == 1) {
-                       //printf("op is %d\n", sarg->op);
-                       switch (sarg->op) {
-                               case MDB_EQUAL:
-                                       return 1; break;
-                               case MDB_LIKE:
-                                       return 4; break;
-                               case MDB_ISNULL:
-                                       return 12; break;
-                               default:
-                                       return 8; break;
-                       }
-               } else {
-                       switch (sarg->op) {
-                               case MDB_EQUAL:
-                                       if (not_all_equal) return 2; 
-                                       else return 1;
-                                       break;
-                               case MDB_LIKE:
-                                       return 6; break;
-                               case MDB_ISNULL:
-                                       return 12; break;
-                               default:
-                                       return 9; break;
-                       }
-               }
-       } else {
-               if (idx->num_keys == 1) {
-                       switch (sarg->op) {
-                               case MDB_EQUAL:
-                                       return 2; break;
-                               case MDB_LIKE:
-                                       return 5; break;
-                               case MDB_ISNULL:
-                                       return 12; break;
-                               default:
-                                       return 10; break;
-                       }
-               } else {
-                       switch (sarg->op) {
-                               case MDB_EQUAL:
-                                       if (not_all_equal) return 3; 
-                                       else return 2;
-                                       break;
-                               case MDB_LIKE:
-                                       return 7; break;
-                               case MDB_ISNULL:
-                                       return 12; break;
-                               default:
-                                       return 11; break;
-                       }
-               }
-       }
-       return 0;
-}
-/*
- * choose_index runs mdb_index_compute_cost for each available index and picks
- * the best.
- *
- * Returns strategy to use (table scan, or index scan)
- */
-MdbStrategy 
-mdb_choose_index(MdbTableDef *table, int *choice)
-{
-       unsigned int i;
-       MdbIndex *idx;
-       int cost = 0;
-       int least = 99;
-
-       *choice = -1;
-       for (i=0;i<table->num_idxs;i++) {
-               idx = g_ptr_array_index (table->indices, i);
-               cost = mdb_index_compute_cost(table, idx);
-               //printf("cost for %s is %d\n", idx->name, cost);
-               if (cost && cost < least) {
-                       least = cost;
-                       *choice = i;
-               }
-       }
-       /* and the winner is: *choice */
-       if (least==99) return MDB_TABLE_SCAN;
-       return MDB_INDEX_SCAN;
-}
-void
-mdb_index_scan_init(MdbHandle *mdb, MdbTableDef *table)
-{
-       int i;
-
-       if (mdb_get_option(MDB_USE_INDEX) && mdb_choose_index(table, &i) == MDB_INDEX_SCAN) {
-               table->strategy = MDB_INDEX_SCAN;
-               table->scan_idx = g_ptr_array_index (table->indices, i);
-               table->chain = g_malloc0(sizeof(MdbIndexChain));
-               table->mdbidx = mdb_clone_handle(mdb);
-               mdb_read_pg(table->mdbidx, table->scan_idx->first_pg);
-               //printf("best index is %s\n",table->scan_idx->name);
-       }
-       //printf("TABLE SCAN? %d\n", table->strategy);
-}
-void 
-mdb_index_scan_free(MdbTableDef *table)
-{
-       if (table->chain) {
-               g_free(table->chain);
-               table->chain = NULL;
-       }
-       if (table->mdbidx) {
-               mdb_close(table->mdbidx);
-               table->mdbidx = NULL;
-       }
-}
-
-void mdb_free_indices(GPtrArray *indices)
-{
-       unsigned int i;
-
-       if (!indices) return;
-       for (i=0; i<indices->len; i++)
-               g_free (g_ptr_array_index(indices, i));
-       g_ptr_array_free(indices, TRUE);
-}
diff --git a/navit/data/poi_geodownload/libmdb/kkd.c b/navit/data/poi_geodownload/libmdb/kkd.c
deleted file mode 100644 (file)
index ea72887..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/* MDB Tools - A library for reading MS Access database file
- * Copyright (C) 2000 Brian Bruns
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "mdbtools.h"
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-
-/*
-** Note: This code is mostly garbage right now...just a test to parse out the
-**       KKD structures.
-*/
-
-GArray *mdb_get_column_props(MdbCatalogEntry *entry, int start)
-{
-int pos, cnt=0;
-int len, tmp, cplen;
-MdbColumnProp prop;
-MdbHandle *mdb = entry->mdb;
-
-       entry->props = g_array_new(FALSE,FALSE,sizeof(MdbColumnProp));
-       len = mdb_pg_get_int16(mdb,start);
-       pos = start + 6;
-       while (pos < start+len) {
-               tmp = mdb_pg_get_int16(mdb,pos); /* length of string */
-               pos += 2;
-               cplen = tmp > MDB_MAX_OBJ_NAME ? MDB_MAX_OBJ_NAME : tmp;
-               g_memmove(prop.name,&mdb->pg_buf[pos],cplen);
-               prop.name[cplen]='\0';
-               pos += tmp; 
-               g_array_append_val(entry->props, prop.name);
-               cnt++;
-       }
-       entry->num_props = cnt;
-       return entry->props;
-}
-
-GHashTable *mdb_get_column_def(MdbCatalogEntry *entry, int start)
-{
-GHashTable *hash = NULL;
-MdbHandle *mdb = entry->mdb;
-MdbColumnProp prop;
-int tmp, pos, col_num, val_len, i;
-int len, col_type;
-unsigned char c;
-int end;
-
-       fprintf(stdout,"\n data\n");
-       fprintf(stdout,"-------\n");
-       len = mdb_pg_get_int16(mdb,start);
-       fprintf(stdout,"length = %3d\n",len);
-       pos = start + 6;
-       end = start + len;
-       while (pos < end) {
-               fprintf(stdout,"pos = %3d\n",pos);
-               start = pos;
-               tmp = mdb_pg_get_int16(mdb,pos); /* length of field */
-               pos += 2;
-               col_type = mdb_pg_get_int16(mdb,pos); /* ??? */
-               pos += 2;
-               col_num = 0;
-               if (col_type) {
-                       col_num = mdb_pg_get_int16(mdb,pos); 
-                       pos += 2;
-               }
-               val_len = mdb_pg_get_int16(mdb,pos);
-               pos += 2;
-               fprintf(stdout,"length = %3d %04x %2d %2d ",tmp, col_type, col_num, val_len);
-               for (i=0;i<val_len;i++) {
-                       c = mdb->pg_buf[pos+i];
-                       if (isprint(c))
-                               fprintf(stdout,"  %c",c);
-                       else 
-                               fprintf(stdout," %02x",c);
-
-               }
-               pos = start + tmp; 
-               prop = g_array_index(entry->props,MdbColumnProp,col_num);
-               fprintf(stdout," Property %s",prop.name); 
-               fprintf(stdout,"\n");
-       }
-       return hash;
-}
-void mdb_kkd_dump(MdbCatalogEntry *entry)
-{
-int rows;
-int kkd_start, kkd_end;
-int i, tmp, pos, row_type, datapos=0;
-MdbColumnProp prop;
-MdbHandle *mdb = entry->mdb;
-int rowid = entry->kkd_rowid;
-
-
-       mdb_read_pg(mdb, entry->kkd_pg);
-       rows = mdb_pg_get_int16(mdb,8);
-       fprintf(stdout,"number of rows = %d\n",rows);
-       kkd_start = mdb_pg_get_int16(mdb,10+rowid*2);
-       fprintf(stdout,"kkd start = %d %04x\n",kkd_start,kkd_start);
-       kkd_end = mdb->fmt->pg_size;
-       for (i=0;i<rows;i++) {
-               tmp = mdb_pg_get_int16(mdb, 10+i*2);
-               if (tmp < mdb->fmt->pg_size &&
-                   tmp > kkd_start &&
-                   tmp < kkd_end) {
-                       kkd_end = tmp;
-               }
-       }
-       fprintf(stdout,"kkd end = %d %04x\n",kkd_end,kkd_end);
-       pos = kkd_start + 4; /* 4 = K K D \0 */
-       while (pos < kkd_end) {
-               tmp = mdb_pg_get_int16(mdb,pos);
-               row_type = mdb_pg_get_int16(mdb,pos+4);
-               fprintf(stdout,"row size = %3d type = 0x%02x\n",tmp,row_type);
-               if (row_type==0x80)  {
-                       fprintf(stdout,"\nColumn Properties\n");
-                       fprintf(stdout,"-----------------\n");
-                       mdb_get_column_props(entry,pos);
-                       for (i=0;i<entry->num_props;i++) {
-                               prop = g_array_index(entry->props,MdbColumnProp,i);
-                               fprintf(stdout,"%3d %s\n",i,prop.name); 
-                       }
-               }
-               if (row_type==0x01) datapos = pos;
-               pos += tmp;
-       }
-       
-       if (datapos) {
-               mdb_get_column_def(entry, datapos);
-       }
-}
-
diff --git a/navit/data/poi_geodownload/libmdb/like.c b/navit/data/poi_geodownload/libmdb/like.c
deleted file mode 100644 (file)
index 0a23d45..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/* MDB Tools - A library for reading MS Access database file
- * Copyright (C) 2000 Brian Bruns
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <mdbtools.h>
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-/**
- * mdb_like_cmp
- * @s: String to search within.
- * @r: Search pattern.
- *
- * Tests the string @s to see if it matches the search pattern @r.  In the
- * search pattern, a percent sign indicates matching on any number of
- * characters, and an underscore indicates matching any single character.
- *
- * Returns: 1 if the string matches, 0 if the string does not match.
- */
-int mdb_like_cmp(char *s, char *r)
-{
-       unsigned int i;
-       int ret;
-
-       mdb_debug(MDB_DEBUG_LIKE, "comparing %s and %s", s, r);
-       switch (r[0]) {
-               case '\0':
-                       if (s[0]=='\0') {
-                               return 1;
-                       } else {
-                               return 0;
-                       }
-               case '_':
-                       /* skip one character */
-                       return mdb_like_cmp(&s[1],&r[1]);
-               case '%':
-                       /* skip any number of characters */
-                       /* the strlen(s)+1 is important so the next call can */
-                       /* if there are trailing characters */
-                       for(i=0;i<strlen(s)+1;i++) {
-                               if (mdb_like_cmp(&s[i],&r[1])) {
-                                       return 1;
-                               }
-                       }
-                       return 0;
-               default:
-                       for(i=0;i<strlen(r);i++) {
-                               if (r[i]=='_' || r[i]=='%') break;
-                       }
-                       if (strncmp(s,r,i)) {
-                               return 0;
-                       } else {
-                               mdb_debug(MDB_DEBUG_LIKE, "at pos %d comparing %s and %s", i, &s[i], &r[i]);
-                               ret = mdb_like_cmp(&s[i],&r[i]);
-                               mdb_debug(MDB_DEBUG_LIKE, "returning %d (%s and %s)", ret, &s[i], &r[i]);
-                               return ret;
-                       }
-       }
-}
diff --git a/navit/data/poi_geodownload/libmdb/map.c b/navit/data/poi_geodownload/libmdb/map.c
deleted file mode 100644 (file)
index 1164b7b..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/* MDB Tools - A library for reading MS Access database file
- * Copyright (C) 2000 Brian Bruns
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "mdbtools.h"
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-static guint32 
-mdb_map_find_next0(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg)
-{
-       guint32 pgnum, i, usage_bitlen;
-       unsigned char *usage_bitmap;
-
-       pgnum = mdb_get_int32(map, 1);
-       usage_bitmap = map + 5;
-       usage_bitlen = (map_sz - 5) * 8;
-
-       i = (start_pg >= pgnum) ? start_pg-pgnum+1 : 0;
-       for (; i<usage_bitlen; i++) {
-               if (usage_bitmap[i/8] & (1 << (i%8))) {
-                       return pgnum + i;
-               }
-       }
-       /* didn't find anything */
-       return 0;
-}
-static int 
-mdb_map_find_next1(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg)
-{
-       guint32 map_ind, max_map_pgs, offset, usage_bitlen;
-
-       /*
-       * start_pg will tell us where to (re)start the scan
-       * for the next data page.  each usage_map entry points to a
-       * 0x05 page which bitmaps (mdb->fmt->pg_size - 4) * 8 pages.
-       *
-       * map_ind gives us the starting usage_map entry
-       * offset gives us a page offset into the bitmap
-       */
-       usage_bitlen = (mdb->fmt->pg_size - 4) * 8;
-       max_map_pgs = (map_sz - 1) / 4;
-       map_ind = (start_pg + 1) / usage_bitlen;
-       offset = (start_pg + 1) % usage_bitlen;
-
-       for (; map_ind<max_map_pgs; map_ind++) {
-               unsigned char *usage_bitmap;
-               guint32 i, map_pg;
-
-               if (!(map_pg = mdb_get_int32(map, (map_ind*4)+1))) {
-                       continue;
-               }
-               if(mdb_read_alt_pg(mdb, map_pg) != mdb->fmt->pg_size) {
-                       fprintf(stderr, "Oops! didn't get a full page at %d\n", map_pg);
-                       exit(1);
-               } 
-
-               usage_bitmap = mdb->alt_pg_buf + 4;
-               for (i=offset; i<usage_bitlen; i++) {
-                       if (usage_bitmap[i/8] & (1 << (i%8))) {
-                               return map_ind*usage_bitlen + i;
-                       }
-               }
-               offset = 0;
-       }
-       /* didn't find anything */
-       return 0;
-}
-guint32 
-mdb_map_find_next(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg)
-{
-       if (map[0] == 0) {
-               return mdb_map_find_next0(mdb, map, map_sz, start_pg);
-       } else if (map[0] == 1) {
-               return mdb_map_find_next1(mdb, map, map_sz, start_pg);
-       }
-
-       fprintf(stderr, "Warning: unrecognized usage map type: %d\n", map[0]);
-       return -1;
-}
-guint32
-mdb_alloc_page(MdbTableDef *table)
-{
-       printf("Allocating new page\n");
-       return 0;
-}
-guint32 
-mdb_map_find_next_freepage(MdbTableDef *table, int row_size)
-{
-       MdbCatalogEntry *entry = table->entry;
-       MdbHandle *mdb = entry->mdb;
-       guint32 pgnum;
-       guint32 cur_pg = 0;
-       int free_space;
-
-       do {
-               pgnum = mdb_map_find_next(mdb, 
-                               table->free_usage_map, 
-                               table->freemap_sz, cur_pg);
-               printf("looking at page %d\n", pgnum);
-               if (!pgnum) {
-                       /* allocate new page */
-                       pgnum = mdb_alloc_page(table);
-                       return pgnum;
-               }
-               cur_pg = pgnum;
-
-               mdb_read_pg(mdb, pgnum);
-               free_space = mdb_pg_get_freespace(mdb);
-               
-       } while (free_space < row_size);
-
-       printf("page %d has %d bytes left\n", pgnum, free_space);
-
-       return pgnum;
-}
diff --git a/navit/data/poi_geodownload/libmdb/mem.c b/navit/data/poi_geodownload/libmdb/mem.c
deleted file mode 100644 (file)
index 208757e..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/* MDB Tools - A library for reading MS Access database files
- * Copyright (C) 2000 Brian Bruns
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "mdbtools.h"
-#include <locale.h>
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-/**
- * mdb_init:
- *
- * Initializes the LibMDB library.  This function should be called exactly once
- * by calling program and prior to any other function.
- *
- **/
-void mdb_init(void)
-{
-       mdb_init_backends();
-}
-
-/**
- * mdb_exit:
- *
- * Cleans up the LibMDB library.  This function should be called exactly once
- * by the calling program prior to exiting (or prior to final use of LibMDB 
- * functions).
- *
- **/
-void mdb_exit(void)
-{
-       mdb_remove_backends();
-}
diff --git a/navit/data/poi_geodownload/libmdb/money.c b/navit/data/poi_geodownload/libmdb/money.c
deleted file mode 100644 (file)
index 7f2cf65..0000000
+++ /dev/null
@@ -1,139 +0,0 @@
-/* MDB Tools - A library for reading MS Access database file
- * Copyright (C) 1998-1999  Brian Bruns
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <stdio.h>
-#include "mdbtools.h"
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-#define MAXPRECISION 20
-/* 
-** these routines are copied from the freetds project which does something
-** very similiar
-*/
-
-static int multiply_byte(unsigned char *product, int num, unsigned char *multiplier);
-static int do_carry(unsigned char *product);
-static char *array_to_string(unsigned char *array, int unsigned scale, char *s);
-
-/**
- * mdb_money_to_string
- * @mdb: Handle to open MDB database file
- * @start: Offset of the field within the current page
- * @s: String that will receieve the value
- *
- * Returns: the string that has received the value.
- */
-char *mdb_money_to_string(MdbHandle *mdb, int start, char *s)
-{
-       int num_bytes = 8;
-       int i;
-       int neg=0;
-       unsigned char multiplier[MAXPRECISION], temp[MAXPRECISION];
-       unsigned char product[MAXPRECISION];
-       unsigned char money[num_bytes];
-
-       memset(multiplier,0,MAXPRECISION);
-       memset(product,0,MAXPRECISION);
-       multiplier[0]=1;
-       memcpy(money, mdb->pg_buf + start, num_bytes);
-
-       /* Perform two's complement for negative numbers */
-       if (money[7] & 0x80) {
-               neg = 1;
-               for (i=0;i<num_bytes;i++) {
-                       money[i] = ~money[i];
-               }
-               for (i=0; i<num_bytes; i++) {
-                       money[i] ++;
-                       if (money[i]!=0) break;
-               }
-       }
-
-       for (i=0;i<num_bytes;i++) {
-               /* product += multiplier * current byte */
-               multiply_byte(product, money[i], multiplier);
-
-               /* multiplier = multiplier * 256 */
-               memcpy(temp, multiplier, MAXPRECISION);
-               memset(multiplier,0,MAXPRECISION);
-               multiply_byte(multiplier, 256, temp);
-       }
-       if (neg) {
-               s[0]='-';
-               array_to_string(product, 4, &s[1]);
-       } else {
-               array_to_string(product, 4, s);
-       }
-       return s;
-}
-static int multiply_byte(unsigned char *product, int num, unsigned char *multiplier)
-{
-       unsigned char number[3];
-       unsigned int i, j;
-
-       number[0]=num%10;
-       number[1]=(num/10)%10;
-       number[2]=(num/100)%10;
-
-       for (i=0;i<MAXPRECISION;i++) {
-               if (multiplier[i] == 0) continue;
-               for (j=0;j<3;j++) {
-                       if (number[j] == 0) continue;
-                       product[i+j] += multiplier[i]*number[j];
-               }
-               do_carry(product);
-       }
-       return 0;
-}
-static int do_carry(unsigned char *product)
-{
-       unsigned int j;
-
-       for (j=0;j<MAXPRECISION-1;j++) {
-               if (product[j]>9) {
-                       product[j+1]+=product[j]/10;
-                       product[j]=product[j]%10;
-               }
-       }
-       if (product[j]>9) {
-               product[j]=product[j]%10;
-       }
-       return 0;
-}
-static char *array_to_string(unsigned char *array, unsigned int scale, char *s)
-{
-       unsigned int top, i, j=0;
-       
-       for (top=MAXPRECISION;(top>0) && (top-1>scale) && !array[top-1];top--);
-
-       if (top == 0) {
-               s[j++] = '0';
-       } else {
-               for (i=top; i>0; i--) {
-                       if (j == top-scale) s[j++]='.';
-                       s[j++]=array[i-1]+'0';
-               }
-       }
-       s[j]='\0';
-
-       return s;
-}
diff --git a/navit/data/poi_geodownload/libmdb/options.c b/navit/data/poi_geodownload/libmdb/options.c
deleted file mode 100644 (file)
index cdbbc66..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/* MDB Tools - A library for reading MS Access database file
- * Copyright (C) 2004 Brian Bruns
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-
-#include <mdbtools.h>
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-#define DEBUG 1
-
-static unsigned long opts;
-static int optset;
-
-static void load_options();
-
-void
-mdb_debug(int klass, char *fmt, ...)
-{
-#ifdef DEBUG
-       va_list ap;
-
-       if (!optset) load_options();
-       if (klass & opts) {     
-       va_start(ap, fmt);
-       vfprintf (stdout,fmt, ap);
-       va_end(ap);
-       fprintf(stdout,"\n");
-       }
-#endif
-}
-
-static void
-load_options()
-{
-       char *opt;
-       char *s;
-
-    if (!optset && (s=getenv("MDBOPTS"))) {
-               opt = strtok(s, ":");
-               do {
-               if (!strcmp(opt, "use_index")) opts |= MDB_USE_INDEX;
-               if (!strcmp(opt, "debug_like")) opts |= MDB_DEBUG_LIKE;
-               if (!strcmp(opt, "debug_write")) opts |= MDB_DEBUG_WRITE;
-               if (!strcmp(opt, "debug_usage")) opts |= MDB_DEBUG_USAGE;
-               if (!strcmp(opt, "debug_ole")) opts |= MDB_DEBUG_OLE;
-               if (!strcmp(opt, "debug_row")) opts |= MDB_DEBUG_ROW;
-               if (!strcmp(opt, "debug_all")) {
-                               opts |= MDB_DEBUG_LIKE;
-                               opts |= MDB_DEBUG_WRITE;
-                               opts |= MDB_DEBUG_USAGE;
-                               opts |= MDB_DEBUG_OLE;
-                               opts |= MDB_DEBUG_ROW;
-                       }
-                       opt = strtok(NULL,":");
-               } while (opt);
-    }
-       optset = 1;
-}
-int
-mdb_get_option(unsigned long optnum)
-{
-       if (!optset) load_options();
-       return ((opts & optnum) > 0);
-}
diff --git a/navit/data/poi_geodownload/libmdb/props.c b/navit/data/poi_geodownload/libmdb/props.c
deleted file mode 100644 (file)
index 61db9f5..0000000
+++ /dev/null
@@ -1,127 +0,0 @@
-/* MDB Tools - A library for reading MS Access database file
- * Copyright (C) 2000 Brian Bruns
- *
- *
- * This library is free software; you can redistribute it and/or 
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "mdbtools.h"
-
-GPtrArray *
-mdb_read_props_list(gchar *kkd, int len)
-{
-       guint32 record_len;
-       int pos = 0;
-       gchar *name;
-       GPtrArray *names = NULL;
-       int i = 0;
-
-       names = g_ptr_array_new();
-#ifdef MDB_DEBUG
-       buffer_dump(kkd, 0, len - 1);
-#endif
-       pos = 0;
-       while (pos < len) {
-               record_len = mdb_get_int16(kkd, pos);
-               pos += 2;
-#ifdef MDB_DEBUG
-               printf("%02d ",i++);
-               buffer_dump(kkd, pos - 2, pos + record_len - 1);
-#endif
-               name = g_malloc(record_len + 1);
-               strncpy(name, &kkd[pos], record_len);
-               name[record_len] = '\0';
-               pos += record_len;
-               g_ptr_array_add(names, name);
-#ifdef MDB_DEBUG
-               printf("new len = %d\n", names->len);
-#endif
-       }
-       return names;
-}
-void
-mdb_free_props(MdbProperties *props)
-{
-       if (!props) return;
-
-       if (props->name) g_free(props->name);
-       g_free(props);
-}
-MdbProperties *
-mdb_alloc_props()
-{
-       MdbProperties *props;
-
-       props = g_malloc0(sizeof(MdbProperties));
-
-       return props;
-}
-MdbProperties * 
-mdb_read_props(MdbHandle *mdb, GPtrArray *names, gchar *kkd, int len)
-{
-       guint32 record_len, name_len;
-       int pos = 0;
-       int elem, dtype, dsize;
-       gchar *name, *value;
-       MdbProperties *props;
-       int i = 0;
-
-#ifdef MDB_DEBUG
-       buffer_dump(kkd, 0, len - 1);
-#endif
-       pos = 0;
-
-       /* skip the name record */
-       record_len = mdb_get_int16(kkd, pos);
-       pos += 4;
-       name_len = mdb_get_int16(kkd, pos);
-       pos += 2;
-       props = mdb_alloc_props();
-       if (name_len) {
-               props->name = g_malloc(name_len + 1);
-               strncpy(props->name, &kkd[pos], name_len);
-               props->name[name_len]='\0';
-       }
-       pos += name_len;
-
-       props->hash = g_hash_table_new(g_str_hash, g_str_equal);
-
-       while (pos < len) {
-               record_len = mdb_get_int16(kkd, pos);
-               elem = mdb_get_int16(kkd, pos + 4);
-               dtype = kkd[pos + 3];
-               dsize = mdb_get_int16(kkd, pos + 6);
-               value = g_malloc(dsize + 1);
-               strncpy(value, &kkd[pos + 8], dsize);
-               value[dsize] = '\0';
-               name = g_ptr_array_index(names,elem);
-#ifdef MDB_DEBUG
-               printf("%02d ",i++);
-               buffer_dump(kkd, pos, pos + record_len - 1);
-               printf("elem %d dsize %d dtype %d\n", elem, dsize, dtype);
-#endif
-               if (dtype == MDB_MEMO) dtype = MDB_TEXT;
-               if (dtype == MDB_BOOL) {
-                       g_hash_table_insert(props->hash, g_strdup(name), g_strdup(kkd[pos + 8] ? "yes" : "no"));
-               } else {
-                       g_hash_table_insert(props->hash, g_strdup(name), g_strdup(mdb_col_to_string(mdb, kkd, pos + 8, dtype, dsize)));
-               }
-               g_free(value);
-               pos += record_len;
-       }
-       return props;
-       
-}
diff --git a/navit/data/poi_geodownload/libmdb/sargs.c b/navit/data/poi_geodownload/libmdb/sargs.c
deleted file mode 100644 (file)
index b14aaa9..0000000
+++ /dev/null
@@ -1,273 +0,0 @@
-/* MDB Tools - A library for reading MS Access database file
- * Copyright (C) 2000 Brian Bruns
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/*
- * code for handling searchable arguments (sargs) used primary by the sql 
- * engine to support where clause handling.  The sargs are configured in 
- * a tree with AND/OR operators connecting the child nodes. NOT operations
- * have only one child on the left side.  Logical operators (=,<,>,etc..)
- * have no children.
- *
- * datatype support is a bit weak at this point.  To add more types create
- * a mdb_test_[type]() function and invoke it from mdb_test_sarg()
- */
-#include "mdbtools.h"
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-void
-mdb_sql_walk_tree(MdbSargNode *node, MdbSargTreeFunc func, gpointer data)
-{
-       if (func(node, data))
-               return;
-       if (node->left) mdb_sql_walk_tree(node->left, func, data);
-       if (node->right) mdb_sql_walk_tree(node->right, func, data);
-}
-int 
-mdb_test_string(MdbSargNode *node, char *s)
-{
-int rc;
-
-       if (node->op == MDB_LIKE) {
-               return mdb_like_cmp(s,node->value.s);
-       }
-       rc = strncmp(node->value.s, s, 255);
-       switch (node->op) {
-               case MDB_EQUAL:
-                       if (rc==0) return 1;
-                       break;
-               case MDB_GT:
-                       if (rc<0) return 1;
-                       break;
-               case MDB_LT:
-                       if (rc>0) return 1;
-                       break;
-               case MDB_GTEQ:
-                       if (rc<=0) return 1;
-                       break;
-               case MDB_LTEQ:
-                       if (rc>=0) return 1;
-                       break;
-               default:
-                       fprintf(stderr, "Calling mdb_test_sarg on unknown operator.  Add code to mdb_test_string() for operator %d\n",node->op);
-                       break;
-       }
-       return 0;
-}
-int mdb_test_int(MdbSargNode *node, gint32 i)
-{
-       switch (node->op) {
-               case MDB_EQUAL:
-                       printf("comparing %x and %x %d\n", i, node->value.i, node->value.i == i);
-                       if (node->value.i == i) return 1;
-                       break;
-               case MDB_GT:
-                       if (node->value.i < i) return 1;
-                       break;
-               case MDB_LT:
-                       if (node->value.i > i) return 1;
-                       break;
-               case MDB_GTEQ:
-                       if (node->value.i <= i) return 1;
-                       break;
-               case MDB_LTEQ:
-                       if (node->value.i >= i) return 1;
-                       break;
-               default:
-                       fprintf(stderr, "Calling mdb_test_sarg on unknown operator.  Add code to mdb_test_int() for operator %d\n",node->op);
-                       break;
-       }
-       return 0;
-}
-#if 0
-#endif
-int
-mdb_find_indexable_sargs(MdbSargNode *node, gpointer data)
-{
-       MdbSarg sarg;
-
-       if (node->op == MDB_OR || node->op == MDB_NOT) return 1;
-
-       /* 
-        * right now all we do is look for sargs that are anded together from
-        * the root.  Later we may put together OR ops into a range, and then 
-        * range scan the leaf pages. That is col1 = 2 or col1 = 4 becomes
-        * col1 >= 2 and col1 <= 4 for the purpose of index scans, and then
-        * extra rows are thrown out when the row is tested against the main
-        * sarg tree.  range scans are generally only a bit better than table
-        * scanning anyway.
-        *
-        * also, later we should support the NOT operator, but it's generally
-        * a pretty worthless test for indexes, ie NOT col1 = 3, we are 
-        * probably better off table scanning.
-        */
-       if (mdb_is_relational_op(node->op) && node->col) {
-               //printf("op = %d value = %s\n", node->op, node->value.s);
-               sarg.op = node->op;
-               sarg.value = node->value;
-               mdb_add_sarg(node->col, &sarg);
-       }
-       return 0;
-}
-int 
-mdb_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSargNode *node, MdbField *field)
-{
-char tmpbuf[256];
-int lastchar;
-
-       if (node->op == MDB_ISNULL) {
-               if (field->is_null) return 0;
-               else return 1;
-       } else if (node->op == MDB_NOTNULL) {
-               if (field->is_null) return 1;
-               else return 0;
-       }
-       switch (col->col_type) {
-               case MDB_BOOL:
-                       return mdb_test_int(node, !field->is_null);
-                       break;
-               case MDB_BYTE:
-                       return mdb_test_int(node, (gint32)((char *)field->value)[0]);
-                       break;
-               case MDB_INT:
-                       return mdb_test_int(node, (gint32)mdb_get_int16(field->value, 0));
-                       break;
-               case MDB_LONGINT:
-                       return mdb_test_int(node, (gint32)mdb_get_int32(field->value, 0));
-                       break;
-               case MDB_TEXT:
-                       if (IS_JET4(mdb)) {
-                               mdb_unicode2ascii(mdb, field->value, 0, field->siz, tmpbuf);
-                       } else {
-                               strncpy(tmpbuf, field->value, 255);
-                               lastchar = field->siz > 255 ? 255 : field->siz;
-                               tmpbuf[lastchar]='\0';
-                       }
-                       return mdb_test_string(node, tmpbuf);
-               default:
-                       fprintf(stderr, "Calling mdb_test_sarg on unknown type.  Add code to mdb_test_sarg() for type %d\n",col->col_type);
-                       break;
-       }
-       return 1;
-}
-int
-mdb_find_field(int col_num, MdbField *fields, int num_fields)
-{
-       int i;
-
-       for (i=0;i<num_fields;i++) {
-               if (fields[i].colnum == col_num) return i;
-       }
-       return -1;
-}
-int
-mdb_test_sarg_node(MdbHandle *mdb, MdbSargNode *node, MdbField *fields, int num_fields)
-{
-       int elem;
-       MdbColumn *col;
-       int rc;
-
-       if (mdb_is_relational_op(node->op)) {
-               col = node->col;
-               /* for const = const expressions */
-               if (!col) {
-                       return (node->value.i);
-               }
-               elem = mdb_find_field(col->col_num, fields, num_fields);
-               if (!mdb_test_sarg(mdb, col, node, &fields[elem])) 
-                       return 0;
-       } else { /* logical op */
-               switch (node->op) {
-               case MDB_NOT:
-                       rc = mdb_test_sarg_node(mdb, node->left, fields, num_fields);
-                       return !rc;
-                       break;
-               case MDB_AND:
-                       if (!mdb_test_sarg_node(mdb, node->left, fields, num_fields))
-                               return 0;
-                       return mdb_test_sarg_node(mdb, node->right, fields, num_fields);
-                       break;
-               case MDB_OR:
-                       if (mdb_test_sarg_node(mdb, node->left, fields, num_fields))
-                               return 1;
-                       return mdb_test_sarg_node(mdb, node->right, fields, num_fields);
-                       break;
-               }
-       }
-       return 1;
-}
-int 
-mdb_test_sargs(MdbTableDef *table, MdbField *fields, int num_fields)
-{
-       MdbSargNode *node;
-       MdbCatalogEntry *entry = table->entry;
-       MdbHandle *mdb = entry->mdb;
-
-       node = table->sarg_tree;
-
-       /* there may not be a sarg tree */
-       if (!node) return 1;
-
-       return mdb_test_sarg_node(mdb, node, fields, num_fields);
-}
-#if 0
-int mdb_test_sargs(MdbHandle *mdb, MdbColumn *col, int offset, int len)
-{
-MdbSarg *sarg;
-int i;
-
-       for (i=0;i<col->num_sargs;i++) {
-               sarg = g_ptr_array_index (col->sargs, i);
-               if (!mdb_test_sarg(mdb, col, sarg, offset, len)) {
-                       /* sarg didn't match, no sense going on */
-                       return 0;       
-               }
-       }
-
-       return 1;
-}
-#endif
-int mdb_add_sarg(MdbColumn *col, MdbSarg *in_sarg)
-{
-MdbSarg *sarg;
-        if (!col->sargs) {
-               col->sargs = g_ptr_array_new();
-       }
-       sarg = g_memdup(in_sarg,sizeof(MdbSarg));
-        g_ptr_array_add(col->sargs, sarg);
-       col->num_sargs++;
-
-       return 1;
-}
-int mdb_add_sarg_by_name(MdbTableDef *table, char *colname, MdbSarg *in_sarg)
-{
-       MdbColumn *col;
-       unsigned int i;
-
-       for (i=0;i<table->num_cols;i++) {
-               col = g_ptr_array_index (table->columns, i);
-               if (!strcasecmp(col->name,colname)) {
-                       return mdb_add_sarg(col, in_sarg);
-               }
-       }
-       /* else didn't find the column return 0! */
-       return 0;
-}
diff --git a/navit/data/poi_geodownload/libmdb/stats.c b/navit/data/poi_geodownload/libmdb/stats.c
deleted file mode 100644 (file)
index 1abf285..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/* MDB Tools - A library for reading MS Access database files
- * Copyright (C) 2000 Brian Bruns
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "mdbtools.h"
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-/**
- * mdb_stats_on:
- * @mdb: Handle to the (open) MDB file to collect stats on.
- *
- * Begins collection of statistics on an MDBHandle.
- *
- * Statistics in LibMDB will track the number of reads from the MDB file.  The
- * collection of statistics is started and stopped with the mdb_stats_on and
- * mdb_stats_off functions.  Collected statistics are accessed by reading the
- * MdbStatistics structure or calling mdb_dump_stats.
- * 
- */
-void
-mdb_stats_on(MdbHandle *mdb)
-{
-       if (!mdb->stats) 
-               mdb->stats = g_malloc0(sizeof(MdbStatistics));
-
-       mdb->stats->collect = TRUE;
-}
-/**
- * mdb_stats_off:
- * @mdb: pointer to handle of MDB file with active stats collection.
- *
- * Turns off statistics collection.
- *
- * If mdb_stats_off is not called, statistics will be turned off when handle
- * is freed using mdb_close.
- **/
-void
-mdb_stats_off(MdbHandle *mdb)
-{
-       if (!mdb->stats) return;
-
-       mdb->stats->collect = FALSE;
-}
-/**
- * mdb_dump_stats:
- * @mdb: pointer to handle of MDB file with active stats collection.
- *
- * Dumps current statistics to stdout.
- **/
-void
-mdb_dump_stats(MdbHandle *mdb)
-{
-       if (!mdb->stats) return;
-
-       fprintf(stdout, "Physical Page Reads: %lu\n", mdb->stats->pg_reads);
-}
diff --git a/navit/data/poi_geodownload/libmdb/table.c b/navit/data/poi_geodownload/libmdb/table.c
deleted file mode 100644 (file)
index 52238ec..0000000
+++ /dev/null
@@ -1,368 +0,0 @@
-/* MDB Tools - A library for reading MS Access database file
- * Copyright (C) 2000 Brian Bruns
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "mdbtools.h"
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-
-static gint mdb_col_comparer(MdbColumn **a, MdbColumn **b)
-{
-       if ((*a)->col_num > (*b)->col_num)
-               return 1;
-       else if ((*a)->col_num < (*b)->col_num)
-               return -1;
-       else
-               return 0;
-}
-
-static unsigned char mdb_col_needs_size(int col_type)
-{
-       if (col_type == MDB_TEXT) {
-               return TRUE;
-       } else {
-               return FALSE;
-       }
-}
-
-MdbTableDef *mdb_alloc_tabledef(MdbCatalogEntry *entry)
-{
-       MdbTableDef *table;
-
-       table = (MdbTableDef *) g_malloc0(sizeof(MdbTableDef));
-       table->entry=entry;
-       strcpy(table->name, entry->object_name);
-
-       return table;   
-}
-void mdb_free_tabledef(MdbTableDef *table)
-{
-       if (!table) return;
-       if (table->is_temp_table) {
-               unsigned int i;
-               for (i=0; i<table->temp_table_pages->len; i++)
-                       g_free(g_ptr_array_index(table->temp_table_pages,i));
-               g_ptr_array_free(table->temp_table_pages, TRUE);
-       }
-       mdb_free_columns(table->columns);
-       mdb_free_indices(table->indices);
-       g_free(table->usage_map);
-       g_free(table->free_usage_map);
-       g_free(table);
-}
-MdbTableDef *mdb_read_table(MdbCatalogEntry *entry)
-{
-       MdbTableDef *table;
-       MdbHandle *mdb = entry->mdb;
-       MdbFormatConstants *fmt = mdb->fmt;
-       int len, row_start, pg_row;
-       char *buf;
-
-       table = mdb_alloc_tabledef(entry);
-
-       mdb_read_pg(mdb, entry->table_pg);
-       if (mdb->pg_buf[0] != 0x02) return NULL; /* not a valid table def page */
-
-       len = mdb_pg_get_int16(mdb,8);
-
-       table->num_rows = mdb_pg_get_int32(mdb, fmt->tab_num_rows_offset);
-       table->num_var_cols = mdb_pg_get_int16(mdb, fmt->tab_num_cols_offset-2);
-       table->num_cols = mdb_pg_get_int16(mdb, fmt->tab_num_cols_offset);
-       table->num_idxs = mdb_pg_get_int32(mdb, fmt->tab_num_idxs_offset); 
-       table->num_real_idxs = mdb_pg_get_int32(mdb, fmt->tab_num_ridxs_offset); 
-       /* grab a copy of the usage map */
-       pg_row = mdb_pg_get_int32(mdb, fmt->tab_usage_map_offset);
-       mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &(table->map_sz));
-       table->usage_map = g_memdup(buf + row_start, table->map_sz);
-       if (mdb_get_option(MDB_DEBUG_USAGE)) 
-               buffer_dump(buf, row_start, row_start+table->map_sz-1);
-       mdb_debug(MDB_DEBUG_USAGE,"usage map found on page %ld row %d start %d len %d",
-               pg_row >> 8, pg_row & 0xff, row_start, table->map_sz);
-
-       /* grab a copy of the free space page map */
-       pg_row = mdb_pg_get_int32(mdb, fmt->tab_free_map_offset);
-       mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &(table->freemap_sz));
-       table->free_usage_map = g_memdup(buf + row_start, table->freemap_sz);
-       mdb_debug(MDB_DEBUG_USAGE,"free map found on page %ld row %d start %d len %d\n",
-               pg_row >> 8, pg_row & 0xff, row_start, table->freemap_sz);
-
-       table->first_data_pg = mdb_pg_get_int16(mdb, fmt->tab_first_dpg_offset);
-
-       return table;
-}
-MdbTableDef *mdb_read_table_by_name(MdbHandle *mdb, gchar *table_name, int obj_type)
-{
-       unsigned int i;
-       MdbCatalogEntry *entry;
-
-       mdb_read_catalog(mdb, obj_type);
-
-       for (i=0; i<mdb->num_catalog; i++) {
-               entry = g_ptr_array_index(mdb->catalog, i);
-               if (!strcasecmp(entry->object_name, table_name))
-                       return mdb_read_table(entry);
-       }
-
-       return NULL;
-}
-
-/*
-** read the next page if offset is > pg_size
-** return true if page was read
-*/ 
-int 
-read_pg_if(MdbHandle *mdb, int *cur_pos, int offset)
-{
-       if (*cur_pos + offset >= mdb->fmt->pg_size) {
-               mdb_read_pg(mdb, mdb_pg_get_int32(mdb,4));
-               *cur_pos = 8 - (mdb->fmt->pg_size - (*cur_pos));
-               return 1;
-       }
-       return 0;
-}
-guint32 
-read_pg_if_32(MdbHandle *mdb, int *cur_pos)
-{
-       unsigned char c[4];
-       int i, rc = 0;
-
-       for (i=0;i<4;i++) {
-               rc += read_pg_if(mdb, cur_pos, i);
-               c[i] = mdb->pg_buf[(*cur_pos) + i];
-       }
-       return mdb_get_int32(c, 0);
-}
-guint16 
-read_pg_if_16(MdbHandle *mdb, int *cur_pos)
-{
-       unsigned char low_byte, high_byte;
-       int rc = 0;
-
-       rc += read_pg_if(mdb, cur_pos, 0);
-       low_byte = mdb->pg_buf[*cur_pos];
-       rc += read_pg_if(mdb, cur_pos, 1);
-       high_byte = mdb->pg_buf[(*cur_pos) + 1];
-
-       return (high_byte * 256 + low_byte);
-}
-guint16 
-read_pg_if_n(MdbHandle *mdb, unsigned char *buf, int *cur_pos, int len)
-{
-       if (*cur_pos + len < mdb->fmt->pg_size) {
-               memcpy(buf, &mdb->pg_buf[*cur_pos], len);
-               return 0;
-       } else {
-               int half = mdb->fmt->pg_size - *cur_pos;
-               memcpy(buf, &mdb->pg_buf[*cur_pos], half);
-               mdb_read_pg(mdb, mdb_pg_get_int32(mdb,4));
-               memcpy(buf + half, &mdb->pg_buf[8], len - half);
-               *cur_pos = 8 - half;
-               return 1;
-       }
-}
-
-void mdb_append_column(GPtrArray *columns, MdbColumn *in_col)
-{
-       g_ptr_array_add(columns, g_memdup(in_col,sizeof(MdbColumn)));
-}
-void mdb_free_columns(GPtrArray *columns)
-{
-       unsigned int i;
-
-       if (!columns) return;
-       for (i=0; i<columns->len; i++)
-               g_free (g_ptr_array_index(columns, i));
-       g_ptr_array_free(columns, TRUE);
-}
-GPtrArray *mdb_read_columns(MdbTableDef *table)
-{
-       MdbHandle *mdb = table->entry->mdb;
-       MdbFormatConstants *fmt = mdb->fmt;
-       MdbColumn *pcol;
-       unsigned char *col;
-       unsigned int i;
-       int cur_pos, name_sz;
-       
-       table->columns = g_ptr_array_new();
-
-       col = (unsigned char *) g_malloc(fmt->tab_col_entry_size);
-
-       cur_pos = fmt->tab_cols_start_offset + 
-               (table->num_real_idxs * fmt->tab_ridx_entry_size);
-
-       /* new code based on patch submitted by Tim Nelson 2000.09.27 */
-
-       /* 
-       ** column attributes 
-       */
-       for (i=0;i<table->num_cols;i++) {
-#ifdef MDB_DEBUG
-       /* printf("column %d\n", i);
-       buffer_dump(mdb->pg_buf, cur_pos ,cur_pos + 18); */
-#endif
-               read_pg_if_n(mdb, col, &cur_pos, fmt->tab_col_entry_size);
-               cur_pos += fmt->tab_col_entry_size;
-               pcol = (MdbColumn *) g_malloc0(sizeof(MdbColumn));
-
-               pcol->col_type = col[0];
-
-               // col_num_offset == 1 or 5
-               pcol->col_num = col[fmt->col_num_offset];
-
-               //fprintf(stdout,"----- column %d -----\n",pcol->col_num);
-               // col_var == 3 or 7
-               pcol->var_col_num = mdb_get_int16(col, fmt->tab_col_offset_var);
-               //fprintf(stdout,"var column pos %d\n",pcol->var_col_num);
-
-               // col_var == 5 or 9
-               pcol->row_col_num = mdb_get_int16(col, fmt->tab_row_col_num_offset);
-               //fprintf(stdout,"row column num %d\n",pcol->row_col_num);
-
-               /* FIXME: can this be right in Jet3 and Jet4? */
-               if (pcol->col_type == MDB_NUMERIC) {
-                       pcol->col_prec = col[11];
-                       pcol->col_scale = col[12];
-               }
-
-               // col_fixed_offset == 13 or 15
-               pcol->is_fixed = col[fmt->col_fixed_offset] & 0x01 ? 1 : 0;
-
-               // col_fixed_offset == 13 or 15
-               pcol->fixed_offset = mdb_get_int16(col, fmt->tab_col_offset_fixed);
-               //fprintf(stdout,"fixed column offset %d\n",pcol->fixed_offset);
-               //fprintf(stdout,"col type %s\n",pcol->is_fixed ? "fixed" : "variable");
-
-               if (pcol->col_type != MDB_BOOL) {
-                       // col_size_offset == 16 or 23
-                       pcol->col_size = mdb_get_int16(col, fmt->col_size_offset);
-               } else {
-                       pcol->col_size=0;
-               }
-               
-               g_ptr_array_add(table->columns, pcol);
-       }
-
-       g_free (col);
-
-       /* 
-       ** column names - ordered the same as the column attributes table
-       */
-       for (i=0;i<table->num_cols;i++) {
-               pcol = g_ptr_array_index(table->columns, i);
-
-               if (IS_JET4(mdb)) {
-                       char *tmp_buf;
-                       name_sz = read_pg_if_16(mdb, &cur_pos);
-                       cur_pos += 2;
-                       tmp_buf = (char *) g_malloc(name_sz);
-                       read_pg_if_n(mdb, tmp_buf, &cur_pos, name_sz);
-                       mdb_unicode2ascii(mdb, tmp_buf, 0, name_sz, pcol->name);
-                       g_free(tmp_buf);
-                       cur_pos += name_sz;
-               } else if (IS_JET3(mdb)) {
-                       read_pg_if(mdb, &cur_pos, 0);
-                       name_sz = mdb->pg_buf[cur_pos];
-                       cur_pos++;
-                       read_pg_if_n(mdb, pcol->name, &cur_pos, name_sz);
-                       pcol->name[name_sz]='\0';
-                       cur_pos += name_sz;
-               } else {
-                       fprintf(stderr,"Unknown MDB version\n");
-               }
-       }
-
-       /* Sort the columns by col_num */
-       g_ptr_array_sort(table->columns, (GCompareFunc)mdb_col_comparer);
-
-       table->index_start = cur_pos;
-       return table->columns;
-}
-
-void mdb_table_dump(MdbCatalogEntry *entry)
-{
-MdbTableDef *table;
-MdbColumn *col;
-int coln;
-MdbIndex *idx;
-MdbHandle *mdb = entry->mdb;
-unsigned int i, bitn;
-guint32 pgnum;
-
-       table = mdb_read_table(entry);
-       fprintf(stdout,"definition page     = %lu\n",entry->table_pg);
-       fprintf(stdout,"number of datarows  = %d\n",table->num_rows);
-       fprintf(stdout,"number of columns   = %d\n",table->num_cols);
-       fprintf(stdout,"number of indices   = %d\n",table->num_real_idxs);
-
-       mdb_read_columns(table);
-       mdb_read_indices(table);
-
-       for (i=0;i<table->num_cols;i++) {
-               col = g_ptr_array_index(table->columns,i);
-       
-               fprintf(stdout,"column %d Name: %-20s Type: %s(%d)\n",
-                       i, col->name,
-                       mdb_get_coltype_string(mdb->default_backend, col->col_type),
-                       col->col_size);
-       }
-
-       for (i=0;i<table->num_idxs;i++) {
-               idx = g_ptr_array_index (table->indices, i);
-               mdb_index_dump(table, idx);
-       }
-       if (table->usage_map) {
-               printf("pages reserved by this object\n");
-               printf("usage map pg %" G_GUINT32_FORMAT "\n",
-                       table->map_base_pg);
-               printf("free map pg %" G_GUINT32_FORMAT "\n",
-                       table->freemap_base_pg);
-               pgnum = mdb_get_int32(table->usage_map,1);
-               /* the first 5 bytes of the usage map mean something */
-               coln = 0;
-               for (i=5;i<table->map_sz;i++) {
-                       for (bitn=0;bitn<8;bitn++) {
-                               if (table->usage_map[i] & 1 << bitn) {
-                                       coln++;
-                                       printf("%6" G_GUINT32_FORMAT, pgnum);
-                                       if (coln==10) {
-                                               printf("\n");
-                                               coln = 0;
-                                       } else {
-                                               printf(" ");
-                                       }
-                               }
-                               pgnum++;
-                       }
-               }
-               printf("\n");
-       }
-}
-
-int mdb_is_user_table(MdbCatalogEntry *entry)
-{
-       return ((entry->object_type == MDB_TABLE)
-        && !(entry->flags & 0x80000002)) ? 1 : 0;
-}
-int mdb_is_system_table(MdbCatalogEntry *entry)
-{
-       return ((entry->object_type == MDB_TABLE)
-        && (entry->flags & 0x80000002)) ? 1 : 0;
-}
diff --git a/navit/data/poi_geodownload/libmdb/worktable.c b/navit/data/poi_geodownload/libmdb/worktable.c
deleted file mode 100644 (file)
index 6f893dc..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/* MDB Tools - A library for reading MS Access database files
- * Copyright (C) 2004 Brian Bruns
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "mdbtools.h"
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-/*
- * Temp table routines.  These are currently used to generate mock results for
- * commands like "list tables" and "describe table"
- */
-
-void
-mdb_fill_temp_col(MdbColumn *tcol, char *col_name, int col_size, int col_type, int is_fixed)
-{
-       memset(tcol,0,sizeof(MdbColumn));
-       strcpy(tcol->name, col_name);
-       tcol->col_type = col_type;
-       if ((col_type == MDB_TEXT) || (col_type == MDB_MEMO)) {
-               tcol->col_size = col_size;
-       } else {
-               tcol->col_size = mdb_col_fixed_size(tcol);
-       }
-       tcol->is_fixed = is_fixed;
-}
-void
-mdb_fill_temp_field(MdbField *field, void *value, int siz, int is_fixed, int is_null, int start, int colnum)
-{
-       field->value = value;
-       field->siz = siz;
-       field->is_fixed = is_fixed;
-       field->is_null = is_null;
-       field->start = start;
-       field->colnum = colnum;
-}
-MdbTableDef *
-mdb_create_temp_table(MdbHandle *mdb, char *name)
-{
-       MdbCatalogEntry *entry;
-       MdbTableDef *table;
-
-       /* dummy up a catalog entry */
-       entry = (MdbCatalogEntry *) g_malloc0(sizeof(MdbCatalogEntry));
-       entry->mdb = mdb;
-       entry->object_type = MDB_TABLE;
-       entry->table_pg = 0;
-       strcpy(entry->object_name, name);
-
-       table = mdb_alloc_tabledef(entry);
-       table->columns = g_ptr_array_new();
-       table->is_temp_table = 1;
-       table->temp_table_pages = g_ptr_array_new();
-
-       return table;
-}
-void
-mdb_temp_table_add_col(MdbTableDef *table, MdbColumn *col)
-{
-       col->col_num = table->num_cols;
-       if (!col->is_fixed)
-               col->var_col_num = table->num_var_cols++;
-       g_ptr_array_add(table->columns, g_memdup(col, sizeof(MdbColumn)));
-       table->num_cols++;
-}
-/*
- * Should be called after setting up all temp table columns
- */
-void mdb_temp_columns_end(MdbTableDef *table)
-{
-       MdbColumn *col;
-       unsigned int i;
-       unsigned int start = 0;
-
-       for (i=0; i<table->num_cols; i++) {
-               col = g_ptr_array_index(table->columns, i);
-               if (col->is_fixed) {
-                       col->fixed_offset = start;
-                       start += col->col_size;
-               }
-       }
-}
diff --git a/navit/data/poi_geodownload/libmdb/write.c b/navit/data/poi_geodownload/libmdb/write.c
deleted file mode 100644 (file)
index 1cff96a..0000000
+++ /dev/null
@@ -1,878 +0,0 @@
-/* MDB Tools - A library for reading MS Access database file
- * Copyright (C) 2000 Brian Bruns
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#include "mdbtools.h"
-#include "time.h"
-#include "math.h"
-
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-
-
-//static int mdb_copy_index_pg(MdbTableDef *table, MdbIndex *idx, MdbIndexPage *ipg);
-static int mdb_add_row_to_leaf_pg(MdbTableDef *table, MdbIndex *idx, MdbIndexPage *ipg, MdbField *idx_fields);
-
-void
-_mdb_put_int16(unsigned char *buf, guint32 offset, guint32 value)
-{
-       buf[offset] = value % 256;
-       value /= 256;
-       buf[offset+1] = value % 256;
-}
-void
-_mdb_put_int32(unsigned char *buf, guint32 offset, guint32 value)
-{
-       buf[offset] = value % 256;
-       value /= 256;
-       buf[offset+1] = value % 256;
-       value /= 256;
-       buf[offset+2] = value % 256;
-       value /= 256;
-       buf[offset+3] = value % 256;
-}
-ssize_t
-mdb_write_pg(MdbHandle *mdb, unsigned long pg)
-{
-       ssize_t len;
-       struct stat status;
-       off_t offset = pg * mdb->fmt->pg_size;
-
-       fstat(mdb->f->fd, &status);
-       /* is page beyond current size + 1 ? */
-       if (status.st_size < offset + mdb->fmt->pg_size) {
-               fprintf(stderr,"offset %lu is beyond EOF\n",offset);
-               return 0;
-       }
-       lseek(mdb->f->fd, offset, SEEK_SET);
-       len = write(mdb->f->fd,mdb->pg_buf,mdb->fmt->pg_size);
-       if (len==-1) {
-               perror("write");
-               return 0;
-       } else if (len<mdb->fmt->pg_size) {
-       /* fprintf(stderr,"EOF reached %d bytes returned.\n",len, mdb->pg_size); */
-               return 0;
-       }
-       mdb->cur_pos = 0;
-       return len;
-}
-
-static int 
-mdb_is_col_indexed(MdbTableDef *table, int colnum)
-{
-       unsigned int i, j;
-       MdbIndex *idx;
-
-       for (i=0;i<table->num_idxs;i++) {
-               idx = g_ptr_array_index (table->indices, i);
-               for (j=0;j<idx->num_keys;j++) {
-                       if (idx->key_col_num[j]==colnum) return 1;
-               }
-       }
-       return 0;
-}
-static int
-mdb_crack_row4(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
-{
-       MdbCatalogEntry *entry = table->entry;
-       MdbHandle *mdb = entry->mdb;
-       MdbColumn *col;
-       unsigned char *pg_buf = mdb->pg_buf;
-       unsigned int i;
-       unsigned int row_var_cols=0, row_fixed_cols, row_cols;
-       unsigned int fixed_cols_found;
-       unsigned int col_start;
-       unsigned char *nullmask;
-       unsigned int bitmask_sz;
-       unsigned int byte_num, bit_num;
-       unsigned int *var_col_offsets = NULL;
-
-       if (mdb_get_option(MDB_DEBUG_ROW)) {
-               buffer_dump(pg_buf, row_start, row_end);
-       }
-
-       row_cols = mdb_pg_get_int16(mdb, row_start);
-
-       bitmask_sz = (row_cols + 7) / 8;
-       nullmask = &pg_buf[row_end - bitmask_sz + 1];
-
-       /* read table of variable column locations */
-       if (table->num_var_cols > 0) {
-               row_var_cols = mdb_pg_get_int16(mdb, row_end - bitmask_sz - 1);
-               var_col_offsets = (int *)g_malloc((row_var_cols+1)*sizeof(int));
-               for (i=0; i<row_var_cols+1; i++) {
-                       var_col_offsets[i] = mdb_pg_get_int16(mdb,
-                               row_end - bitmask_sz - 3 - (i*2));
-               }
-       }
-       fixed_cols_found = 0;
-       row_fixed_cols = row_cols - row_var_cols;
-
-       /* read information into fields[] */
-       for (i=0;i<table->num_cols;i++) {
-               col = g_ptr_array_index(table->columns,i);
-               fields[i].colnum = i;
-               fields[i].is_fixed = (mdb_is_fixed_col(col)) ? 1 : 0;
-               byte_num = col->col_num / 8;
-               bit_num = col->col_num % 8;
-               /* logic on nulls is reverse, 1 is not null, 0 is null */
-               fields[i].is_null = nullmask[byte_num] & (1 << bit_num) ? 0 : 1;
-
-               if ((fields[i].is_fixed)
-                && (fixed_cols_found < row_fixed_cols)) {
-                       col_start = col->fixed_offset + 2;
-                       fields[i].start = row_start + col_start;
-                       fields[i].value = &pg_buf[row_start + col_start];
-                       fields[i].siz = col->col_size;
-                       fixed_cols_found++;
-               /* Use col->var_col_num because a deleted column is still
-                * present in the variable column offsets table for the row */
-               } else if ((!fields[i].is_fixed)
-                && (col->var_col_num < row_var_cols)) {
-                       col_start = var_col_offsets[col->var_col_num];
-                       fields[i].start = row_start + col_start;
-                       fields[i].value = &pg_buf[row_start + col_start];
-                       fields[i].siz = var_col_offsets[(col->var_col_num)+1] -
-                               col_start;
-               } else {
-                       fields[i].start = 0;
-                       fields[i].value = NULL;
-                       fields[i].siz = 0;
-                       fields[i].is_null = 1;
-               }
-       }
-       g_free(var_col_offsets);
-
-       return row_cols;
-}
-static int
-mdb_crack_row3(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
-{
-       MdbCatalogEntry *entry = table->entry;
-       MdbHandle *mdb = entry->mdb;
-       MdbColumn *col;
-       unsigned char *pg_buf = mdb->pg_buf;
-       unsigned int i;
-       unsigned int row_var_cols = 0, row_fixed_cols, row_cols;
-       unsigned int fixed_cols_found, var_cols_found;
-       unsigned int col_start;
-       unsigned char *nullmask;
-       unsigned int bitmask_sz;
-       unsigned int byte_num, bit_num;
-       unsigned int *var_col_offsets = NULL;
-       unsigned int num_jumps = 0, jumps_used = 0;
-       unsigned int col_ptr, row_len;
-
-       if (mdb_get_option(MDB_DEBUG_ROW)) {
-               buffer_dump(pg_buf, row_start, row_end);
-       }
-
-       row_cols = pg_buf[row_start];
-
-       bitmask_sz = (row_cols + 7) / 8;
-       nullmask = &pg_buf[row_end - bitmask_sz + 1];
-
-       /* read table of variable column locations */
-       if (table->num_var_cols > 0) {
-               row_var_cols = pg_buf[row_end - bitmask_sz];
-               row_len = row_end - row_start + 1;
-               num_jumps = (row_len - 1) / 256;
-               col_ptr = row_end - bitmask_sz - num_jumps - 1;
-               /* If last jump is a dummy value, ignore it */
-               if ((col_ptr-row_start-row_var_cols)/256 < num_jumps)
-                       num_jumps--;
-
-               var_col_offsets = (int *)g_malloc((row_var_cols+1)*sizeof(int));
-               jumps_used = 0;
-               for (i=0; i<row_var_cols+1; i++) {
-                       if ((jumps_used < num_jumps)
-                        && (i == pg_buf[row_end-bitmask_sz-jumps_used-1])) {
-                               jumps_used++;
-                       }
-                       var_col_offsets[i] = pg_buf[col_ptr-i]+(jumps_used*256);
-               }
-       }
-       fixed_cols_found = 0;
-       var_cols_found = 0;
-       row_fixed_cols = row_cols - row_var_cols;
-
-       if (mdb_get_option(MDB_DEBUG_ROW)) {
-               fprintf(stdout,"bitmask_sz %d num_jumps %d\n",bitmask_sz, num_jumps);
-               fprintf(stdout,"row_var_cols %d\n", row_var_cols);
-               fprintf(stdout,"row_fixed_cols %d\n", row_fixed_cols);
-       }
-
-       /* read information into fields[] */
-       for (i=0;i<table->num_cols;i++) {
-               col = g_ptr_array_index (table->columns, i);
-               fields[i].colnum = i;
-               fields[i].is_fixed = (mdb_is_fixed_col(col)) ? 1 : 0;
-               byte_num = col->col_num / 8;
-               bit_num = col->col_num % 8;
-               /* logic on nulls is reverse, 1 is not null, 0 is null */
-               fields[i].is_null = nullmask[byte_num] & (1 << bit_num) ? 0 : 1;
-
-               if ((fields[i].is_fixed)
-                && (fixed_cols_found < row_fixed_cols)) {
-                       col_start = col->fixed_offset + 1;
-                       fields[i].start = row_start + col_start;
-                       fields[i].value = &pg_buf[row_start + col_start];
-                       fields[i].siz = col->col_size;
-                       fixed_cols_found++;
-               } else if ((!fields[i].is_fixed)
-                  && (var_cols_found < row_var_cols)) {
-                       col_start = var_col_offsets[var_cols_found];
-                       fields[i].start = row_start + col_start;
-                       fields[i].value = &pg_buf[row_start + col_start];
-                       fields[i].siz = var_col_offsets[var_cols_found+1] -
-                               col_start;
-                       var_cols_found++;
-               } else {
-                       fields[i].start = 0;
-                       fields[i].value = NULL;
-                       fields[i].siz = 0;
-                       fields[i].is_null = 1;
-               }
-       }
-       g_free(var_col_offsets);
-
-       return row_cols;
-}
-/**
- * mdb_crack_row:
- * @table: Table that the row belongs to
- * @row_start: offset to start of row on current page
- * @row_end: offset to end of row on current page
- * @fields: pointer to MdbField array to be popluated by mdb_crack_row
- *
- * Cracks a row buffer apart into its component fields.  
- * 
- * A row buffer is that portion of a data page which contains the values for
- * that row.  Its beginning and end can be found in the row offset table.
- *
- * The resulting MdbField array contains pointers into the row for each field 
- * present.  Be aware that by modifying field[]->value, you would be modifying 
- * the row buffer itself, not a copy.
- *
- * This routine is mostly used internally by mdb_fetch_row() but may have some
- * applicability for advanced application programs.
- *
- * Return value: number of fields present.
- */
-int
-mdb_crack_row(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
-{
-MdbCatalogEntry *entry = table->entry;
-MdbHandle *mdb = entry->mdb;
-
-       if (IS_JET4(mdb)) {
-               return mdb_crack_row4(table, row_start, row_end, fields);
-       } else {
-               return mdb_crack_row3(table, row_start, row_end, fields);
-       }
-}
-
-static int
-mdb_pack_null_mask(unsigned char *buffer, int num_fields, MdbField *fields)
-{
-       int pos = 0, bit = 0, byte = 0;
-       int i;
-
-       /* 'Not null' bitmap */
-       for (i=0; i<num_fields; i++) {
-               /* column is null if bit is clear (0) */
-               if (!fields[i].is_null) {
-                       byte |= 1 << bit;
-                       //printf("%d %d %d %d\n", i, bit, 1 << bit, byte);
-               }
-               bit++;
-               if (bit==8) {
-                       buffer[pos++] = byte;
-                       bit = byte = 0;
-               }
-       }
-       /* if we've written any bits to the current byte, flush it */
-       if (bit)
-               buffer[pos++] = byte;
-       
-       return pos;
-}
-/* fields must be ordered with fixed columns first, then vars, subsorted by 
- * column number */
-static int
-mdb_pack_row4(MdbTableDef *table, unsigned char *row_buffer, unsigned int num_fields, MdbField *fields)
-{
-       unsigned int pos = 0;
-       unsigned int var_cols = 0;
-       unsigned int i;
-
-       row_buffer[pos++] = num_fields & 0xff;
-       row_buffer[pos++] = (num_fields >> 8) & 0xff; 
-
-       /* Fixed length columns */
-       for (i=0;i<num_fields;i++) {
-               if (fields[i].is_fixed) {
-                       fields[i].offset = pos;
-                       if (!fields[i].is_null) {
-                               memcpy(&row_buffer[pos], fields[i].value, fields[i].siz);
-                       }
-                       pos += fields[i].siz;
-               }
-       }
-       /* For tables without variable-length columns */
-       if (table->num_var_cols == 0) {
-               pos += mdb_pack_null_mask(&row_buffer[pos], num_fields, fields);
-               return pos;
-       }
-       /* Variable length columns */
-       for (i=0;i<num_fields;i++) {
-               if (!fields[i].is_fixed) {
-                       var_cols++;
-                       fields[i].offset = pos;
-                       if (! fields[i].is_null) {
-                               memcpy(&row_buffer[pos], fields[i].value, fields[i].siz);
-                               pos += fields[i].siz;
-                       }
-               }
-       }
-       /* EOD */
-       row_buffer[pos] = pos & 0xff;
-       row_buffer[pos+1] = (pos >> 8) & 0xff;
-       pos += 2;
-
-       /* Offsets of the variable-length columns */
-       for (i=num_fields; i>0; i--) {
-               if (!fields[i-1].is_fixed) {
-                       row_buffer[pos++] = fields[i-1].offset & 0xff;
-                       row_buffer[pos++] = (fields[i-1].offset >> 8) & 0xff;
-               }
-       }
-       /* Number of variable-length columns */
-       row_buffer[pos++] = var_cols & 0xff;
-       row_buffer[pos++] = (var_cols >> 8) & 0xff;
-
-       pos += mdb_pack_null_mask(&row_buffer[pos], num_fields, fields);
-       return pos;
-}
-
-static int
-mdb_pack_row3(MdbTableDef *table, unsigned char *row_buffer, unsigned int num_fields, MdbField *fields)
-{
-       unsigned int pos = 0;
-       unsigned int var_cols = 0;
-       unsigned int i, j;
-       unsigned char *offset_high;
-
-       row_buffer[pos++] = num_fields;
-
-       /* Fixed length columns */
-       for (i=0;i<num_fields;i++) {
-               if (fields[i].is_fixed) {
-                       fields[i].offset = pos;
-                       if (!fields[i].is_null) {
-                               memcpy(&row_buffer[pos], fields[i].value, fields[i].siz);
-                       }
-                       pos += fields[i].siz;
-               }
-       }
-       /* For tables without variable-length columns */
-       if (table->num_var_cols == 0) {
-               pos += mdb_pack_null_mask(&row_buffer[pos], num_fields, fields);
-               return pos;
-       }
-       /* Variable length columns */
-       for (i=0;i<num_fields;i++) {
-               if (!fields[i].is_fixed) {
-                       var_cols++;
-                       fields[i].offset = pos;
-                       if (! fields[i].is_null) {
-                               memcpy(&row_buffer[pos], fields[i].value, fields[i].siz);
-                               pos += fields[i].siz;
-                       }
-               }
-       }
-
-       offset_high = (unsigned char *) g_malloc(var_cols+1);
-       offset_high[0] = (pos << 8) & 0xff;
-       j = 1;
-       
-       /* EOD */
-       row_buffer[pos] = pos & 0xff;
-       pos++;
-
-       /* Variable length column offsets */
-       for (i=num_fields; i>0; i--) {
-               if (!fields[i-1].is_fixed) {
-                       row_buffer[pos++] = fields[i-1].offset & 0xff;
-                       offset_high[j++] = (fields[i-1].offset << 8) & 0xff;
-               }
-       }
-
-       /* Dummy jump table entry */
-       if (offset_high[0] < (pos+(num_fields+7)/8-1)/255) {
-               row_buffer[pos++] = 0xff;
-       }
-       /* Jump table */
-       for (i=0; i<var_cols; i++) {
-               if (offset_high[i] > offset_high[i+1]) {
-                       row_buffer[pos++] = var_cols-i;
-               }
-       }
-       g_free(offset_high);
-
-       row_buffer[pos++] = var_cols;
-
-       pos += mdb_pack_null_mask(&row_buffer[pos], num_fields, fields);
-       return pos;
-}
-int
-mdb_pack_row(MdbTableDef *table, unsigned char *row_buffer, int unsigned num_fields, MdbField *fields)
-{
-       if (table->is_temp_table) {
-               unsigned int i;
-               for (i=0; i<num_fields; i++) {
-                       MdbColumn *c = g_ptr_array_index(table->columns, i);
-                       fields[i].is_null = (fields[i].value) ? 0 : 1;
-                       fields[i].colnum = i;
-                       fields[i].is_fixed = c->is_fixed;
-                       if ((c->col_type != MDB_TEXT)
-                        && (c->col_type != MDB_MEMO)) {
-                               fields[i].siz = c->col_size;
-                       }
-               }
-       }
-       if (IS_JET4(table->entry->mdb)) {
-               return mdb_pack_row4(table, row_buffer, num_fields, fields);
-       } else {
-               return mdb_pack_row3(table, row_buffer, num_fields, fields);
-       }
-}
-int
-mdb_pg_get_freespace(MdbHandle *mdb)
-{
-       int rows, free_start, free_end;
-       int row_count_offset = mdb->fmt->row_count_offset;
-
-       rows = mdb_pg_get_int16(mdb, row_count_offset);
-       free_start = row_count_offset + 2 + (rows * 2);
-        free_end = mdb_pg_get_int16(mdb, row_count_offset + (rows * 2));
-       mdb_debug(MDB_DEBUG_WRITE,"free space left on page = %d", free_end - free_start);
-       return (free_end - free_start);
-}
-unsigned char *
-mdb_new_leaf_pg(MdbCatalogEntry *entry)
-{
-       MdbHandle *mdb = entry->mdb;
-       unsigned char *new_pg;
-
-       new_pg = (unsigned char *) g_malloc0(mdb->fmt->pg_size);
-               
-       new_pg[0]=0x04;
-       new_pg[1]=0x01;
-       _mdb_put_int32(new_pg, 4, entry->table_pg);
-       
-       return new_pg;
-}
-unsigned char *
-mdb_new_data_pg(MdbCatalogEntry *entry)
-{
-       MdbFormatConstants *fmt = entry->mdb->fmt;
-       unsigned char *new_pg;
-
-       new_pg = (unsigned char *) g_malloc0(fmt->pg_size);
-               
-       new_pg[0]=0x01;
-       new_pg[1]=0x01;
-       _mdb_put_int16(new_pg, 2, fmt->pg_size - fmt->row_count_offset - 2);
-       _mdb_put_int32(new_pg, 4, entry->table_pg);
-       
-       return new_pg;
-}
-
-int
-mdb_update_indexes(MdbTableDef *table, int num_fields, MdbField *fields, guint32 pgnum, guint16 rownum)
-{
-       unsigned int i;
-       MdbIndex *idx;
-       
-       for (i=0;i<table->num_idxs;i++) {
-               idx = g_ptr_array_index (table->indices, i);
-               mdb_debug(MDB_DEBUG_WRITE,"Updating %s (%d).", idx->name, idx->index_type);
-               if (idx->index_type==1) {
-                       mdb_update_index(table, idx, num_fields, fields, pgnum, rownum);
-               }
-       }
-       return 1;
-}
-
-int
-mdb_init_index_chain(MdbTableDef *table, MdbIndex *idx)
-{
-       MdbCatalogEntry *entry = table->entry;
-       MdbHandle *mdb = entry->mdb;
-
-       table->scan_idx = idx;
-       table->chain = g_malloc0(sizeof(MdbIndexChain));
-       table->mdbidx = mdb_clone_handle(mdb);
-       mdb_read_pg(table->mdbidx, table->scan_idx->first_pg);
-
-       return 1;
-}
-
-int
-mdb_update_index(MdbTableDef *table, MdbIndex *idx, unsigned int num_fields, MdbField *fields, guint32 pgnum, guint16 rownum)
-{
-       MdbCatalogEntry *entry = table->entry;
-       MdbHandle *mdb = entry->mdb;
-       int idx_xref[16];
-       unsigned int i, j;
-       MdbIndexChain *chain;
-       MdbField idx_fields[10];
-
-       for (i = 0; i < idx->num_keys; i++) {
-               for (j = 0; j < num_fields; j++) {
-                       // key_col_num is 1 based, can't remember why though
-                       if (fields[j].colnum == idx->key_col_num[i]-1) {
-                               idx_xref[i] = j;
-                               idx_fields[i] = fields[j];
-                       }
-               }
-       }
-       for (i = 0; i < idx->num_keys; i++) {
-               fprintf(stdout, "key col %d (%d) is mapped to field %d (%d %d)\n",
-                       i, idx->key_col_num[i], idx_xref[i], fields[idx_xref[i]].colnum, 
-                       fields[idx_xref[i]].siz);
-       }
-       for (i = 0; i < num_fields; i++) {
-               fprintf(stdout, "%d (%d %d)\n",
-                       i, fields[i].colnum, 
-                       fields[i].siz);
-       }
-
-       chain = g_malloc0(sizeof(MdbIndexChain));
-
-       mdb_index_find_row(mdb, idx, chain, pgnum, rownum);
-       printf("chain depth = %d\n", chain->cur_depth);
-       printf("pg = %" G_GUINT32_FORMAT "\n",
-               chain->pages[chain->cur_depth-1].pg);
-       //mdb_copy_index_pg(table, idx, &chain->pages[chain->cur_depth-1]);
-       mdb_add_row_to_leaf_pg(table, idx, &chain->pages[chain->cur_depth-1], idx_fields);
-       
-       return 1;
-}
-
-int
-mdb_insert_row(MdbTableDef *table, int num_fields, MdbField *fields)
-{
-       int new_row_size;
-       unsigned char row_buffer[4096];
-       MdbCatalogEntry *entry = table->entry;
-       MdbHandle *mdb = entry->mdb;
-       MdbFormatConstants *fmt = mdb->fmt;
-       guint32 pgnum;
-       guint16 rownum;
-
-       if (!mdb->f->writable) {
-               fprintf(stderr, "File is not open for writing\n");
-               return 0;
-       }
-       new_row_size = mdb_pack_row(table, row_buffer, num_fields, fields);
-       if (mdb_get_option(MDB_DEBUG_WRITE)) {
-               buffer_dump(row_buffer, 0, new_row_size-1);
-       }
-       pgnum = mdb_map_find_next_freepage(table, new_row_size);
-       if (!pgnum) {
-               fprintf(stderr, "Unable to allocate new page.\n");
-               return 0;
-       }
-
-       rownum = mdb_add_row_to_pg(table, row_buffer, new_row_size);
-
-       if (mdb_get_option(MDB_DEBUG_WRITE)) {
-               buffer_dump(mdb->pg_buf, 0, 39);
-               buffer_dump(mdb->pg_buf, fmt->pg_size - 160, fmt->pg_size-1);
-       }
-       mdb_debug(MDB_DEBUG_WRITE, "writing page %d", pgnum);
-       if (!mdb_write_pg(mdb, pgnum)) {
-               fprintf(stderr, "write failed! exiting...\n");
-               exit(1);
-       }
-
-       mdb_update_indexes(table, num_fields, fields, pgnum, rownum);
-       return 1;
-}
-/*
- * Assumes caller has verfied space is available on page and adds the new 
- * row to the current pg_buf.
- */
-guint16
-mdb_add_row_to_pg(MdbTableDef *table, unsigned char *row_buffer, int new_row_size)
-{
-       unsigned char *new_pg;
-       int num_rows, i, pos, row_start, row_end, row_size;
-       MdbCatalogEntry *entry = table->entry;
-       MdbHandle *mdb = entry->mdb;
-       MdbFormatConstants *fmt = mdb->fmt;
-
-       if (table->is_temp_table) {
-               GPtrArray *pages = table->temp_table_pages;
-               if (pages->len == 0) {
-                       new_pg = mdb_new_data_pg(entry);
-                       g_ptr_array_add(pages, new_pg);
-               } else {
-                       new_pg = g_ptr_array_index(pages, pages->len - 1);
-                       if (mdb_get_int16(new_pg, 2) < new_row_size + 2) {
-                               new_pg = mdb_new_data_pg(entry);
-                               g_ptr_array_add(pages, new_pg);
-                       }
-               }
-
-               num_rows = mdb_get_int16(new_pg, fmt->row_count_offset);
-               pos = (num_rows == 0) ? fmt->pg_size :
-                       mdb_get_int16(new_pg, fmt->row_count_offset + (num_rows*2));
-       } else {  /* is not a temp table */
-               new_pg = mdb_new_data_pg(entry);
-
-               num_rows = mdb_pg_get_int16(mdb, fmt->row_count_offset);
-               pos = fmt->pg_size;
-
-               /* copy existing rows */
-               for (i=0;i<num_rows;i++) {
-                       row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (i*2));
-                       row_end = mdb_find_end_of_row(mdb, i);
-                       row_size = row_end - row_start + 1;
-                       pos -= row_size;
-                       memcpy(&new_pg[pos], &mdb->pg_buf[row_start], row_size);
-                       _mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (i*2), pos);
-               }
-       }
-
-       /* add our new row */
-       pos -= new_row_size;
-       memcpy(&new_pg[pos], row_buffer, new_row_size);
-       /* add row to the row offset table */
-       _mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (num_rows*2), pos);
-
-       /* update number rows on this page */
-       num_rows++;
-       _mdb_put_int16(new_pg, fmt->row_count_offset, num_rows);
-
-       /* update the freespace */
-       _mdb_put_int16(new_pg,2,pos - fmt->row_count_offset - 2 - (num_rows*2));
-
-       /* copy new page over old */
-       if (!table->is_temp_table) {
-               memcpy(mdb->pg_buf, new_pg, fmt->pg_size);
-               g_free(new_pg);
-       }
-
-       return num_rows;
-}
-int 
-mdb_update_row(MdbTableDef *table)
-{
-int row_start, row_end;
-unsigned int i;
-MdbColumn *col;
-MdbCatalogEntry *entry = table->entry;
-MdbHandle *mdb = entry->mdb;
-MdbFormatConstants *fmt = mdb->fmt;
-MdbField fields[256];
-unsigned char row_buffer[4096];
-int old_row_size, new_row_size, delta;
-unsigned int num_fields;
-
-       if (!mdb->f->writable) {
-               fprintf(stderr, "File is not open for writing\n");
-               return 0;
-       }
-       row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + ((table->cur_row-1)*2)); 
-       row_end = mdb_find_end_of_row(mdb, table->cur_row-1);
-       old_row_size = row_end - row_start;
-
-       row_start &= 0x0FFF; /* remove flags */
-
-       mdb_debug(MDB_DEBUG_WRITE,"page %lu row %d start %d end %d", (unsigned long) table->cur_phys_pg, table->cur_row-1, row_start, row_end);
-       if (mdb_get_option(MDB_DEBUG_LIKE))
-               buffer_dump(mdb->pg_buf, row_start, row_end);
-
-       for (i=0;i<table->num_cols;i++) {
-               col = g_ptr_array_index(table->columns,i);
-               if (col->bind_ptr && mdb_is_col_indexed(table,i)) {
-                       fprintf(stderr, "Attempting to update column that is part of an index\n");
-                       return 0;
-               }
-       }
-       num_fields = mdb_crack_row(table, row_start, row_end, fields);
-
-       if (mdb_get_option(MDB_DEBUG_WRITE)) {
-               for (i=0;i<num_fields;i++) {
-                       printf("col %d %d start %d siz %d\n", i, fields[i].colnum, fields[i].start, fields[i].siz);
-               }
-       }
-       for (i=0;i<table->num_cols;i++) {
-               col = g_ptr_array_index(table->columns,i);
-               if (col->bind_ptr) {
-                       printf("yes\n");
-                       fields[i].value = col->bind_ptr;
-                       fields[i].siz = *(col->len_ptr);
-               }
-       }
-
-       new_row_size = mdb_pack_row(table, row_buffer, num_fields, fields);
-       if (mdb_get_option(MDB_DEBUG_WRITE)) 
-               buffer_dump(row_buffer, 0, new_row_size-1);
-       delta = new_row_size - old_row_size;
-       if ((mdb_pg_get_freespace(mdb) - delta) < 0) {
-               fprintf(stderr, "No space left on this page, update will not occur\n");
-               return 0;
-       }
-       /* do it! */
-       mdb_replace_row(table, table->cur_row-1, row_buffer, new_row_size);
-       return 0;
-}
-int 
-mdb_replace_row(MdbTableDef *table, int row, unsigned char *new_row, int new_row_size)
-{
-MdbCatalogEntry *entry = table->entry;
-MdbHandle *mdb = entry->mdb;
-MdbFormatConstants *fmt = mdb->fmt;
-unsigned char *new_pg;
-guint16 num_rows;
-int row_start, row_end, row_size;
-int i, pos;
-
-       if (mdb_get_option(MDB_DEBUG_WRITE)) {
-               buffer_dump(mdb->pg_buf, 0, 39);
-               buffer_dump(mdb->pg_buf, fmt->pg_size - 160, fmt->pg_size-1);
-       }
-       mdb_debug(MDB_DEBUG_WRITE,"updating row %d on page %lu", row, (unsigned long) table->cur_phys_pg);
-       new_pg = mdb_new_data_pg(entry);
-
-       num_rows = mdb_pg_get_int16(mdb, fmt->row_count_offset);
-       _mdb_put_int16(new_pg, fmt->row_count_offset, num_rows);
-
-       pos = mdb->fmt->pg_size;
-
-       /* rows before */
-       for (i=0;i<row;i++) {
-               row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (i*2));
-               row_end = mdb_find_end_of_row(mdb, i);
-               row_size = row_end - row_start + 1;
-               pos -= row_size;
-               memcpy(&new_pg[pos], &mdb->pg_buf[row_start], row_size);
-               _mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (i*2), pos);
-       }
-       
-       /* our row */
-       pos -= new_row_size;
-       memcpy(&new_pg[pos], new_row, new_row_size);
-       _mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (row*2), pos);
-       
-       /* rows after */
-       for (i=row+1;i<num_rows;i++) {
-               row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (i*2));
-               row_end = mdb_find_end_of_row(mdb, i);
-               row_size = row_end - row_start + 1;
-               pos -= row_size;
-               memcpy(&new_pg[pos], &mdb->pg_buf[row_start], row_size);
-               _mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (i*2), pos);
-       }
-
-       /* almost done, copy page over current */
-       memcpy(mdb->pg_buf, new_pg, fmt->pg_size);
-
-       g_free(new_pg);
-
-       _mdb_put_int16(mdb->pg_buf, 2, mdb_pg_get_freespace(mdb));
-       if (mdb_get_option(MDB_DEBUG_WRITE)) {
-               buffer_dump(mdb->pg_buf, 0, 39);
-               buffer_dump(mdb->pg_buf, fmt->pg_size - 160, fmt->pg_size-1);
-       }
-       /* drum roll, please */
-       if (!mdb_write_pg(mdb, table->cur_phys_pg)) {
-               fprintf(stderr, "write failed! exiting...\n");
-               exit(1);
-       }
-       return 0;
-}
-static int
-mdb_add_row_to_leaf_pg(MdbTableDef *table, MdbIndex *idx, MdbIndexPage *ipg, MdbField *idx_fields) 
-/*,  guint32 pgnum, guint16 rownum) 
-static int
-mdb_copy_index_pg(MdbTableDef *table, MdbIndex *idx, MdbIndexPage *ipg)
-*/
-{
-       MdbCatalogEntry *entry = table->entry;
-       MdbHandle *mdb = entry->mdb;
-       MdbColumn *col;
-       guint32 pg;
-       guint16 row;
-       unsigned char *new_pg;
-       unsigned char key_hash[256];
-       unsigned char iflag;
-       int keycol;
-
-       new_pg = mdb_new_leaf_pg(entry);
-
-       mdb_index_page_reset(ipg);
-       mdb_read_pg(mdb, ipg->pg);
-
-       /* do we support this index type yet? */
-       if (idx->num_keys > 1) {
-               fprintf(stderr,"multikey indexes not yet supported, aborting\n");
-               return 0;
-       }
-       keycol = idx->key_col_num[0];
-       col = g_ptr_array_index (table->columns, keycol - 1);
-       printf("keycol = %d (%s)\n", keycol, col->name);
-       if (!mdb_is_fixed_col(col)) {
-               fprintf(stderr,"variable length key columns not yet supported, aborting\n");
-               return 0;
-       }
-       printf("col size = %d\n", col->col_size);
-
-       while (mdb_index_find_next_on_page(mdb, ipg)) {
-
-               /* check for compressed indexes.  */
-               if (ipg->len < col->col_size + 1) {
-                       fprintf(stderr,"compressed indexes not yet supported, aborting\n");
-                       return 0;
-               }
-
-               pg = mdb_pg_get_int24_msb(mdb, ipg->offset + ipg->len - 4);
-               row = mdb->pg_buf[ipg->offset + ipg->len - 1];
-               iflag = mdb->pg_buf[ipg->offset];
-               mdb_index_swap_n(&mdb->pg_buf[ipg->offset + 1], col->col_size, key_hash);
-               key_hash[col->col_size - 1] &= 0x7f;
-               printf("length = %d\n", ipg->len);
-               printf("iflag = %d pg = %" G_GUINT32_FORMAT
-                       " row = %" G_GUINT16_FORMAT "\n", iflag, pg, row);
-               buffer_dump(mdb->pg_buf, ipg->offset, ipg->offset + ipg->len - 1);
-               buffer_dump(mdb->pg_buf, ipg->offset + 1, ipg->offset + col->col_size);
-               buffer_dump(key_hash, 0, col->col_size - 1);
-               ipg->offset += ipg->len;
-               ipg->len = 0;
-               row++;
-       }
-       g_free(new_pg);
-
-       return ipg->len;
-}
diff --git a/navit/data/poi_geodownload/poi_geodownload.c b/navit/data/poi_geodownload/poi_geodownload.c
deleted file mode 100644 (file)
index 3545cde..0000000
+++ /dev/null
@@ -1,756 +0,0 @@
-#include <mdbtools.h>
-#include "config.h"
-#include "debug.h"
-#include "coord.h"
-#include "projection.h"
-#include "item.h"
-#include "map.h"
-#include "plugin.h"
-
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <dirent.h>
-
-struct map_priv
-{
-       char *filename;
-       MdbHandle *h;
-       MdbHandle *h_idx;
-       MdbTableDef *table;
-       GPtrArray *table_col;
-       MdbColumn **cols;
-       MdbIndex *idx;
-       int idx_size;
-       enum item_type type;
-       int name_col;
-};
-
-struct map_rect_priv
-{
-       struct item item;
-       struct map_priv *m;
-       enum attr_type attr_next;
-       int cidx;
-       char buffer[4096];
-};
-
-#if 0
-struct index_data {
-       unsigned char data[15];
-};
-struct poi {
-       char filename[1024];
-       char icon[1024];
-       long pos;
-       MdbHandle *h;
-       MdbHandle *h_idx;
-       MdbTableDef *table;
-       GPtrArray *table_col;
-       MdbColumn **cols;
-       MdbIndex *idx;
-       int idx_size;
-       struct index_data index_data;
-       MdbIndexChain chain;
-       struct poi *next;
-} *poi_list;
-
-struct poi_data {
-       struct poi *poi;
-       int page;
-       int row;
-};
-
-       char poipath[256];
-       char poibmp[256];
-
-
-#endif
-
-static void
-print_col(MdbHandle *h, MdbColumn *col, char *buffer, int hex)
-{
-       char *s;
-       dbg(1,"type=%d\n", col->col_type);
-       switch (col->col_type) {
-       case MDB_BOOL:
-               strcpy(buffer, mdb_pg_get_byte(h, col->cur_value_start) ? "True" : "False");
-               break;
-       case MDB_BYTE:
-               sprintf(buffer, "%d", mdb_pg_get_byte(h, col->cur_value_start));
-               break;
-       case MDB_LONGINT:
-               if (hex)
-                       sprintf(buffer, "0x%lx", mdb_pg_get_int32(h, col->cur_value_start));
-               else
-                       sprintf(buffer, "%ld", mdb_pg_get_int32(h, col->cur_value_start));
-               break;
-       case MDB_DOUBLE:
-               sprintf(buffer, "%f", mdb_pg_get_double(h, col->cur_value_start));
-               break;
-       case MDB_TEXT:
-               dbg(1,"pg_buf %p start %d len %d\n", h->pg_buf, col->cur_value_start, col->cur_value_len);
-               if (col->cur_value_len) {
-                       s=mdb_col_to_string (h, h->pg_buf, col->cur_value_start, col->col_type, col->cur_value_len);
-                       dbg(1,"s=%p\n", s);
-                       sprintf(buffer, "%s", s);
-               }
-               break;
-       default:
-               sprintf(buffer, "unknown (%d)", col->col_type);
-       }
-}
-
-#if 0
-
-static void
-setup_idx_data(struct index_data *idx, struct coord *c, unsigned int geoflags, int size)
-{
-       /* 7f 80 1c 91 0a 7f 80 5c  f5 41 7f 80 00 00 05 */
-       idx->data[0]=0x7f;
-       idx->data[1]=(c->x >> 24) ^ 0x80;
-       idx->data[2]=c->x >> 16;
-       idx->data[3]=c->x >> 8;
-       idx->data[4]=c->x;
-       idx->data[5]=0x7f;
-       idx->data[6]=(c->y >> 24) ^ 0x80;
-       idx->data[7]=c->y >> 16;
-       idx->data[8]=c->y >> 8;
-       idx->data[9]=c->y;
-       idx->data[10]=0x7f;
-       if (size > 12) {
-               idx->data[11]=0x80 | (geoflags >> 24);
-               idx->data[12]=geoflags >> 16;
-               idx->data[13]=geoflags >> 8;
-               idx->data[14]=geoflags;
-       } else {
-               idx->data[11]=geoflags;
-       }
-}
-
-static void
-setup_idx_rect(struct coord *rect, struct index_data *idx, int size)
-{
-       struct coord r[2];
-       r[0].x=rect[0].x;
-       r[0].y=rect[1].y;
-       r[1].x=rect[1].x;
-       r[1].y=rect[0].y;
-#if 0
-       printf("low 0x%x 0%x\n", r[0].x, r[0].y);
-       printf("high 0x%x 0%x\n", r[1].x, r[1].y);
-#endif
-       setup_idx_data(idx, r, 0, size);
-       setup_idx_data(idx+1, r+1, 0xffffffff, size);
-}
-
-#endif
-
-static int
-load_row(struct map_priv *poi, int pg, int row)
-{
-       int row_start, row_end, offset;
-       unsigned int num_fields, i;
-       MdbField fields[256];
-       MdbFormatConstants *fmt;
-       int debug=0;
-
-       fmt=poi->h->fmt;
-       mdb_read_pg(poi->h, pg);
-       dbg(1, "enter poi=%p pg=%d row=%d\n", poi, pg, row);
-       dbg(1,"Page Type %d row_count_offset %d\n",poi->h->pg_buf[0], fmt->row_count_offset);
-       for (i = 0; i <= row; i++) {
-               offset=(fmt->row_count_offset + 2) + i * 2;
-               dbg(1,"row %d %d 0x%x\n", i, offset, mdb_pg_get_int16(poi->h, offset));
-       }
-       row_start = mdb_pg_get_int16(poi->h, (fmt->row_count_offset + 2) + row * 2);
-       if (row_start & 0x4000)
-               return 1;
-       row_end = mdb_find_end_of_row(poi->h, row);
-       if (debug) {
-               printf("start=0x%x end=0x%x\n", row_start, row_end);
-               buffer_dump(poi->h->pg_buf, row_start, row_end);
-       }
-
-       poi->h->cur_pos=row_start & 0x1fff;
-       poi->table->cur_row=row;
-       num_fields = mdb_crack_row(poi->table, row_start & 0x1fff, row_end, fields);
-       dbg(1,"num_fields=%d\n", num_fields);
-       for (i = 0; i < num_fields; i++) {
-               dbg(1,"i=%d/%d\n", i, num_fields);
-               poi->cols[i]->cur_value_start=fields[i].start;
-               poi->cols[i]->cur_value_len=fields[i].siz;
-       }
-       return 0;
-}
-
-#if 0
-
-static MdbIndexPage *
-index_next_row(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
-{
-       MdbIndexPage *ipg;
-
-       ipg = mdb_index_read_bottom_pg(mdb, idx, chain);
-       if (!mdb_index_find_next_on_page(mdb, ipg)) {
-#if 0
-               printf("no next\n");    
-#endif
-               if (!chain->clean_up_mode) {
-#if 0
-                       printf("no cleanup\n"); 
-#endif
-                       if (!(ipg = mdb_index_unwind(mdb, idx, chain)))
-                               chain->clean_up_mode = 1;
-               }
-               if (chain->clean_up_mode) {
-#if 0
-                       printf("cleanup\n");    
-#endif
-                       //fprintf(stdout,"in cleanup mode\n");
-
-                       if (!chain->last_leaf_found) {
-                               printf("no last_leaf_found\n");
-                               return NULL;
-                       }
-                       mdb_read_pg(mdb, chain->last_leaf_found);
-                       chain->last_leaf_found =
-                           mdb_pg_get_int24(mdb, 0x0c);
-                       //printf("next leaf %lu\n", chain->last_leaf_found);
-                       mdb_read_pg(mdb, chain->last_leaf_found);
-                       /* reuse the chain for cleanup mode */
-                       chain->cur_depth = 1;
-                       ipg = &chain->pages[0];
-                       mdb_index_page_init(ipg);
-                       ipg->pg = chain->last_leaf_found;
-                       //printf("next on page %d\n",
-                       if (!mdb_index_find_next_on_page(mdb, ipg)) {
-#if 0
-                               printf("no find_next_on_page\n");
-#endif
-                               return NULL;
-                       }
-               }
-       }
-       return ipg;
-}
-
-static int
-index_next(struct poi *poi, struct index_data *idx)
-{
-       MdbIndexPage *ipg;
-       MdbIndexChain *chain = &poi->chain;
-       int row;
-       int pg;
-       int offset;
-       char *cmp, *low, *high;
-       int debug=0;
-
-
-       for(;;) {
-       for(;;) {
-       ipg=index_next_row(poi->h_idx, poi->idx, chain);
-       if (! ipg)
-               return 0;
-       row = poi->h_idx->pg_buf[ipg->offset + ipg->len - 1];
-       pg = mdb_pg_get_int24_msb(poi->h_idx, ipg->offset + ipg->len - 4);
-
-       offset=poi->idx_size+4-ipg->len;
-       memcpy(poi->index_data.data+offset, poi->h_idx->pg_buf+ipg->offset, ipg->len - 4);
-       cmp=poi->index_data.data;
-       low=idx[0].data;
-       high=idx[1].data;
-       if (debug > 1) {
-               buffer_dump(low, 0, poi->idx_size-1);
-               buffer_dump(cmp, 0, poi->idx_size-1);
-               buffer_dump(high, 0, poi->idx_size-1);
-               printf("%d %d %d\n", memcmp(cmp, low, poi->idx_size), memcmp(cmp, high, poi->idx_size), offset);
-       }
-#if 0
-       buffer_dump(poi->h_idx->pg_buf, ipg->offset, ipg->offset+ipg->len-1);
-#endif
-       ipg->offset += ipg->len;
-       if (memcmp(cmp, low, poi->idx_size) >= 0) {
-               if (memcmp(cmp, high, poi->idx_size) <=0 ) {
-                       if (debug) {
-                               printf("match\n");
-                               buffer_dump(low, 0, poi->idx_size-1);
-                               buffer_dump(cmp, 0, poi->idx_size-1);
-                               buffer_dump(high, 0, poi->idx_size-1);
-                               printf("%d %d %d\n", memcmp(cmp, low, poi->idx_size), memcmp(cmp, high, poi->idx_size), offset);
-                       }
-                       break;
-               } else {
-                       return 0;
-               }
-       }
-       if (debug > 1)
-               printf("row=0x%x pg=0x%x len=%d\n", row, pg, ipg->len);
-       }
-       if (debug)
-               printf("match: row=0x%x pg=0x%x len=%d\n", row, pg, ipg->len);
-               if (!load_row(poi, pg, row))
-                       break;
-       }
-       return 1;
-}
-
-#endif
-
-static int
-load_poi_table(struct map_priv *m, MdbCatalogEntry *entry)
-{
-       int j;
-       MdbIndex *idx;
-
-       m->h_idx=NULL;
-       m->table = mdb_read_table(entry);
-       m->table_col = mdb_read_columns(m->table);
-       mdb_read_indices(m->table);
-       m->cols = (MdbColumn **) (m->table_col->pdata);
-       if (m->table_col->len < 4 || strcasecmp(m->cols[0]->name, "X") ||
-               strcasecmp(m->cols[1]->name, "Y") || strcasecmp(m->cols[3]->name, "GEOFLAGS")) 
-                       return 1;
-       m->name_col=-1;
-       for (j = 0; j < m->table_col->len ; j++) {
-               if (!strcasecmp(m->cols[j]->name, "NAME"))
-                       m->name_col=j;
-       }
-       for (j = 0; j < m->table->num_idxs; j++) {
-               idx = m->table->indices->pdata[j];
-               if (idx->num_keys == 3 && idx->key_col_num[0] == 1 &&
-                   idx->key_col_num[1] == 2 && idx->key_col_num[2] == 4) {
-                       m->idx = idx;
-                       m->idx_size=3+m->cols[0]->col_size+m->cols[1]->col_size+m->cols[3]->col_size;
-                       m->h_idx=mdb_clone_handle(m->h);
-               }
-       }
-       return 0;       
-}
-
-#if 0
-
-static void
-load_poi(char *filename, char *icon, int type)
-{
-       int i;
-       MdbCatalogEntry *entry;
-       GPtrArray *catalog;
-       struct poi *new = g_new0(struct poi, 1);
-
-       FILE *fp = fopen(filename,"r");
-       if( fp ) {
-              fclose(fp);
-       } else {
-               printf("ERR : POI file %s does not exists!\n",filename);
-               exit(0);
-               return -1;
-       }
-
-
-       fp = fopen(icon,"r");
-       if( fp ) {
-              fclose(fp);
-       } else {
-               printf("ERR : WARNING INCORRECT PICTURE! %s!\n",icon);
-               exit(0);
-               return -1;
-       }
-
-       strcpy(new->filename,filename);
-       strcpy(new->icon,icon);
-       new->type = type;
-
-
-       if (type == 0) {
-               new->h = mdb_open(filename, MDB_NOFLAGS);
-               catalog = mdb_read_catalog(new->h, MDB_TABLE);
-               for (i = 0; i < catalog->len; i++) {
-                       entry = catalog->pdata[i];
-                       if (!strcasecmp(entry->object_name, "_INDEXDATA")) {
-                               if (load_poi_table(new, entry)) {
-                                       printf("%s invalid\n", filename);
-                                       g_free(new);
-                                       new=NULL;
-                               }
-                       }
-               }
-               g_ptr_array_free(catalog, 1);
-       }
-       if (new) {
-               new->next = poi_list;
-               poi_list = new;
-       }
-}
-
-static void
-get_coord(struct poi *p, struct coord *c)
-{
-       c->x=mdb_pg_get_int32(p->h, p->cols[0]->cur_value_start);
-       c->y=mdb_pg_get_int32(p->h, p->cols[1]->cur_value_start);
-}
-
-static void
-poi_info(struct display_list *list, struct popup_item **popup)
-{
-       struct poi_data *data=list->data;
-       struct poi *poi=data->poi;
-       struct popup_item *popup_last, *popup_val_last;
-       char *text,buffer[4096];
-       int j;
-       MdbColumn *col;
-       char *v;
-
-       popup_last = *popup;
-
-       popup_val_last = NULL;
-       sprintf(buffer,"File:%s", poi->filename);
-       popup_item_new_text(&popup_val_last, buffer, 1);
-       sprintf(buffer,"Icon:%s", poi->icon);
-       popup_item_new_text(&popup_val_last, buffer, 2);
-       if (poi->type == 0) {
-               printf("poi_info pg=%d row=%d\n", data->page, data->row);
-               load_row(poi, data->page, data->row);
-               sprintf(buffer,"Page:%d", data->page);
-               popup_item_new_text(&popup_val_last, buffer, 3);
-               sprintf(buffer,"Row:%d", data->row);
-               popup_item_new_text(&popup_val_last, buffer, 4);
-               for (j = 0; j < poi->table_col->len; j++) {
-                       col = poi->table_col->pdata[j];
-       #if 0
-                       printf("start: %d type:%d\n", col->cur_value_start, col->col_type);
-       #endif
-                       sprintf(buffer, "%s:", col->name);
-                       v = buffer + strlen(buffer);
-                       if (!strcasecmp(col->name,"X") || !strcasecmp(col->name,"Y")) 
-                               print_col(poi->h, col, v, 1);
-                       else
-                               print_col(poi->h, col, v, 0);
-       #if 0
-                       printf("%s\n", buffer);
-       #endif
-                       text=g_convert(buffer,-1,"utf-8","iso8859-1",NULL,NULL,NULL);
-                       popup_item_new_text(&popup_val_last, buffer, j+10);
-                       g_free(text);
-               }
-       }
-       popup_item_new_text(&popup_last, "POI", 20)->submenu = popup_val_last;
-       *popup=popup_last;
-}
-
-static void
-draw_poi(struct poi *p, struct container *co, struct point *pnt)
-{
-       struct poi_data data;
-       data.poi=p;
-       if (p->type == 0) {
-               data.page=p->h->cur_pg;
-               data.row=p->table->cur_row-1;
-       }
-       if (p->type == 1) {
-               data.row=p->pos;
-       }
-       display_add(&co->disp[display_poi], 5, 0, p->icon, 1, pnt, poi_info, &data, sizeof(data));
-}
-
-static void
-plugin_draw(struct container *co)
-{
-       struct coord c;
-       struct point pnt;
-       struct poi *p;
-       struct index_data idx[2];
-       int use_index=0;
-       int debug=1;
-
-       p = poi_list;
-
-       if (co->trans->scale > 1024)
-               return; 
-       if (debug) {
-               printf("scale=%ld\n", co->trans->scale);
-               printf("rect 0x%lx,0%lx-0x%lx,0x%lx\n", co->trans->rect[0].x, co->trans->rect[0].y, co->trans->rect[1].x, co->trans->rect[1].y);
-       }
-       while (p) {
-               if (p->type == 0) {
-                       if (use_index)
-                               setup_idx_rect(co->trans->rect, idx, p->idx_size);
-                       if (! use_index) {
-                               printf("rewind %s %p\n", p->filename, p->table);
-                               mdb_rewind_table(p->table);
-                               while (mdb_fetch_row(p->table)) {
-                                       get_coord(p, &c);
-                                       if (transform(co->trans, &c, &pnt)) {
-                                               if (debug)
-                                                       printf("coord 0x%lx,0x%lx pg %d row %d\n", c.x, c.y, p->h->cur_pg, p->table->cur_row);
-                                               draw_poi(p, co, &pnt);
-                                       }
-                               }
-                       }  else {
-                               memset(&p->chain, 0, sizeof(p->chain));
-                               while (index_next(p, idx)) {
-                                       get_coord(p, &c);
-                                       if (transform(co->trans, &c, &pnt)) {
-                                               if (debug)
-                                                       printf("coord 0x%lx,0x%lx pg %d row %d\n", c.x, c.y, p->h->cur_pg, p->table->cur_row);
-                                               draw_poi(p, co, &pnt);
-                                       }
-                               }
-                       }
-               }
-               if (p->type == 1) {
-                       FILE *f;
-                       char line[1024];
-                       struct text_poi tpoi;
-                       if(!(f=fopen(p->filename, "r"))){
-                               printf("can't open poi file for drawing!\n");
-                               exit(0);
-                       }
-#if 0
-                       printf("opened poi file %s for drawing!\n",p->filename);
-#endif
-                       p->pos=ftell(f);
-                       fgets(line, 1024, f);
-                       while (!feof(f)) {
-                               if (strlen(line)) {
-                                       line[strlen(line)-1]='\0';
-                               }
-                               if (parse_text_poi(line, &tpoi)) {
-                                       transform_mercator(&tpoi.lat,&tpoi.lng,&c);
-//                                     printf("%ld %ld\n", c.x, c.y);
-                                       if (transform(co->trans, &c, &pnt)) {
-                                               draw_poi(p, co, &pnt);
-                                       }
-                               }
-                               p->pos=ftell(f);
-                               fgets(line, 1024, f);
-                       }
-                       fclose(f);                      
-               }
-               p = p->next;
-       }
-
-}
-
-#endif
-
-static void
-map_destroy_poi_geodownload(struct map_priv *m)
-{
-        dbg(1,"enter\n");
-        g_free(m);
-}
-
-static void
-poi_geodownload_coord_rewind(void *priv_data)
-{
-       struct map_rect_priv *mr=priv_data;
-       mr->cidx=0;
-}
-
-
-static int
-poi_geodownload_coord_get(void *priv_data, struct coord *c, int count)
-{
-       struct map_rect_priv *mr=priv_data;
-       dbg(1,"enter\n");
-       if (mr->cidx || !count)
-               return 0;
-       c->x=mdb_pg_get_int32(mr->m->h, mr->m->cols[0]->cur_value_start);
-       c->y=mdb_pg_get_int32(mr->m->h, mr->m->cols[1]->cur_value_start);
-       dbg(1,"x=0x%x y=0x%x\n", c->x, c->y);
-       return 1;
-}
-
-static void
-poi_geodownload_attr_rewind(void *priv_data)
-{
-       struct map_rect_priv *mr=priv_data;
-       mr->attr_next=attr_label;
-}
-
-static int
-poi_geodownload_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
-{
-       struct map_rect_priv *mr=priv_data;
-       struct map_priv *m=mr->m;
-       MdbColumn *col;
-       char *v;
-       int j;
-
-       dbg(1,"enter\n");
-       attr->type=attr_type;
-       switch (attr_type) {
-       case attr_any:
-               while (mr->attr_next != attr_none) {
-                       if (poi_geodownload_attr_get(mr, mr->attr_next, attr))
-                               return 1;
-                }
-                return 0;
-       case attr_label:
-               mr->attr_next=attr_debug;
-               if (m->name_col == -1)
-                       return 0;
-               col=m->cols[m->name_col];
-               if (col->cur_value_len) 
-                       attr->u.str=mdb_col_to_string (m->h, m->h->pg_buf, col->cur_value_start, col->col_type, col->cur_value_len);
-               else
-                       attr->u.str="";
-               return 1;
-       case attr_debug:
-               mr->attr_next=attr_none;
-               v=mr->buffer;
-               *v='\0';
-               for (j = 0; j < mr->m->table_col->len; j++) {
-                       col = mr->m->table_col->pdata[j];
-                       printf("start: %d type:%d\n", col->cur_value_start, col->col_type);
-                       sprintf(v, "%s:", col->name);
-                       v += strlen(v);
-                       if (!strcasecmp(col->name,"X") || !strcasecmp(col->name,"Y")) 
-                               print_col(mr->m->h, col, v, 1);
-                       else
-                               print_col(mr->m->h, col, v, 0);
-                       v += strlen(v);
-                       *v++='\n';
-                       *v='\0';
-               }
-               attr->u.str=mr->buffer;
-               return 1;
-       default:
-               break;
-       }
-       return 0;
-}
-
-static struct item_methods methods_poi_geodownload = {
-       poi_geodownload_coord_rewind,
-       poi_geodownload_coord_get,
-       poi_geodownload_attr_rewind,
-       poi_geodownload_attr_get,
-};
-
-
-static struct map_rect_priv *
-map_rect_new_poi_geodownload(struct map_priv *map, struct map_selection *sel)
-{
-        struct map_rect_priv *mr;
-
-        dbg(1,"enter\n");
-        mr=g_new0(struct map_rect_priv, 1);
-       mr->item.meth=&methods_poi_geodownload;
-       mr->item.id_hi=0;
-       mr->item.id_lo=0;
-       mr->item.priv_data=mr;
-       mr->item.type=map->type;
-       mr->m=map;
-       mdb_rewind_table(map->table);
-        return mr;
-}
-
-
-static void
-map_rect_destroy_poi_geodownload(struct map_rect_priv *mr)
-{
-       g_free(mr);
-}
-
-static struct item *
-map_rect_get_item_poi_geodownload(struct map_rect_priv *mr)
-{
-       dbg(1,"enter\n");
-       if (mdb_fetch_row(mr->m->table)) {
-               mr->item.id_hi=mr->m->table->cur_phys_pg;
-               mr->item.id_lo=mr->m->table->cur_row-1;
-               poi_geodownload_attr_rewind(mr);
-               return &mr->item;
-       }
-       return NULL;
-}
-
-static struct item *
-map_rect_get_item_byid_poi_geodownload(struct map_rect_priv *mr, int id_hi, int id_lo)
-{
-       char *v, buffer[4096];
-       int j;
-       MdbColumn *col;
-
-       dbg(1,"enter\n");
-       load_row(mr->m, id_hi, id_lo);
-       for (j = 0; j < mr->m->table_col->len; j++) {
-               col = mr->m->table_col->pdata[j];
-               printf("start: %d type:%d\n", col->cur_value_start, col->col_type);
-               sprintf(buffer, "%s:", col->name);
-               v = buffer + strlen(buffer);
-               if (!strcasecmp(col->name,"X") || !strcasecmp(col->name,"Y")) 
-                       print_col(mr->m->h, col, v, 1);
-               else
-                       print_col(mr->m->h, col, v, 0);
-               printf("%s\n", buffer);
-       }
-       dbg(1,"ret=%p\n", &mr->item);
-       poi_geodownload_attr_rewind(mr);
-       return &mr->item;
-}
-
-
-static struct map_methods map_methods_poi_geodownload = {
-       projection_mg,
-       "iso8859-1",
-       map_destroy_poi_geodownload,
-       map_rect_new_poi_geodownload,
-       map_rect_destroy_poi_geodownload,
-       map_rect_get_item_poi_geodownload,
-       map_rect_get_item_byid_poi_geodownload,
-};
-
-static struct map_priv *
-map_new_poi_geodownload(struct map_methods *meth, struct attr **attrs)
-{
-        struct map_priv *m;
-       MdbCatalogEntry *entry;
-       GPtrArray *catalog;
-       int i;
-       struct attr *attr;
-       struct attr *data=attr_search(attrs, NULL, attr_data);
-       char *filename;
-        if (! data)
-               return NULL;
-       filename=data->u.str;
-        dbg(1,"filename %s\n",filename);
-        *meth=map_methods_poi_geodownload;
-
-        m=g_new(struct map_priv, 1);
-        m->filename=g_strdup(filename);
-       m->h = mdb_open(m->filename, MDB_NOFLAGS);
-       m->type=type_none;
-       dbg(1,"attr_search\n");
-       attr=attr_search(attrs, NULL, attr_item_type);
-       dbg(1,"attr_search result %p\n", attr);
-       if (attr) 
-               m->type=attr->u.item_type;
-               
-       
-       catalog = mdb_read_catalog(m->h, MDB_TABLE);
-       for (i = 0; i < catalog->len; i++) {
-               entry = catalog->pdata[i];
-               dbg(1,"object name '%s'\n", entry->object_name);
-               if (!strcasecmp(entry->object_name, "_INDEXDATA")) {
-                       if (load_poi_table(m, entry)) {
-                               printf("%s invalid\n", filename);
-                               g_free(m);
-                               m=NULL;
-                       }
-               }
-       }
-       g_ptr_array_free(catalog, 1);
-        return m;
-}
-
-void
-plugin_init(void)
-{
-       dbg(1,"plugin_init\n");
-       plugin_register_map_type("poi_geodownload", map_new_poi_geodownload);
-       mdb_init();
-}
-
diff --git a/navit/data/textfile/Makefile.am b/navit/data/textfile/Makefile.am
deleted file mode 100644 (file)
index 50aacae..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-include $(top_srcdir)/Makefile.inc
-AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/navit -DMODULE=data_textfile
-if PLUGINS
-  moduledata_LTLIBRARIES = libdata_textfile.la
-else
-  noinst_LTLIBRARIES = libdata_textfile.la
-endif
-libdata_textfile_la_SOURCES = textfile.c textfile.h
diff --git a/navit/data/textfile/textfile.c b/navit/data/textfile/textfile.c
deleted file mode 100644 (file)
index aa2fa01..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-/**
- * Navit, a modular navigation system.
- * Copyright (C) 2005-2008 Navit Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA  02110-1301, USA.
- */
-
-#include <glib.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#include "config.h"
-#include "debug.h"
-#include "plugin.h"
-#include "projection.h"
-#include "item.h"
-#include "map.h"
-#include "maptype.h"
-#include "attr.h"
-#include "transform.h"
-#include "file.h"
-
-#include "textfile.h"
-
-static int map_id;
-
-static int
-get_tag(char *line, char *name, int *pos, char *ret, char *name_ret)
-{
-       int len=0,quoted;
-       char *p,*e,*n;
-
-       dbg(1,"get_tag %s from %s\n", name, line); 
-       if (name)
-               len=strlen(name);
-       if (pos) 
-               p=line+*pos;
-       else
-               p=line;
-       for(;;) {
-               while (*p == ' ') {
-                       p++;
-               }
-               if (! *p)
-                       return 0;
-               n=p;
-               e=strchr(p,'=');
-               if (! e)
-                       return 0;
-               p=e+1;
-               quoted=0;
-               while (*p) {
-                       if (*p == ' ' && !quoted)
-                               break;
-                       if (*p == '"')
-                               quoted=1-quoted;
-                       p++;
-               }
-               if (name == NULL || (e-n == len && !strncmp(n, name, len))) {
-                       if (name_ret) {
-                               len=e-n;
-                               strncpy(name_ret, n, len);
-                               name_ret[len]='\0';
-                       }
-                       e++;
-                       len=p-e;
-                       if (e[0] == '"') {
-                               e++;
-                               len-=2;
-                       }
-                       strncpy(ret, e, len);
-                       ret[len]='\0';
-                       if (pos)
-                               *pos=p-line;
-                       return 1;
-               }
-       }       
-       return 0;
-}
-
-static void
-get_line(struct map_rect_priv *mr)
-{
-       if(mr->f) {
-               mr->pos=ftell(mr->f);
-               fgets(mr->line, SIZE, mr->f);
-               if (strlen(mr->line) >= SIZE-1) 
-                       printf("line too long\n");
-       }
-}
-
-static void
-map_destroy_textfile(struct map_priv *m)
-{
-       dbg(1,"map_destroy_textfile\n");
-       g_free(m);
-}
-
-static void
-textfile_coord_rewind(void *priv_data)
-{
-}
-
-static int
-parse_line(struct map_rect_priv *mr, int attr)
-{
-       int pos;
-
-       pos=coord_parse(mr->line, projection_mg, &mr->c);
-       if (pos < strlen(mr->line) && attr) {
-               strcpy(mr->attrs, mr->line+pos);
-       }
-       return pos;
-}
-
-static int
-textfile_coord_get(void *priv_data, struct coord *c, int count)
-{
-       struct map_rect_priv *mr=priv_data;
-       int ret=0;
-       dbg(1,"textfile_coord_get %d\n",count);
-       while (count--) {
-               if (mr->f && !feof(mr->f) && (!mr->item.id_hi || !mr->eoc) && parse_line(mr, mr->item.id_hi)) {
-                       *c=mr->c;
-                       dbg(1,"c=0x%x,0x%x\n", c->x, c->y);
-                       c++;
-                       ret++;          
-                       get_line(mr);
-                       if (mr->item.id_hi)
-                               mr->eoc=1;
-               } else {
-                       mr->more=0;
-                       break;
-               }
-       }
-       return ret;
-}
-
-static void
-textfile_attr_rewind(void *priv_data)
-{
-}
-
-static void
-textfile_encode_attr(char *attr_val, enum attr_type attr_type, struct attr *attr)
-{
-       if (attr_type >= attr_type_int_begin && attr_type <= attr_type_int_end) 
-               attr->u.num=atoi(attr_val);
-       else
-               attr->u.str=attr_val;
-}
-
-static int
-textfile_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
-{      
-       struct map_rect_priv *mr=priv_data;
-       char *str=NULL;
-       dbg(1,"textfile_attr_get mr=%p attrs='%s' ", mr, mr->attrs);
-       if (attr_type != mr->attr_last) {
-               dbg(1,"reset attr_pos\n");
-               mr->attr_pos=0;
-               mr->attr_last=attr_type;
-       }
-       if (attr_type == attr_any) {
-               dbg(1,"attr_any");
-               if (get_tag(mr->attrs,NULL,&mr->attr_pos,mr->attr, mr->attr_name)) {
-                       attr_type=attr_from_name(mr->attr_name);
-                       dbg(1,"found attr '%s' 0x%x\n", mr->attr_name, attr_type);
-                       attr->type=attr_type;
-                       textfile_encode_attr(mr->attr, attr_type, attr);
-                       return 1;
-               }
-       } else {
-               str=attr_to_name(attr_type);
-               dbg(1,"attr='%s' ",str);
-               if (get_tag(mr->attrs,str,&mr->attr_pos,mr->attr, NULL)) {
-                       textfile_encode_attr(mr->attr, attr_type, attr);
-                       dbg(1,"found\n");
-                       return 1;
-               }
-       }
-       dbg(1,"not found\n");
-       return 0;
-}
-
-static struct item_methods methods_textfile = {
-        textfile_coord_rewind,
-        textfile_coord_get,
-        textfile_attr_rewind,
-        textfile_attr_get,
-};
-
-static struct map_rect_priv *
-map_rect_new_textfile(struct map_priv *map, struct map_selection *sel)
-{
-       struct map_rect_priv *mr;
-
-       dbg(1,"map_rect_new_textfile\n");
-       mr=g_new0(struct map_rect_priv, 1);
-       mr->m=map;
-       mr->sel=sel;
-       mr->item.id_hi=0;
-       mr->item.id_lo=0;
-       mr->item.meth=&methods_textfile;
-       mr->item.priv_data=mr;
-       if (map->is_pipe) {
-               char *oargs,*args=g_strdup(map->filename),*sep=" ";
-               enum layer_type lay;
-               g_free(mr->args);
-               while (sel) {
-                       oargs=args;
-                       args=g_strdup_printf("%s 0x%x 0x%x 0x%x 0x%x", oargs, sel->u.c_rect.lu.x, sel->u.c_rect.lu.y, sel->u.c_rect.rl.x, sel->u.c_rect.rl.y);
-                       g_free(oargs);
-                       for (lay=layer_town ; lay < layer_end ; lay++) {
-                               oargs=args;
-                               args=g_strdup_printf("%s%s%d", oargs, sep, sel->order);
-                               g_free(oargs);
-                               sep=",";
-                       }
-                       sel=sel->next;
-               }
-               dbg(1,"popen args %s\n", args);
-               mr->args=args;
-               mr->f=popen(mr->args, "r");
-       } else {
-               mr->f=fopen(map->filename, "r");
-       }
-       if(!mr->f) {
-               printf("map_rect_new_textfile unable to open textfile %s\n",map->filename);
-       }
-       get_line(mr);
-       return mr;
-}
-
-
-static void
-map_rect_destroy_textfile(struct map_rect_priv *mr)
-{
-       if (mr->f) {
-               if (mr->m->is_pipe)
-                       pclose(mr->f);
-               else
-                       fclose(mr->f);
-       }
-        g_free(mr);
-}
-
-static struct item *
-map_rect_get_item_textfile(struct map_rect_priv *mr)
-{
-       char *p,type[SIZE];
-       dbg(1,"map_rect_get_item_textfile id_hi=%d line=%s", mr->item.id_hi, mr->line);
-       if (!mr->f) {
-               return NULL;
-       }
-       while (mr->more) {
-               struct coord c;
-               textfile_coord_get(mr, &c, 1);
-       }
-       for(;;) {
-               if (feof(mr->f)) {
-                       dbg(1,"map_rect_get_item_textfile: eof\n");
-                       if (mr->item.id_hi) {
-                               return NULL;
-                       }
-                       mr->item.id_hi++;
-                       if (mr->m->is_pipe) {
-                               pclose(mr->f);
-                               mr->f=popen(mr->args, "r");
-                       } else
-                               fseek(mr->f, 0, SEEK_SET);
-                       get_line(mr);
-               }
-               if ((p=strchr(mr->line,'\n'))) 
-                       *p='\0';
-               if (mr->item.id_hi) {
-                       mr->attrs[0]='\0';
-                       if (!parse_line(mr, 1)) {
-                               get_line(mr);
-                               continue;
-                       }
-                       dbg(1,"map_rect_get_item_textfile: point found\n");
-                       mr->eoc=0;
-                       mr->item.id_lo=mr->pos;
-               } else {
-                       if (parse_line(mr, 1)) {
-                               get_line(mr);
-                               continue;
-                       }
-                       dbg(1,"map_rect_get_item_textfile: line found\n");
-                       if (! mr->line[0]) {
-                               get_line(mr);
-                               continue;
-                       }
-                       mr->item.id_lo=mr->pos;
-                       strcpy(mr->attrs, mr->line);
-                       get_line(mr);
-                       dbg(1,"mr=%p attrs=%s\n", mr, mr->attrs);
-               }
-               dbg(1,"get_attrs %s\n", mr->attrs);
-               if (get_tag(mr->attrs,"type",NULL,type,NULL)) {
-                       dbg(1,"type='%s'\n", type);
-                       mr->item.type=item_from_name(type);
-                       if (mr->item.type == type_none) 
-                               printf("Warning: type '%s' unknown\n", type);
-               } else {
-                       get_line(mr);
-                       continue;
-               }
-               mr->attr_last=attr_none;
-               mr->more=1;
-               dbg(1,"return attr='%s'\n", mr->attrs);
-               return &mr->item;
-       }
-}
-
-static struct item *
-map_rect_get_item_byid_textfile(struct map_rect_priv *mr, int id_hi, int id_lo)
-{
-       if (mr->m->is_pipe) {
-               pclose(mr->f);
-               mr->f=popen(mr->args, "r");
-       } else
-               fseek(mr->f, id_lo, SEEK_SET);
-       get_line(mr);
-       mr->item.id_hi=id_hi;
-       return map_rect_get_item_textfile(mr);
-}
-
-static struct map_methods map_methods_textfile = {
-       projection_mg,
-       "iso8859-1",
-       map_destroy_textfile,
-       map_rect_new_textfile,
-       map_rect_destroy_textfile,
-       map_rect_get_item_textfile,
-       map_rect_get_item_byid_textfile,
-};
-
-static struct map_priv *
-map_new_textfile(struct map_methods *meth, struct attr **attrs)
-{
-       struct map_priv *m;
-       struct attr *data=attr_search(attrs, NULL, attr_data);
-       struct attr *charset=attr_search(attrs, NULL, attr_charset);
-       struct file_wordexp *wexp;
-       int len,is_pipe=0;
-       char *wdata;
-       char **wexp_data;
-       if (! data)
-               return NULL;
-       dbg(1,"map_new_textfile %s\n", data->u.str);    
-       wdata=g_strdup_printf(data->u.str);
-       len=strlen(wdata);
-       if (len && wdata[len-1] == '|') {
-               wdata[len-1]='\0';
-               is_pipe=1;
-       }
-       wexp=file_wordexp_new(wdata);
-       wexp_data=file_wordexp_get_array(wexp);
-       *meth=map_methods_textfile;
-
-       m=g_new0(struct map_priv, 1);
-       m->id=++map_id;
-       m->filename=g_strdup(wexp_data[0]);
-       m->is_pipe=is_pipe;
-       dbg(1,"map_new_textfile %s %s\n", m->filename, wdata);
-       if (charset) {
-               m->charset=g_strdup(charset->u.str);
-               meth->charset=m->charset;
-       }
-       file_wordexp_destroy(wexp);
-       return m;
-}
-
-void
-plugin_init(void)
-{
-       dbg(1,"textfile: plugin_init\n");
-       plugin_register_map_type("textfile", map_new_textfile);
-}
-
diff --git a/navit/data/textfile/textfile.h b/navit/data/textfile/textfile.h
deleted file mode 100644 (file)
index b7a77be..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * Navit, a modular navigation system.
- * Copyright (C) 2005-2008 Navit Team
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the
- * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA  02110-1301, USA.
- */
-
-#include <stdio.h>
-#include "attr.h"
-#include "coord.h"
-struct map_priv {
-       int id;
-       char *filename;
-       char *charset;
-       int is_pipe;
-};
-
-#define SIZE 512
-
-struct map_rect_priv {
-       struct map_selection *sel;
-
-       FILE *f;
-       long pos;
-       char line[SIZE];
-       int attr_pos;
-       enum attr_type attr_last;
-       char attrs[SIZE];
-       char attr[SIZE];
-       char attr_name[SIZE];
-       struct coord c;
-       int eoc;
-       int more;
-       struct map_priv *m;
-       struct item item;
-       char *args;
-};
-
diff --git a/navit/map/Makefile.am b/navit/map/Makefile.am
new file mode 100644 (file)
index 0000000..6a35548
--- /dev/null
@@ -0,0 +1,11 @@
+SUBDIRS=mg textfile binfile
+#  garmin_img
+if HAVELIBGARMIN
+SUBDIRS+=garmin
+endif
+if MAP_POI_GEODOWNLOAD
+SUBDIRS+=poi_geodownload
+endif
+
+DIST_SUBDIRS=mg textfile poi_geodownload binfile garmin
+
diff --git a/navit/map/binfile/Makefile.am b/navit/map/binfile/Makefile.am
new file mode 100644 (file)
index 0000000..f208994
--- /dev/null
@@ -0,0 +1,8 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/navit -DMODULE=map_binfile
+if PLUGINS
+  modulemap_LTLIBRARIES = libmap_binfile.la
+else
+  noinst_LTLIBRARIES = libmap_binfile.la
+endif
+libmap_binfile_la_SOURCES = binfile.c
diff --git a/navit/map/binfile/binfile.c b/navit/map/binfile/binfile.c
new file mode 100644 (file)
index 0000000..7a91dcb
--- /dev/null
@@ -0,0 +1,907 @@
+/**
+ * Navit, a modular navigation system.
+ * Copyright (C) 2005-2008 Navit Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <glib.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "config.h"
+#include "debug.h"
+#include "plugin.h"
+#include "projection.h"
+#include "item.h"
+#include "map.h"
+#include "maptype.h"
+#include "attr.h"
+#include "coord.h"
+#include "transform.h"
+#include "file.h"
+#include "zipfile.h"
+#include "endianess.h"
+
+static int map_id;
+
+struct minmax {
+       short min;
+       short max;
+};
+
+struct tile {
+       int *start;
+       int *end;
+       int *pos;
+       int *pos_coord_start;
+       int *pos_coord;
+       int *pos_attr_start;
+       int *pos_attr;
+       int *pos_next;
+       int zipfile_num;
+};
+
+struct map_priv {
+       int id;
+       char *filename;
+       char *cachedir;
+       struct file *fi;
+       struct zip_cd *index_cd;
+       int index_offset;
+       int cde_size;
+       struct zip_eoc *eoc;
+       int zip_members;
+       unsigned char *search_data;
+       int search_offset;
+       int search_size;
+       int version;
+       int check_version;
+};
+
+struct map_rect_priv {
+       int *start;
+       int *end;
+       enum attr_type attr_last;
+       int label;
+       int *label_attr[4];
+        struct map_selection *sel;
+        struct map_priv *m;
+        struct item item;
+       int tile_depth;
+       struct tile tiles[8];
+       struct tile *t;
+       int country_id;
+       char *url;
+};
+
+struct map_search_priv {
+       struct map_rect_priv *mr;
+       struct attr *search;
+       struct map_selection *ms;
+       int partial;
+       GHashTable *search_results;
+};
+
+
+static void minmax_to_cpu(struct minmax * mima) {
+       dbg_assert(mima  != NULL);
+       mima->min = le16_to_cpu(mima->min);
+       mima->max = le16_to_cpu(mima->max);
+}
+
+static void lfh_to_cpu(struct zip_lfh *lfh) {
+       dbg_assert(lfh != NULL);
+       lfh->ziplocsig = le32_to_cpu(lfh->ziplocsig);
+       lfh->zipver    = le16_to_cpu(lfh->zipver);
+       lfh->zipgenfld = le16_to_cpu(lfh->zipgenfld);
+       lfh->zipmthd   = le16_to_cpu(lfh->zipmthd);
+       lfh->ziptime   = le16_to_cpu(lfh->ziptime);
+       lfh->zipdate   = le16_to_cpu(lfh->zipdate);
+       lfh->zipcrc    = le32_to_cpu(lfh->zipcrc);
+       lfh->zipsize   = le32_to_cpu(lfh->zipsize);
+       lfh->zipuncmp  = le32_to_cpu(lfh->zipuncmp);
+       lfh->zipfnln   = le16_to_cpu(lfh->zipfnln);
+       lfh->zipxtraln = le16_to_cpu(lfh->zipxtraln);
+}
+
+static void cd_to_cpu(struct zip_cd *zcd) {
+       dbg_assert(zcd != NULL);
+       zcd->zipcensig = le32_to_cpu(zcd->zipcensig);
+       zcd->zipccrc   = le32_to_cpu(zcd->zipccrc);
+       zcd->zipcsiz   = le32_to_cpu(zcd->zipcsiz);
+       zcd->zipcunc   = le32_to_cpu(zcd->zipcunc);
+       zcd->zipcfnl   = le16_to_cpu(zcd->zipcfnl);
+       zcd->zipcxtl   = le16_to_cpu(zcd->zipcxtl);
+       zcd->zipccml   = le16_to_cpu(zcd->zipccml);
+       zcd->zipdsk    = le16_to_cpu(zcd->zipdsk);
+       zcd->zipint    = le16_to_cpu(zcd->zipint);
+       zcd->zipext    = le32_to_cpu(zcd->zipext);
+       zcd->zipofst   = le32_to_cpu(zcd->zipofst);
+}
+
+static void eoc_to_cpu(struct zip_eoc *eoc) {
+       dbg_assert(eoc != NULL);
+       eoc->zipesig   = le32_to_cpu(eoc->zipesig);
+       eoc->zipedsk   = le16_to_cpu(eoc->zipedsk);
+       eoc->zipecen   = le16_to_cpu(eoc->zipecen);
+       eoc->zipenum   = le16_to_cpu(eoc->zipenum);
+       eoc->zipecenn  = le16_to_cpu(eoc->zipecenn);
+       eoc->zipecsz   = le32_to_cpu(eoc->zipecsz);
+       eoc->zipeofst  = le32_to_cpu(eoc->zipeofst);
+       eoc->zipecoml  = le16_to_cpu(eoc->zipecoml);
+}
+
+static void binfile_check_version(struct map_priv *m);
+
+static struct zip_eoc *
+binfile_read_eoc(struct file *fi)
+{
+       struct zip_eoc *eoc;
+       eoc=(struct zip_eoc *)file_data_read(fi,fi->size-sizeof(struct zip_eoc), sizeof(struct zip_eoc));
+       if (eoc) {
+               eoc_to_cpu(eoc);
+               dbg(1,"sig 0x%x\n", eoc->zipesig);
+               if (eoc->zipesig != zip_eoc_sig) {
+                       file_data_free(fi,(unsigned char *)eoc);
+                       eoc=NULL;
+               }
+       }
+       return eoc;
+}
+
+static struct zip_cd *
+binfile_read_cd(struct map_priv *m, int offset, int len)
+{
+       struct zip_cd *cd;
+       if (len == -1) {
+               cd=(struct zip_cd *)file_data_read(m->fi,m->eoc->zipeofst+offset, sizeof(*cd));
+               cd_to_cpu(m->index_cd);
+               len=cd->zipcfnl;
+               file_data_free(m->fi,(unsigned char *)cd);
+       }
+       cd=(struct zip_cd *)file_data_read(m->fi,m->eoc->zipeofst+offset, sizeof(*cd)+len);
+       if (cd) {
+               cd_to_cpu(cd);
+               dbg(1,"sig 0x%x\n", cd->zipcensig);
+               if (cd->zipcensig != zip_cd_sig) {
+                       file_data_free(m->fi,(unsigned char *)cd);
+                       cd=NULL;
+               }
+       }
+       return cd;
+}
+
+static struct zip_lfh *
+binfile_read_lfh(struct file *fi, int offset)
+{
+       struct zip_lfh *lfh;
+
+       lfh=(struct zip_lfh *)(file_data_read(fi,offset,sizeof(struct zip_lfh)));
+       if (lfh) {
+               lfh_to_cpu(lfh);
+               if (lfh->ziplocsig != zip_lfh_sig) {
+                       file_data_free(fi,(unsigned char *)lfh);
+                       lfh=NULL;
+               }
+       }
+       return lfh;
+}
+
+static unsigned char *
+binfile_read_content(struct file *fi, int offset, struct zip_lfh *lfh)
+{
+       offset+=sizeof(struct zip_lfh)+lfh->zipfnln+lfh->zipxtraln;
+       switch (lfh->zipmthd) {
+       case 0:
+               return file_data_read(fi,offset, lfh->zipuncmp);
+       case 8:
+               return file_data_read_compressed(fi,offset, lfh->zipsize, lfh->zipuncmp);
+       default:
+               dbg(0,"Unknown compression method %d\n", lfh->zipmthd);
+               return NULL;
+       }
+}
+
+static int
+binfile_search_cd(struct map_priv *m, int offset, char *name, int partial, int skip)
+{
+       int size=4096;
+       int end=m->eoc->zipecsz;
+       int len=strlen(name);
+       struct zip_cd *cd;
+#if 0
+       dbg(0,"end=%d\n",end);
+#endif
+       while (offset < end) {
+               cd=(struct zip_cd *)(m->search_data+offset-m->search_offset);
+               if (! m->search_data || 
+                     m->search_offset > offset || 
+                     offset-m->search_offset+sizeof(*cd) > m->search_size ||
+                     offset-m->search_offset+sizeof(*cd)+cd->zipcfnl > m->search_size
+                  ) {
+#if 0
+                       dbg(0,"reload %p %d %d\n", m->search_data, m->search_offset, offset);
+#endif
+                       if (m->search_data)
+                               file_data_free(m->fi,m->search_data);
+                       m->search_offset=offset;
+                       m->search_size=end-offset;
+                       if (m->search_size > size)
+                               m->search_size=size;
+                       m->search_data=file_data_read(m->fi,m->eoc->zipeofst+m->search_offset,m->search_size);
+                       cd=(struct zip_cd *)m->search_data;
+               }
+#if 0
+               dbg(0,"offset=%d search_offset=%d search_size=%d search_data=%p cd=%p\n", offset, m->search_offset, m->search_size, m->search_data, cd);
+               dbg(0,"offset=%d fn='%s'\n",offset,cd->zipcfn);
+#endif
+               if (!skip && 
+                   (partial || cd->zipcfnl == len) &&
+                   !strncmp(cd->zipcfn, name, len)) 
+                       return offset;
+               skip=0;
+               offset+=sizeof(*cd)+cd->zipcfnl+cd->zipcxtl+cd->zipccml;
+;
+       }
+       return -1;
+}
+
+static void
+map_destroy_binfile(struct map_priv *m)
+{
+       dbg(1,"map_destroy_binfile\n");
+       g_free(m);
+}
+
+static void
+binfile_coord_rewind(void *priv_data)
+{
+       struct map_rect_priv *mr=priv_data;
+       struct tile *t=mr->t;
+       t->pos_coord=t->pos_coord_start;
+}
+
+static int
+binfile_coord_get(void *priv_data, struct coord *c, int count)
+{
+       struct map_rect_priv *mr=priv_data;
+       struct tile *t=mr->t;
+       int ret=0;
+       dbg(2,"binfile_coord_get %d\n",count);
+       while (count--) {
+               dbg(2,"%p vs %p\n", t->pos_coord, t->pos_attr_start);
+               if (t->pos_coord >= t->pos_attr_start)
+                       break;
+               c->x=le32_to_cpu(*(t->pos_coord++));
+               c->y=le32_to_cpu(*(t->pos_coord++));
+               c++;
+               ret++;
+       }
+       return ret;
+}
+
+static void
+binfile_attr_rewind(void *priv_data)
+{
+       struct map_rect_priv *mr=priv_data;
+       struct tile *t=mr->t;
+       t->pos_attr=t->pos_attr_start;
+       
+}
+
+static char *
+binfile_extract(struct map_priv *m, char *dir, char *filename, int partial)
+{
+       char *full,*fulld,*sep;
+       unsigned char *start;
+       int len,offset=m->index_offset;
+       struct zip_cd *cd;
+       struct zip_lfh *lfh;
+       FILE *f;
+
+       for (;;) {
+               offset=binfile_search_cd(m, offset, filename, partial, 1);
+               if (offset == -1)
+                       break;
+               cd=binfile_read_cd(m, offset, -1);
+               len=strlen(dir)+1+cd->zipcfnl+1;
+               full=g_malloc(len);
+               strcpy(full,dir);
+               strcpy(full+strlen(full),"/");
+               strncpy(full+strlen(full),cd->zipcfn,cd->zipcfnl);
+               full[len-1]='\0';
+               fulld=g_strdup(full);
+               sep=strrchr(fulld, '/');
+               if (sep) {
+                       *sep='\0';
+                       file_mkdir(fulld, 1);
+               }
+               if (full[len-2] != '/') {
+                       lfh=binfile_read_lfh(m->fi, cd->zipofst);
+                       start=binfile_read_content(m->fi, cd->zipofst, lfh);
+                       dbg(0,"fopen '%s'\n", full);
+                       f=fopen(full,"w");
+                       fwrite(start, lfh->zipuncmp, 1, f);
+                       fclose(f);
+                       file_data_free(m->fi, start);
+                       file_data_free(m->fi, (unsigned char *)lfh);
+               }
+               file_data_free(m->fi, (unsigned char *)cd);
+               g_free(fulld);
+               g_free(full);
+               if (! partial)
+                       break;
+       }
+       
+       return g_strdup_printf("%s/%s",dir,filename);
+}
+
+static int
+binfile_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{      
+       struct map_rect_priv *mr=priv_data;
+       struct tile *t=mr->t;
+       enum attr_type type;
+       int i,size;
+
+       if (attr_type != mr->attr_last) {
+               t->pos_attr=t->pos_attr_start;
+               mr->attr_last=attr_type;
+       }
+       while (t->pos_attr < t->pos_next) {
+               size=le32_to_cpu(*(t->pos_attr++));
+               type=le32_to_cpu(t->pos_attr[0]);
+               if (type == attr_label) 
+                       mr->label=1;
+               if (type == attr_house_number)
+                       mr->label_attr[0]=t->pos_attr;
+               if (type == attr_street_name)
+                       mr->label_attr[1]=t->pos_attr;
+               if (type == attr_street_name_systematic)
+                       mr->label_attr[2]=t->pos_attr;
+               if (type == attr_town_name)
+                       mr->label_attr[3]=t->pos_attr;
+               if (type == attr_type || attr_type == attr_any) {
+                       if (attr_type == attr_any) {
+                               dbg(1,"pos %p attr %s size %d\n", t->pos_attr-1, attr_to_name(type), size);
+                       }
+                       attr->type=type;
+                       attr_data_set(attr, t->pos_attr+1);
+                       if (type == attr_url_local) {
+                               g_free(mr->url);
+                               mr->url=binfile_extract(mr->m, mr->m->cachedir, attr->u.str, 1);
+                               attr->u.str=mr->url;
+                       }
+                       t->pos_attr+=size;
+                       return 1;
+               } else {
+                       t->pos_attr+=size;
+               }
+       }
+       if (!mr->label && (attr_type == attr_any || attr_type == attr_label)) {
+               for (i = 0 ; i < sizeof(mr->label_attr)/sizeof(int *) ; i++) {
+                       if (mr->label_attr[i]) {
+                               mr->label=1;
+                               attr->type=attr_label;
+                               attr_data_set(attr, mr->label_attr[i]+1);
+                               return 1;
+                       }
+               }
+       }
+       return 0;
+}
+
+static struct item_methods methods_binfile = {
+        binfile_coord_rewind,
+        binfile_coord_get,
+        binfile_attr_rewind,
+        binfile_attr_get,
+};
+
+static void
+push_tile(struct map_rect_priv *mr, struct tile *t)
+{
+       dbg_assert(mr->tile_depth < 8);
+       mr->t=&mr->tiles[mr->tile_depth++];
+       *(mr->t)=*t;
+       mr->t->pos=mr->t->pos_next=mr->t->start;
+}
+
+static int
+pop_tile(struct map_rect_priv *mr)
+{
+       if (mr->tile_depth <= 1)
+               return 0;
+       file_data_free(mr->m->fi, (unsigned char *)(mr->t->start));
+       mr->t=&mr->tiles[--mr->tile_depth-1];
+       return 1;
+}
+
+
+static int
+zipfile_to_tile(struct file *f, struct zip_cd *cd, struct tile *t)
+{
+       char buffer[1024];
+       struct zip_lfh *lfh;
+       char *zipfn;
+       dbg(1,"enter %p %p %p\n", f, cd, t);
+       dbg(1,"cd->zipofst=0x%x\n", cd->zipofst);
+       t->start=NULL;
+       lfh=binfile_read_lfh(f, cd->zipofst);
+       zipfn=(char *)(file_data_read(f,cd->zipofst+sizeof(struct zip_lfh), lfh->zipfnln));
+       strncpy(buffer, zipfn, lfh->zipfnln);
+       buffer[lfh->zipfnln]='\0';
+       t->start=(int *)binfile_read_content(f, cd->zipofst, lfh);
+       t->end=t->start+lfh->zipuncmp/4;
+       dbg(1,"0x%x '%s' %d %d,%d\n", lfh->ziplocsig, buffer, sizeof(*cd)+cd->zipcfnl, lfh->zipsize, lfh->zipuncmp);
+       file_data_free(f, (unsigned char *)zipfn);
+       file_data_free(f, (unsigned char *)lfh);
+       return t->start != NULL;
+}
+
+static void
+push_zipfile_tile(struct map_rect_priv *mr, int zipfile)
+{
+        struct map_priv *m=mr->m;
+       struct file *f=m->fi;
+       struct tile t;
+       struct zip_cd *cd=(struct zip_cd *)(file_data_read(f, m->eoc->zipeofst + zipfile*m->cde_size, sizeof(struct zip_cd)));
+       cd_to_cpu(cd);
+       dbg(1,"enter %p %d\n", mr, zipfile);
+       t.zipfile_num=zipfile;
+       if (zipfile_to_tile(f, cd, &t))
+               push_tile(mr, &t);
+       file_data_free(f, (unsigned char *)cd);
+}
+
+static struct map_rect_priv *
+map_rect_new_binfile(struct map_priv *map, struct map_selection *sel)
+{
+       struct map_rect_priv *mr;
+       struct tile t={};
+
+       binfile_check_version(map);
+       dbg(1,"map_rect_new_binfile\n");
+       mr=g_new0(struct map_rect_priv, 1);
+       mr->m=map;
+       mr->sel=sel;
+       mr->item.id_hi=0;
+       mr->item.id_lo=0;
+       dbg(1,"zip_members=%d\n", map->zip_members);
+       if (map->eoc) 
+               push_zipfile_tile(mr, map->zip_members-1);
+       else {
+               unsigned char *d=file_data_read(map->fi, 0, map->fi->size);
+               t.start=(int *)d;
+               t.end=(int *)(d+map->fi->size);
+               t.zipfile_num=0;
+               push_tile(mr, &t);
+       }
+       mr->item.meth=&methods_binfile;
+       mr->item.priv_data=mr;
+       return mr;
+}
+
+
+static void
+map_rect_destroy_binfile(struct map_rect_priv *mr)
+{
+       while (pop_tile(mr));
+       file_data_free(mr->m->fi, (unsigned char *)(mr->tiles[0].start));
+       g_free(mr->url);
+        g_free(mr);
+}
+
+static void
+setup_pos(struct map_rect_priv *mr)
+{
+       int size,coord_size;
+       struct tile *t=mr->t;
+       size=le32_to_cpu(*(t->pos++));
+       if (size > 1024*1024 || size < 0) {
+               dbg(0,"size=0x%x\n", size);
+#if 0
+               fprintf(stderr,"offset=%d\n", (unsigned char *)(mr->pos)-mr->m->f->begin);
+#endif
+               dbg(0,"size error");
+       }
+       t->pos_next=t->pos+size;
+       mr->item.type=le32_to_cpu(*(t->pos++));
+       coord_size=le32_to_cpu(*(t->pos++));
+       t->pos_coord_start=t->pos_coord=t->pos;
+       t->pos_attr_start=t->pos_attr=t->pos_coord+coord_size;
+}
+
+static int
+selection_contains(struct map_selection *sel, struct coord_rect *r, struct minmax *mima)
+{
+       int order;
+       if (! sel)
+               return 1;
+       while (sel) {
+               if (coord_rect_overlap(r, &sel->u.c_rect)) {
+                       order=sel->order;
+                       dbg(1,"min %d max %d order %d\n", mima->min, mima->max, order);
+                       if (!mima->min && !mima->max)
+                               return 1;
+                       if (order >= mima->min && order <= mima->max)
+                               return 1;
+               }
+               sel=sel->next;
+       }
+       return 0;
+}
+
+static void
+map_parse_country_binfile(struct map_rect_priv *mr)
+{
+       struct attr at;
+       if (binfile_attr_get(mr->item.priv_data, attr_country_id, &at)) {
+               if (at.u.num == mr->country_id)
+               {
+                       if (binfile_attr_get(mr->item.priv_data, attr_zipfile_ref, &at))
+                       {
+                               push_zipfile_tile(mr, at.u.num);
+                       }
+               }
+       }
+}
+
+static struct item *
+map_rect_get_item_binfile(struct map_rect_priv *mr)
+{
+       struct tile *t;
+       struct minmax *mima;
+       for (;;) {
+               t=mr->t;
+               if (! t)
+                       return NULL;
+               t->pos=t->pos_next;
+               if (t->pos >= t->end) {
+                       if (pop_tile(mr))
+                               continue;
+                       return NULL;
+               }
+               mr->item.id_hi=t->zipfile_num;
+               mr->item.id_lo=t->pos-t->start;
+               mr->label=0;
+               memset(mr->label_attr, 0, sizeof(mr->label_attr));
+               setup_pos(mr);
+               if ((mr->item.type == type_submap) && (!mr->country_id)) {
+                       struct coord_rect r;
+                       r.lu.x=le32_to_cpu(t->pos_coord[0]);
+                       r.lu.y=le32_to_cpu(t->pos_coord[3]);
+                       r.rl.x=le32_to_cpu(t->pos_coord[2]);
+                       r.rl.y=le32_to_cpu(t->pos_coord[1]);
+                       mima=(struct minmax *)(t->pos_attr+2);
+                       minmax_to_cpu(mima);
+                       if (!mr->m->eoc || !selection_contains(mr->sel, &r, mima)) {
+                               continue;
+                       }
+                       dbg(1,"pushing zipfile %d from %d\n", le32_to_cpu(t->pos_attr[5]), t->zipfile_num);
+                       push_zipfile_tile(mr, le32_to_cpu(t->pos_attr[5]));
+                       continue;
+                               
+               }
+               if (mr->country_id)
+               {
+                       if (mr->item.type == type_countryindex) {
+                               map_parse_country_binfile(mr);
+                       }
+                       if (item_is_town(mr->item))
+                       {
+                               return &mr->item;
+                       } else {
+                               continue;
+                       }
+               }
+               return &mr->item;
+       }
+}
+
+static struct item *
+map_rect_get_item_byid_binfile(struct map_rect_priv *mr, int id_hi, int id_lo)
+{
+       struct tile *t;
+       if (mr->m->eoc) 
+               push_zipfile_tile(mr, id_hi);
+       t=mr->t;
+       t->pos=t->start+id_lo;
+       mr->item.id_hi=id_hi;
+       mr->item.id_lo=id_lo;
+       mr->label=0;
+       memset(mr->label_attr, 0, sizeof(mr->label_attr));
+       setup_pos(mr);
+       return &mr->item;
+}
+
+static struct map_search_priv *
+binmap_search_new(struct map_priv *map, struct item *item, struct attr *search, int partial)
+{
+       struct map_rect_priv *map_rec;
+       struct map_search_priv *msp;
+       struct map_selection *ms;
+       struct item *town;
+       
+       /*
+     * NOTE: If you implement search for other attributes than attr_town_name and attr_street_name,
+     * please update this comment and the documentation for map_search_new() in map.c
+     */
+       switch (search->type) {
+               case attr_country_name:
+                       break;
+               case attr_town_name:
+                       msp = g_new(struct map_search_priv, 1);
+                       msp->search_results = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+                       map_rec = map_rect_new_binfile(map, NULL);
+                       map_rec->country_id = item->id_lo;
+                       msp->mr = map_rec;
+                       msp->search = search;
+                       msp->partial = partial;
+                       return msp;
+                       break;
+               case attr_town_postal:
+                       break;
+               case attr_street_name:
+                       if (! item->map)
+                               break;
+                       if (!map_priv_is(item->map, map))
+                               break;
+                       ms = g_new(struct map_selection, 1);
+                       ms->next = NULL;
+                       ms->range = item_range_all; /* FIXME */
+                       ms->order = 18;
+                       map_rec = map_rect_new_binfile(map, ms);
+                       town = map_rect_get_item_byid_binfile(map_rec, item->id_hi, item->id_lo);
+                       if (town) {
+                               struct map_search_priv *msp = g_new(struct map_search_priv, 1);
+                               struct coord *c = g_new(struct coord, 1);
+                               int size = 10000;
+                               switch (town->type) {
+                                       case type_town_label_2e5:
+                                               size = 10000;
+                                               break;
+                                       case type_town_label_2e4:
+                                               size = 5000;
+                                               break;
+                                       case type_town_label_2e3:
+                                               size = 2500;
+                                               break;
+                                       case type_town_label_2e2:
+                                               size = 1000;
+                                               break;
+                                       default:
+                                               break;
+                               }
+                               item_coord_get(town, c, 1);
+                               ms->u.c_rect.lu.x = c->x-size;
+                               ms->u.c_rect.lu.y = c->y+size;
+                               ms->u.c_rect.rl.x = c->x+size;
+                               ms->u.c_rect.rl.y = c->y-size;
+                               
+                               map_rect_destroy_binfile(map_rec);
+                               map_rec = map_rect_new_binfile(map, ms);
+                               msp->mr = map_rec;
+                               msp->search = search;
+                               msp->partial = partial;
+                               msp->search_results = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+                               return msp;
+                       }
+                       map_rect_destroy_binfile(map_rec);
+                       g_free(ms);
+                       break;
+               default:
+                       break;
+       }
+       return NULL;
+}
+static int
+ascii_cmp(char *name, char *match, int partial)
+{
+       if (partial)
+               return g_ascii_strncasecmp(name, match, strlen(match));
+       else
+               return g_ascii_strcasecmp(name, match);
+}
+
+static struct item *
+binmap_search_get_item(struct map_search_priv *map_search)
+{
+       struct item* it;
+       while ((it  = map_rect_get_item_binfile(map_search->mr))) {
+               if (map_search->search->type == attr_town_name) {
+                       if (item_is_town(*it)) {
+                               struct attr at;
+                               if (binfile_attr_get(it->priv_data, attr_label, &at)) {
+                                       if (!ascii_cmp(at.u.str, map_search->search->u.str, map_search->partial)) {
+                                               return it;
+                                       }
+                               }
+                       }
+               } else if (map_search->search->type == attr_street_name) {
+                       if ((it->type == type_street_3_city) || (it->type == type_street_2_city) || (it->type == type_street_1_city)) {
+                               struct attr at;
+                               if (map_selection_contains_item_rect(map_search->mr->sel, it) && binfile_attr_get(it->priv_data, attr_label, &at)) {
+                                       if (!ascii_cmp(at.u.str, map_search->search->u.str, map_search->partial)) {
+                                               if (!g_hash_table_lookup(map_search->search_results, at.u.str)) {
+                                                       item_coord_rewind(it);
+                                                       item_attr_rewind(it);
+                                                       g_hash_table_insert(map_search->search_results, g_strdup(at.u.str), "");
+                                                       return it;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       return NULL;
+}
+
+static void
+binmap_search_destroy(struct map_search_priv *ms)
+{
+       g_hash_table_destroy(ms->search_results);
+       g_free(ms->mr->sel);
+       map_rect_destroy_binfile(ms->mr);
+       g_free(ms);
+}
+
+static struct map_methods map_methods_binfile = {
+       projection_mg,
+       "utf-8",
+       map_destroy_binfile,
+       map_rect_new_binfile,
+       map_rect_destroy_binfile,
+       map_rect_get_item_binfile,
+       map_rect_get_item_byid_binfile,
+       binmap_search_new,
+       binmap_search_destroy,
+       binmap_search_get_item
+};
+
+static int
+binfile_get_index(struct map_priv *m)
+{
+       int len;
+       int cde_index_size;
+       int offset;
+       struct zip_cd *cd;
+
+       len = strlen("index");
+       cde_index_size = sizeof(struct zip_cd)+len;
+       offset = m->eoc->zipecsz-cde_index_size;
+       cd = binfile_read_cd(m, offset, len);
+
+       if (cd) {
+               if (cd->zipcfnl == len && !strncmp(cd->zipcfn, "index", len)) {
+                       m->index_offset=offset;
+                       m->index_cd=cd;
+                       return 1;
+               }
+       }
+       offset=binfile_search_cd(m, 0, "index", 0, 0);
+       if (offset == -1)
+               return 0;
+       cd=binfile_read_cd(m, offset, len);
+       if (!cd)
+               return 0;
+       m->index_offset=offset;
+       m->index_cd=cd;
+       return 1;
+}
+
+static int
+map_binfile_open(struct map_priv *m)
+{
+       int *magic;
+       struct zip_cd *first_cd;
+
+       dbg(1,"file_create %s\n", m->filename);
+       m->fi=file_create(m->filename);
+       if (! m->fi) {
+               dbg(0,"Failed to load '%s'\n", m->filename);
+               return 0;
+       }
+       if (m->check_version)
+               m->version=file_version(m->fi, m->check_version == 2);
+       magic=(int *)file_data_read(m->fi, 0, 4);
+       *magic = le32_to_cpu(*magic);
+       if (*magic == zip_lfh_sig) {
+               if ((m->eoc=binfile_read_eoc(m->fi)) && binfile_get_index(m) && (first_cd=binfile_read_cd(m, 0, 0))) {
+                       m->cde_size=sizeof(struct zip_cd)+first_cd->zipcfnl;
+                       m->zip_members=m->index_offset/m->cde_size+1;
+                       dbg(1,"cde_size %d\n", m->cde_size);
+                       dbg(1,"members %d\n",m->zip_members);
+                       file_data_free(m->fi, (unsigned char *)first_cd);
+               } else {
+                       dbg(0,"invalid file format for '%s'\n", m->filename);
+                       return 0;
+               }
+       } else 
+               file_mmap(m->fi);
+       file_data_free(m->fi, (unsigned char *)magic);
+       m->cachedir="/tmp/navit";
+       return 1;
+}
+
+static void
+map_binfile_close(struct map_priv *m)
+{
+       file_data_free(m->fi, (unsigned char *)m->index_cd);
+       file_data_free(m->fi, (unsigned char *)m->eoc);
+       file_destroy(m->fi);
+}
+
+static void
+map_binfile_destroy(struct map_priv *m)
+{
+       g_free(m->filename);
+       g_free(m);
+}
+
+
+static void
+binfile_check_version(struct map_priv *m)
+{
+       int version;
+       if (!m->check_version)
+               return;
+       version=file_version(m->fi, m->check_version == 2);
+       if (version != m->version) {
+               map_binfile_close(m);
+               map_binfile_open(m);
+       }
+}
+
+
+static struct map_priv *
+map_new_binfile(struct map_methods *meth, struct attr **attrs)
+{
+       struct map_priv *m;
+       struct attr *data=attr_search(attrs, NULL, attr_data);
+       struct attr *check_version;
+       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);
+       dbg(1,"map_new_binfile %s\n", data->u.str);     
+       *meth=map_methods_binfile;
+
+       m=g_new0(struct map_priv, 1);
+       m->id=++map_id;
+       m->filename=g_strdup(wexp_data[0]);
+       file_wordexp_destroy(wexp);
+       check_version=attr_search(attrs, NULL, attr_check_version);
+       if (check_version) 
+               m->check_version=check_version->u.num;
+       if (!map_binfile_open(m)) {
+               map_binfile_destroy(m);
+               m=NULL;
+       }
+       return m;
+}
+
+void
+plugin_init(void)
+{
+       dbg(1,"binfile: plugin_init\n");
+       plugin_register_map_type("binfile", map_new_binfile);
+}
+
diff --git a/navit/map/garmin/Makefile.am b/navit/map/garmin/Makefile.am
new file mode 100644 (file)
index 0000000..764671b
--- /dev/null
@@ -0,0 +1,32 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@   -I$(top_srcdir)/navit -DMODULE=map_garmin
+AM_CPPFLAGS+= @LIBGARMIN_CFLAGS@
+INCLUDES=-I$(top_srcdir)/navit/map/garmin/libgarmin
+AM_CPPFLAGS+=-I$(top_srcdir)/navit/map/garmin/libgarmin
+AM_CPPFLAGS+=-I$(srcdir)
+
+modulemap_LTLIBRARIES = libmap_garmin.la
+libmap_garmin_la_SOURCES = garmin.c garmin.h gar2navit.c gar2navit.h
+libmap_garmin_la_LIBADD = @LIBGARMIN_LIBS@
+nodist_libmap_garmin_la_SOURCES = g2nbuiltin.h
+builddir = @builddir@
+
+gar2navit.l$(OBJEXT): g2nbuiltin.h
+
+CLEANFILES = g2nbuiltin.h
+
+noinst_PROGRAMS=gentypes$(EXEEXT)
+gentypes_SOURCES=gentypes.c
+
+gentypes.$(OBJEXT): gentypes.c
+       $(CC_FOR_BUILD) -I$(top_srcdir)/navit -c -o $@ $<
+
+gentypes$(EXEEXT): $(gentypes_OBJECTS) $(gentypes_DEPENDENCIES) 
+       @rm -f gentypes$(EXEEXT)
+       $(CCLD_FOR_BUILD) -o $@ $(gentypes_OBJECTS)
+
+g2nbuiltin.h: gentypes$(EXEEXT) garmintypes.txt
+       ./gentypes$(EXEEXT) $(top_srcdir)/navit/map/garmin/garmintypes.txt $@
+
+EXTRA_DIST = garmintypes.txt
+
diff --git a/navit/map/garmin/gar2navit.c b/navit/map/garmin/gar2navit.c
new file mode 100644 (file)
index 0000000..7c44504
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+       Copyright (C) 2007  Alexander Atanasov      <aatanasov@gmail.com>
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; version 2 of the License.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+       MA  02110-1301  USA
+    
+       Garmin and MapSource are registered trademarks or trademarks
+       of Garmin Ltd. or one of its subsidiaries.
+
+*/
+
+/*
+File format is:
+
+POINT
+GROUP,0x0100 = town_label_1e5, Megapolis (10M +)
+GROUP,0x0200 = town_label_5e4, Megapolis (5-10M)
+...
+GROUP,0x1e00-0x1e3f = district_label, District, Province, State Name
+...
+POLYLINE
+GROUP,0x00 = ALL, street_1_land, Road
+GROUP,0x01 = MCTL, highway_land, Major HWY thick
+GROUP,0x02 = MCTL, street_4_land, Principal HWY-thick
+GROUP,0x03 = MCTL, street_2_land, Principal HWY-medium
+....
+POLYGONE
+GROUP,0x01 = town_poly, City (>200k)
+GROUP,0x02 = town_poly, City (<200k)
+GROUP,0x03 = town_poly, Village
+
+GROUP is
+0 - RGN1
+1 - RGN2-4
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include "item.h"
+#include "attr.h"
+#include "garmin.h"
+#include "gar2navit.h"
+
+static int add_def(struct gar2nav_conv *conv, int type, unsigned short minid,
+               unsigned short maxid, unsigned int group, char *ntype,
+               char *descr)
+{
+       enum item_type it;
+       struct gar2navit *g2n;
+       dlog(11, "group=%d type=%d routable=%u min=%04X max=%04X ntype=%s descr=%s\n",
+               group, type,  minid, maxid, ntype, descr);
+       it = item_from_name(ntype);
+       if (it==type_none) {
+               dlog(1, "Please define: %s\n", ntype);
+       } 
+       g2n = calloc(1, sizeof(*g2n));
+       if (!g2n)
+               return -1;
+       g2n->id = minid;
+       g2n->maxid = maxid;
+       g2n->ntype = it;
+       g2n->descr = strdup(descr);
+       g2n->group = group;
+       if (type == 1) {
+               g2n->next = conv->points;
+               conv->points = g2n;
+       } else if (type == 2) {
+               g2n->next = conv->polylines;
+               conv->polylines = g2n;
+       } else if (type == 3) {
+               g2n->next = conv->polygons;
+               conv->polygons = g2n;
+       }
+       return 0;
+}
+
+static int load_types_file(char *file, struct gar2nav_conv *conv)
+{
+       char buf[4096];
+       char descr[4096];
+       char ntype[4096];
+       FILE *fp;
+       unsigned int minid, maxid, group;
+       int rc;
+       int type = -1;
+
+       fp = fopen(file, "r");
+       if (!fp)
+               return -1;
+       while (fgets(buf, sizeof(buf), fp)) {
+               if (*buf == '#' || *buf == '\n')
+                       continue;
+               if (!strncasecmp(buf, "POINT", 5)) {
+                       type = 1;
+                       continue;
+               } else if (!strncasecmp(buf, "POI", 3)) {
+                       type = 1;
+                       continue;
+               } else if (!strncasecmp(buf, "POLYLINE", 8)) {
+                       type = 2;
+                       continue;
+               } else if (!strncasecmp(buf, "POLYGONE", 8)) {
+                       type = 3;
+                       continue;
+               }
+               // assume only lines are routable
+               rc = sscanf(buf, "%d, 0x%04X - 0x%04X = %[^\t , ] , %[^\n]",
+                       &group, &minid, &maxid, ntype, descr);
+               if (rc != 5) { 
+                       maxid = 0;
+                       rc = sscanf(buf, "%d,0x%04X = %[^\t, ], %[^\n]",
+                               &group, &minid, ntype, descr);
+                       if (rc != 4) {
+                               dlog(1, "Invalid line rc=%d:[%s]\n",rc, buf);
+                               dlog(1, "minid=%04X ntype=[%s] des=[%s]\n",
+                                       minid, ntype, descr);
+                               continue;
+                       }
+               }
+               add_def(conv, type, minid, maxid, group, ntype, descr);
+       }
+       fclose(fp);
+       return 1;
+}
+
+struct gar2nav_conv *g2n_conv_load(char *file)
+{
+       struct gar2nav_conv *c;
+       int rc;
+
+       c = calloc(1, sizeof(*c));
+       if (!c)
+               return c;
+       rc = load_types_file(file, c);
+       if (rc < 0) {
+               dlog(1, "Failed to load: [%s]\n", file);
+               free(c);
+               return NULL;
+       }
+       return c;
+}
+
+enum item_type g2n_get_type(struct gar2nav_conv *c, unsigned int type, unsigned short id)
+{
+       struct gar2navit *def = NULL;
+       int group;
+       group = (type >> G2N_KIND_SHIFT);
+       type &= ~G2N_KIND_MASK;
+       if (type == G2N_POINT)
+               def = c->points;
+       else if (type == G2N_POLYLINE)
+               def = c->polylines;
+       else if (type == G2N_POLYGONE)
+               def = c->polygons;
+       else {
+               dlog(1, "Unknown conversion type:%d\n", type);
+               return type_none;
+       }
+
+       if (!def) {
+               dlog(5, "No conversion data for %d\n", type);
+               return type_none;
+       }
+
+       while (def) {
+               if (def->group == group &&
+                       ((!def->maxid && def->id == id) || 
+                       (def->id <= id && id <= def->maxid)))
+                       return def->ntype;
+               def = def->next;
+       }
+       dlog(5, "Type[%d]:ID:[%04X] unknown\n", type, id);
+       return type == G2N_POINT ? type_point_unkn : type_street_unkn;
+}
+
+char *g2n_get_descr(struct gar2nav_conv *c, int type, unsigned short id)
+{
+       struct gar2navit *def = NULL;
+       if (type == G2N_POINT)
+               def = c->points;
+       else if (type == G2N_POLYLINE)
+               def = c->polylines;
+       else if (type == G2N_POLYGONE)
+               def = c->polygons;
+       else {
+               dlog(1, "Unknown conversion type:%d\n", type);
+               return NULL;
+       }
+       while (def) {
+               if ((!def->maxid && def->id == id) || 
+                               (def->id <= id && id <= def->maxid))
+                       return def->descr;
+               def = def->next;
+       }
+       dlog(5, "Type[%d]:ID:[%04X] unknown\n", type, id);
+       return NULL;
+}
+
+#if 0
+int main(int argc, char **argv)
+{
+       load_types_file(argv[1], NULL);
+       return 0;
+}
+#endif
+
+#include "g2nbuiltin.h"
diff --git a/navit/map/garmin/gar2navit.h b/navit/map/garmin/gar2navit.h
new file mode 100644 (file)
index 0000000..46b6885
--- /dev/null
@@ -0,0 +1,30 @@
+#define GROUP_RGN1     0
+#define GROUP_RGN2     1
+
+struct gar2navit {
+       unsigned short id;
+       unsigned short maxid;
+       enum item_type ntype;
+       unsigned group;
+       char *descr;
+       struct gar2navit *next;
+};
+
+#define G2N_POINT              1
+#define G2N_POLYLINE           2
+#define G2N_POLYGONE           3
+#define G2N_KIND_MASK          0xF0000000
+#define G2N_KIND_SHIFT         28
+#define G2N_RGN1               (GROUP_RGN1<<29)
+#define G2N_RGN2               (GROUP_RGN2<<29)
+
+struct gar2nav_conv {
+       struct gar2navit *points;
+       struct gar2navit *polylines;
+       struct gar2navit *polygons;
+};
+
+struct gar2nav_conv *g2n_conv_load(char *file);
+enum item_type g2n_get_type(struct gar2nav_conv *c, unsigned int type, unsigned short id);
+char *g2n_get_descr(struct gar2nav_conv *c, int type, unsigned short id);
+struct gar2nav_conv *g2n_default_conv(void);
diff --git a/navit/map/garmin/garmin.c b/navit/map/garmin/garmin.c
new file mode 100644 (file)
index 0000000..da0f580
--- /dev/null
@@ -0,0 +1,997 @@
+/*
+       Copyright (C) 2007  Alexander Atanasov      <aatanasov@gmail.com>
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; version 2 of the License.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+       MA  02110-1301  USA
+    
+       Garmin and MapSource are registered trademarks or trademarks
+       of Garmin Ltd. or one of its subsidiaries.
+
+*/
+
+#include <glib.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include "config.h"
+#include "plugin.h"
+#include "data.h"
+#include "projection.h"
+#include "item.h"
+#include "debug.h"
+#include "map.h"
+#include "maptype.h"
+#include "attr.h"
+#include "coord.h"
+#include "transform.h"
+#include <stdio.h>
+#include "attr.h"
+#include "coord.h"
+#include <libgarmin.h>
+#include "garmin.h"
+#include "gar2navit.h"
+
+
+static int map_id;
+
+struct map_priv {
+       int id;
+       char *filename;
+       struct gar2nav_conv *conv;
+       struct gar *g;
+};
+
+struct map_rect_priv {
+       int id;
+       struct coord_rect r;
+       char *label;            // FIXME: Register all strings for searches
+       int limit;
+       struct map_priv *mpriv;
+       struct gmap *gmap;
+       struct gobject *cobj;
+       struct gobject *objs;
+       struct item item;
+       unsigned int last_coord;
+       void *last_itterated;
+       struct coord last_c;
+       void *last_oattr;
+       unsigned int last_attr;
+       struct gar_search *search;
+};
+
+int garmin_debug = 10;
+
+void 
+logfn(char *file, int line, int level, char *fmt, ...)
+{
+       va_list ap;
+       char fileline[256];
+       int sz;
+       if (level > garmin_debug)
+               return;
+       va_start(ap, fmt);
+       sz = sprintf(fileline, "%s:%d:%d|", file, line, level);
+       debug_vprintf(0, "", strlen(""), fileline, sz,
+               1, fmt, ap);
+       va_end(ap);
+}
+// need a base map and a map
+struct gscale {
+       char *label;
+       float scale;
+       int bits;
+};
+
+static struct gscale mapscales[] = {
+       {"7000 km", 70000.0, 8}
+       ,{"5000 km", 50000.0, 8}
+       ,{"3000 km", 30000.0, 9}
+       ,{"2000 km", 20000.0, 9}
+       ,{"1500 km", 15000.0, 10}
+       ,{"1000 km", 10000.0, 10}
+       ,{"700 km", 7000.0, 11}
+       ,{"500 km", 5000.0, 11}
+       ,{"300 km", 3000.0, 13}
+       ,{"200 km", 2000.0, 13}
+       ,{"150 km", 1500.0, 13}
+       ,{"100 km", 1000.0, 14}
+       ,{"70 km", 700.0, 15}
+       ,{"50 km", 500.0, 16}
+       ,{"30 km", 300.0, 16}
+       ,{"20 km", 200.0, 17}
+       ,{"15 km", 150.0, 17}
+       ,{"10 km", 100.0, 18}
+       ,{"7 km", 70.0, 18}
+       ,{"5 km", 50.0, 19}
+       ,{"3 km", 30.0, 19}
+       ,{"2 km", 20.0, 20}
+       ,{"1.5 km", 15.0, 22}
+       ,{"1 km", 10.0, 24}
+       ,{"700 m", 7.0, 24}
+       ,{"500 m", 5.0, 24}
+       ,{"300 m", 3.0, 24}
+       ,{"200 m", 2.0, 24}
+       ,{"150 m", 1.5, 24}
+       ,{"100 m", 1.0, 24}
+       ,{"70 m", 0.7, 24}
+       ,{"50 m", 0.5, 24}
+       ,{"30 m", 0.3, 24}
+       ,{"20 m", 0.2, 24}
+       ,{"15 m", 0.1, 24}
+       ,{"10 m", 0.15, 24}
+};
+
+
+static int 
+garmin_object_label(struct gobject *o, struct attr *attr)
+{
+       struct map_rect_priv *mr = o->priv_data;
+       char *codepage;
+       char *label;
+       if (!mr) {
+               dlog(1, "Error object do not have priv_data!!\n");
+               return 0;
+       }
+       if (mr->label) {
+               free(mr->label);
+       }
+       label = gar_get_object_lbl(o);
+       if (label) {
+               codepage = gar_obj_codepage(o);
+               if (*codepage != 'a') {
+                       mr->label = g_convert(label, -1,"utf-8",codepage,NULL,NULL,NULL);
+                       free(label);
+               } else
+                       mr->label = label;
+       } else {
+               mr->label = NULL;
+               return 0;
+       }
+       if (mr->label) {
+               char *cp = mr->label;
+#warning FIXME Process label and give only the visible part
+               if (*mr->label == '@' || *mr->label == '^')
+                       cp++; 
+               /* FIXME: If zoomlevel is high convert ^ in the string to spaces */
+               attr->u.str = cp;
+               return 1;
+       }
+       return 0;
+}
+
+static int 
+garmin_object_debug(struct gobject *o, struct attr *attr)
+{
+       struct map_rect_priv *mr = o->priv_data;
+       if (!mr) {
+               dlog(1, "Error object do not have priv_data!!\n");
+               return 0;
+       }
+       if (mr->label)
+               free(mr->label);
+       mr->label = gar_object_debug_str(o);
+       if (mr->label) {
+               attr->u.str = mr->label;
+               return 1;
+       }
+       return 0;
+}
+
+
+static struct map_search_priv *
+gmap_search_new(struct map_priv *map, struct item *item, struct attr *search, int partial)
+{
+       struct map_rect_priv *mr=g_new0(struct map_rect_priv, 1);
+       struct gar_search *gs;
+       int rc;
+
+       dlog(1, "Called!\n");
+       mr->mpriv=map;
+       gs = g_new0(struct gar_search,1);
+       if (!gs) {
+               dlog(1, "Can not init search \n");
+               free(mr);
+               return NULL;
+       }
+       mr->search = gs;
+       switch (search->type) {
+               case attr_country_name:
+                       gs->type = GS_COUNTRY;
+                               break;
+               case attr_town_name:
+                       gs->type = GS_CITY;
+                               break;
+               case attr_town_postal:
+                       gs->type = GS_ZIP;
+                               break;
+               case attr_street_name:
+                       gs->type = GS_ROAD;
+                               break;
+#if someday
+               case attr_region_name:
+               case attr_intersection:
+               case attr_housenumber:
+#endif
+               default:
+                       dlog(1, "Don't know how to search for %d\n", search->type);
+                       goto out_err;
+       }
+       gs->match = partial ? GM_START : GM_EXACT;
+       gs->needle = strdup(search->u.str);
+       dlog(5, "Needle: %s\n", gs->needle);
+
+       mr->gmap = gar_find_subfiles(mr->mpriv->g, gs, GO_GET_SEARCH);
+       if (!mr->gmap) {
+               dlog(1, "Can not init search \n");
+               goto out_err;
+       }
+       rc = gar_get_objects(mr->gmap, 0, gs, &mr->objs, GO_GET_SEARCH);
+       if (rc < 0) {
+               dlog(1, "Error loading objects\n");
+               goto out_err;
+       }
+       mr->cobj = mr->objs;
+       dlog(4, "Loaded %d objects\n", rc);
+       return (struct map_search_priv *)mr;
+
+out_err:
+       free(gs);
+       free(mr);
+       return NULL;
+}
+
+/* Assumes that only one item will be itterated at time! */
+static void 
+coord_rewind(void *priv_data)
+{
+       struct gobject *g = priv_data;
+       struct map_rect_priv *mr = g->priv_data;
+       mr->last_coord = 0;
+};
+
+static void 
+attr_rewind(void *priv_data)
+{
+       struct gobject *g = priv_data;
+       struct map_rect_priv *mr = g->priv_data;
+       mr->last_attr = 0;
+};
+
+static int 
+point_coord_get(void *priv_data, struct coord *c, int count)
+{
+       struct gobject *g = priv_data;
+       struct map_rect_priv *mr = g->priv_data;
+       struct gcoord gc;
+       if (!count)
+               return 0;
+       if (g != mr->last_itterated) {
+               mr->last_itterated = g;
+               mr->last_coord = 0;
+       }
+
+       if (mr->last_coord > 0)
+               return 0;
+
+       gar_get_object_coord(mr->gmap, g, &gc);
+       c->x = gc.x;
+       c->y = gc.y;
+       mr->last_coord++;
+//     dlog(1,"point: x=%d y=%d\n", c->x, c->y);
+       // dlog(1, "point: x=%f y=%f\n", GARDEG(c->x), GARDEG(c->y));
+       return 1;
+}
+
+static int
+coord_is_node(void *priv_data)
+{
+       struct gobject *g = priv_data;
+       struct map_rect_priv *mr = g->priv_data;
+
+       return gar_is_object_dcoord_node(mr->gmap, g, mr->last_coord);
+}
+
+static int 
+poly_coord_get(void *priv_data, struct coord *c, int count)
+{
+       struct gobject *g = priv_data;
+       struct map_rect_priv *mr = g->priv_data;
+       int ndeltas = 0, total = 0;
+       struct gcoord dc;
+
+       if (!count)
+               return 0;
+
+       if (g != mr->last_itterated) {
+               mr->last_itterated = g;
+               mr->last_coord = 0;
+       }
+       ndeltas = gar_get_object_deltas(g);
+       if (mr->last_coord > ndeltas + 1)
+               return 0;
+       while (count --) {
+               if (mr->last_coord == 0) {
+                       gar_get_object_coord(mr->gmap, g, &dc);
+                       mr->last_c.x = dc.x;
+                       mr->last_c.y = dc.y;
+               } else {
+                       if (!gar_get_object_dcoord(mr->gmap, g, mr->last_coord - 1, &dc)) {
+                               mr->last_coord = ndeltas + 2;
+                               return total;
+                       }
+                       mr->last_c.x += dc.x;
+                       mr->last_c.y += dc.y;
+               }
+               c->x = mr->last_c.x;
+               c->y = mr->last_c.y;
+               ddlog(1, "poly: x=%f y=%f\n", GARDEG(c->x), GARDEG(c->y));
+//             dlog(1,"poly: x=%d y=%d\n", c->x, c->y);
+               c++;
+               total++;
+               mr->last_coord ++;
+       }
+       return total;
+}
+
+// for _any we must return one by one 
+static int 
+point_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{
+       struct gobject *g = priv_data;
+       struct map_rect_priv *mr = g->priv_data;
+       int rc;
+       switch (attr_type) {
+       case attr_any:
+                       if (g != mr->last_oattr) {
+                               mr->last_oattr = g;
+                               mr->last_attr = 0;
+                       }
+                       switch(mr->last_attr) {
+                               case 0:
+                                       mr->last_attr++;
+                                       attr->type = attr_label;
+                                       rc = garmin_object_label(g, attr);
+                                       if (rc)
+                                               return rc;
+                               case 1:
+                                       mr->last_attr++;
+                                       attr->type = attr_debug;
+                                       rc = garmin_object_debug(g, attr);
+                                       if (rc)
+                                               return rc;
+                               case 2:
+                                       mr->last_attr++;
+                                       if (g->type == GO_POLYLINE) {
+                                               attr->type = attr_street_name;
+                                               rc = garmin_object_label(g, attr);
+                                               if (rc)
+                                                       return rc;
+                                       }
+                               case 3:
+                                       mr->last_attr++;
+                                       attr->type = attr_flags;
+                                       attr->u.num = 0;
+                                       rc = gar_object_flags(g);
+                                       if (rc & F_ONEWAY)
+                                               attr->u.num |= AF_ONEWAY;
+                                       if (rc & F_SEGMENTED)
+                                               attr->u.num |= AF_SEGMENTED;
+                                       return 1;
+                               default:
+                                       return 0;
+                       }
+                       break;
+       case attr_label:
+               attr->type = attr_label;
+               return garmin_object_label(g, attr);
+       case attr_town_name:
+               attr->type = attr_town_name;
+               return garmin_object_label(g, attr);
+       case attr_street_name:
+               attr->type = attr_type;
+               return garmin_object_label(g, attr);
+       case attr_street_name_systematic:
+               /* TODO: Get secondary labels of roads */
+               return 0;
+       case attr_flags:
+               attr->type = attr_flags;
+               attr->u.num = 0;
+               rc = gar_object_flags(g);
+               if (rc & F_ONEWAY)
+                       attr->u.num |= AF_ONEWAY;
+               if (rc & F_SEGMENTED)
+                       attr->u.num |= AF_SEGMENTED;
+               return 1;
+       default:
+               dlog(1, "Dont know about attribute %d[%04X]=%s yet\n", attr_type,attr_type, attr_to_name(attr_type));
+       }
+
+       return 0;
+}
+
+static struct item_methods methods_garmin_point = {
+       coord_rewind,
+       point_coord_get,
+       attr_rewind,
+       point_attr_get,
+};
+
+static struct item_methods methods_garmin_poly = {
+       coord_rewind,
+       poly_coord_get,
+       attr_rewind,    // point_attr_rewind,
+       point_attr_get, // poly_attr_get,
+       coord_is_node,
+};
+
+static int
+search_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{
+       struct gobject *g = priv_data;
+       struct map_rect_priv *mr = g->priv_data;
+       int rc;
+       switch (attr_type) {
+       case attr_any:
+                       if (g != mr->last_oattr) {
+                               mr->last_oattr = g;
+                               mr->last_attr = 0;
+                       }
+                       switch(mr->last_attr) {
+                               case 0:
+                                       mr->last_attr++;
+                                       attr->type = attr_label;
+                                       rc = garmin_object_label(g, attr);
+                                       if (rc)
+                                               return rc;
+                               case 1:
+                                       mr->last_attr++;
+                                       attr->type = attr_debug;
+                                       rc = garmin_object_debug(g, attr);
+                                       if (rc)
+                                               return rc;
+                               case 2:
+                                       mr->last_attr++;
+                                       if (g->type == GO_POLYLINE) {
+                                               attr->type = attr_street_name;
+                                               rc = garmin_object_label(g, attr);
+                                               if (rc)
+                                                       return rc;
+                                       }
+                               case 3:
+                                       mr->last_attr++;
+                                       attr->type = attr_flags;
+                                       attr->u.num = 0;
+                                       rc = gar_object_flags(g);
+                                       if (rc & F_ONEWAY)
+                                               attr->u.num |= AF_ONEWAY;
+                                       if (rc & F_SEGMENTED)
+                                               attr->u.num |= AF_SEGMENTED;
+                                       return 1;
+                               default:
+                                       return 0;
+                       }
+                       break;
+       case attr_label:
+               attr->type = attr_label;
+               return garmin_object_label(g, attr);
+       case attr_town_name:
+               attr->type = attr_town_name;
+               if (mr->label)
+                       free(mr->label);
+               mr->label = gar_srch_get_city(g);
+               attr->u.str = mr->label;
+               if (attr->u.str)
+                       return 1;
+               return 0;
+       case attr_town_id:
+               rc = gar_srch_get_cityid(g);
+               if (rc) {
+                       attr->type = attr_town_id;
+                       attr->u.num = rc;
+                       return 1;
+               }
+               return 0;
+       case attr_town_postal:
+               attr->type = attr_town_postal;
+               attr->u.str = gar_srch_get_zip(g);
+               if (attr->u.str)
+                       return 1;
+               return 0;
+       case attr_street_name:
+               attr->type = attr_street_name;
+               if (mr->label)
+                       free(mr->label);
+               mr->label = gar_srch_get_roadname(g);
+               attr->u.str = mr->label;
+               if (attr->u.str)
+                       return 1;
+               return 0;
+       case attr_street_id:
+               attr->type = attr_street_id;
+               attr->u.num = gar_srch_get_roadid(g);
+               if (attr->u.num)
+                       return 1;
+               return 0;
+       case attr_flags:
+               attr->type = attr_flags;
+               attr->u.num = 0;
+               rc = gar_object_flags(g);
+               if (rc & F_ONEWAY)
+                       attr->u.num |= AF_ONEWAY;
+               if (rc & F_SEGMENTED)
+                       attr->u.num |= AF_SEGMENTED;
+               return 1;
+       case attr_country_id:
+               rc = gar_srch_get_countryid(g);
+               if (rc) {
+                       attr->type = attr_country_id;
+                       attr->u.num = rc;
+                       return 1;
+               }
+               return 0;
+       case attr_country_name:
+               attr->type = attr_country_name;
+               attr->u.str = gar_srch_get_country(g);
+               if (attr->u.str)
+                       return 1;
+               return 0;
+       case attr_district_id:
+               rc = gar_srch_get_regionid(g);
+               if (rc) {
+                       attr->type = attr_district_id;
+                       attr->u.num = rc;
+                       return 1;
+               }
+               return 0;
+       case attr_district_name:
+               attr->type = attr_district_name;
+               attr->u.str = gar_srch_get_region(g);
+               if (attr->u.str)
+                       return 1;
+               return 0;
+       case attr_town_streets_item:
+               return 0;
+       default:
+               dlog(1, "Dont know about attribute %d[%04X]=%s yet\n",
+                               attr_type,attr_type, attr_to_name(attr_type));
+       }
+
+       return 0;
+}
+
+static int
+search_coord_get(void *priv_data, struct coord *c, int count)
+{
+       struct gobject *g = priv_data;
+       struct map_rect_priv *mr = g->priv_data;
+       struct gcoord gc;
+       if (!count)
+               return 0;
+       if (g != mr->last_itterated) {
+               mr->last_itterated = g;
+               mr->last_coord = 0;
+       }
+
+       if (mr->last_coord > 0)
+               return 0;
+
+       if (gar_get_object_coord(mr->gmap, g, &gc)) {
+               c->x = gc.x;
+               c->y = gc.y;
+               mr->last_coord++;
+               return 1;
+       }
+       return 0;
+}
+
+static struct item_methods methods_garmin_search = {
+       coord_rewind,
+       search_coord_get,
+       attr_rewind,
+       search_attr_get,
+};
+
+
+static struct item *
+garmin_poi2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype)
+{
+       if (mr->mpriv->conv) {
+               int mask = gar_object_group(o) << G2N_KIND_SHIFT;
+               mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POINT|mask, otype);
+       }
+       mr->item.meth = &methods_garmin_point;
+       return &mr->item;
+}
+
+static struct item *
+garmin_pl2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype)
+{
+       if (mr->mpriv->conv) {
+               int mask = gar_object_group(o) << G2N_KIND_SHIFT;
+               mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POLYLINE|mask, otype);
+       }
+       mr->item.meth = &methods_garmin_poly;
+       return &mr->item;
+}
+
+static struct item *
+garmin_pg2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype)
+{
+       if (mr->mpriv->conv) {
+               int mask = gar_object_group(o) << G2N_KIND_SHIFT;
+               mr->item.type = g2n_get_type(mr->mpriv->conv, G2N_POLYGONE|mask, otype);
+       }
+       mr->item.meth = &methods_garmin_poly;
+       return &mr->item;
+}
+
+static struct item *
+garmin_srch2item(struct map_rect_priv *mr, struct gobject *o, unsigned short otype)
+{
+       mr->item.type = type_country_label;
+       mr->item.meth = &methods_garmin_search;
+       return &mr->item;
+}
+
+static struct item *
+garmin_obj2item(struct map_rect_priv *mr, struct gobject *o)
+{
+       unsigned short otype;
+       otype = gar_obj_type(o);
+       mr->item.type = type_none;
+       switch (o->type) {
+               case GO_POINT:
+                       return garmin_poi2item(mr, o, otype);
+               case GO_POLYLINE:
+                       return garmin_pl2item(mr, o, otype);
+               case GO_POLYGON:
+                       return garmin_pg2item(mr, o, otype);
+               case GO_ROAD:
+                       return garmin_pl2item(mr, o, otype);
+#if 0
+               case GO_SEARCH:
+                       return garmin_srch2item(mr, o, otype);
+#endif
+               default:
+                       dlog(1, "Unknown garmin object type:%d\n",
+                               o->type);
+       }
+       return NULL;
+}
+
+static struct item *
+gmap_rect_get_item_byid(struct map_rect_priv *mr, int id_hi, int id_lo)
+{
+       struct gobject *o;
+       o = mr->objs = gar_get_object_by_id(mr->mpriv->g, id_hi, id_lo);
+       if (!o) {
+               dlog(1, "Can not find object\n");
+               return NULL;
+       }
+
+       mr->item.id_hi = id_hi;
+       mr->item.id_lo = id_lo;
+       mr->item.priv_data = o;
+       mr->item.type = type_none;
+       o->priv_data = mr;
+       if (!garmin_obj2item(mr, o))
+               return NULL;
+       return &mr->item;
+}
+
+static struct item *
+gmap_rect_get_item(struct map_rect_priv *mr)
+{
+       struct gobject *o;
+       if (!mr->objs)
+               return NULL;
+       if (!mr->cobj)
+               return NULL;
+               // mr->cobj = mr->objs;
+       o = mr->cobj;
+//     dlog(1, "gi:o=%p\n", o);
+       mr->cobj = mr->cobj->next;
+       if (o) {
+               mr->item.id_hi = gar_object_mapid(o);
+               mr->item.id_lo = gar_object_index(o);
+               mr->item.priv_data = o;
+               mr->item.type = type_none;
+               o->priv_data = mr;
+               if (!garmin_obj2item(mr, o))
+                       return NULL;
+               return &mr->item;
+       }
+       return NULL;
+}
+
+#define max(a,b) ((a) > (b) ? (a) : (b))
+struct nl2gl_t {
+       int g;
+       int bits;
+       char *descr;
+};
+
+struct nl2gl_t nl2gl_1[] = { 
+       { /* 0 */  .g = 12, .descr = "0-120m", },
+       { /* 1 */  .g = 11, .descr = "0-120m", },
+       { /* 2 */  .g = 10, .descr = "0-120m", },
+       { /* 3 */  .g = 9, .descr = "0-120m", },
+       { /* 4 */  .g = 8, .descr = "0-120m", },
+       { /* 5 */  .g = 7, .descr = "0-120m", },
+       { /* 6 */  .g = 6, .descr = "0-120m", },
+       { /* 7 */  .g = 5, .descr = "0-120m", },
+       { /* 8 */  .g = 4, .descr = "0-120m", },
+       { /* 9 */  .g = 4, .descr = "0-120m", },
+       { /* 10 */ .g = 3, .descr = "0-120m", },
+       { /* 11 */ .g = 3, .descr = "0-120m", },
+       { /* 12 */ .g = 2, .descr = "0-120m", },
+       { /* 13 */ .g = 2, .descr = "0-120m", },
+       { /* 14 */ .g = 2, .descr = "0-120m", },
+       { /* 15 */ .g = 1, .descr = "0-120m", },
+       { /* 16 */ .g = 1, .descr = "0-120m", },
+       { /* 17 */ .g = 1, .descr = "0-120m", },
+       { /* 18 */ .g = 0, .descr = "0-120m", },
+};
+
+struct nl2gl_t nl2gl[] = { 
+       { /* 0 */  .g = 9, .descr = "0-120m", },
+       { /* 1 */  .g = 9, .descr = "0-120m", },
+       { /* 2 */  .g = 8, .descr = "0-120m", },
+       { /* 3 */  .g = 8, .descr = "0-120m", },
+       { /* 4 */  .g = 7, .descr = "0-120m", },
+       { /* 5 */  .g = 7, .descr = "0-120m", },
+       { /* 6 */  .g = 6, .descr = "0-120m", },
+       { /* 7 */  .g = 6, .descr = "0-120m", },
+       { /* 8 */  .g = 5, .descr = "0-120m", },
+       { /* 9 */  .g = 5, .descr = "0-120m", },
+       { /* 10 */ .g = 4, .descr = "0-120m", },
+       { /* 11 */ .g = 4, .descr = "0-120m", },
+       { /* 12 */ .g = 3, .descr = "0-120m", },
+       { /* 13 */ .g = 3, .descr = "0-120m", },
+       { /* 14 */ .g = 2, .descr = "0-120m", },
+       { /* 15 */ .g = 2, .descr = "0-120m", },
+       { /* 16 */ .g = 1, .descr = "0-120m", },
+       { /* 17 */ .g = 1, .descr = "0-120m", },
+       { /* 18 */ .g = 0, .descr = "0-120m", },
+};
+
+static int 
+get_level(struct map_selection *sel)
+{
+       return sel->order;
+}
+
+static int
+garmin_get_selection(struct map_rect_priv *map, struct map_selection *sel)
+{
+       struct gar_rect r;
+       struct gmap *gm;
+       struct gobject **glast = NULL;
+       int rc;
+       int sl, el;
+       int level = 0; // 18;   /* max level for maps, overview maps can have bigger
+                          /* levels we do not deal w/ them
+                       */
+       int flags = 0;
+       if (sel && sel->range.min == type_street_0 && sel->range.max == type_ferry) {
+               // Get all roads 
+               flags = GO_GET_ROUTABLE;
+       } else if (sel)
+               flags = GO_GET_SORTED;
+
+       if (sel) {
+               r.lulat = sel->u.c_rect.lu.y;
+               r.lulong = sel->u.c_rect.lu.x;
+               r.rllat = sel->u.c_rect.rl.y;
+               r.rllong = sel->u.c_rect.rl.x;
+               level = get_level(sel);
+//             level = nl2gl[level].g;
+               dlog(2, "Looking level=%d for %f %f %f %f\n",
+                       level, r.lulat, r.lulong, r.rllat, r.rllong);
+       }
+       gm = gar_find_subfiles(map->mpriv->g, sel ? &r : NULL, flags);
+       if (!gm) {
+               if (sel) {
+                       dlog(1, "Can not find map data for the area: %f %f %f %f\n",
+                               r.lulat, r.lulong, r.rllat, r.rllong);
+               } else {
+                       dlog(1, "Can not find map data\n");
+               }
+               return -1;
+       }
+#if 0
+       sl = (18-(gm->maxlevel - gm->minlevel))/2;
+       el = sl + (gm->maxlevel - gm->minlevel);
+       if (level < sl)
+               level = sl;
+       if (level > el)
+               level = el;
+       level = level - sl;
+       level = (gm->maxlevel - gm->minlevel) - level;
+       dlog(3, "sl=%d el=%d level=%d\n", sl, el, level);
+#endif
+       sl = (18-gm->zoomlevels)/2;
+       el = sl + gm->zoomlevels;
+       if (level < sl)
+               level = sl;
+       if (level > el)
+               level = el;
+       level = level - sl;
+       level = gm->basebits + level;
+       dlog(3, "sl=%d el=%d level=%d\n", sl, el, level);
+       map->gmap = gm;
+       glast = &map->objs;
+       while (*glast) {
+               if ((*glast)->next) {
+                       *glast = (*glast)->next;
+               } else
+                       break;
+       }
+       rc = gar_get_objects(gm, level, sel ? &r : NULL, glast, flags);
+       if (rc < 0) {
+               dlog(1, "Error loading objects\n");
+               return -1;
+       }
+       map->cobj = map->objs;
+       dlog(2, "Loaded %d objects\n", rc);
+       return rc;
+}
+// Can not return NULL, navit segfaults
+static struct map_rect_priv *
+gmap_rect_new(struct map_priv *map, struct map_selection *sel)
+{
+       struct map_selection *ms = sel;
+       struct map_rect_priv *mr;
+
+       if (!map)
+               return NULL;
+       mr = calloc(1, sizeof(*mr));
+       if (!mr)
+               return mr;
+       mr->mpriv = map;
+       if (!sel) {
+               return mr;
+       } else {
+               while (ms) {
+                       dlog(2, "order %d\n", ms->order); 
+                       if (garmin_get_selection(mr, ms) < 0) {
+                       //      free(mr);
+                       //      return NULL;
+                       }
+                       ms = ms->next;
+               }
+       }
+       return mr;
+}
+
+static void
+gmap_rect_destroy(struct map_rect_priv *mr)
+{
+       dlog(11,"destroy maprect\n");
+       if (mr->gmap)
+               gar_free_gmap(mr->gmap);
+       if (mr->objs)
+               gar_free_objects(mr->objs);
+       if (mr->label)
+               free(mr->label);
+       free(mr);
+}
+
+static void 
+gmap_search_destroy(struct map_search_priv *ms)
+{
+       gmap_rect_destroy((struct map_rect_priv *)ms);
+}
+
+static void
+gmap_destroy(struct map_priv *m)
+{
+       dlog(5, "garmin_map_destroy\n");
+       if (m->g)
+               gar_free(m->g);
+       if (m->filename)
+               free(m->filename);
+       free(m);
+}
+
+static struct map_methods map_methods = {
+       projection_garmin,
+       "utf-8",
+       gmap_destroy,
+       gmap_rect_new,
+       gmap_rect_destroy,
+       gmap_rect_get_item,
+       gmap_rect_get_item_byid,
+       gmap_search_new,
+       gmap_search_destroy,
+       gmap_rect_get_item,
+};
+
+static struct map_priv *
+gmap_new(struct map_methods *meth, struct attr **attrs)
+{
+       struct map_priv *m;
+       struct attr *data;
+       struct attr *debug;
+       struct attr *flags;
+       char buf[PATH_MAX];
+       struct stat st;
+       int dl = 1;
+       struct gar_config cfg;
+       int debugmask = 0;
+
+       data=attr_search(attrs, NULL, attr_data);
+       if (! data)
+               return NULL;
+       debug=attr_search(attrs, NULL, attr_debug);
+       if (debug) {
+               dl = atoi(debug->u.str);
+               if (!dl)
+                       dl = 1;
+       }
+       flags=attr_search(attrs, NULL, attr_flags);
+       if (flags) {
+               debugmask = flags->u.num;
+       }
+       m=g_new(struct map_priv, 1);
+       m->id=++map_id;
+       m->filename = strdup(data->u.str);
+       if (!m->filename) {
+               g_free(m);
+               return NULL;
+       }
+       memset(&cfg, 0, sizeof(struct gar_config));
+       cfg.opm = OPM_GPS;
+       cfg.debuglevel = dl;
+       cfg.debugmask = debugmask;
+       garmin_debug = dl;
+       m->g = gar_init_cfg(NULL, logfn, &cfg);
+       if (!m->g) {
+               g_free(m->filename);
+               g_free(m);
+               return NULL;
+       }
+       // we want the data now, later we can load only what's necessery
+       if (gar_img_load(m->g, m->filename, 1) < 0) {
+               gar_free(m->g);
+               g_free(m->filename);
+               g_free(m);
+               return NULL;
+       }
+       m->conv = NULL;
+       snprintf(buf, sizeof(buf), "%s.types", m->filename);
+       if (!stat(buf, &st)) {
+               dlog(1, "Loading custom types from %s\n", buf);
+               m->conv = g2n_conv_load(buf);
+       }
+       if (!m->conv) {
+               dlog(1, "Using builtin types\n");
+               m->conv = g2n_default_conv();
+       }
+       if (!m->conv) {
+               dlog(1, "Failed to load map types\n");
+       }
+       *meth=map_methods;
+       return m;
+}
+
+void
+plugin_init(void)
+{
+       plugin_register_map_type("garmin", gmap_new);
+}
diff --git a/navit/map/garmin/garmin.h b/navit/map/garmin/garmin.h
new file mode 100644 (file)
index 0000000..50935b0
--- /dev/null
@@ -0,0 +1,10 @@
+#define dlog(x,y ...) logfn(__FILE__,__LINE__,x, ##y)
+#ifdef HARDDEBUG
+#define ddlog(x,y ...) logfn(__FILE__,__LINE__,x, ##y)
+#else
+#define ddlog(x,y ...)
+#endif
+
+extern int garmin_debug;
+void logfn(char *file, int line, int level, char *fmt, ...);
+
diff --git a/navit/map/garmin/garmintypes.txt b/navit/map/garmin/garmintypes.txt
new file mode 100644 (file)
index 0000000..7df6831
--- /dev/null
@@ -0,0 +1,707 @@
+#
+#
+#
+POINT
+0, 0x0000 = label_unkn, Unknown label
+0, 0x0100 = town_label_1e5, Megapolis (10M +)
+0, 0x0200 = town_label_5e4, Megapolis (5-10M)
+0, 0x0300 = town_label_2e4, Big City (2-5M)
+0, 0x0400 = town_label_1e4, Big City (1-2M)
+0, 0x0500 = town_label_5e3, Big City (0.5-1M)
+0, 0x0600 = town_label_2e3, City (200-500k)
+0, 0x0700 = town_label_1e3, City (100-200k)
+0, 0x0800 = town_label_5e2, City (50-100k)
+0, 0x0900 = town_label_2e2, City (20-50k)
+0, 0x0a00 = town_label_1e2, City (10-20k)
+0, 0x0b00 = town_label_5e1, Small City (5-10k)
+0, 0x0c00 = town_label_2e1, Small City (2-5k)
+0, 0x0d00 = town_label_1e1, Village (1-2k)
+0, 0x0e00 = town_label_5e0, Village (500-1000)
+0, 0x0f00 = town_label_2e0, Village (200-500)
+0, 0x1000 = town_label_1e0, Village (100-200)
+0, 0x1100 = town_label_0e0, Village (0-100)
+
+0, 0x1200 = port_label, Port with services
+0, 0x1300 = label_unkn, Unknown label2
+0, 0x1400-0x14FF = country_label, Large Country Name
+0, 0x1500-0x15FF = country_label, Country Name
+0, 0x1c00 = poi_wreck, Unclassified Obstruction
+0, 0x1c01 = poi_wreck, Wreck
+0, 0x1c02 = poi_dangerous, submerged wreck, dangerous
+0, 0x1c03 = poi_nondangerous,  submerged wreck, non-dangerous
+0, 0x1c04 = poi_wreck, Wreck, cleared by wire drag
+0, 0x1c05 = poi_rock, Obstruction, visible at high water
+0, 0x1c06 = poi_rock, Obstruction, awash
+0, 0x1c07 = poi_rock, Obstruction, submerged
+0, 0x1c08 = poi_rock, Obstruction, cleared by wire drag
+0, 0x1c09 = poi_rock, Rock, awash
+0, 0x1c0a = poi_rock, Rock, submerged at low Water
+0, 0x1c0b = poi_sounding, Sounding
+0, 0x1d00 = poi_tide, Tide Prediction
+
+0, 0x1e00-0x1e3f = district_label, District, Province, State Name
+0, 0x1f00 = district_label_0e0, Region, District Name
+
+# Fixme if it has label how to change to highway_exit_with_label ??
+0, 0x2000-0x203F = highway_exit, Exit
+0, 0x2100-0x213F = highway_exit, Exit with Services
+0, 0x2200-0x223F = highway_exit, Exit with Restroom
+0, 0x2300-0x233F = highway_exit, Exit with Convinience Store
+0, 0x2400-0x243F = highway_exit, Exit with Weight Station
+0, 0x2500-0x253F = highway_exit, Exit with Toolbooth Booth
+0, 0x2600-0x263F = highway_exit, Exit with Information
+0, 0x2700-0x273F = highway_exit, Exit
+
+0, 0x2800-0x283F = district_label_1e0, Region Name
+
+0, 0x2900 = poi_public_utilities, Services
+
+0, 0x2A00 = poi_dining, Dining(Other)
+0, 0x2A01 = poi_dining, Dining(American)
+0, 0x2A02 = poi_dining, Dining(Asian)
+0, 0x2A03 = poi_dining, Dining(Barbecue)
+0, 0x2A04 = poi_dining, Dining(Chinese)
+0, 0x2A05 = poi_dining, Dining(Deli/Bakery)
+0, 0x2A06 = poi_dining, Dining(International)
+0, 0x2A07 = poi_fastfood, Fast Food
+0, 0x2A08 = poi_dining, Dining(Italian)
+0, 0x2A09 = poi_dining, Dining(Mexican)
+0, 0x2A0A = poi_dining, Dining(Pizza)
+0, 0x2A0B = poi_dining, Dining(Sea Food)
+0, 0x2A0C = poi_dining, Dining(Steak/Grill)
+0, 0x2A0D = poi_dining, Dining(Bagel/Donut)
+0, 0x2A0E = poi_dining, Dining(Cafe/Diner)
+0, 0x2A0F = poi_dining, Dining(French)
+0, 0x2A10 = poi_dining, Dining(German)
+0, 0x2A11 = poi_dining, Dining(British Isles)
+0, 0x2A12 = poi_dining, Dining(Special Foods)
+
+0, 0x2B00 = poi_hotel, Hotel(Other)
+0, 0x2B01 = poi_hotel, Hotel/Motel
+0, 0x2B02 = poi_hotel, Bed & Breakfast inn
+0, 0x2B03 = poi_camp_rv, Camping/RV-Park
+0, 0x2B04 = poi_resort, Resort
+
+0, 0x2C00 = poi_attraction, Amusement Park
+0, 0x2C01 = poi_attraction, Amusement Park
+0, 0x2C02 = poi_museum_history, Museum/History
+0, 0x2C03 = poi_library, Libraries
+0, 0x2C04 = poi_landmark, Land Mark
+0, 0x2C05 = poi_school, School
+0, 0x2C06 = poi_park, Park
+0, 0x2C07 = poi_zoo, Zoo
+0, 0x2C08 = poi_stadium, Sportpark, Stadium,(point)
+0, 0x2C09 = poi_fair, Fair, Conference(point)
+0, 0x2C0A = poi_wine, Wine restaurant(point)
+0, 0x2C0B = poi_worship, Place of Worship
+0, 0x2C0C = poi_hotspring, Hot Spring
+
+0, 0x2D00 = poi_theater, Theater
+0, 0x2D01 = poi_theater, Theater
+0, 0x2D02 = poi_bar, Bar
+0, 0x2D03 = poi_cinema, Cinema
+0, 0x2D04 = poi_casino, Casino
+0, 0x2D05 = poi_golf, Golf
+0, 0x2D06 = poi_skiing, Skiing Center
+0, 0x2D07 = poi_bowling, Bowling
+0, 0x2D08 = poi_icesport, Ice/Sporting
+0, 0x2D09 = poi_swimming, Swimming
+0, 0x2D0A = poi_sport, Sports(point)
+0, 0x2D0B = poi_sailing, Sailing Airport
+
+0, 0x2E00 = poi_shopping, Shoping general
+0, 0x2E01 = poi_shop_department, Department Store
+0, 0x2E02 = poi_shop_grocery, Grocery
+0, 0x2E03 = poi_shop_merchandise, General Merchandiser
+0, 0x2E04 = poi_mall, Shopping Center
+0, 0x2E05 = poi_pharmacy, Pharmacy
+0, 0x2E06 = poi_shopping, Convenience
+0, 0x2E07 = poi_shop_apparel, Apparel
+0, 0x2E08 = poi_shop_handg, House and Garden
+0, 0x2E09 = poi_shop_furnish, Home Furnishing
+0, 0x2E0a = poi_shop_retail, Special Retail
+0, 0x2E0b = poi_shop_computer, Computer/Software
+0, 0x2E0c = poi_shop_computer, Mobile Communications
+
+0, 0x2F00 = poi_service, generic service
+0, 0x2F01 = poi_fuel, Fuel/Gas
+0, 0x2F02 = poi_car_rent, Car Rental
+0, 0x2F03 = poi_autoservice, Car Repair
+0, 0x2F04 = poi_airport, Airport
+0, 0x2F05 = poi_post, Post Office
+0, 0x2F06 = poi_bank, Bank
+0, 0x2F07 = poi_car_dealer_parts, Car Dealer(point)
+0, 0x2F08 = poi_bus_station, Bus Station
+0, 0x2F09 = poi_marina, Marina
+0, 0x2F0A = poi_wrecker, Wrecker Service
+0, 0x2F0B = poi_car_parking, Parking
+0, 0x2F0C = poi_rest_room, Restroom
+0, 0x2F0D = poi_auto_club, Automobile Club
+0, 0x2F0E = poi_car_wash, Car Wash
+0, 0x2F0F = poi_garmin, Garmin Dealer
+0, 0x2F10 = poi_personal_service, Personal Service
+0, 0x2F11 = poi_bussines_service, Business Service
+0, 0x2F12 = poi_communication, Communication
+0, 0x2F13 = poi_repair_service, Repair Service
+0, 0x2F14 = poi_social_service, Social Service
+0, 0x2F15 = poi_public_utilities, Utility
+0, 0x2F16 = poi_truck_stop, Truck Stop
+0, 0x2F17 = poi_bus_stop, Bus Stop
+
+0, 0x3000 = poi_emergency, generic emergency/government
+0, 0x3001 = poi_police, Police Station
+0, 0x3002 = poi_hospital, Hospital
+0, 0x3003 = poi_public_office, Public Office
+0, 0x3004 = poi_justice, Justice
+0, 0x3005 = poi_concert, Concert hall(point)
+0, 0x3006 = poi_border_station, Border Station(point)
+0, 0x3007 = poi_goverment_building, Goverment Building
+0, 0x3008 = poi_firebrigade, FireFighters Station
+
+0, 0x4000-0x403F = poi_golf, Golf
+0, 0x4100-0x413F = poi_fish, Fish
+0, 0x4200-0x423F = poi_wreck, Wreck
+0, 0x4300-0x433F = poi_marina, Marina
+0, 0x4400-0x443F = poi_fuel, Gas
+0, 0x4500-0x453F = poi_restaurant, Restaurant
+0, 0x4600-0x463F = poi_bar, Bar
+0, 0x4700-0x473F = poi_boat_ramp, Boat Ramp
+0, 0x4800-0x483F = poi_camping, Camping
+0, 0x4900-0x493F = poi_park, Park
+0, 0x4A00-0x4A3F = poi_picnic, Picnic Area
+0, 0x4B00-0x4B3F = poi_hospital, Hospital
+0, 0x4C00-0x4C3F = poi_information, Information
+0, 0x4D00-0x4D3F = poi_car_parking, Parking
+0, 0x4E00-0x4E3F = poi_restroom, Restroom
+0, 0x4F00-0x4F3F = poi_shower, Shower
+0, 0x5000-0x503F = poi_drinking_water, Drinking Water
+0, 0x5100-0x513F = poi_telephone, Telephone
+0, 0x5200-0x523F = poi_scenic_area, Scenic Area
+0, 0x5300-0x533F = poi_skiing, Skiing
+0, 0x5400-0x543F = poi_swimming, Swimming
+0, 0x5500-0x553F = poi_dam, Dam
+
+0, 0x5600-0x563F = poi_forbiden_area, Forbiden Area
+0, 0x5700-0x573F = poi_danger_area, Danger Area
+0, 0x5800-0x583F = poi_restricted_area, Restricted Area
+
+0, 0x5900 = poi_airport, Generic Airport
+0, 0x5901 = poi_airport, Large Airport
+0, 0x5902 = poi_airport, Medium Airport
+0, 0x5903 = poi_airport, Small Airport
+0, 0x5904 = poi_heliport, Heliport
+0, 0x5905-0x593F = poi_airport, Airport
+
+0, 0x5a00 = poi_mark, Kilometer Pole
+0, 0x5b00 = poi_mark, Kolokol
+0, 0x5c00 = poi_diving, Diving Place
+
+0, 0x5D00-0x5D3F = poi_daymark, Daymark,Green Square
+0, 0x5E00-0x5E3F = poi_daymark, Daymark,Red Triangle
+
+0, 0x6000 = poi_loudspeaker, LoudSpeaker
+0, 0x6100 = poi_building, House
+
+0, 0x6200 = poi_height, Height with point in feet one decimal place
+0, 0x6300 = poi_height, Height without point in feet no decimal place
+0, 0x6400 = poi_manmade_feature, Manmade Feature
+0, 0x6401 = poi_bridge, Bridge
+0, 0x6402 = poi_building, Building
+0, 0x6403 = poi_cemetery, Cemetery
+0, 0x6404 = poi_church, Church
+0, 0x6405 = poi_civil, Civil
+0, 0x6406 = poi_crossing, Crossing
+0, 0x6407 = poi_dam, Dam
+0, 0x6408 = poi_hospital, Hospital
+0, 0x6409 = poi_levee, Levee
+0, 0x640A = poi_locale, Locale
+0, 0x640B = poi_military, Military
+0, 0x640C = poi_mine, Mine
+0, 0x640D = poi_oil_field, Oil Field
+0, 0x640E = poi_park, Park
+0, 0x640F = poi_post, Post
+0, 0x6410 = poi_school, School
+0, 0x6411 = poi_tower, Tower
+0, 0x6412 = poi_trail, Trail
+0, 0x6413 = poi_tunnel, Tunnel
+0, 0x6414 = poi_drinking_water, Drink water
+0, 0x6415 = town_ghost, Ghost Town
+0, 0x6416 = poi_subdivision, Subdivision
+
+0, 0x6500 = poi_water_feature, Water Feature
+0, 0x6501 = poi_water_feature, Arroyo
+0, 0x6502 = poi_water_feature, Sand Bar
+0, 0x6503 = poi_bay, Bay
+0, 0x6504 = poi_bend, Bend
+0, 0x6505 = poi_water_feature, Canal
+0, 0x6506 = poi_water_feature, Channel
+0, 0x6507 = poi_cove, Cove
+0, 0x6508 = poi_water_feature, Falls
+0, 0x6509 = poi_water_feature, Geyser
+0, 0x650A = poi_water_feature, Glacier
+0, 0x650B = poi_marine, Harbour
+0, 0x650C = poi_island, Island
+0, 0x650D = poi_water_feature, Lake
+0, 0x650E = poi_water_feature, Rapids
+0, 0x650F = poi_water_feature, Reservoir
+0, 0x6510 = poi_water_feature, Sea
+0, 0x6511 = poi_water_feature, Spring
+0, 0x6512 = poi_water_feature, Stream
+0, 0x6513 = poi_water_feature, Swamp
+
+0, 0x6600 = poi_land_feature, Land Feature
+0, 0x6601 = poi_land_feature, Arch
+0, 0x6602 = poi_land_feature, Area
+0, 0x6603 = poi_land_feature, Basin
+0, 0x6604 = poi_land_feature, Beach
+0, 0x6605 = poi_land_feature, Bench
+0, 0x6606 = poi_land_feature, Cape
+0, 0x6607 = poi_land_feature, Cliff
+0, 0x6608 = poi_land_feature, Crater
+0, 0x6609 = poi_land_feature, Flat
+0, 0x660A = poi_land_feature, Forest
+0, 0x660B = poi_land_feature, Gap
+0, 0x660C = poi_land_feature, Gut
+0, 0x660D = poi_land_feature, Isthmus
+0, 0x660E = poi_land_feature, Lava
+0, 0x660F = poi_land_feature, Pillar
+0, 0x6610 = poi_land_feature, Plain
+0, 0x6611 = poi_land_feature, Range
+0, 0x6612 = poi_land_feature, Reserve
+0, 0x6613 = poi_land_feature, Ridge
+0, 0x6614 = poi_land_feature, Rock
+0, 0x6615 = poi_land_feature, Slope
+0, 0x6616 = poi_land_feature, Summit
+0, 0x6617 = poi_land_feature, Valley
+0, 0x6618 = poi_land_feature, Woods
+
+# This are dublicated to 0x1700, 0x1800, 0x1900, 0x1A00, 0x1B00
+# fix them if you need them
+0, 0x1600 = poi_marine_type, Beakon
+0, 0x1601 = poi_marine_type, Fog Horn
+0, 0x1602 = poi_marine_type, Radio Beacon
+0, 0x1603 = poi_marine_type, Racon
+0, 0x1604 = poi_marine_type, Day Beacon, red triangle
+0, 0x1605 = poi_marine_type, Day Beacon, green square
+0, 0x1606 = poi_marine_type, Day Beacon, white diamond
+0, 0x1607 = poi_marine_type, unlit Navaid, white
+0, 0x1608 = poi_marine_type, unlit Navaid, red
+0, 0x1609 = poi_marine_type, unlit Navaid, green
+0, 0x160a = poi_marine_type, unlit Navaid, black
+0, 0x160b = poi_marine_type, unlit Navaid, yellow or amber
+0, 0x160c = poi_marine_type, unlit Navaid, orange
+0, 0x160d = poi_marine_type, unlit Navaid, multi colored
+0, 0x160e = poi_marine_type, Navaid, unknown
+0, 0x160f = poi_marine_type, lighted Navaid, white
+0, 0x1610 = poi_marine_type, lighted Navaid, red
+0, 0x1611 = poi_marine_type, lighted Navaid, green
+0, 0x1612 = poi_marine_type, lighted Navaid, yellow or amber
+0, 0x1613 = poi_marine_type, lighted Navaid, orange
+0, 0x1614 = poi_marine_type, lighted Navaid, violet
+0, 0x1615 = poi_marine_type, lighted Navaid, blue
+0, 0x1616 = poi_marine_type, lighted Navaid, multi colored
+# RGN2-4 types 
+# Marine types start
+1, 0x0100 = point_unkn, Light
+1, 0x0102 = point_unkn, Light with north topmark
+1, 0x0103 = point_unkn, Light with south topmark
+1, 0x0104 = point_unkn, Light with east topmark
+1, 0x0105 = point_unkn, Light with west topmark
+1, 0x0106 = point_unkn, Isolated danger light
+1, 0x0107 = point_unkn, Port hand light
+1, 0x0108 = point_unkn, Starboard hand light
+1, 0x0109 = point_unkn, Special purpose light
+1, 0x010a = point_unkn, Safe water light
+1, 0x0200 = point_unkn, Buoy
+1, 0x0201 = point_unkn, Buoy
+1, 0x0202 = point_unkn, Buoy with north topmark
+1, 0x0203 = point_unkn, Buoy with south topmark
+1, 0x0204 = point_unkn, Buoy with east topmark
+1, 0x0205 = point_unkn, Buoy with west topmark
+1, 0x0206 = point_unkn, Beacon
+1, 0x0207 = point_unkn, Spar buoy
+1, 0x0208 = point_unkn, Isolated danger buoy
+1, 0x0209 = point_unkn, Port hand buoy
+1, 0x020a = point_unkn, Starboard hand buoy
+1, 0x020b = point_unkn, Special purpose buoy
+1, 0x020c = point_unkn, Safe water buoy
+1, 0x020d = point_unkn, Platform buoy
+1, 0x020e = point_unkn, Beacon with north topmark
+1, 0x020f = point_unkn, Beacon with south north topmark
+1, 0x0210 = point_unkn, Beacon with east topmark
+1, 0x0211 = point_unkn, Beacon with west topmark
+1, 0x0212 = point_unkn, Isolated danger beacon
+1, 0x0213 = point_unkn, Port hand beacon
+1, 0x0214 = point_unkn, Starboard hand beacon
+1, 0x0215 = point_unkn, Special purpose beacon
+1, 0x0216 = point_unkn, Mooring buoy
+1, 0x0217 = point_unkn, Fixed point
+1, 0x0218 = point_unkn, Pole
+1, 0x0300 = point_unkn, Depth point
+1, 0x0301 = point_unkn, Depth point invisible
+1, 0x0302 = point_unkn, Depth point underscore
+1, 0x0303 = point_unkn, Spot height
+1, 0x0304 = point_unkn, Building
+1, 0x0305 = point_unkn, Chimney
+1, 0x0306 = point_unkn, Church
+1, 0x0307 = point_unkn, Tanks
+1, 0x0308 = point_unkn, Tower
+1, 0x0309 = point_unkn, Rock
+1, 0x030a = point_unkn, Triangulation point
+1, 0x030b = point_unkn, Radio mast
+1, 0x0400 = point_unkn, Isolated danger
+1, 0x0401 = point_unkn, Obstruction
+1, 0x0402 = point_unkn, Wreck
+1, 0x0403 = point_unkn, Exposed wreck
+1, 0x0404 = point_unkn, Well
+1, 0x0405 = point_unkn, Foul
+1, 0x0406 = point_unkn, Explosive
+1, 0x0407 = point_unkn, Fish haven
+1, 0x0408 = point_unkn, Obstruction that covers
+1, 0x0409 = point_unkn, Marine farm
+1, 0x040a = point_unkn, Dangerous rock
+1, 0x040b = point_unkn, No bottom found
+1, 0x040c = point_unkn, Exposed rock
+1, 0x040d = point_unkn, Dangerous rock
+1, 0x040e = point_unkn, Underwater rock (non-dangerous rock)
+1, 0x040f = point_unkn, Shoal
+1, 0x0500 = point_unkn, Label point
+1, 0x0600 = point_unkn, Centered label
+1, 0x0700 = point_unkn, Miscellaneous point
+1, 0x0701 = point_unkn, Recommended anchorage
+1, 0x0702 = point_unkn, Pilot boarding place
+1, 0x0703 = point_unkn, Yacht harbour
+1, 0x0704 = point_unkn, Pile
+1, 0x0705 = point_unkn, Anchoring prohibited
+1, 0x0706 = point_unkn, Fishing prohibited
+1, 0x0707 = point_unkn, Precautionary area
+1, 0x0708 = point_unkn, Radio report point
+1, 0x0709 = point_unkn, Anchorage berths
+1, 0x070a = point_unkn, Rescue station
+1, 0x070b = point_unkn, Fishing harbour
+1, 0x070c = point_unkn, Airport
+1, 0x0800 = point_unkn, Information
+1, 0x0901 = point_unkn, Bottom conditions
+1, 0x0902 = point_unkn, Fishing information
+1, 0x0903 = point_unkn, Facility
+# NT types start
+1, 0x0b00 = poi_dining, Dining(Other)
+1, 0x0b04 = poi_dining, Dining(Chinese)
+1, 0x0b05 = poi_dining, Dining (Deli/Bakery)
+1, 0x0b06 = poi_dining, Dining (International)
+1, 0x0b07 = poi_fastfood, Fast Food
+1, 0x0b09 = poi_dining, Dining(Mexican)
+1, 0x0b0a = poi_dining, Dining(Pizza)
+1, 0x0b0b = poi_dining, Dining (Sea Food)
+1, 0x0b0c = poi_dining, Dining (Steak/Grill)
+1, 0x0b0d = poi_dining, Dining(Bagel/Donut)
+1, 0x0b0e = poi_dining, Dining(Cafe/Diner)
+1, 0x0c01 = poi_hotel, Hotel/Motel
+1, 0x0c02 = poi_hotel, Bed & Breakfast inn
+1, 0x0c03 = poi_camp_rv, Camping/RV-Park
+1, 0x0c04 = poi_resort, Resort
+1, 0x0d01 = poi_attraction, Amusement Park
+1, 0x0d02 = poi_museum_history, Museum/History
+1, 0x0d03 = poi_fair, Fair, Conference(point)
+1, 0x0d04 = poi_scenic_area, Scenic Area
+1, 0x0d05 = poi_school, School
+1, 0x0d06 = poi_park, Park
+1, 0x0d07 = poi_zoo, Zoo
+1, 0x0d08 = poi_stadium, Sportpark, Stadium
+1, 0x0d0a = poi_bar, Wine Bar
+1, 0x0d14 = poi_hospital, Hospital 
+1, 0x0e01 = poi_theater, Theater
+1, 0x0e02 = poi_bar, Bar
+1, 0x0e03 = poi_cinema, Cinema
+1, 0x0e04 = poi_casino, Casino
+1, 0x0e05 = poi_golf, Golf
+1, 0x0e06 = poi_skiing, Skiing Center/Lift
+1, 0x0e07 = poi_bar, Night Bar/Piano
+1, 0x0e08 = poi_icesport, Ice/Sporting
+1, 0x0e09 = poi_swimming, Swimming
+1, 0x0e0a = poi_sport, Sports(point)
+1, 0x0f00 = poi_hotel, Hotel(Other)
+1, 0x0f01 = poi_shop_department, Department Store
+1, 0x0f02 = poi_shop_grocery, Grocery
+1, 0x0f03 = poi_hotel, Hotel/Motel
+1, 0x0f04 = poi_resort, Resort
+1, 0x0f05 = poi_pharmacy, Pharmacy
+1, 0x1001 = poi_fuel, Fuel/Gas
+1, 0x1002 = poly_car_parking, Parking Lot
+1, 0x1003 = poi_autoservice, Car Repair
+1, 0x1004 = poi_airport, Airport
+1, 0x1005 = poi_post, Post Office
+1, 0x1006 = poi_bank, Bank
+1, 0x1008 = poi_bus_station, Bus station
+1, 0x1009 = poi_marina, SeaPort
+1, 0x100a = poi_wrecker, Wrecker Service
+1, 0x100b = poi_car_parking, Parking
+1, 0x100d = poi_car_dealer_parts, Car Dealer(point)
+1, 0x100e = poi_car_wash, Car Wash
+1, 0x1011 = poi_bussines_service, Business Service
+1, 0x1012 = poi_communication, Communication
+1, 0x1013 = poi_repair_service, Repair Service 
+1, 0x1014 = poi_social_service, Social Service
+1, 0x1015 = poi_public_utilities, Utility
+1, 0x1101 = poi_police, Police Station
+1, 0x1102 = poi_hospital, Hospital
+1, 0x1104 = poi_justice, Justice
+1, 0x1107 = poi_public_office, Public Office
+1, 0x1400 = town_label_1e5, Megapolis (10M +)
+1, 0x1401 = town_label_5e4, Megapolis (5-10M)
+1, 0x1402 = town_label_2e4, Big City (2-5M)
+1, 0x1403 = town_label_5e3, Big City (0.5-1M)
+1, 0x1404 = town_label_2e3, City (200-500k)
+1, 0x1405 = town_label_1e3, City (100-200k)
+1, 0x1406 = town_label_5e2, City (50-100k)
+1, 0x1405 = town_label_2e2, City (20-50k)
+1, 0x1406 = town_label_1e2, City (10-20k)
+1, 0x1407 = town_label_5e1, Small City (5-10k)
+1, 0x1408 = town_label_2e1, Small City (2-5k)
+1, 0x1409 = town_label_1e1, Village (1-2k)
+1, 0x140a = town_label_5e0, Village (500-1000)
+1, 0x140b = town_label_2e0, Village (200-500)
+1, 0x140c = town_label_1e0, Village (100-200)
+1, 0x140d = town_label_0e0, Village (0-100)
+1, 0x1500 = poi_personal_service, Personal Service
+1, 0x1501 = poi_bussines_service, Bussines Service
+
+
+POLYLINE
+0, 0x00 = street_1_land, Road
+0, 0x01 = highway_land, Major HWY thick
+0, 0x02 = street_4_land, Principal HWY-thick
+0, 0x03 = street_2_land, Principal HWY-medium
+0, 0x04 = street_3_city, Arterial Road-medium
+0, 0x05 = street_4_city, Arterial Road-thick
+0, 0x06 = street_2_city, Road-thin
+0, 0x07 = street_1_city, Alley-thick
+0, 0x08 = ramp, Ramp
+0, 0x09 = ramp, Ramp highspeed
+0, 0x0a = street_0, Unpaved Road-thin
+0, 0x0b = ramp, Major HWY Connector-thick
+0, 0x0c = roundabout, Roundabout
+0, 0x0d = street_unkn, Custom defined street 1
+0, 0x0e = street_unkn, Custom defined street 2
+0, 0x0f = street_unkn, Custom defined street 3
+0, 0x10 = street_unkn, Custom defined street 4
+0, 0x11 = street_unkn, Custom defined street 5
+0, 0x12 = street_unkn, Custom defined street 6
+0, 0x13 = street_unkn, Custom defined street 7
+0, 0x14 = rail, Railroad
+0, 0x15 = water_line, Shoreline
+0, 0x16 = street_nopass, Trail
+0, 0x18 = water_line, Stream-thin
+0, 0x19 = time_zone, Time-Zone
+0, 0x1a = ferry, Ferry
+0, 0x1b = ferry, Ferry
+0, 0x1c = border_country, Political Boundary
+0, 0x1d = border_country, County Boundary
+0, 0x1e = border_country, Intl. Boundary
+0, 0x1f = water_line, River
+0, 0x20 = height_line_1, Land Contour (thin) Height in feet
+0, 0x21 = height_line_2, Land Contour (medium) Height in feet
+0, 0x22 = height_line_3, Land Contour (thick) Height in feet
+0, 0x23 = depth_line_1, Depth Contour (thin) Depth in feet
+0, 0x24 = depth_line_2, Depth Contour (medium) Depth in feet
+0, 0x25 = depth_line_3, Depth Contour (thick) Depth in feet
+0, 0x26 = water_line, Intermittent River
+0, 0x27 = street_nopass, Airport Runway
+0, 0x28 = pipeline, Pipeline
+0, 0x29 = powerline, Powerline
+0, 0x2a = marine_boundary, Marine Boundary (no line)
+0, 0x2b = marine_hazard, Marine Hazard (no line)
+# RGN2-4
+# Marine
+1, 0x0100 = street_unkn, Miscellaneous line
+1, 0x0101 = street_unkn, Line
+1, 0x0102 = street_unkn, Cartographic line
+1, 0x0103 = street_unkn, Road
+1, 0x0104 = street_unkn, Clearing line
+1, 0x0105 = street_unkn, Contour line
+1, 0x0106 = street_unkn, Overhead cable
+1, 0x0107 = street_unkn, Bridge
+1, 0x0108 = street_unkn, Recommended route
+1, 0x0109 = street_unkn, Chart border
+1, 0x0300 = street_unkn, Depth contour
+1, 0x0301 = street_unkn, Depth contour value
+1, 0x0307 = street_unkn, Intertidal zone border
+1, 0x0400 = street_unkn, Obstruction line
+1, 0x0401 = street_unkn, Submarine cable
+1, 0x0402 = street_unkn, Submarine pipeline
+1, 0x0403 = street_unkn, Pile barrier
+1, 0x0404 = street_unkn, Fishing stakes
+1, 0x0405 = street_unkn, Supply pipeline area
+1, 0x0406 = street_unkn, Submarine cable area
+1, 0x0407 = street_unkn, Dumping ground
+1, 0x0408 = street_unkn, Explosive dumping ground
+1, 0x0409 = street_unkn, Danger line
+1, 0x040a = street_unkn, Overhead cable
+1, 0x040b = street_unkn, Submerged construction
+1, 0x040c = street_unkn, Pier/jetty
+1, 0x0500 = street_unkn, Restriction
+1, 0x0501 = street_unkn, Anchoring prohibited
+1, 0x0502 = street_unkn, Fishing prohibited
+1, 0x0503 = street_unkn, Prohibited area
+1, 0x0504 = street_unkn, Military practice area
+1, 0x0505 = street_unkn, Anchoring and fishing prohibited
+1, 0x0506 = street_unkn, Limit of nature reservation
+1, 0x0507 = street_unkn, Restricted area
+1, 0x0508 = street_unkn, Minefield
+1, 0x0600 = street_unkn, Miscellaneous line
+1, 0x0601 = street_unkn, Cartographic line
+1, 0x0602 = street_unkn, Traffic separation line
+1, 0x0603 = street_unkn, International maritime boundary
+1, 0x0604 = street_unkn, Straight territorial sea baseline
+1, 0x0605 = street_unkn, Seaward limit of territorial sea
+1, 0x0606 = street_unkn, Anchorage area
+1, 0x0607 = street_unkn, Quarantine anchorage area
+1, 0x0608 = street_unkn, Fishery zone
+1, 0x0609 = street_unkn, Swept area
+1, 0x060a = street_unkn, Traffic separation zone
+1, 0x060b = street_unkn, Limit of exclusive economic zone
+1, 0x060c = street_unkn, Established direction of traffic flow
+1, 0x060d = street_unkn, Recommended direction of traffic flow
+1, 0x060e = street_unkn, Harbour limit
+1, 0x060f = street_unkn, Inadequately surveyed area
+1, 0x0610 = street_unkn, Inshore traffic zone
+1, 0x0611 = street_unkn, Limit of traffic lane
+1, 0x0701 = street_unkn, River channel
+1, 0x0702 = street_unkn, Submerged object
+1, 0x0703 = street_unkn, Submerged object
+1, 0x0704 = street_unkn, Submerged object
+1, 0x0705 = street_unkn, Submerged object
+1, 0x0706 = street_unkn, Chart boundary
+# NT types
+1, 0x0a00 = water_line, River
+1, 0x0a01 = water_line, Small River
+1, 0x0a19 = street_unkn, Dry Creek
+1, 0x0b04 = border_country, Country Border
+
+
+POLYGONE
+0, 0x01 = poly_town, City (>200k)
+0, 0x02 = poly_town, City (<200k)
+0, 0x03 = poly_town, Village
+0, 0x04 = poly_military_zone, Military
+0, 0x05 = poly_car_parking, Parking Lot
+0, 0x06 = poly_car_parking, Parking Garage
+0, 0x07 = poly_airport, Airport
+0, 0x08 = poly_commercial_center, Shopping Center
+0, 0x09 = poly_marine, Marina
+0, 0x0a = poly_university, University/College
+0, 0x0b = poly_hospital, Hospital
+0, 0x0c = poly_industry, Industrial
+0, 0x0d = area, Reservation
+0, 0x0e = poly_airport, Airport Runway
+0, 0x13 = area_unspecified, Man made area
+0, 0x14 = poly_national_park, National park
+0, 0x15 = poly_national_park, National park
+0, 0x16 = poly_nature_park, National park
+0, 0x17 = poly_park, City Park
+0, 0x18 = poly_golf_course, Golf
+0, 0x19 = poly_sport, Sport
+0, 0x1a = poly_cemetery, Cemetery
+0, 0x1e = poly_nature_park, State Park
+0, 0x1f = poly_park, State Park
+0, 0x20 = poly_park, State Park
+0, 0x28 = poly_water, Ocean
+0, 0x29 = poly_water, Water Reservour
+0, 0x32 = poly_water, Sea
+0, 0x3b = poly_water, Water Reservour
+0, 0x3c = poly_water, Lake (250-600 km2)
+0, 0x3d = poly_water, Lake (77-250 km2)
+0, 0x3e = poly_water, Lake (25-77 km2)
+0, 0x3f = poly_water, Lake (11-25 km2)
+0, 0x40 = poly_water, Lake (0.25-11 km2)
+0, 0x41 = poly_water, Lake (<0.25 km2)
+0, 0x42 = poly_water, Lake (>3.3k km2)
+0, 0x43 = poly_water, Lake (1.1-3.3k km2)
+0, 0x44 = poly_water, Lake (0.6-1.1k km2)
+0, 0x45 = poly_water, Water Reservour
+0, 0x46 = poly_water, River (>1km)
+0, 0x47 = poly_water, River (200m-1km)
+0, 0x48 = poly_water, River (40-200m)
+0, 0x49 = poly_water, River (<40m)
+0, 0x4a = area, Definition Area
+0, 0x4b = area, Background
+0, 0x4c = poly_water, Intermittent River/Lake
+0, 0x4d = poly_glacier, Glaciers
+0, 0x4e = plantation, Orchard or plantation
+0, 0x4f = poly_scrub, Scrub
+0, 0x50 = poly_wood, Woods
+0, 0x51 = poly_wetland, Wetland
+0, 0x52 = tundra, Tundra
+0, 0x53 = poly_flats, Flats
+# RGN2-4 
+# Marine
+1, 0x0100 = street_unkn, Land - white
+1, 0x0101 = street_unkn, Land - non-urban
+1, 0x0102 = street_unkn, Land - urban
+1, 0x0103 = street_unkn, Chart exclusion area
+1, 0x0104 = street_unkn, Chart background
+1, 0x0105 = street_unkn, Bridge
+1, 0x0300 = street_unkn, Depth area - white 1
+1, 0x0301 = street_unkn, Intertidal zone
+1, 0x0302 = street_unkn, Depth area - blue 1
+1, 0x0303 = street_unkn, Depth area - blue 2
+1, 0x0304 = street_unkn, Depth area - blue 3
+1, 0x0305 = street_unkn, Depth area - blue 4
+1, 0x0306 = street_unkn, Depth area - blue 5
+1, 0x0307 = street_unkn, Depth area - white
+1, 0x0400 = street_unkn, Obstruction (invisible)
+1, 0x0401 = street_unkn, Submarine cable (invisible)
+1, 0x0402 = street_unkn, Submarine pipeline (invisible)
+1, 0x0403 = street_unkn, Pile barrier (invisible)
+1, 0x0404 = street_unkn, Fishing stakes (invisible)
+1, 0x0405 = street_unkn, Supply pipeline area/line (invisible)
+1, 0x0406 = street_unkn, Submarine cable area/line (invisible)
+1, 0x0407 = street_unkn, Dumping ground (invisible)
+1, 0x0408 = street_unkn, Explosive dumping ground (invisible)
+1, 0x0409 = street_unkn, Danger line (invisible)
+1, 0x040a = street_unkn, Overhead cable (invisible)
+1, 0x040b = street_unkn, Submerged construction (invisible)
+1, 0x040c = street_unkn, Pier/jetty (invisible)
+1, 0x0500 = street_unkn, Restriction area/line (invisible)
+1, 0x0501 = street_unkn, Anchoring prohibited (invisible)
+1, 0x0502 = street_unkn, Fishing prohibited (invisible)
+1, 0x0503 = street_unkn, Prohibited area (invisible)
+1, 0x0504 = street_unkn, Military practice area (invisible)
+1, 0x0505 = street_unkn, Anchoring and fishing prohibited (invisible)
+1, 0x0506 = street_unkn, Limit of nature reservation (invisible)
+1, 0x0507 = street_unkn, Restricted area (invisible)
+1, 0x0508 = street_unkn, Minefield (invisible)
+1, 0x0600 = street_unkn, Miscellaneous area
+1, 0x0601 = street_unkn, Cartographic area
+1, 0x0602 = street_unkn, Traffic separation area
+1, 0x0603 = street_unkn, International maritime boundary
+1, 0x0604 = street_unkn, Straight territorial sea baseline
+1, 0x0605 = street_unkn, Seaward limit of territorial sea
+1, 0x0606 = street_unkn, Anchorage area
+1, 0x0607 = street_unkn, Quarantine anchorage area
+1, 0x0608 = street_unkn, Fishery zone
+1, 0x0609 = street_unkn, Swept area
+1, 0x060a = street_unkn, Traffic separation zone
+1, 0x060b = street_unkn, Limit of exclusive economic zone
+1, 0x060c = street_unkn, Established direction of traffic flow
+1, 0x0701 = street_unkn, Fishing area
+1, 0x0702 = street_unkn, Restricted area
+1, 0x0703 = street_unkn, Anchorage area
+1, 0x0704 = street_unkn, Fishing Hot Spots chart
+# NT types
+1, 0x0800 = poly_town, Large City
+1, 0x0801 = poly_town, City
+1, 0x0900 = poly_plaza, Square/Place
+1, 0x0902 = poly_car_parking, Car Park (Parking Lot)
+1, 0x0904 = poly_airport, Airport
+1, 0x090d = poly_sports_stadium, Stage like circus/sport/stadium
+1, 0x090e = poly_cemetery, Graveyard/Cemetery
+1, 0x0a01 = poly_national_park, National Park
+1, 0x0a04 = poly_park, City Park
+1, 0x0a05 = poly_nature_park, Nature Park
+1, 0x0a06 = street_unkn, Dam/Man made/ ??
+1, 0x0b02 = poly_water, Sea
+1, 0x0b03 = poly_water, Water Reservour
+1, 0x0b07 = poly_water, Dam/Lake
+1, 0x0b08 = poly_water, Dam/Lake
+1, 0x0b0c = poly_water, River
diff --git a/navit/map/garmin/gentypes.c b/navit/map/garmin/gentypes.c
new file mode 100644 (file)
index 0000000..16682a5
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+       Copyright (C) 2007  Alexander Atanasov      <aatanasov@gmail.com>
+
+       This program is free software; you can redistribute it and/or modify
+       it under the terms of the GNU General Public License as published by
+       the Free Software Foundation; version 2 of the License.
+
+       This program is distributed in the hope that it will be useful,
+       but WITHOUT ANY WARRANTY; without even the implied warranty of
+       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+       GNU General Public License for more details.
+
+       You should have received a copy of the GNU General Public License
+       along with this program; if not, write to the Free Software
+       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
+       MA  02110-1301  USA
+    
+       Garmin and MapSource are registered trademarks or trademarks
+       of Garmin Ltd. or one of its subsidiaries.
+
+*/
+
+/*
+File format is:
+
+POINT
+GROUP,0x0100 = town_label_1e5, Megapolis (10M +)
+GROUP,0x0200 = town_label_5e4, Megapolis (5-10M)
+...
+GROUP,0x1e00-0x1e3f = district_label, District, Province, State Name
+...
+POLYLINE
+GROUP,0x00 = street_1_land, Road
+GROUP,0x01 = highway_land, Major HWY thick
+GROUP,0x02 = street_4_land, Principal HWY-thick
+GROUP,0x03 = street_2_land, Principal HWY-medium
+....
+POLYGONE
+GROUP,0x01 = town_poly, City (>200k)
+GROUP,0x02 = town_poly, City (<200k)
+GROUP,0x03 = town_poly, Village
+
+GROUP is
+0 - good old garmin types in RGN1
+1 - NT types in RGN2-4 5 is completely unknown yet
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <malloc.h>
+#include <unistd.h>
+#include "item.h"
+#include "gar2navit.h"
+
+#define dlog(x, y...) fprintf(stderr, ## y)
+/*
+static int add_def(struct gar2nav_conv *conv, int type, unsigned short minid,
+               unsigned short maxid, unsigned int routable, char *ntype,
+               char *descr)
+*/
+
+static void print_header(FILE *fp)
+{
+       fprintf(fp, "// This is autogenerated file -- DO NOT EDIT\n");
+       fprintf(fp, "struct gar2nav_conv *g2n_default_conv(void)\n"
+                       "{\n"
+                       "\tstruct gar2nav_conv *conv;\n"
+                       "\n"
+                       "\tconv = calloc(1, sizeof(*conv));\n"
+                       "\tif (!conv)\n"
+                       "\t\treturn conv;\n");
+}
+
+static int load_types_file(char *file, char *out)
+{
+       char buf[4096];
+       char descr[4096];
+       char ntype[4096];
+       FILE *fp;
+       unsigned int minid, maxid, group;
+       int rc;
+       int type = -1;
+       FILE *fpout = stdout;
+
+       fp = fopen(file, "r");
+       if (!fp)
+               return -1;
+       if (out) {
+               fpout = fopen(out, "w");
+               if (!fpout)
+                       return -1;
+       }
+       print_header(fpout);
+       while (fgets(buf, sizeof(buf), fp)) {
+               if (*buf == '#' || *buf == '\n')
+                       continue;
+               if (!strncasecmp(buf, "POINT", 5)) {
+                       type = 1;
+                       continue;
+               } else if (!strncasecmp(buf, "POI", 3)) {
+                       type = 1;
+                       continue;
+               } else if (!strncasecmp(buf, "POLYLINE", 8)) {
+                       type = 2;
+                       continue;
+               } else if (!strncasecmp(buf, "POLYGONE", 8)) {
+                       type = 3;
+                       continue;
+               }
+
+               rc = sscanf(buf, "%d, 0x%04X - 0x%04X = %[^\t , ] , %[^\n]",
+                       &group, &minid, &maxid, ntype, descr);
+               if (rc != 5) { 
+                       maxid = 0;
+                       rc = sscanf(buf, "%d, 0x%04X = %[^\t, ], %[^\n]",
+                               &group,&minid, ntype, descr);
+                       if (rc != 4) {
+                               dlog(1, "Invalid line rc=%d:[%s]\n",rc, buf);
+                               dlog(1, "minid=%04X ntype=[%s] des=[%s]\n",
+                                       minid, ntype, descr);
+                               continue;
+                       }
+               }
+
+               fprintf(fpout, "\tadd_def(conv, %d, %#.04x, %#.04x, %d, \"%s\", \"%s\");\n",
+                               type, minid, maxid, group, ntype, descr);
+       }
+       fprintf(fpout, "\treturn conv;\n");
+       fprintf(fpout, "}\n");
+       fclose(fp);
+       if (out)
+               fclose(fpout);
+       return 1;
+}
+
+int main(int argc, char **argv)
+{
+       if (argc!=3) {
+               fprintf(stderr, "Usage: %s garmintypes.txt outfile.c\n",
+                       argv[0]);
+               return -1;
+       }
+       if (load_types_file(argv[1], argv[2]) < 0) {
+               unlink(argv[2]);
+               return -1;
+       }
+       return 0;
+}
diff --git a/navit/map/garmin_img/Makefile.am b/navit/map/garmin_img/Makefile.am
new file mode 100644 (file)
index 0000000..bd4baae
--- /dev/null
@@ -0,0 +1,4 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/navit -DMODULE=map_garmin_img
+modulemap_LTLIBRARIES = libmap_garmin_img.la
+libmap_garmin_img_la_SOURCES = garmin_img.c
diff --git a/navit/map/garmin_img/garmin_img.c b/navit/map/garmin_img/garmin_img.c
new file mode 100644 (file)
index 0000000..58fe489
--- /dev/null
@@ -0,0 +1,1513 @@
+/**
+ * Navit, a modular navigation system.
+ * Copyright (C) 2005-2008 Navit Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <glib.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "config.h"
+#include "plugin.h"
+#include "data.h"
+#include "projection.h"
+#include "map.h"
+#include "maptype.h"
+#include "item.h"
+#include "attr.h"
+#include "coord.h"
+#include "transform.h"
+#include <stdio.h>
+#include "attr.h"
+#include "coord.h"
+
+struct file {
+       FILE *f;
+       int offset;
+};
+
+
+int shift=5;
+int subdiv_next=0x10;
+
+
+static void *
+file_read(struct file *f, int offset, int size)
+{
+       void *ptr;
+       int ret;
+
+       ptr=calloc(size, 1);
+       if (! ptr)
+               return ptr;
+       fseek(f->f, f->offset+offset, SEEK_SET);
+       ret=fread(ptr, size, 1, f->f);
+       if (ret != 1) {
+               printf("fread %d vs %d offset %d+%d(0x%x)\n", ret, size, f->offset, offset,offset);
+               g_assert(1==0);
+       }
+       return ptr;
+}
+
+static void
+file_free(void *ptr)
+{
+       free(ptr);
+}
+
+struct offset_len {
+       int offset;
+       int length;
+} __attribute ((packed));
+
+static void
+dump_offset_len(struct offset_len *off_len)
+{
+       printf("offset: 0x%x(%d) length 0x%x(%d)\n", off_len->offset, off_len->offset, off_len->length, off_len->length);
+}
+
+struct timestamp {
+       short creation_year;
+       char creation_month;
+       char creation_day;
+       char creation_hour;
+       char creation_minute;
+       char creation_second;
+} __attribute__((packed));
+
+struct img_header {
+       char xor;
+       char zero1[9];
+       char update_month;
+       char update_year;
+       char zero2[3];
+       char checksum[1];
+       char signature[7];
+       char unknown1[1];
+       char unknown2[2];
+       char unknown3[2];
+       char unknown4[2];
+       char unknown5[2];
+       char zero3[25];
+       struct timestamp ts;
+       char unknown6;
+       char map_file_identifier[7];
+       char unknown12;
+       char map_description1[20];
+       short unknown13;
+       short unknown14;
+       char e1;
+       char e2;
+       char other[413];
+       char zero4[512];
+       char unknown7;
+       char unknown8[11];
+       int file_offset;
+       char unknown9;
+       char unknown10[15];
+       char unknown11[480];
+} __attribute__((packed));
+
+static void
+dump_ts(struct timestamp *ts)
+{
+       printf("%d-%02d-%02d %02d:%02d:%02d\n", ts->creation_year, ts->creation_month, ts->creation_day, ts->creation_hour, ts->creation_minute, ts->creation_second);
+}
+
+#if 0
+static void
+dump_img(struct img_header *img_hdr)
+{
+       printf("signature: '%s'\n", img_hdr->signature);
+       printf("creation: ");
+       dump_ts(&img_hdr->ts);
+       printf("map_file_identifier: '%s'\n", img_hdr->map_file_identifier);
+       printf("file_offset: 0x%x\n", img_hdr->file_offset);
+       printf("e1: 0x%x(%d)\n", img_hdr->e1, img_hdr->e1);
+       printf("e2: 0x%x(%d)\n", img_hdr->e2, img_hdr->e2);
+       printf("offset 0x%x\n", (int) &img_hdr->e1 - (int) img_hdr);
+       printf("size %d\n", sizeof(*img_hdr));
+}
+#endif
+
+struct fat_block {
+       char flag;
+       char filename[8];
+       char type[3];
+       int size;
+       char zero1;
+       char part;
+       char zero[14];
+       unsigned short blocks[240];
+} __attribute__((packed));
+
+#if 0
+static void
+dump_fat_block(struct fat_block *fat_blk)
+{
+       int i=0;
+       char name[9];
+       char type[4];
+       printf("flag: 0x%x(%d)\n", fat_blk->flag, fat_blk->flag);
+       strcpy(name, fat_blk->filename);
+       name[8]='\0';
+       strcpy(type, fat_blk->type);
+       type[3]='\0';
+       printf("name: '%s.%s'\n", name, type);
+       printf("size: 0x%x(%d)\n", fat_blk->size, fat_blk->size);
+       printf("part: 0x%x(%d)\n", fat_blk->part, fat_blk->part);
+       printf("blocks: ");
+       while (i < 240) {
+               printf("0x%x(%d) ",fat_blk->blocks[i], fat_blk->blocks[i]);
+               if (fat_blk->blocks[i] == 0xffff)
+                       break;
+               i++;
+       }
+       printf("size: %d\n", sizeof(*fat_blk));
+       
+}
+#endif
+
+struct file_header {
+       short header_len;
+       char type[10];
+       char unknown1;
+       char unknown2;
+       struct timestamp ts;
+} __attribute__((packed));
+
+static void
+dump_file(struct file_header *fil_hdr)
+{
+       printf("header_len: %d\n", fil_hdr->header_len);
+       printf("type: '%s'\n", fil_hdr->type);
+       printf("unknown1: 0x%x(%d)\n", fil_hdr->unknown1, fil_hdr->unknown1);
+       printf("unknown2: 0x%x(%d)\n", fil_hdr->unknown2, fil_hdr->unknown2);
+       printf("creation: ");
+       dump_ts(&fil_hdr->ts);
+       printf("size %d\n", sizeof(*fil_hdr));
+}
+
+struct region_header {
+       struct file_header fil_hdr;
+       struct offset_len offset_len;
+} __attribute__((packed));
+
+#if 0
+static void
+dump_region(struct region_header *rgn_hdr)
+{
+       dump_offset_len(&rgn_hdr->offset_len);
+}
+#endif
+
+struct map_priv {
+       int id;
+       char *filename;
+};
+
+struct map_rect_priv {
+       struct coord_rect r;
+       int limit;
+
+       struct file tre;
+       struct tree_header *tre_hdr;
+       struct file rgn;
+       struct region_header *rgn_hdr;
+       struct file lbl;
+       struct label_header *lbl_hdr;
+       char *label;
+
+       int subdiv_level_count;
+       int subdiv_pos;
+       char *subdiv;
+
+       int rgn_offset;
+       int rgn_end;
+       struct rgn_point *pnt;
+       struct rgn_poly *ply;
+       unsigned char *ply_data;
+       int ply_bitpos;
+       int ply_bitcount;
+       int ply_lngbits;
+       int ply_latbits;
+       int ply_lng;
+       int ply_lat;
+       int ply_lnglimit;
+       int ply_latlimit;
+       int ply_lngsign;
+       int ply_latsign;
+       struct offset_len rgn_items[4];
+       int rgn_type;
+
+       int count;
+
+       FILE *f;
+       long pos;
+       char line[256];
+       int attr_pos;
+       enum attr_type attr_last;
+       char attrs[256];
+       char attr[256];
+       double lat,lng;
+       char lat_c,lng_c;
+       int eoc;
+       struct map_priv *m;
+       struct item item;
+};
+
+static int map_id;
+
+static int
+contains_coord(char *line)
+{
+       return g_ascii_isdigit(line[0]);
+}
+
+static int debug=1;
+
+static int
+get_tag(char *line, char *name, int *pos, char *ret)
+{
+       int len,quoted;
+       char *p,*e,*n;
+
+       if (debug)
+               printf("get_tag %s from %s\n", name, line); 
+       if (! name)
+               return 0;
+       len=strlen(name);
+       if (pos) 
+               p=line+*pos;
+       else
+               p=line;
+       for(;;) {
+               while (*p == ' ') {
+                       p++;
+               }
+               if (! *p)
+                       return 0;
+               n=p;
+               e=index(p,'=');
+               if (! e)
+                       return 0;
+               p=e+1;
+               quoted=0;
+               while (*p) {
+                       if (*p == ' ' && !quoted)
+                               break;
+                       if (*p == '"')
+                               quoted=1-quoted;
+                       p++;
+               }
+               if (e-n == len && !strncmp(n, name, len)) {
+                       e++;
+                       len=p-e;
+                       if (e[0] == '"') {
+                               e++;
+                               len-=2;
+                       }
+                       strncpy(ret, e, len);
+                       ret[len]='\0';
+                       if (pos)
+                               *pos=p-line;
+                       return 1;
+               }
+       }       
+       return 0;
+}
+
+static void
+get_line(struct map_rect_priv *mr)
+{
+       mr->pos=ftell(mr->f);
+       fgets(mr->line, 256, mr->f);
+}
+
+static void
+map_destroy_garmin_img(struct map_priv *m)
+{
+       if (debug)
+               printf("map_destroy_garmin_img\n");
+       g_free(m);
+}
+
+static char *
+map_charset_garmin_img(struct map_priv *m)
+{
+       return "iso8859-1";
+}
+
+static enum projection
+map_projection_garmin_img(struct map_priv *m)
+{
+       return projection_garmin;
+}
+
+struct label_data_offset {
+       struct offset_len offset_len;
+       char multiplier;
+       char data;
+} __attribute ((packed));
+
+#if 0
+static void
+dump_label_data_offset(struct label_data_offset *lbl_dat)
+{
+       dump_offset_len(&lbl_dat->offset_len);
+       printf("multiplier 0x%x(%d)\n", lbl_dat->multiplier, lbl_dat->multiplier);
+       printf("data 0x%x(%d)\n", lbl_dat->data, lbl_dat->data);
+}
+#endif
+
+struct label_data {
+       struct offset_len offset_len;
+       short size;
+       int zero;
+} __attribute ((packed));
+
+static void
+dump_label_data(struct label_data *lbl_dat)
+{
+       dump_offset_len(&lbl_dat->offset_len);
+       printf("size 0x%x(%d)\n", lbl_dat->size, lbl_dat->size);
+}
+
+struct tree_header {
+       struct file_header fil_hdr;
+       char boundary[12];
+       struct offset_len level;
+       struct offset_len subdivision;
+       struct label_data copyright;
+       struct offset_len tre7;
+       short unknown1;
+       char zero1;
+       struct label_data polyline;
+       struct label_data polygon;
+       struct label_data point;
+       int mapid;
+};
+
+static void
+dump_tree_header(struct tree_header *tre_hdr)
+{
+       printf("tree_header:\n");
+       dump_file(&tre_hdr->fil_hdr);
+       printf("level: "); dump_offset_len(&tre_hdr->level);
+       printf("subdivision: "); dump_offset_len(&tre_hdr->subdivision);
+       printf("copyright: "); dump_label_data(&tre_hdr->copyright);
+       printf("polyline: "); dump_label_data(&tre_hdr->polyline);
+       printf("polygon: "); dump_label_data(&tre_hdr->polygon);
+       printf("point: "); dump_label_data(&tre_hdr->point);
+       printf("len: 0x%x(%d)\n", sizeof(*tre_hdr), sizeof(*tre_hdr));
+}
+
+struct label_header {
+       struct file_header fil_hdr;
+       struct label_data_offset label;
+       struct label_data country;
+       struct label_data region;
+       struct label_data city;
+       struct label_data poi_index;
+       struct label_data_offset poi_properties;
+       short zero1;
+       char zero2;
+       struct label_data poi_types;
+       struct label_data zip;
+       struct label_data hway;
+       struct label_data exit;
+       struct label_data hway_data;
+       int unknown1;
+       short unknown2;
+       struct offset_len sort_descriptor;
+       struct label_data lbl13;
+       struct label_data lbl14;
+} __attribute((packed));
+
+#if 0
+static void
+dump_label(struct label_header *lbl_hdr)
+{
+       dump_file(&lbl_hdr->fil_hdr);
+       printf("label:\n");
+       dump_label_data_offset(&lbl_hdr->label);
+       printf("country:\n");
+       dump_label_data(&lbl_hdr->country);
+       printf("region:\n");
+       dump_label_data(&lbl_hdr->region);
+       printf("city:\n");
+       dump_label_data(&lbl_hdr->city);
+       printf("poi_index:\n");
+       dump_label_data(&lbl_hdr->poi_index);
+       printf("poi_properties:\n");
+       dump_label_data_offset(&lbl_hdr->poi_properties);
+       printf("poi_types:\n");
+       dump_label_data(&lbl_hdr->poi_types);
+       printf("zip:\n");
+       dump_label_data(&lbl_hdr->zip);
+       printf("hway:\n");
+       dump_label_data(&lbl_hdr->hway);
+       printf("exit:\n");
+       dump_label_data(&lbl_hdr->exit);
+       printf("hway_data:\n");
+       dump_label_data(&lbl_hdr->hway_data);
+       printf("lbl13:\n");
+       dump_label_data(&lbl_hdr->lbl13);
+       printf("lbl14:\n");
+       dump_label_data(&lbl_hdr->lbl14);
+       printf("len: 0x%x(%d)\n", sizeof(*lbl_hdr), sizeof(*lbl_hdr));
+}
+#endif
+
+struct triple {
+       unsigned char data[3];
+} __attribute((packed));
+
+static unsigned int
+triple_u(struct triple *t)
+{
+       return t->data[0] | (t->data[1] << 8)  | (t->data[2] << 16);
+}
+
+static int
+triple(struct triple *t)
+{
+       int ret=t->data[0] | (t->data[1] << 8)  | (t->data[2] << 16);
+       if (ret > 1<<23)
+               ret=ret-(1<<24);
+       return ret;
+}
+
+static void
+dump_triple_u(struct triple *t)
+{
+       int val=triple_u(t);
+       printf("0x%x(%d)\n", val, val);
+}
+
+struct tcoord {
+       struct triple lng,lat;
+} __attribute((packed));
+
+static void
+dump_tcoord(struct tcoord *t)
+{
+       printf ("0x%x(%d),0x%x(%d)\n", triple_u(&t->lng), triple_u(&t->lng), triple_u(&t->lat), triple_u(&t->lat));
+}
+
+struct level {
+       unsigned char zoom;
+       unsigned char bits_per_coord;
+       unsigned short subdivisions;
+} __attribute((packed));
+
+static void
+dump_level(struct level *lvl)
+{
+       printf("level:\n");
+       printf("\tzoom 0x%x(%d)\n", lvl->zoom, lvl->zoom);
+       printf("\tbits_per_coord 0x%x(%d)\n", lvl->bits_per_coord, lvl->bits_per_coord);
+       printf("\tsubdivisions 0x%x(%d)\n", lvl->subdivisions, lvl->subdivisions);
+}
+
+struct subdivision {
+       struct triple rgn_offset;
+       unsigned char types;
+       struct tcoord center;
+       unsigned short width;
+       unsigned short height;
+       unsigned short next; 
+} __attribute((packed));
+
+static void
+dump_subdivision(struct subdivision *sub)
+{
+       printf("subdivision:\n");
+       printf("\trgn_offset: "); dump_triple_u(&sub->rgn_offset);
+       printf("\ttypes: 0x%x(%d)\n", sub->types, sub->types);
+       printf("\tcenter: "); dump_tcoord(&sub->center);
+       printf("\tsize: 0x%x(%d)x0x%x(%d) %s\n",sub->width & 0x7fff, sub->width & 0x7fff, sub->height, sub->height, sub->width & 0x8000 ? "Terminating" : "");
+       printf("\tnext: 0x%x(%d)\n",sub->next, sub->next);
+       
+       printf("\tlen: 0x%x(%d)\n", sizeof(*sub), sizeof(*sub));
+}
+
+struct rgn_point {
+       unsigned char info;
+       struct triple lbl_offset;
+       short lng_delta;
+       short lat_delta;
+       unsigned char subtype;
+} __attribute((packed));
+
+static void
+dump_point(struct rgn_point *pnt)
+{
+       printf("point:\n");
+       printf("\tinfo 0x%x(%d)\n", pnt->info, pnt->info);
+       printf("\tlbl_offset 0x%x(%d)\n", triple_u(&pnt->lbl_offset), triple_u(&pnt->lbl_offset));
+       printf("\tlng_delta 0x%x(%d)\n", pnt->lng_delta, pnt->lng_delta);
+       printf("\tlat_delta 0x%x(%d)\n", pnt->lat_delta, pnt->lat_delta);
+       printf("\tsubtype 0x%x(%d)\n", pnt->subtype, pnt->subtype);
+       printf("\tlen: 0x%x(%d)\n", sizeof(*pnt), sizeof(*pnt));
+}
+
+struct rgn_poly {
+       unsigned char info;
+       struct triple lbl_offset;
+       short lng_delta;
+       short lat_delta;
+       union {
+               struct {
+                       unsigned char bitstream_len;
+                       unsigned char bitstream_info;
+               } __attribute((packed)) p1;
+               struct {
+                       unsigned short bitstream_len;
+                       unsigned char bitstream_info;
+               } __attribute((packed)) p2;
+       } __attribute((packed)) u;
+} __attribute((packed));
+
+static void
+dump_poly(struct rgn_poly *ply)
+{
+       printf("poly:\n");
+       printf("\tinfo 0x%x(%d)\n", ply->info, ply->info);
+       printf("\tlbl_offset 0x%x(%d)\n", triple_u(&ply->lbl_offset), triple_u(&ply->lbl_offset));
+       printf("\tlng_delta 0x%x(%d)\n", ply->lng_delta, ply->lng_delta);
+       printf("\tlat_delta 0x%x(%d)\n", ply->lat_delta, ply->lat_delta);
+       if (ply->info & 0x80) {
+               printf("\tbitstream_len 0x%x(%d)\n", ply->u.p2.bitstream_len, ply->u.p2.bitstream_len);
+               printf("\tbitstream_info 0x%x(%d)\n", ply->u.p2.bitstream_info, ply->u.p2.bitstream_info);
+       } else {
+               printf("\tbitstream_len 0x%x(%d)\n", ply->u.p1.bitstream_len, ply->u.p1.bitstream_len);
+               printf("\tbitstream_info 0x%x(%d)\n", ply->u.p1.bitstream_info, ply->u.p1.bitstream_info);
+       }
+       printf("\tlen: 0x%x(%d)\n", sizeof(*ply), sizeof(*ply));
+}
+
+static void
+dump_hex(void *ptr, int len)
+{
+       unsigned char *c=ptr;
+       while (len--) {
+               printf("%02x ", *c++);
+       }
+       printf("\n");
+}
+
+static void
+dump_hex_r(void *ptr, int len, int rec)
+{
+       unsigned char *c=ptr;
+       int l=rec;
+       while (len--) {
+               printf("%02x ", *c++);
+               if (! --l) {
+                       printf("\n");
+                       l=rec;
+               }
+       }
+       printf("\n");
+}
+
+#if 0
+static void
+dump_label_offset(struct map_rect_priv *mr, int offset)
+{
+       void *p;
+       p=file_read(&mr->lbl, mr->lbl_hdr->label.offset_len.offset+offset, 128);
+       printf("%s\n", (char *)p);
+}
+#endif
+
+
+#if 0
+static void
+dump_region_item(struct subdivision *sub, struct file *rgn, struct map_rect_priv *mr)
+{
+       int offset,item_offset,i,j;
+       unsigned short count=0;
+       unsigned short *offsets[4];
+       unsigned short *file_offsets;
+       struct rgn_point *pnt;
+
+       offset=triple_u(&sub->rgn_offset)+mr->rgn_hdr->offset_len.offset;
+       file_offsets=file_read(rgn, offset, 90*sizeof(unsigned short));
+       printf("0x%x ", offset); dump_hex(file_offsets, 90);
+       for (i=0 ; i < 4 ; i++) {
+               printf("i=%d\n", i);
+               if (sub->types & (0x10 << i)) {
+                       if (count) {    
+                               offsets[i]=&file_offsets[count-1];
+                       } else
+                               offsets[i]=&count;
+                       count++;
+               } else
+                       offsets[i]=NULL;
+               
+       }
+       count--;
+       count*=2;
+       for (i=0 ; i < 4 ; i++) {
+               printf("i=%d\n", i);
+               if (offsets[i]) {
+                       printf("offset[%d]=0x%x(%d)\n", i, *offsets[i], *offsets[i]);
+                       switch (i) {
+                       case 0:
+                               printf("point\n");
+                               break;
+                       case 1:
+                               printf("indexed point\n");
+                               break;
+                       case 2:
+                               printf("polyline\n");
+                               break;
+                       case 3:
+                               printf("polygon\n");
+                               break;
+                       }
+                       item_offset=offset+*offsets[i];
+                       switch (i) {
+                       case 0:
+                       case 1:
+                               for (j = 0 ; j < 10 ; j++) {
+                                       struct coord_geo g;
+                                       char buffer[1024];
+                                       double conv=180.0/(1UL<<23);
+                                       pnt=file_read(rgn, item_offset, sizeof(*pnt)*20);
+                                       // printf("0x%x ", item_offset); dump_hex(pnt, 32);
+                                       dump_point(pnt);
+                                       g.lng=(triple(&sub->center.lng)+(pnt->lng_delta << shift))*conv;
+                                       g.lat=(triple(&sub->center.lat)+(pnt->lat_delta << shift))*conv;
+                                       printf("%f %f\n", g.lng, g.lat);
+                                       coord_format(g.lat,g.lng,DEGREES_MINUTES_SECONDS,
+                                                    buffer,sizeof(buffer));
+                                       printf("%s\n", buffer);
+                                       dump_label_offset(mr, triple_u(&pnt->lbl_offset));
+                                       if (pnt->info & 0x80) 
+                                               item_offset+=sizeof(*pnt);
+                                       else
+                                               item_offset+=sizeof(*pnt)-1;
+                               }
+                       }
+               } else {
+                       printf("offset[%d] doesn't exist\n", i);
+               }
+       }
+       file_free(file_offsets);
+}
+
+#endif
+
+static void
+dump_levels(struct map_rect_priv *mr)
+{
+       int i,offset;
+       struct level *lvl;
+
+       offset=mr->tre_hdr->level.offset;
+       for (i = 0 ; i < mr->tre_hdr->level.length/sizeof(*lvl) ; i++) {
+               lvl=file_read(&mr->tre, offset, sizeof(*lvl));
+               dump_level(lvl);
+               offset+=sizeof(*lvl);
+       }
+}
+
+#if 0
+static void
+dump_tree(struct file *f, struct file *rgn, struct map_rect_priv *mr)
+{
+       struct tree_header *tre_hdr;
+       struct subdivision *sub;
+       int i,offset;
+
+       tre_hdr=file_read(f, 0, sizeof(*tre_hdr));
+       dump_tree_header(tre_hdr);
+       offset=tre_hdr->subdivision.offset;
+       sub=file_read(f, offset, sizeof(*sub));
+       dump_subdivision(sub);
+       offset+=sizeof(*sub);
+       for (i = 1 ; i < tre_hdr->subdivision.length/sizeof(*sub) ; i++) {
+               printf("i=%d\n", i);
+               sub=file_read(f, offset, sizeof(*sub));
+               dump_subdivision(sub);
+               dump_region_item(sub, rgn, mr);
+               if (sub->width & 0x8000)
+                       break;          
+               offset+=sizeof(*sub);
+       }
+       file_free(tre_hdr);
+}
+#endif
+
+#if 0
+static void
+dump_labels(struct file *f)
+{
+       struct label_header *lbl_hdr;
+       
+       lbl_hdr=file_read(f, 0, sizeof(*lbl_hdr));
+       printf("**labels**\n");
+       dump_label(lbl_hdr);
+       file_free(lbl_hdr);
+#if 0
+       labels=alloca(lbl_hdr.label_length);
+       file_read(f, lbl_hdr.label_offset, labels, lbl_hdr.label_length);
+       l=labels;
+       while (l < labels+lbl_hdr.label_length) {
+               printf("'%s'(%d)\n", l, strlen(l));
+               l+=strlen(l)+1;
+       }
+#endif
+       
+}
+#endif
+
+static void
+garmin_img_coord_rewind(void *priv_data)
+{
+}
+
+static void
+parse_line(struct map_rect_priv *mr)
+{
+       int pos=0;
+       sscanf(mr->line,"%lf %c %lf %c %n",&mr->lat,&mr->lat_c,&mr->lng,&mr->lng_c,&pos);
+       if (pos < strlen(mr->line)) {
+               strcpy(mr->attrs, mr->line+pos);
+       }
+}
+
+static int
+get_bits(struct map_rect_priv *mr, int bits)
+{
+       unsigned long ret;
+       ret=L(*((unsigned long *)(mr->ply_data+mr->ply_bitpos/8)));
+       ret >>= (mr->ply_bitpos & 7);
+       ret &= (1 << bits)-1;
+       mr->ply_bitpos+=bits;
+       return ret;
+}
+
+static int
+garmin_img_coord_get(void *priv_data, struct coord *c, int count)
+{
+       struct map_rect_priv *mr=priv_data;
+       struct subdivision *sub=(struct subdivision *)(mr->subdiv+mr->subdiv_pos);
+       int ret=0;
+       int debug=0;
+       if (debug)
+               printf("garmin_img_coord_get %d\n",count);
+       if (debug)
+               dump_subdivision(sub);
+       while (count--) {
+               if (mr->rgn_type < 2) {
+                       c->x=triple(&sub->center.lng)+(mr->pnt->lng_delta << shift);
+                       c->y=triple(&sub->center.lat)+(mr->pnt->lat_delta << shift);
+               } else {
+                       if (! mr->ply_bitpos) {
+                               if (mr->ply->info & 0x80) {
+                                       mr->ply_bitcount=mr->ply->u.p2.bitstream_len*8;
+                                       mr->ply_lngbits=mr->ply->u.p2.bitstream_info & 0xf;
+                                       mr->ply_latbits=mr->ply->u.p2.bitstream_info >> 4;
+                               } else {
+                                       mr->ply_bitcount=mr->ply->u.p1.bitstream_len*8;
+                                       mr->ply_lngbits=mr->ply->u.p1.bitstream_info & 0xf;
+                                       mr->ply_latbits=mr->ply->u.p1.bitstream_info >> 4;
+                               }
+                               if (mr->ply_lngbits <= 9)
+                                       mr->ply_lngbits+=2;
+                               if (mr->ply_latbits <= 9)
+                                       mr->ply_latbits+=2;
+                               if (! get_bits(mr,1)) {
+                                       mr->ply_lngbits+=1;
+                                       mr->ply_lngsign=0;
+                               } else  
+                                       if (get_bits(mr, 1))
+                                               mr->ply_lngsign=-1;
+                                       else
+                                               mr->ply_lngsign=1;
+                               if (! get_bits(mr,1)) {
+                                       mr->ply_latbits+=1;
+                                       mr->ply_latsign=0;
+                               } else
+                                       if (get_bits(mr, 1))
+                                               mr->ply_latsign=-1;
+                                       else
+                                               mr->ply_latsign=1;
+                               mr->ply_lnglimit=1 << (mr->ply_lngbits-1);
+                               mr->ply_latlimit=1 << (mr->ply_latbits-1);
+                               mr->ply_lng=mr->ply->lng_delta;
+                               mr->ply_lat=mr->ply->lat_delta;
+                               if (debug)
+                                       printf("lngbits %d latbits %d bitcount %d\n", mr->ply_lngbits, mr->ply_latbits, mr->ply_bitcount);
+                               c->x=0;
+                               c->y=0;
+                       } else {
+                       if (mr->ply_bitpos + mr->ply_lngbits + mr->ply_latbits > mr->ply_bitcount) {
+                               if (debug)
+                                       printf("out of bits %d + %d + %d >= %d\n", mr->ply_bitpos, mr->ply_lngbits, mr->ply_latbits, mr->ply_bitcount);
+                               return ret;
+                       }
+                       c->x=0;
+                       c->y=0;
+                       int x,y;
+                       for (;;) {
+                               x=get_bits(mr,mr->ply_lngbits);
+                               if (debug)
+                                       printf("x %d ", x);
+                               if (mr->ply_lngsign || x != mr->ply_lnglimit)
+                                       break;
+                               c->x += x-1;
+                       }
+                       if (mr->ply_lngsign) {
+                               c->x=x*mr->ply_lngsign;
+                       } else {
+                               if (x >= mr->ply_lnglimit) 
+                                       c->x = x - (mr->ply_lnglimit << 1) - c->x;
+                               else
+                                       c->x +=x;
+                       }
+                       for (;;) {
+                               y=get_bits(mr,mr->ply_latbits);
+                               if (debug)
+                                       printf("y %d ", y);
+                               if (mr->ply_latsign || y != mr->ply_latlimit)
+                                       break;
+                               c->y += y-1;
+                       }
+                       if (mr->ply_latsign) {
+                               c->y=y*mr->ply_latsign;
+                       } else {
+                               if (y >= mr->ply_latlimit) 
+                                       c->y = y - (mr->ply_latlimit << 1) - c->y;
+                               else
+                                       c->y +=y;
+                       }
+                       mr->ply_lng += c->x;
+                       mr->ply_lat += c->y;
+                       }
+                       if (debug)
+                               printf(": x %d y %d\n", c->x, c->y);
+               
+                       c->x=triple(&sub->center.lng)+(mr->ply_lng << shift);
+                       c->y=triple(&sub->center.lat)+(mr->ply_lat << shift);
+               }
+#if 0
+               c->x-=0x6f160;
+                c->y-=0x181f59;
+               c->x+=0x168ca1;
+               c->y+=0x68d815;
+#endif
+               c++;
+               ret++;          
+               if (mr->rgn_type < 2)
+                       return ret;
+       }
+       return ret;
+}
+
+static char * 
+get_label_offset(struct map_rect_priv *mr, int offset)
+{
+       g_assert(offset < mr->lbl_hdr->label.offset_len.length);
+       return file_read(&mr->lbl, mr->lbl_hdr->label.offset_len.offset+offset, 128);
+}
+
+static void
+garmin_img_attr_rewind(void *priv_data)
+{
+}
+
+static int
+garmin_img_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{      
+       struct map_rect_priv *mr=priv_data;
+       int debug=0;
+
+       if (debug)
+               printf("garmin_img_attr_get\n");
+       if (attr_type == attr_label) {
+               if (debug)
+                       printf("garmin_img_attr_get label\n");
+               attr->type=attr_type;
+               if (mr->rgn_type < 2) {
+                       if (mr->label) 
+                               file_free(mr->label);
+                       mr->label=get_label_offset(mr, triple_u(&mr->pnt->lbl_offset) & 0x3fffff);
+                       attr->u.str=mr->label;
+               } else {
+                       attr->u.str="";
+               }
+               return 1;
+       }
+       return 0;
+}
+
+static struct item_methods methods_garmin_img = {
+        garmin_img_coord_rewind,
+        garmin_img_coord_get,
+        garmin_img_attr_rewind,
+        garmin_img_attr_get,
+};
+
+static int rgn_next_type(struct map_rect_priv *mr)
+{
+       while (mr->rgn_type < 3) {
+               mr->rgn_type++;
+               if (mr->rgn_items[mr->rgn_type].offset && mr->rgn_items[mr->rgn_type].length != 0) {
+                       mr->rgn_offset=mr->rgn_items[mr->rgn_type].offset;
+                       mr->rgn_end=mr->rgn_offset+mr->rgn_items[mr->rgn_type].length;
+                       return 0;
+               }
+       }
+       return 1;
+}
+
+static int
+sub_next(struct map_rect_priv *mr, int next)
+{
+       int i,offset,first=-1,last=-1,count=-1;
+       int end;
+       unsigned short *offsets;
+       int debug=0;
+
+       if (mr->subdiv_level_count <= 0)
+               return 1;
+       if (debug)
+               printf("%d left\n", mr->subdiv_level_count);
+       mr->subdiv_level_count--;
+               
+#if 0
+       if (next && mr->subdiv[mr->subdiv_current].width & 0x8000)
+               return 1;
+#endif
+       if (debug) 
+               dump_hex_r(mr->subdiv+mr->subdiv_pos, 64, 14);
+       mr->subdiv_pos+=next;
+       if (debug)
+               printf("subdiv_pos 0x%x\n", mr->subdiv_pos);
+       if (mr->subdiv_pos > mr->tre_hdr->subdivision.length)
+               return 1;
+       struct subdivision *sub=(struct subdivision *)(mr->subdiv+mr->subdiv_pos);
+       offset=triple_u(&sub->rgn_offset)+mr->rgn_hdr->offset_len.offset;
+       if (debug) {
+               printf("offset=0x%x\n", offset);
+               dump_subdivision(sub);
+       }
+       offsets=file_read(&mr->rgn, offset, 3*sizeof(unsigned short));
+
+       if (! next)
+               next=subdiv_next;
+       if (mr->subdiv_pos+next < mr->tre_hdr->subdivision.length) 
+               end=triple_u(&((struct subdivision *)(mr->subdiv+mr->subdiv_pos+next))->rgn_offset)+mr->rgn_hdr->offset_len.offset;
+       else
+               end=mr->rgn_hdr->offset_len.offset+mr->rgn_hdr->offset_len.length;
+       if (debug) {
+               dump_subdivision(sub);
+               dump_hex(offsets, 6);
+       }
+       for (i=0 ; i < 4 ; i++) {
+               if (debug)
+                       printf("i=%d ", i);
+               if (sub->types & (0x10 << i)) {
+                       if (debug)
+                               printf("+ ");
+                       if (first == -1) {
+                               first=i;
+                               mr->rgn_items[i].offset=offset;
+                               if (debug)
+                                       printf("\n");
+                       } else {
+                               mr->rgn_items[i].offset=offset+offsets[count];
+                               if (debug)
+                                       printf("0x%x\n", offsets[count]);
+                               mr->rgn_items[last].length=mr->rgn_items[i].offset-mr->rgn_items[last].offset;
+                       }
+                       last=i;
+                       count++;
+               } else {
+                       if (debug)
+                               printf("-\n");
+                       mr->rgn_items[i].offset=0;
+                       mr->rgn_items[i].length=0;
+               }
+               
+       }
+       if (first != -1) {
+               mr->rgn_items[first].offset+=count*2;
+               mr->rgn_items[first].length-=count*2;
+               mr->rgn_items[last].length=end-mr->rgn_items[last].offset;
+       }
+       if (debug) {
+               for (i=0 ; i < 4 ; i++) {
+                       printf("%d 0x%x 0x%x\n", i, mr->rgn_items[i].offset, mr->rgn_items[i].length);
+               }
+       }
+       mr->rgn_type=-1;
+       rgn_next_type(mr);
+       if (debug)
+               printf("*** offset 0x%x\n", mr->rgn_offset);
+       file_free(offsets);
+       return 0;               
+}
+
+int item_count;
+
+static struct map_rect_priv *
+map_rect_new_garmin_img(struct map_priv *map, struct coord_rect *r, struct layer *layers, int limit)
+{
+       struct map_rect_priv *mr;
+       struct img_header img;
+
+       if (debug)
+               printf("map_rect_new_garmin_img\n");
+       mr=g_new0(struct map_rect_priv, 1);
+       mr->m=map;
+       if (r) 
+               mr->r=*r;
+       mr->limit=limit;
+       mr->item.id_hi=0;
+       mr->item.id_lo=0;
+       mr->item.meth=&methods_garmin_img;
+       mr->item.priv_data=mr;
+       mr->f=fopen(map->filename, "r");
+       
+       fread(&img, sizeof(img), 1, mr->f);
+#if 0
+       dump_img(&img);
+       for (i = 0 ; i < (img.file_offset-sizeof(img))/sizeof(fat_blk) ; i++) {
+               fread(&fat_blk, sizeof(fat_blk), 1, mr->f);
+               if (!fat_blk.flag)
+                       break;
+               dump_fat_block(&fat_blk);
+       }
+#endif
+       mr->rgn.offset=0xa*2048;
+       mr->rgn.f=mr->f;
+       mr->rgn_hdr=file_read(&mr->rgn, 0, sizeof(*mr->rgn_hdr));
+
+       mr->tre.offset=0x62b*2048;
+       mr->tre.f=mr->f;
+       mr->tre_hdr=file_read(&mr->tre, 0, sizeof(*mr->tre_hdr));
+
+       mr->lbl.offset=0x64a*2048;
+       mr->lbl.f=mr->f;
+       mr->lbl_hdr=file_read(&mr->lbl, 0, sizeof(*mr->lbl_hdr));
+
+       mr->subdiv=file_read(&mr->tre, mr->tre_hdr->subdivision.offset, mr->tre_hdr->subdivision.length);
+#if 0
+       dump_hex_r(mr->subdiv, mr->tre_hdr->subdivision.length, 16);
+#endif
+       dump_tree_header(mr->tre_hdr);
+
+       dump_levels(mr);
+
+
+       printf("limit=%d\n", limit);
+       if (limit < 3) {
+               mr->subdiv_pos=0; 
+               mr->subdiv_level_count=1;
+               shift=11;
+       } else if (limit < 6) {
+               mr->subdiv_pos=1*sizeof(struct subdivision); 
+               mr->subdiv_level_count=5;
+               shift=9;
+       } else if (limit < 8) {
+               mr->subdiv_pos=6*sizeof(struct subdivision); 
+               mr->subdiv_level_count=9;
+               shift=7;
+       } else if (limit < 10) {
+               mr->subdiv_pos=15*sizeof(struct subdivision); 
+               mr->subdiv_level_count=143;
+               shift=5;
+       } else {
+               mr->subdiv_pos=158*sizeof(struct subdivision); 
+               mr->subdiv_level_count=4190;
+               shift=2;
+               subdiv_next=14;
+       }
+
+#if 0
+       mr->rgn_offset=triple_u(&mr->subdiv[mr->subdiv_current].rgn_offset)+mr->rgn_hdr->offset_len.offset+4;
+       mr->rgn_type=1;
+       mr->rgn_end=mr->rgn_offset+20*8;
+#endif
+       mr->count=0;
+       item_count=0;
+
+#if 0
+       printf("*** offset 0x%x\n", 0x656c-mr->rgn.offset);
+       printf("*** offset 0x%x\n", mr->rgn_offset);
+#endif
+#if 1
+       sub_next(mr, 0);
+#endif
+#if 0
+       {
+               struct rgn_point *pnt;
+               int i;
+               int offset=0x65cc;
+               for (i = 0 ; i < 26 ; i++) {
+                       pnt=file_read(&mr->rgn, 0x656c+8*i-mr->rgn.offset, sizeof(*pnt));
+                       // dump_hex(pnt, sizeof(*pnt));
+                       dump_point(pnt);
+                       dump_label_offset(mr, triple_u(&pnt->lbl_offset));
+               }
+       }
+       exit(0);
+#endif
+#if 0
+       dump_tree(&mr->tre,&mr->rgn,mr);
+#endif
+
+#if 0
+       f.offset=0x64a*2048;
+       f.f=mr->f;
+       dump_labels(&f);
+#endif
+#if 0
+       fseek(mr->f, img.file_offset, SEEK_SET);
+       fread(&fil, sizeof(fil), 1, mr->f);
+       dump_file(&fil);
+       fread(&rgn, sizeof(rgn), 1, mr->f);
+       dump_region(&rgn);
+       fseek(mr->f, rgn.data_length, SEEK_CUR);
+       fread(&fil, sizeof(fil), 1, mr->f);
+       dump_file(&fil);
+#endif
+       return mr;
+}
+
+
+static void
+map_rect_destroy_garmin_img(struct map_rect_priv *mr)
+{
+       fclose(mr->f);
+        g_free(mr);
+}
+
+
+static struct item *
+map_rect_get_item_garmin_img(struct map_rect_priv *mr)
+{
+       char *p,type[256];
+       int ptype;
+       int debug=0;
+
+       item_count++;
+
+       if (debug)
+               printf("map_rect_get_item_garmin_img\n");
+       for (;;) {
+               if (mr->rgn_offset < mr->rgn_end) {
+                       if (debug)
+                               printf("data available\n");
+                       if (mr->rgn_type >= 2) {
+                               int len;
+                               if (debug)
+                                       printf("polyline %d\n", mr->count);
+                               if (mr->ply)
+                                       file_free(mr->ply);
+                               mr->ply=file_read(&mr->rgn, mr->rgn_offset, sizeof(*mr->ply)*3);
+                               if(triple_u(&mr->ply->lbl_offset) >= mr->lbl_hdr->label.offset_len.length) {
+                                       printf("item_count %d\n", item_count);
+                                       dump_poly(mr->ply);
+                                       dump_hex(mr->ply, 32);
+                                       printf("%d vs %d\n", triple_u(&mr->ply->lbl_offset), mr->lbl_hdr->label.offset_len.length);
+                               }
+                               g_assert(triple_u(&mr->ply->lbl_offset) < mr->lbl_hdr->label.offset_len.length);
+                               if (debug) {
+                                       dump_hex(mr->ply, 16);
+                                       dump_poly(mr->ply);
+                               }
+                               if (mr->ply_data)
+                                       file_free(mr->ply_data);
+                               mr->rgn_offset+=10;
+                               if (mr->ply->info & 0x80) {
+                                       mr->rgn_offset++;
+                                       len=mr->ply->u.p2.bitstream_len;
+                               } else
+                                       len=mr->ply->u.p1.bitstream_len;
+               
+                               mr->ply_data=file_read(&mr->rgn, mr->rgn_offset, len);
+                               mr->rgn_offset += len;
+                               mr->ply_bitpos=0;
+                               // dump_hex(mr->ply_data, 32);
+                               if (mr->rgn_type == 3) {
+                                       switch(mr->ply->info & 0x7f) {
+                                       case 0x1:       /* large urban area (>200k) */
+                                               mr->item.type=type_town_poly;
+                                               break;
+                                       case 0xd:       /* reservation */
+                                               mr->item.type=type_park_poly;
+                                               break;
+                                       case 0xe:       /* airport runway */
+                                               mr->item.type=type_airport_poly;
+                                               break;
+                                       case 0x14:      /* national park */
+                                               mr->item.type=type_park_poly;
+                                               break;
+                                       case 0x32:      /* sea */
+                                       case 0x3d:      /* large lake (77-250km2) */
+                                       case 0x4c:      /* intermittend water */
+                                               mr->item.type=type_water_poly;
+                                               break;
+                                       case 0x4b:      /* background */
+                                               continue;
+                                       default:
+                                               printf("unknown polygon: 0x%x\n", mr->ply->info);
+                                               mr->item.type=type_street_3_city;
+                                       }
+                               } else {
+                                       switch(mr->ply->info & 0x3f) {
+                                       case 0x1:       /* major highway */
+                                               mr->item.type=type_highway_land;
+                                               break;
+                                       case 0x2:       /* principal highway */
+                                               mr->item.type=type_street_3_land;
+                                               break;
+                                       case 0x6:       /* residental street */
+                                               mr->item.type=type_street_2_land;
+                                               break;
+                                       case 0x16:      /* walkway/trail */
+                                               mr->item.type=type_street_1_land;
+                                               break;
+                                       case 0x1e:      /* international boundary */
+                                               mr->item.type=type_border_country;
+                                               break;
+                                       case 0x20:      /* minor land contour 1/10 */
+                                               mr->item.type=type_height_line_1;
+                                               break;
+                                       case 0x21:      /* major land contour 1/2 */
+                                               mr->item.type=type_height_line_2;
+                                               break;
+                                       default:
+                                               printf("unknown polyline: 0x%x\n", mr->ply->info);
+                                               mr->item.type=type_street_3_city;
+                                       }
+                               }
+                               return &mr->item;
+                       } 
+                       if (mr->pnt)
+                               file_free(mr->pnt);
+                       mr->pnt=file_read(&mr->rgn, mr->rgn_offset, sizeof(*mr->pnt));
+                       mr->item.type=type_none;
+                       int subtype=mr->pnt->subtype;
+                       if (mr->pnt->lbl_offset.data[2] & 0x80) 
+                               mr->rgn_offset+=9;
+                       else {
+                               mr->rgn_offset+=8;
+                               subtype=0;
+                       }
+                       switch(mr->pnt->info) {
+                       case 0x3:       /* large city 2-5M */
+                               mr->item.type=type_town_label_2e6;
+                               break;
+                       case 0xa:       /* small city/town 10-20k */
+                               mr->item.type=type_town_label_1e4;
+                               break;
+                       case 0xd:       /* settlement 1-2K  */
+                               mr->item.type=type_town_label_1e3;
+                               break;
+                       case 0x11:      /* settlement less 100 */
+                               mr->item.type=type_town_label_5e1;
+                               break;
+                       case 0x1c:
+                               switch(subtype) {
+                               case 0x01:
+                                       mr->item.type=type_poi_wreck;
+                                       break;
+                               }
+                               break;
+                       case 0x20:
+                               mr->item.type=type_highway_exit;
+                               break;
+                       case 0x25:
+                               mr->item.type=type_poi_toll_booth;
+                               break;
+                       case 0x2b:
+                               switch(subtype) {
+                               case 0x01:
+                                       mr->item.type=type_poi_hotel;
+                                       break;
+                               case 0x03:
+                                       mr->item.type=type_poi_camp_rv;
+                                       break;
+                               }
+                               break;
+                       case 0x2c:
+                               switch(subtype) {
+                               case 0x00:
+                                       mr->item.type=type_poi_attraction;
+                                       break;
+                               case 0x02:
+                                       mr->item.type=type_poi_museum_history;
+                                       break;
+                               }
+                               break;
+                       case 0x2e:
+                               mr->item.type=type_poi_shopping;
+                               break;
+                       case 0x2f:
+                               switch(subtype) {
+                               case 0x01:
+                                       mr->item.type=type_poi_fuel;
+                                       break;
+                               case 0x07:
+                                       mr->item.type=type_poi_car_dealer_parts;
+                                       break;
+                               case 0x0b:
+                                       mr->item.type=type_poi_car_parking;
+                                       break;
+                               case 0x15:
+                                       mr->item.type=type_poi_public_utilities;
+                                       break;
+                               }
+                               break;
+                       case 0x30:
+                               switch(subtype) {
+                               case 0x02:
+                                       mr->item.type=type_poi_hospital;
+                                       break;
+                               }
+                               break;
+                       case 0x43:
+                               mr->item.type=type_poi_marina;
+                               break;
+                       case 0x46:
+                               mr->item.type=type_poi_bar;
+                               break;
+                       case 0x48:
+                               mr->item.type=type_poi_camping;
+                               break;
+                       case 0x49:
+                               mr->item.type=type_poi_park;
+                               break;
+                       case 0x4a:
+                               mr->item.type=type_poi_picnic;
+                               break;
+                       case 0x59:      /* airport */
+                               mr->item.type=type_poi_airport;
+                               break;
+                       case 0x64:
+                               switch(subtype) {
+                               case 0x1:
+                                       mr->item.type=type_poi_bridge;
+                                       break;
+                               case 0x2:
+                                       mr->item.type=type_poi_building;
+                                       break;
+                               case 0x15:
+                                       mr->item.type=type_town_ghost;
+                                       break;
+                               }
+                               break;
+                       case 0x65:
+                               switch(subtype) {
+                               case 0x0:
+                                       mr->item.type=type_poi_water_feature;
+                                       break;
+                               case 0xc:
+                                       mr->item.type=type_poi_island;
+                                       break;
+                               case 0xd:
+                                       mr->item.type=type_poi_lake;
+                                       break;
+                               }
+                               break;
+                       case 0x66:
+                               switch(subtype) {
+                               case 0x0:
+                                       mr->item.type=type_poi_land_feature;
+                                       break;
+                               case 0x6:
+                                       mr->item.type=type_poi_cape;
+                                       break;
+                               case 0x14:
+                                       mr->item.type=type_poi_rock;
+                                       break;
+                               }
+                               break;
+                       }
+                       if (mr->item.type == type_none) {
+                               printf("unknown point: 0x%x 0x%x\n", mr->pnt->info, mr->pnt->subtype);
+                               dump_point(mr->pnt);
+                               printf("label: %s\n", get_label_offset(mr, triple_u(&mr->pnt->lbl_offset) & 0x3fffff));
+                               mr->item.type=type_town_label;
+                       }
+                       return &mr->item;
+               }
+               if (debug)
+                       printf("out of data for type\n");
+               if (rgn_next_type(mr)) {
+                       if (debug)
+                               printf("out of data for region\n");
+                       if (sub_next(mr, subdiv_next)) {
+                               if (debug)
+                                       printf("out of data for subdivision\n");
+                               return NULL;
+                       }
+               }
+       }
+}
+
+static struct item *
+map_rect_get_item_byid_garmin_img(struct map_rect_priv *mr, int id_hi, int id_lo)
+{
+       fseek(mr->f, id_lo, SEEK_SET);
+       get_line(mr);
+       mr->item.id_hi=id_hi;
+       return map_rect_get_item_garmin_img(mr);
+}
+
+static struct map_methods map_methods_garmin_img = {
+       projection_garmin,
+       "iso8859-1",
+       map_destroy_garmin_img,
+       map_charset_garmin_img,
+       map_projection_garmin_img,
+       map_rect_new_garmin_img,
+       map_rect_destroy_garmin_img,
+       map_rect_get_item_garmin_img,
+       map_rect_get_item_byid_garmin_img,
+};
+
+static struct map_priv *
+map_new_garmin_img(struct map_methods *meth, struct attr **attrs)
+{
+       struct map_priv *m;
+       struct attr *data=attr_search(attrs, NULL, attr_data);
+       if (! data)
+               return NULL;
+
+       *meth=map_methods_garmin_img;
+       m=g_new(struct map_priv, 1);
+       m->id=++map_id;
+       m->filename=g_strdup(data->u.str);
+       return m;
+}
+
+void
+plugin_init(void)
+{
+       plugin_register_map_type("garmin_img", map_new_garmin_img);
+}
+
diff --git a/navit/map/mg/Makefile.am b/navit/map/mg/Makefile.am
new file mode 100644 (file)
index 0000000..e408e6b
--- /dev/null
@@ -0,0 +1,8 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/navit -DMODULE=map_mg
+if PLUGINS
+  modulemap_LTLIBRARIES = libmap_mg.la
+else
+  noinst_LTLIBRARIES = libmap_mg.la
+endif
+libmap_mg_la_SOURCES = map.c block.c town.c tree.c poly.c street.c mg.h
diff --git a/navit/map/mg/block.c b/navit/map/mg/block.c
new file mode 100644 (file)
index 0000000..e22440a
--- /dev/null
@@ -0,0 +1,286 @@
+/**
+ * Navit, a modular navigation system.
+ * Copyright (C) 2005-2008 Navit Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "debug.h"
+#include "mg.h"
+
+
+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;
+};
+
+struct block_index {
+       unsigned int blocks;
+        unsigned int size;
+        unsigned int next;      
+       struct block_index_item list[0];
+};
+
+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;
+
+
+       blk_idx=(struct block_index *)(file->begin+0x1000);
+       max=(blk_idx->size-sizeof(struct block_index))/sizeof(struct block_index_item);
+       block_mem+=24;
+       while (id >= max) {
+               blk_idx=(struct block_index *)(file->begin+blk_idx->next*512);
+               id-=max;
+       }
+       blk_num=blk_idx->list[id].blocknum;
+
+       *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(1,"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+blk->b->size;
+
+       return 1;
+}
+
+static void
+block_setup_tags(struct map_rect_priv *mr)
+{
+       int len;
+       unsigned char *p,*t;
+       char *str;
+
+       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;
+       }
+}
+
+#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);
+}
+#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);
+}
+
+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)
+{
+       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+mr->b.b->blocks*512;
+               if (mr->b.p >= mr->file->end) {
+                       dbg(1,"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+mr->b.b->size;
+               if (mr->b.b->count == -1) {
+                       dbg(1,"empty blocks\n");
+                       return 0;
+               }
+               if (!mr->cur_sel || coord_rect_overlap(&mr->cur_sel->u.c_rect, &mr->b.b->r)) {
+                       block_active_count++;
+                       block_active_mem+=mr->b.b->blocks*512-sizeof(struct block *);
+                       dbg(1,"block ok\n");
+                       return 1;
+               }
+               dbg(2,"block not in cur_sel\n");
+       }
+}
+
+int
+block_next(struct map_rect_priv *mr)
+{
+       int blk_num,coord,r_h,r_w;
+       struct block_bt_priv *bt=&mr->b.bt;
+
+       if (!mr->b.binarytree || ! mr->cur_sel)
+               return block_next_lin(mr);
+       for (;;) {
+               if (! bt->p) {
+                       dbg(1,"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+mr->b.bt.b->size;
+                       bt->next=bt->b->next;
+                       bt->order=0;
+                       dbg(1,"size 0x%x next 0x%x\n", bt->b->size, bt->b->next);
+                       if (! mr->b.bt.block_count) {
+#if 0
+                               if (debug) {
+                                       printf("idx rect ");
+                                       block_rect_print(&mr->b.bt.b->r);
+                               }
+#endif
+                               bt->r=bt->b->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(1,"%p vs %p coord 0x%x ", mr->b.bt.end, mr->b.bt.p, coord);
+                       dbg(1,"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+mr->b.b->size;
+                                       block_rect_same(&mr->b.b->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+=mr->b.b->blocks*512;
+                               return 1;
+                       }
+               }
+               bt->p=NULL;
+       }       
+       return 0;
+}
diff --git a/navit/map/mg/map.c b/navit/map/mg/map.c
new file mode 100644 (file)
index 0000000..7e5f895
--- /dev/null
@@ -0,0 +1,514 @@
+/**
+ * Navit, a modular navigation system.
+ * Copyright (C) 2005-2008 Navit Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "config.h"
+#include "debug.h"
+#include "plugin.h"
+#include "maptype.h"
+#include "mg.h"
+
+
+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},
+};
+
+struct map_priv * map_new_mg(struct map_methods *meth, struct attr **attrs);
+
+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",
+};
+
+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_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;
+}
+
+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 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 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]);
+       }
+}
+
+extern int block_lin_count,block_idx_count,block_active_count,block_mem,block_active_mem;
+
+static 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;
+}
+
+
+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(1,"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_byid_mg(struct map_rect_priv *mr, int id_hi, int id_lo)
+{
+       mr->current_file = id_hi >> 16;
+       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;
+       default:        
+               if (poly_get_byid(mr, &mr->poly, id_hi, id_lo, &mr->item))
+                       return &mr->item;
+               break;
+       }
+       return NULL;
+}
+
+
+static 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(1,"0x%x\n", *str);
+                       *c++=*str;
+                       break;
+               }
+               if (! *str)
+                       return ret;
+               str++;
+       }
+}
+
+
+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);
+       char *prefix;
+       dbg(1,"id_lo=0x%x\n", item->id_lo);
+       dbg(1,"search=%s\n", search->u.str);
+       mr->m=map;
+       mr->search_type=search->type;
+
+       /*
+     * NOTE: If you implement search for other attributes than attr_town_postal, attr_town_name and attr_street_name,
+     * please update this comment and the documentation for map_search_new() in map.c
+     */
+
+       switch (search->type) {
+       case attr_town_postal:
+               if (item->type != type_country_label)
+                       return NULL;
+               prefix=mg_country_postal_prefix(item->id_lo);
+               if (! prefix)
+                       return NULL;
+               tree_search_init(map->dirname, "town.b1", &mr->ts, 0);
+               mr->current_file=file_town_twn;
+               mr->search_str=g_strdup_printf("%s%s",prefix,search->u.str);
+               dbg(0,"search_str='%s'\n",mr->search_str);
+               mr->search_country=mg_country_from_isonum(item->id_lo);
+               break;
+       case attr_town_name:
+               if (item->type != type_country_label)
+                       return NULL;
+               tree_search_init(map->dirname, "town.b2", &mr->ts, 0x1000);
+               mr->current_file=file_town_twn;
+               mr->search_str=map_search_mg_convert_special(search->u.str);
+               mr->search_country=mg_country_from_isonum(item->id_lo);
+               break;
+       case attr_street_name:
+               if (item->type != type_town_streets)
+                       return NULL;
+               dbg(1,"street_assoc=0x%x\n", item->id_lo);
+               tree_search_init(map->dirname, "strname.b1", &mr->ts, 0);
+               mr->current_file=file_strname_stn;
+               mr->search_str=g_strdup(search->u.str);
+               break;
+       default:
+               dbg(0,"unknown search\n");
+               g_free(mr);
+               return NULL;
+       }
+       mr->search_item=*item;
+       mr->search_partial=partial;
+       mr->file=mr->m->file[mr->current_file];
+       block_init(mr);
+       return (struct map_search_priv *)mr;
+}
+
+static void
+map_search_destroy_mg(struct map_search_priv *ms)
+{
+       struct map_rect_priv *mr=(struct map_rect_priv *)ms;
+
+       dbg(1,"mr=%p\n", mr);
+       if (! mr)
+               return;
+       g_free(mr->search_str);
+       tree_search_free(&mr->ts);
+       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;
+
+       if (! mr)
+               return NULL;
+       switch (mr->search_type) {
+       case attr_town_postal:
+       case attr_town_name:
+               return town_search_get_item(mr);
+       case attr_street_name:
+               return street_search_get_item(mr);
+       default:
+               return NULL;
+       }
+}
+
+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,
+};
+
+struct map_priv *
+map_new_mg(struct map_methods *meth, struct attr **attrs)
+{
+       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);
+                       if (! m->file[i]) {
+                               maybe_missing=(i == file_border_ply || i == file_height_ply || i == file_sea_ply);
+                               if (! maybe_missing)
+                                       dbg(0,"Failed to load %s\n", filename);
+                       } else
+                               file_mmap(m->file[i]);
+                       g_free(filename);
+               }
+       }
+
+       return m;
+}
+
+void
+plugin_init(void)
+{
+       plugin_register_map_type("mg", map_new_mg);
+}
diff --git a/navit/map/mg/mg.h b/navit/map/mg/mg.h
new file mode 100644 (file)
index 0000000..302b65f
--- /dev/null
@@ -0,0 +1,314 @@
+/**
+ * Navit, a modular navigation system.
+ * Copyright (C) 2005-2008 Navit Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <glib.h>
+#include "item.h"
+#include "attr.h"
+#include "coord.h"
+#include "data.h"
+#include "projection.h"
+#include "map.h"
+#include "file.h"
+
+struct block_data {
+       struct file *file;
+};
+
+struct block {
+       int blocks;
+       int size;
+       int next;
+       struct coord_rect r;
+       int count;
+};
+
+struct item_priv {
+       int cidx;
+       int aidx;
+       unsigned char *cstart,*cp,*cend;
+       unsigned char *astart,*ap,*aend;
+       enum attr_type attr_last;
+       enum attr_type attr_next;
+       struct item item;
+};
+
+struct town_priv {
+       unsigned int id; /*!< Identifier */
+       struct coord c; /*!< Coordinates */
+       char *name; /*!< Name */
+       char *district; /*!< District */
+       char *postal_code1; /*!< Postal code */
+       unsigned char order; /*!< Order (Importance) */
+       unsigned char type; /*!< Type */
+       unsigned short country; /*!< Country */
+       unsigned int unknown2; /*!< Unknown */
+       unsigned char size; /*!< Size of town */
+       unsigned int street_assoc; /*!< Association to streets */
+       unsigned char unknown3; /*!< Unknown */
+       char *postal_code2; /*!< 2nd postal code */
+       unsigned int unknown4; /*!< Unknown */
+
+       int cidx;
+       int aidx;
+       enum attr_type attr_next;
+       char debug[256];
+       char postal[32];
+       struct item town_attr_item;
+};
+
+struct poly_priv {
+       int poly_num;
+       unsigned char *poly_next;
+       int subpoly_num;
+       int subpoly_num_all;
+       unsigned char *subpoly_next;
+       unsigned char *subpoly_start;
+       unsigned char *p;
+       struct coord c[2];
+       char *name;
+       unsigned char order;
+       unsigned char type;
+       unsigned int polys;
+       unsigned int *count;
+       unsigned int count_sum;
+
+       int aidx;
+       enum attr_type attr_next;
+};
+
+struct street_header {
+        unsigned char order;
+        int count;
+} __attribute__((packed));
+
+struct street_type {
+        unsigned char order;
+        unsigned short country;
+} __attribute__((packed));
+
+struct street_header_type {
+       struct street_header *header;
+       int type_count;
+       struct street_type *type;
+};
+
+struct street_str {
+        int segid;
+        unsigned char limit;            /* 0x03,0x30=One Way,0x33=No Passing */
+        unsigned char unknown2;
+        unsigned char unknown3;
+        unsigned char type;
+        unsigned int nameid;
+};
+
+struct street_name_segment {
+       int segid;
+       int country;
+};
+
+struct street_name {
+       int len;
+       int country;
+       int townassoc;
+       char *name1;
+       char *name2;
+       int segment_count;
+       struct street_name_segment *segments;
+       int aux_len;
+       unsigned char *aux_data;
+       int tmp_len;
+       unsigned char *tmp_data;
+};
+
+struct street_name_numbers {
+       int len;
+       int tag;
+       int dist;
+       int country;
+       struct coord *c;
+       int first;
+       int last;
+       int segment_count;
+       struct street_name_segment *segments;
+       int aux_len;
+       unsigned char *aux_data;
+       int tmp_len;
+       unsigned char *tmp_data;
+};
+
+struct street_name_number {
+        int len;
+        int tag;
+        struct coord *c;
+        int first;
+        int last;
+        struct street_name_segment *segment;
+};
+
+
+
+struct street_priv {
+       struct file *name_file;
+       struct street_header *header;
+       int type_count;
+       struct street_type *type;
+       struct street_str *str;
+       struct street_str *str_start;
+       unsigned char *coord_begin;
+       unsigned char *p;
+       unsigned char *p_rewind;
+       unsigned char *end;
+       unsigned char *next;
+       int status;
+       int status_rewind;
+       struct coord *ref;
+       int bytes;
+       int more;
+       struct street_name name;
+       enum attr_type attr_next;
+       char debug[256];
+};
+
+enum file_index {
+        file_border_ply=0,
+        file_bridge_ply,
+       file_build_ply,
+       file_golf_ply,
+        file_height_ply,
+       file_natpark_ply,
+       file_nature_ply,
+        file_other_ply,
+        file_rail_ply,
+        file_sea_ply,
+        file_street_bti,
+        file_street_str,
+        file_strname_stn,
+        file_town_twn,
+        file_tunnel_ply,
+        file_water_ply,
+        file_woodland_ply,
+        file_end
+};
+
+struct map_priv {
+       int id;
+       struct file *file[file_end];
+       char *dirname;
+};
+
+#define BT_STACK_SIZE 32
+
+struct block_bt_priv {
+       struct block *b;
+       struct coord_rect r, r_curr;
+       int next;
+       int block_count;
+       struct coord_rect stack[BT_STACK_SIZE];
+       int stackp;
+       int order;
+       unsigned char *p;
+       unsigned char *end;
+};
+
+struct block_priv {
+       int block_num;
+       struct coord_rect b_rect;
+       unsigned char *block_start;
+       struct block *b;
+       unsigned char *p;
+       unsigned char *end;
+       unsigned char *p_start;
+       int binarytree;
+       struct block_bt_priv bt;
+};
+
+struct block_offset {
+       unsigned short offset;
+       unsigned short block;
+};
+
+
+struct tree_search_node {
+       struct tree_hdr *hdr;
+       unsigned char *p;
+       unsigned char *last;
+       unsigned char *end;
+       int low;
+       int high;
+       int last_low;
+       int last_high;
+       };
+
+struct tree_search {
+       struct file *f;
+       int last_node;
+       int curr_node;
+       struct tree_search_node nodes[5];
+};
+
+
+struct map_rect_priv {
+       struct map_selection *xsel;
+       struct map_selection *cur_sel;
+
+       struct map_priv *m;
+       enum file_index current_file;
+       struct file *file;
+       struct block_priv b;
+       struct item item;
+       struct town_priv town;
+       struct poly_priv poly;
+       struct street_priv street;
+       struct tree_search ts;
+       int search_country;
+       struct item search_item;
+       char *search_str;
+       int search_partial;
+       int search_linear;
+       unsigned char *search_p;
+       int search_blk_count;
+       enum attr_type search_type;
+       struct block_offset *search_blk_off;
+       int search_block;
+       GHashTable *block_hash[file_end];
+       struct item_priv item3;
+};
+
+int mg_country_from_isonum(int isonum);
+int mg_country_to_isonum(int country);
+int mg_country_postal_len(int country);
+
+int block_init(struct map_rect_priv *mr);
+int block_next(struct map_rect_priv *mr);
+int block_get_byindex(struct file *file, int idx, struct block_priv *blk);
+int block_next_lin(struct map_rect_priv *mr);
+
+int tree_search_hv(char *dirname, char *filename, unsigned int search1, unsigned int search2, int *result);
+int town_get(struct map_rect_priv *mr, struct town_priv *poly, struct item *item);
+int town_get_byid(struct map_rect_priv *mr, struct town_priv *twn, int id_hi, int id_lo, struct item *item);
+struct item * town_search_get_item(struct map_rect_priv *mr);
+int poly_get(struct map_rect_priv *mr, struct poly_priv *poly, struct item *item);
+int poly_get_byid(struct map_rect_priv *mr, struct poly_priv *poly, int id_hi, int id_lo, struct item *item);
+int street_get(struct map_rect_priv *mr, struct street_priv *street, struct item *item);
+int street_get_byid(struct map_rect_priv *mr, struct street_priv *street, int id_hi, int id_lo, struct item *item);
+struct item * street_search_get_item(struct map_rect_priv *mr);
+void tree_search_init(char *dirname, char *filename, struct tree_search *ts, int offset);
+void tree_search_free(struct tree_search *ts);
+int tree_search_next(struct tree_search *ts, unsigned char **p, int dir);
+int tree_search_next_lin(struct tree_search *ts, unsigned char **p);
diff --git a/navit/map/mg/poly.c b/navit/map/mg/poly.c
new file mode 100644 (file)
index 0000000..2618a89
--- /dev/null
@@ -0,0 +1,265 @@
+/**
+ * Navit, a modular navigation system.
+ * Copyright (C) 2005-2008 Navit Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <string.h>
+#include "debug.h"
+#include "mg.h"
+
+static void
+poly_coord_rewind(void *priv_data)
+{
+       struct poly_priv *poly=priv_data;
+
+       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 void 
+poly_attr_rewind(void *priv_data)
+{
+       struct poly_priv *poly=priv_data;
+
+       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;
+
+       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,
+};
+
+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 >= mr->b.b->count)
+                       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(0,"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(1,"%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(1,"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_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
new file mode 100644 (file)
index 0000000..284ad6f
--- /dev/null
@@ -0,0 +1,775 @@
+/**
+ * Navit, a modular navigation system.
+ * Copyright (C) 2005-2008 Navit Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "debug.h"
+#include "mg.h"
+
+int coord_debug;
+
+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 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=get_u24(p);
+       name_numbers->last=get_u24(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 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=get_u24(p);
+        name_number->last=get_u24(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 *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[0].x+x;
+               f->y=ref[1].y+y;
+       }
+       dbg(1,"0x%x,0x%x + 0x%x,0x%x = 0x%x,0x%x\n", x, y, ref[0].x, ref[1].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 (L(str->segid)) {
+               str++;
+       }
+       (*p)=(unsigned char *)str;
+       (*p)+=4;
+}
+
+
+static void
+street_coord_rewind(void *priv_data)
+{
+       /* struct street_priv *street=priv_data; */
+
+}
+
+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;
+
+       if (! street->p && count) {
+               street->p=street->coord_begin;
+               scount=street->str-street->str_start;
+               for (i = 0 ; i < scount ; i++) {
+                       street->status=L(street->str[i+1].segid) >= 0 ? 0:1;
+                       while (street_coord_get_helper(street, c));
+                       street->p=street->next;
+               }
+               street->status_rewind=street->status=L(street->str[1].segid) >= 0 ? 0:1;
+       }
+       while (count > 0) {
+               if (street_coord_get_helper(street, c)) {
+                       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(1,"segid 0x%x\n", L(street->str->segid));
+       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=L(street->str->nameid);
+               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=L(street->str->nameid);
+               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=L(street->str->nameid);
+               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:
+               if (street->str->type & 0x40) {
+                       attr->u.num=(street->str->limit & 0x30) ? AF_ONEWAYREV:0;
+                       attr->u.num|=(street->str->limit & 0x03) ? AF_ONEWAY:0;
+               } else {
+                       attr->u.num=(street->str->limit & 0x30) ? AF_ONEWAY:0;
+                       attr->u.num|=(street->str->limit & 0x03) ? AF_ONEWAYREV:0;
+               }
+               street->attr_next=attr_country_id;
+               return 1;
+       case attr_country_id:
+               street->attr_next=attr_debug;
+               nameid=L(street->str->nameid);
+               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->order,str->segid,str->limit,str->unknown2,str->unknown3,str->type,str->nameid, 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,
+};
+
+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->count;
+       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)
+{      
+       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->order > limit[mr->cur_sel->order])
+                               return 0;
+                       street->end=mr->b.end;
+                       street->ref=&mr->b.b->r.lu;
+                       street->bytes=street_get_bytes(&mr->b.b->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 (! L(street->str->segid))
+                       return 0;
+               if (L(street->str->segid) < 0)
+                       street->type++;
+#if 0
+               dbg_assert(street->p != NULL);
+#endif
+               street->next=NULL;
+               street->status_rewind=street->status=L(street->str[1].segid) >= 0 ? 0:1;
+#if 0
+               if (street->type->country != 0x31) {
+                       printf("country=0x%x\n", street->type->country);
+               }
+#endif
+               item->id_hi=street->type->country | (mr->current_file << 16);
+               item->id_lo=L(street->str->segid) > 0 ? L(street->str->segid) : -L(street->str->segid);
+               switch(street->str->type & 0x1f) {
+               case 0xf: /* very small street */
+                       if (street->str->limit == 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->limit == 0x03 || street->str->limit == 0x30) && street->header->order < 4)
+                               item->type=type_street_4_city;
+                       else    
+                               item->type=type_street_3_city;
+                       break;
+               case 0x9:
+                       if (street->header->order < 5)
+                               item->type=type_street_4_city;
+                       else if (street->header->order < 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->limit == 0x03 || street->str->limit == 0x30) && street->header->order < 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(0,"unknown type 0x%x\n",street->str->type);
+               }
+#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;
+               if (!map_selection_contains_item(mr->cur_sel, 0, item->type)) 
+                       continue;
+               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;
+       dbg(1,"enter(%p,%p,0x%x,0x%x,%p)\n", mr, street, id_hi, id_lo, item);
+       if (! country)
+               return 0;
+        tree_search_hv(mr->m->dirname, "street", (id_lo >> 8) | (country << 24), id_lo & 0xff, &res);
+       dbg(1,"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;
+       street->ref=&mr->b.b->r.lu;
+       street->bytes=street_get_bytes(&mr->b.b->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(1,"segid 0x%x\n", L(street->str[1].segid));
+       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;
+}
+     
+
+struct street_name_index {
+       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 == 0xd6 || c == 0xdc)
+               return c+0x20;
+       return c;
+}
+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
+street_search_compare_do(struct map_rect_priv *mr, int country, int town_assoc, char *name)
+{
+        int d;
+
+       dbg(1,"enter");
+       dbg(1,"country 0x%x town_assoc 0x%x name '%s'\n", country, town_assoc, name);
+       d=(mr->search_item.id_hi & 0xffff)-country;
+       dbg(1,"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(1,"town_assoc match (0x%x)\n", town_assoc);
+                       if (mr->search_partial)
+                               d=strncasecmp_latin1(mr->search_str, name, strlen(mr->search_str));
+                       else
+                               d=strncasecmp_latin1(mr->search_str, name, INT_MAX);
+                       dbg(1,"string %d\n", d);
+               } else {
+                       if (town_assoc < mr->search_item.id_lo)
+                               d=1;
+                       else
+                               d=-1;
+                       dbg(1,"assoc %d 0x%x-0x%x\n",d, mr->search_item.id_lo, town_assoc);
+               }
+       }
+       dbg(1,"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(1,"enter\n");
+       i=(struct street_name_index *)(*p);
+       *p+=sizeof(*i)+strlen(i->name)+1;
+
+       dbg(1,"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_numbers_coord_rewind(void *priv_data)
+{
+       /* struct street_priv *street=priv_data; */
+
+}
+
+static void
+street_name_numbers_attr_rewind(void *priv_data)
+{
+       /* struct street_priv *street=priv_data; */
+
+}
+
+static int
+street_name_numbers_coord_get(void *priv_data, struct coord *c, int count)
+{
+       return 0;
+}
+
+static int
+street_name_numbers_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{
+       attr->type=attr_type;
+       switch (attr_type) {
+       default:
+               dbg(0,"unknown item\n");
+               return 0;
+       }
+}
+
+
+
+
+
+static struct item_methods street_name_numbers_meth = {
+       street_name_numbers_coord_rewind,
+       street_name_numbers_coord_get,
+       street_name_numbers_attr_rewind,
+       street_name_numbers_attr_get,
+};
+
+
+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(1,"aux_data=%p\n", p);
+       if (count) {
+               street_name_numbers_get(&snns, &p);
+               *c=*(snns.c);
+               return 1;
+       }
+       
+       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;
+       struct item *item;
+
+       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_street_name_numbers_item:
+               item=&mr->item3.item;
+               attr->u.item=item;
+               item->type=type_street_name_numbers;
+               item->id_hi=0;
+               item->id_lo=1;
+               item->meth=&street_name_numbers_meth;
+               item->map=NULL;
+               item->priv_data=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);
+                                       printf("  last %d\n", nns.last);
+                                       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);
+                                               printf("    last %d\n", nn.last);
+                                       }
+                               }
+                       }
+               }
+               return 1;
+       default:
+               dbg(0,"unknown item\n");
+               return 0;
+       }
+}
+
+
+
+
+
+static struct item_methods street_name_meth = {
+       street_name_coord_rewind,
+       street_name_coord_get,
+       street_name_attr_rewind,
+       street_name_attr_get,
+};
+
+
+struct item *
+street_search_get_item(struct map_rect_priv *mr)
+{
+       int dir=1,leaf;
+       unsigned char *last;
+
+       dbg(1,"enter\n");
+       if (! mr->search_blk_count) {
+               dbg(1,"partial 0x%x '%s' ***\n", mr->town.street_assoc, mr->search_str);
+               if (mr->search_linear)
+                       return NULL;
+               dbg(1,"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(1,"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(1,"name id 0x%x\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(1,"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(1,"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(1,"end of data\n");
+                               mr->search_blk_count=0;
+                               return NULL;
+                       }
+                       if (!dir) {
+                               dbg(1,"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=mr->street.name.country | (mr->current_file << 16) | 0x10000000;
+                               mr->item.id_lo=last-mr->m->file[mr->current_file]->begin;
+                               mr->item.meth=&street_name_meth;
+                               mr->item.map=NULL;
+                               mr->item.priv_data=mr;
+                               return &mr->item;
+                       }
+               }
+       }
+}
diff --git a/navit/map/mg/town.c b/navit/map/mg/town.c
new file mode 100644 (file)
index 0000000..aedf34a
--- /dev/null
@@ -0,0 +1,285 @@
+/**
+ * Navit, a modular navigation system.
+ * Copyright (C) 2005-2008 Navit Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "debug.h"
+#include "mg.h"
+
+
+
+static void
+town_coord_rewind(void *priv_data)
+{
+       struct town_priv *twn=priv_data;
+
+       twn->cidx=0;
+}
+
+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;
+}
+
+static void
+town_attr_rewind(void *priv_data)
+{
+       struct town_priv *twn=priv_data;
+
+       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;
+
+       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:
+               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_assert(1==0);
+               return 0;
+       }
+       return 1;
+}
+
+static struct item_methods town_meth = {
+       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
+}
+                            /*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;
+                       }
+               }
+       }
+}
+
+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;
+
+       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(1,"country 0x%x ", country);
+               name=get_string(p);
+               dbg(1,"name '%s' ",name);
+               mr->search_blk_count=get_u32_unal(p);
+               mr->search_blk_off=(struct block_offset *)(*p);
+               dbg(1,"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(1,"%d \n",d);
+       return d;
+
+}
+
+
+
+struct item *
+town_search_get_item(struct map_rect_priv *mr)
+{
+       int dir=1,leaf;
+
+       if (! mr->search_blk_count) {
+               dbg(1,"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 && leaf) {
+                                       mr->search_linear=1;
+                                       mr->search_p=NULL;
+                                       break;
+                               }
+                       }
+                       if (! mr->search_linear) {
+                               dbg(1,"not found\n");
+                               return NULL;
+                       }
+               }
+               if (! tree_search_next_lin(&mr->ts, &mr->search_p)) {
+                       dbg(1,"linear not found\n");
+                       return NULL;
+               }
+               if (town_search_compare(&mr->search_p, mr)) {
+                       dbg(1,"no match\n");
+                       return NULL;
+               }
+               dbg(1,"found %d blocks\n",mr->search_blk_count);
+       }
+       if (! mr->search_blk_count)
+               return NULL;
+       dbg(1,"block 0x%x offset 0x%x\n", mr->search_blk_off->block, mr->search_blk_off->offset);
+       block_get_byindex(mr->m->file[mr->current_file], mr->search_blk_off->block, &mr->b);
+       mr->b.p=mr->b.block_start+mr->search_blk_off->offset;
+       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
new file mode 100644 (file)
index 0000000..695b401
--- /dev/null
@@ -0,0 +1,263 @@
+/**
+ * Navit, a modular navigation system.
+ * Copyright (C) 2005-2008 Navit Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include "debug.h"
+#include "mg.h"
+
+struct tree_hdr {
+       unsigned int addr;
+       unsigned int size;
+       unsigned int low;
+};
+
+struct tree_hdr_h {
+       unsigned int addr;
+       unsigned int size;
+};
+
+struct tree_leaf_h {
+       unsigned int lower;
+       unsigned int higher;
+       unsigned int match;
+       unsigned int value;
+};
+
+
+struct tree_hdr_v {
+       unsigned int count;
+       unsigned int next;
+       unsigned int unknown;
+};
+
+struct tree_leaf_v {
+       unsigned char key;
+       int value;
+} __attribute__((packed));
+
+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(1,"enter\n");
+       while (i++ < 1000) {
+               thdr=(struct tree_hdr_h *)p;
+               p+=sizeof(*thdr);
+               end=p+thdr->size;
+               dbg(1,"@0x%x\n", p-file->begin);
+               last=0;
+               while (p < end) {
+                       tleaf=(struct tree_leaf_h *)p;
+                       p+=sizeof(*tleaf);
+                       dbg(1,"low:0x%x high:0x%x match:0x%x val:0x%x search:0x%x\n", tleaf->lower, tleaf->higher, tleaf->match, tleaf->value, search);
+                       value=tleaf->value;
+                       if (value == search)
+                               return tleaf->match;
+                       if (value > search) {
+                               dbg(1,"lower\n");
+                               lower=tleaf->lower;
+                               if (lower)
+                                       last=lower;
+                               break;
+                       }
+                       last=tleaf->higher;
+               }
+               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=L(thdr->count);
+               dbg(1,"offset=0x%x count=0x%x\n", p-file->begin, count);
+               while (count--) {
+                       tleaf=(struct tree_leaf_v *)p;
+                       p+=sizeof(*tleaf);
+                       dbg(1,"0x%x 0x%x\n", tleaf->key, search);
+                       if (tleaf->key == search)
+                               return L(tleaf->value);
+               }
+               next=L(thdr->next);
+               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;
+
+       dbg(1,"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);
+       if (! f_idx_h)
+               return 0;
+       file_mmap(f_idx_h);     
+       sprintf(buffer, "%s/%s.v1", dirname, filename);
+       f_idx_v=file_create_caseinsensitive(buffer);
+       dbg(1,"%p %p\n", f_idx_h, f_idx_v);
+       if (! f_idx_v) {
+               file_destroy(f_idx_h);
+               return 0;
+       }
+       file_mmap(f_idx_v);
+       if ((h=tree_search_h(f_idx_h, search_h))) {
+               dbg(1,"h=0x%x\n", h);
+               if ((v=tree_search_v(f_idx_v, h, search_v))) {
+                       dbg(1,"v=0x%x\n", v);
+                       *result=v;
+                       file_destroy(f_idx_v);
+                       file_destroy(f_idx_h);
+                       dbg(1,"return 1\n");
+                       return 1;
+               }
+       }
+       file_destroy(f_idx_v);
+       file_destroy(f_idx_h);
+       dbg(1,"return 0\n");
+       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+tsn->hdr->size;
+       tsn->low=tsn->hdr->low;
+       tsn->high=tsn->hdr->low;
+       dbg(1,"pos 0x%x addr 0x%x size 0x%x low 0x%x end 0x%x\n", p-ts->f->begin, tsn->hdr->addr, tsn->hdr->size, tsn->hdr->low, 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];
+
+       if (! *p) 
+               *p=tsn->p;
+       dbg(1,"next *p=%p dir=%d\n", *p, dir);
+       dbg(1,"low1=0x%x high1=0x%x\n", tsn->low, tsn->high);
+       if (dir <= 0) {
+               dbg(1,"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(1,"saving last2 %d 0x%x\n", ts->curr_node, tsn->last-ts->f->begin);
+                       dbg(1,"high2=0x%x\n", tsn->high);
+                       return 0;
+               }
+               return -1;
+       }
+       tsn->low=tsn->high;
+       tsn->last=*p;
+       tsn->high=get_u32_unal(p);
+       dbg(1,"saving last3 %d %p\n", ts->curr_node, tsn->last);
+       if (*p < tsn->end)
+               return (tsn->low == 0xffffffff ? 1 : 0);
+       dbg(1,"end reached high=0x%x\n",tsn->high);
+       if (tsn->low != 0xffffffff) {
+               dbg(1,"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(1,"saving last4 %d 0x%x\n", ts->curr_node, tsn->last-ts->f->begin);
+               dbg(1,"high4=0x%x\n", 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(1,"pos=%d 0x%x\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(1,"reload %d\n",ts->curr_node);
+                               high=tsn->low;
+                       }
+                       return 1;
+               }
+               dbg(1,"eon %d 0x%x 0x%x\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;
+       }
+
+       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);
+       ts->curr_node=-1;
+       if (ts->f) {
+               file_mmap(ts->f);
+               tree_search_enter(ts, offset);
+       }
+}
+
+void
+tree_search_free(struct tree_search *ts)
+{
+       file_destroy(ts->f);
+}
diff --git a/navit/map/poi_geodownload/Makefile.am b/navit/map/poi_geodownload/Makefile.am
new file mode 100644 (file)
index 0000000..f2d6680
--- /dev/null
@@ -0,0 +1,6 @@
+SUBDIRS=libmdb
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/navit -I$(srcdir)/libmdb/include -DMODULE=map_poi_geodownload
+modulemap_LTLIBRARIES = libmap_poi_geodownload.la
+libmap_poi_geodownload_la_SOURCES = poi_geodownload.c
+libmap_poi_geodownload_la_LIBADD = -Llibmdb -lmdb
diff --git a/navit/map/poi_geodownload/libmdb/Makefile.am b/navit/map/poi_geodownload/libmdb/Makefile.am
new file mode 100644 (file)
index 0000000..e2e440b
--- /dev/null
@@ -0,0 +1,4 @@
+SUBDIRS=include
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(srcdir)/include
+noinst_LTLIBRARIES = libmdb.la
+libmdb_la_SOURCES=backend.c catalog.c data.c dump.c file.c iconv.c index.c kkd.c like.c map.c mem.c money.c options.c props.c sargs.c stats.c table.c worktable.c write.c
diff --git a/navit/map/poi_geodownload/libmdb/backend.c b/navit/map/poi_geodownload/libmdb/backend.c
new file mode 100644 (file)
index 0000000..902805c
--- /dev/null
@@ -0,0 +1,301 @@
+/* MDB Tools - A library for reading MS Access database files
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+** functions to deal with different backend database engines
+*/
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+static int is_init;
+static GHashTable *mdb_backends;
+
+   /*    Access data types */
+static MdbBackendType mdb_access_types[] = {
+               {"Unknown 0x00", 0,0,0 },
+               {"Boolean", 0,0,0},
+               {"Byte", 0,0,0},
+               {"Integer", 0,0,0},
+               {"Long Integer", 0,0,0},
+               {"Currency", 0,0,0},
+               {"Single", 0,0,0},
+               {"Double", 0,0,0},
+               {"DateTime (Short)", 0,0,1},
+               {"Unknown 0x09", 0,0,0},
+               {"Text", 1,0,1},
+               {"OLE", 1,0,1},
+               {"Memo/Hyperlink",1,0,1},
+               {"Unknown 0x0d",0,0,0},
+               {"Unknown 0x0e",0,0,0},
+               {"Replication ID",0,0,0},
+               {"Numeric",1,1,0}
+};
+
+/*    Oracle data types */
+static MdbBackendType mdb_oracle_types[] = {
+               {"Oracle_Unknown 0x00",0,0,0},
+               {"NUMBER",1,0,0},
+               {"NUMBER",1,0,0},
+               {"NUMBER",1,0,0},
+               {"NUMBER",1,0,0},
+               {"NUMBER",1,0,0},
+               {"FLOAT",0,0,0},
+               {"FLOAT",0,0,0},
+               {"DATE",0,0,0},
+               {"Oracle_Unknown 0x09",0,0,0},
+               {"VARCHAR2",1,0,1},
+               {"BLOB",1,0,1},
+               {"CLOB",1,0,1},
+               {"Oracle_Unknown 0x0d",0,0,0},
+               {"Oracle_Unknown 0x0e",0,0,0},
+               {"NUMBER",1,0,0},
+               {"NUMBER",1,0,0},
+};
+
+/*    Sybase/MSSQL data types */
+static MdbBackendType mdb_sybase_types[] = {
+               {"Sybase_Unknown 0x00",0,0,0},
+               {"bit",0,0,0},
+               {"char",1,0,1},
+               {"smallint",0,0,0},
+               {"int",0,0,0},
+               {"money",0,0,0},
+               {"real",0,0,0},
+               {"float",0,0,0},
+               {"smalldatetime",0,0,0},
+               {"Sybase_Unknown 0x09",0,0,0},
+               {"varchar",1,0,1},
+               {"varbinary",1,0,1},
+               {"text",1,0,1},
+               {"Sybase_Unknown 0x0d",0,0,0},
+               {"Sybase_Unknown 0x0e",0,0,0},
+               {"Sybase_Replication ID",0,0,0},
+               {"numeric",1,1,0},
+};
+
+/*    Postgres data types */
+static MdbBackendType mdb_postgres_types[] = {
+               {"Postgres_Unknown 0x00",0,0,0},
+               {"Bool",0,0,0},
+               {"Int2",0,0,0},
+               {"Int4",0,0,0},
+               {"Int8",0,0,0},
+               {"Money",0,0,0},
+               {"Float4",0,0,0},
+               {"Float8",0,0,0},
+               {"Timestamp",0,0,0},
+               {"Postgres_Unknown 0x09",0,0,0},
+               {"Char",1,0,1},
+               {"Postgres_Unknown 0x0b",0,0,0},
+               {"Postgres_Unknown 0x0c",0,0,0},
+               {"Postgres_Unknown 0x0d",0,0,0},
+               {"Postgres_Unknown 0x0e",0,0,0},
+               {"Serial",0,0,0},
+               {"Postgres_Unknown 0x10",0,0,0},
+};
+/*    MySQL data types */
+static MdbBackendType mdb_mysql_types[] = {
+               {"Text",1,0,1},
+               {"char",0,0,0},
+               {"int",0,0,0},
+               {"int",0,0,0},
+               {"int",0,0,0},
+               {"float",0,0,0},
+               {"float",0,0,0},
+               {"float",0,0,0},
+               {"date",0,0,1},
+               {"varchar",1,0,1},
+               {"varchar",1,0,1},
+               {"varchar",1,0,1},
+               {"text",1,0,1},
+               {"blob",0,0,0},
+               {"text",1,0,1},
+               {"numeric",1,1,0},
+               {"numeric",1,1,0},
+};
+
+static gboolean mdb_drop_backend(gpointer key, gpointer value, gpointer data);
+
+char *mdb_get_coltype_string(MdbBackend *backend, int col_type)
+{
+       static char buf[16];
+
+       if (col_type > 0x10 ) {
+               // return NULL;
+               snprintf(buf,sizeof(buf), "type %04x", col_type);
+               return buf;
+       } else {
+               return backend->types_table[col_type].name;
+       }
+}
+
+int mdb_coltype_takes_length(MdbBackend *backend, int col_type)
+{
+       return backend->types_table[col_type].needs_length;
+}
+
+/**
+ * mdb_init_backends
+ *
+ * Initializes the mdb_backends hash and loads the builtin backends.
+ * Use mdb_remove_backends() to destroy this hash when done.
+ */
+void mdb_init_backends(void)
+{
+       mdb_backends = g_hash_table_new(g_str_hash, g_str_equal);
+
+       mdb_register_backend(mdb_access_types, "access");
+       mdb_register_backend(mdb_sybase_types, "sybase");
+       mdb_register_backend(mdb_oracle_types, "oracle");
+       mdb_register_backend(mdb_postgres_types, "postgres");
+       mdb_register_backend(mdb_mysql_types, "mysql");
+}
+void mdb_register_backend(MdbBackendType *backend_type, char *backend_name)
+{
+       MdbBackend *backend = (MdbBackend *) g_malloc0(sizeof(MdbBackend));
+       backend->types_table = backend_type;
+       g_hash_table_insert(mdb_backends, backend_name, backend);
+}
+
+/**
+ * mdb_remove_backends
+ *
+ * Removes all entries from and destroys the mdb_backends hash.
+ */
+void mdb_remove_backends(void)
+{
+       g_hash_table_foreach_remove(mdb_backends, mdb_drop_backend, NULL);
+       g_hash_table_destroy(mdb_backends);
+}
+static gboolean mdb_drop_backend(gpointer key, gpointer value, gpointer data)
+{
+       MdbBackend *backend = (MdbBackend *)value;
+       g_free (backend);
+       return TRUE;
+}
+
+/**
+ * mdb_set_default_backend
+ * @mdb: Handle to open MDB database file
+ * @backend_name: Name of the backend to set as default
+ *
+ * Sets the default backend of the handle @mdb to @backend_name.
+ *
+ * Returns: 1 if successful, 0 if unsuccessful.
+ */
+int mdb_set_default_backend(MdbHandle *mdb, char *backend_name)
+{
+       MdbBackend *backend;
+
+       backend = (MdbBackend *) g_hash_table_lookup(mdb_backends, backend_name);
+       if (backend) {
+               mdb->default_backend = backend;
+               mdb->backend_name = (char *) g_strdup(backend_name);
+               is_init = 0;
+               return 1;
+       } else {
+               return 0;
+       }
+}
+
+/**
+ * mdb_get_relationships
+ * @mdb: Handle to open MDB database file
+ *
+ * Generates relationships by reading the MSysRelationships table.
+ *   'szColumn' contains the column name of the child table.
+ *   'szObject' contains the table name of the child table.
+ *   'szReferencedColumn' contains the column name of the parent table.
+ *   'szReferencedObject' contains the table name of the parent table.
+ *
+ * Returns: a string stating that relationships are not supported for the
+ *   selected backend, or a string containing SQL commands for setting up
+ *   the relationship, tailored for the selected backend.  The caller is
+ *   responsible for freeing this string.
+ */
+char *mdb_get_relationships(MdbHandle *mdb)
+{
+       unsigned int i;
+       gchar *text = NULL;  /* String to be returned */
+       static char *bound[4];  /* Bound values */
+       static MdbTableDef *table;  /* Relationships table */
+       int backend = 0;  /* Backends: 1=oracle */
+
+       if (strncmp(mdb->backend_name,"oracle",6) == 0) {
+               backend = 1;
+       } else {
+               if (is_init == 0) { /* the first time through */
+                       is_init = 1;
+                       return (char *) g_strconcat(
+                               "-- relationships are not supported for ",
+                               mdb->backend_name, NULL);
+               } else { /* the second time through */
+                       is_init = 0;
+                       return NULL;
+               }
+       }
+
+       if (is_init == 0) {
+               table = mdb_read_table_by_name(mdb, "MSysRelationships", MDB_TABLE);
+               if ((!table) || (table->num_rows == 0)) {
+                       return NULL;
+               }
+
+               mdb_read_columns(table);
+               for (i=0;i<4;i++) {
+                       bound[i] = (char *) g_malloc0(MDB_BIND_SIZE);
+               }
+               mdb_bind_column_by_name(table, "szColumn", bound[0]);
+               mdb_bind_column_by_name(table, "szObject", bound[1]);
+               mdb_bind_column_by_name(table, "szReferencedColumn", bound[2]);
+               mdb_bind_column_by_name(table, "szReferencedObject", bound[3]);
+               mdb_rewind_table(table);
+
+               is_init = 1;
+       }
+       else if (table->cur_row >= table->num_rows) {  /* past the last row */
+               for (i=0;i<4;i++)
+                       g_free(bound[i]);
+               is_init = 0;
+               return NULL;
+       }
+
+       if (!mdb_fetch_row(table)) {
+               for (i=0;i<4;i++)
+                       g_free(bound[i]);
+               is_init = 0;
+               return NULL;
+       }
+
+       switch (backend) {
+         case 1:  /* oracle */
+               text = g_strconcat("alter table ", bound[1],
+                       " add constraint ", bound[3], "_", bound[1],
+                       " foreign key (", bound[0], ")"
+                       " references ", bound[3], "(", bound[2], ")", NULL);
+               break;
+       }
+
+       return (char *)text;
+}
+
diff --git a/navit/map/poi_geodownload/libmdb/catalog.c b/navit/map/poi_geodownload/libmdb/catalog.c
new file mode 100644 (file)
index 0000000..dc08abd
--- /dev/null
@@ -0,0 +1,138 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+char *
+mdb_get_objtype_string(int obj_type)
+{
+static char *type_name[] = {"Form",
+                       "Table",
+                       "Macro",
+                       "System Table",
+                       "Report",
+                       "Query",
+                       "Linked Table",
+                       "Module",
+                       "Relationship",
+                       "Unknown 0x09",
+                       "Unknown 0x0a",
+                       "Database"
+               };
+
+       if (obj_type > 11) {
+               return NULL;
+       } else {
+               return type_name[obj_type]; 
+       }
+}
+
+void mdb_free_catalog(MdbHandle *mdb)
+{
+       unsigned int i;
+
+       if (!mdb->catalog) return;
+       for (i=0; i<mdb->catalog->len; i++)
+               g_free (g_ptr_array_index(mdb->catalog, i));
+       g_ptr_array_free(mdb->catalog, TRUE);
+       mdb->catalog = NULL;
+}
+
+GPtrArray *mdb_read_catalog (MdbHandle *mdb, int objtype)
+{
+       MdbCatalogEntry *entry, msysobj;
+       MdbTableDef *table;
+       char obj_id[256];
+       char obj_name[256];
+       char obj_type[256];
+       char obj_flags[256];
+       int type;
+
+       if (mdb->catalog) mdb_free_catalog(mdb);
+       mdb->catalog = g_ptr_array_new();
+       mdb->num_catalog = 0;
+
+       /* dummy up a catalog entry so we may read the table def */
+       memset(&msysobj, 0, sizeof(MdbCatalogEntry));
+       msysobj.mdb = mdb;
+       msysobj.object_type = MDB_TABLE;
+       msysobj.table_pg = 2;
+       strcpy(msysobj.object_name, "MSysObjects");
+
+       /* mdb_table_dump(&msysobj); */
+
+       table = mdb_read_table(&msysobj);
+       if (!table) return NULL;
+
+       mdb_read_columns(table);
+
+       mdb_bind_column_by_name(table, "Id", obj_id);
+       mdb_bind_column_by_name(table, "Name", obj_name);
+       mdb_bind_column_by_name(table, "Type", obj_type);
+       mdb_bind_column_by_name(table, "Flags", obj_flags);
+
+       mdb_rewind_table(table);
+
+       while (mdb_fetch_row(table)) {
+               type = atoi(obj_type);
+               if (objtype==MDB_ANY || type == objtype) {
+                       // fprintf(stdout, "obj_id: %10ld objtype: %-3d obj_name: %s\n", 
+                       // (atol(obj_id) & 0x00FFFFFF), type, obj_name); 
+                       entry = (MdbCatalogEntry *) g_malloc0(sizeof(MdbCatalogEntry));
+                       entry->mdb = mdb;
+                       strcpy(entry->object_name, obj_name);
+                       entry->object_type = (type & 0x7F);
+                       entry->table_pg = atol(obj_id) & 0x00FFFFFF;
+                       entry->flags = atol(obj_flags);
+                       mdb->num_catalog++;
+                       g_ptr_array_add(mdb->catalog, entry); 
+               }
+       }
+       //mdb_dump_catalog(mdb, MDB_TABLE);
+       mdb_free_tabledef(table);
+
+       return mdb->catalog;
+}
+
+void 
+mdb_dump_catalog(MdbHandle *mdb, int obj_type)
+{
+       unsigned int i;
+       MdbCatalogEntry *entry;
+
+       mdb_read_catalog(mdb, obj_type);
+       for (i=0;i<mdb->num_catalog;i++) {
+                entry = g_ptr_array_index(mdb->catalog,i);
+               if (obj_type==MDB_ANY || entry->object_type==obj_type) {
+                       fprintf(stdout,"Type: %-10s Name: %-18s T pg: %04x KKD pg: %04x row: %2d\n",
+                       mdb_get_objtype_string(entry->object_type),
+                       entry->object_name,
+                       (unsigned int) entry->table_pg,
+                       (unsigned int) entry->kkd_pg,
+                       entry->kkd_rowid);
+               }
+        }
+       return;
+}
+
diff --git a/navit/map/poi_geodownload/libmdb/data.c b/navit/map/poi_geodownload/libmdb/data.c
new file mode 100644 (file)
index 0000000..e50e57d
--- /dev/null
@@ -0,0 +1,856 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+#include "time.h"
+#include "math.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+#define OFFSET_MASK 0x1fff
+
+char *mdb_money_to_string(MdbHandle *mdb, int start, char *s);
+static int _mdb_attempt_bind(MdbHandle *mdb, 
+       MdbColumn *col, unsigned char isnull, int offset, int len);
+static char *mdb_num_to_string(MdbHandle *mdb, int start, int datatype, int prec, int scale);
+int mdb_copy_ole(MdbHandle *mdb, char *dest, int start, int size);
+
+static char date_fmt[64] = "%x %X";
+
+void mdb_set_date_fmt(const char *fmt)
+{
+               date_fmt[63] = 0; 
+               strncpy(date_fmt, fmt, 63);
+}
+
+void mdb_bind_column(MdbTableDef *table, int col_num, void *bind_ptr)
+{
+MdbColumn *col;
+
+       /* 
+       ** the column arrary is 0 based, so decrement to get 1 based parameter 
+       */
+       col=g_ptr_array_index(table->columns, col_num - 1);
+       col->bind_ptr = bind_ptr;
+}
+int
+mdb_bind_column_by_name(MdbTableDef *table, gchar *col_name, void *bind_ptr)
+{
+       unsigned int i;
+       int col_num = -1;
+       MdbColumn *col;
+       
+       for (i=0;i<table->num_cols;i++) {
+               col=g_ptr_array_index(table->columns,i);
+               if (!strcmp(col->name,col_name)) {
+                       col_num = col->col_num + 1;
+                       mdb_bind_column(table, col_num, bind_ptr);
+                       break;
+               }
+       }
+
+       return col_num;
+}
+void mdb_bind_len(MdbTableDef *table, int col_num, int *len_ptr)
+{
+MdbColumn *col;
+
+       col=g_ptr_array_index(table->columns, col_num - 1);
+       col->len_ptr = len_ptr;
+}
+
+/**
+ * mdb_find_pg_row
+ * @mdb: Database file handle
+ * @pg_row: Lower byte contains the row number, the upper three contain page
+ * @buf: Pointer for returning a pointer to the page
+ * @off: Pointer for returning an offset to the row
+ * @len: Pointer for returning the length of the row
+ * 
+ * Returns: 0 on success.  1 on failure.
+ */
+int mdb_find_pg_row(MdbHandle *mdb, int pg_row, char **buf, int *off, int *len)
+{
+       unsigned int pg = pg_row >> 8;
+       unsigned int row = pg_row & 0xff;
+
+       if (mdb_read_alt_pg(mdb, pg) != mdb->fmt->pg_size)
+               return 1;
+       mdb_swap_pgbuf(mdb);
+       *off = mdb_pg_get_int16(mdb, mdb->fmt->row_count_offset + 2 + (row*2));
+       *len = mdb_find_end_of_row(mdb, row) - *off + 1;
+       mdb_swap_pgbuf(mdb);
+       *buf = mdb->alt_pg_buf;
+       return 0;
+}
+
+int 
+mdb_find_end_of_row(MdbHandle *mdb, int row)
+{
+       MdbFormatConstants *fmt = mdb->fmt;
+       int row_end;
+
+       /* Search the previous "row start" values for the first non-'lookupflag' one.
+       * If we don't find one, then the end of the page is the correct value.
+       */
+#if 1
+       if (row==0) {
+               row_end = fmt->pg_size - 1;
+       } else {
+               row_end = (mdb_pg_get_int16(mdb, ((fmt->row_count_offset + 2) + (row - 1) * 2)) & OFFSET_MASK) - 1;
+       }
+       return row_end;
+#else
+               int i, row_start;
+
+               /* if lookupflag is     not set, it's good (deleteflag is ok) */
+        for (i = row - 1; i >= 0; i--) {
+                row_start = mdb_pg_get_int16(mdb, ((fmt->row_count_offset + 2) + i * 2));
+                if (!(row_start & 0x8000)) {
+                        break;
+                }
+        }
+
+        if (i == -1) {
+                row_end = fmt->pg_size - 1;
+        } else {
+                row_end = (row_start & OFFSET_MASK) - 1;
+        }
+       return row_end;
+#endif
+}
+int mdb_is_null(unsigned char *null_mask, int col_num)
+{
+int byte_num = (col_num - 1) / 8;
+int bit_num = (col_num - 1) % 8;
+
+       if ((1 << bit_num) & null_mask[byte_num]) {
+               return 0;
+       } else {
+               return 1;
+       }
+}
+/* bool has to be handled specially because it uses the null bit to store its 
+** value*/
+static int 
+mdb_xfer_bound_bool(MdbHandle *mdb, MdbColumn *col, int value)
+{
+       
+       col->cur_value_len = value;
+       if (col->bind_ptr) {
+               strcpy(col->bind_ptr,  value ? "0" : "1");
+       }
+
+       return 0;
+}
+static int mdb_xfer_bound_ole(MdbHandle *mdb, int start, MdbColumn *col, int len)
+{
+       int ret = 0;
+       if (len) {
+               col->cur_value_start = start;
+               col->cur_value_len = len;
+       } else {
+               col->cur_value_start = 0;
+               col->cur_value_len = 0;
+       }
+       if (col->bind_ptr || col->len_ptr) {
+               //ret = mdb_copy_ole(mdb, col->bind_ptr, start, len);
+               memcpy(col->bind_ptr, &mdb->pg_buf[start], MDB_MEMO_OVERHEAD);
+       }
+       if (col->len_ptr) {
+               *col->len_ptr = MDB_MEMO_OVERHEAD;
+       }
+       return ret;
+}
+static int mdb_xfer_bound_data(MdbHandle *mdb, int start, MdbColumn *col, int len)
+{
+int ret;
+       //if (!strcmp("Name",col->name)) {
+               //printf("start %d %d\n",start, len);
+       //}
+       if (len) {
+               col->cur_value_start = start;
+               col->cur_value_len = len;
+       } else {
+               col->cur_value_start = 0;
+               col->cur_value_len = 0;
+       }
+       if (col->bind_ptr) {
+               if (!len) {
+                       strcpy(col->bind_ptr, "");
+               } else if (col->col_type == MDB_NUMERIC) {
+                       //fprintf(stdout,"len %d size %d\n",len, col->col_size);
+                       char *str = mdb_num_to_string(mdb, start, col->col_type,
+                               col->col_prec, col->col_scale);
+                       strcpy(col->bind_ptr, str);
+                       g_free(str);
+               } else {
+                       //fprintf(stdout,"len %d size %d\n",len, col->col_size);
+                       char *str = mdb_col_to_string(mdb, mdb->pg_buf, start,
+                               col->col_type, len);
+                       strcpy(col->bind_ptr, str);
+                       
+               }
+               ret = strlen(col->bind_ptr);
+               if (col->len_ptr) {
+                       *col->len_ptr = ret;
+               }
+               return ret;
+       }
+       return 0;
+}
+int mdb_read_row(MdbTableDef *table, unsigned int row)
+{
+       MdbHandle *mdb = table->entry->mdb;
+       MdbFormatConstants *fmt = mdb->fmt;
+       MdbColumn *col;
+       unsigned int i;
+       int rc;
+       int row_start, row_end;
+       int delflag, lookupflag;
+       MdbField fields[256];
+       int num_fields;
+
+       if (table->num_rows <= row) 
+               return 0;
+
+       row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (row*2)); 
+       row_end = mdb_find_end_of_row(mdb, row);
+
+       delflag = lookupflag = 0;
+       if (row_start & 0x8000) lookupflag++;
+       if (row_start & 0x4000) delflag++;
+       row_start &= OFFSET_MASK; /* remove flags */
+#if MDB_DEBUG
+       fprintf(stdout,"Row %d bytes %d to %d %s %s\n", 
+               row, row_start, row_end,
+               lookupflag ? "[lookup]" : "",
+               delflag ? "[delflag]" : "");
+#endif 
+
+       if (!table->noskip_del && delflag) {
+               row_end = row_start-1;
+               return 0;
+       }
+
+       num_fields = mdb_crack_row(table, row_start, row_end, fields);
+       if (!mdb_test_sargs(table, fields, num_fields)) return 0;
+       
+#if MDB_DEBUG
+       fprintf(stdout,"sarg test passed row %d \n", row);
+#endif 
+
+#if MDB_DEBUG
+       buffer_dump(mdb->pg_buf, row_start, row_end);
+#endif
+
+       /* take advantage of mdb_crack_row() to clean up binding */
+       /* use num_cols instead of num_fields -- bsb 03/04/02 */
+       for (i = 0; i < table->num_cols; i++) {
+               col = g_ptr_array_index(table->columns,fields[i].colnum);
+               rc = _mdb_attempt_bind(mdb, col, fields[i].is_null,
+                       fields[i].start, fields[i].siz);
+       }
+
+       return 1;
+}
+static int _mdb_attempt_bind(MdbHandle *mdb, 
+       MdbColumn *col, 
+       unsigned char isnull, 
+       int offset, 
+       int len)
+{
+       if (col->col_type == MDB_BOOL) {
+               mdb_xfer_bound_bool(mdb, col, isnull);
+       } else if (isnull) {
+               mdb_xfer_bound_data(mdb, 0, col, 0);
+       } else if (col->col_type == MDB_OLE) {
+               mdb_xfer_bound_ole(mdb, offset, col, len);
+       } else {
+               //if (!mdb_test_sargs(mdb, col, offset, len)) {
+                       //return 0;
+               //}
+               mdb_xfer_bound_data(mdb, offset, col, len);
+       }
+       return 1;
+}
+int mdb_read_next_dpg(MdbTableDef *table)
+{
+       MdbCatalogEntry *entry = table->entry;
+       MdbHandle *mdb = entry->mdb;
+       int next_pg;
+
+#ifndef SLOW_READ
+       next_pg = mdb_map_find_next(mdb, table->usage_map,
+               table->map_sz, table->cur_phys_pg);
+
+       if (next_pg >= 0) {
+               if (mdb_read_pg(mdb, next_pg)) {
+                       table->cur_phys_pg = next_pg;
+                       return table->cur_phys_pg;
+               } else {
+                       return 0;
+               }
+       }
+       fprintf(stderr, "Warning: defaulting to brute force read\n");
+#endif 
+       /* can't do a fast read, go back to the old way */
+       do {
+               if (!mdb_read_pg(mdb, table->cur_phys_pg++))
+                       return 0;
+       } while (mdb->pg_buf[0]!=0x01 || mdb_pg_get_int32(mdb, 4)!=entry->table_pg);
+       /* fprintf(stderr,"returning new page %ld\n", table->cur_phys_pg); */
+       return table->cur_phys_pg;
+}
+int mdb_rewind_table(MdbTableDef *table)
+{
+       table->cur_pg_num=0;
+       table->cur_phys_pg=0;
+       table->cur_row=0;
+
+       return 0;
+}
+int 
+mdb_fetch_row(MdbTableDef *table)
+{
+       MdbHandle *mdb = table->entry->mdb;
+       MdbFormatConstants *fmt = mdb->fmt;
+       unsigned int rows;
+       int rc;
+       guint32 pg;
+
+       if (table->num_rows==0)
+               return 0;
+
+       /* initialize */
+       if (!table->cur_pg_num) {
+               table->cur_pg_num=1;
+               table->cur_row=0;
+               if ((!table->is_temp_table)&&(table->strategy!=MDB_INDEX_SCAN))
+                       if (!mdb_read_next_dpg(table)) return 0;
+       }
+
+       do {
+               if (table->is_temp_table) {
+                       GPtrArray *pages = table->temp_table_pages;
+                       rows = mdb_get_int16(
+                               g_ptr_array_index(pages, table->cur_pg_num-1),
+                               fmt->row_count_offset);
+                       if (table->cur_row >= rows) {
+                               table->cur_row = 0;
+                               table->cur_pg_num++;
+                               if (table->cur_pg_num > pages->len)
+                                       return 0;
+                       }
+                       memcpy(mdb->pg_buf,
+                               g_ptr_array_index(pages, table->cur_pg_num-1),
+                               fmt->pg_size);
+               } else if (table->strategy==MDB_INDEX_SCAN) {
+               
+                       if (!mdb_index_find_next(table->mdbidx, table->scan_idx, table->chain, &pg, (guint16 *) &(table->cur_row))) {
+                               mdb_index_scan_free(table);
+                               return 0;
+                       }
+                       mdb_read_pg(mdb, pg);
+               } else {
+                       rows = mdb_pg_get_int16(mdb,fmt->row_count_offset);
+
+                       /* if at end of page, find a new page */
+                       if (table->cur_row >= rows) {
+                               table->cur_row=0;
+       
+                               if (!mdb_read_next_dpg(table)) {
+                                       return 0;
+                               }
+                       }
+               }
+
+               /* printf("page %d row %d\n",table->cur_phys_pg, table->cur_row); */
+               rc = mdb_read_row(table, table->cur_row);
+               table->cur_row++;
+       } while (!rc);
+
+       return 1;
+}
+void mdb_data_dump(MdbTableDef *table)
+{
+       unsigned int i;
+       char *bound_values[MDB_MAX_COLS]; 
+
+       for (i=0;i<table->num_cols;i++) {
+               bound_values[i] = (char *) g_malloc(256);
+               mdb_bind_column(table, i+1, bound_values[i]);
+       }
+       mdb_rewind_table(table);
+       while (mdb_fetch_row(table)) {
+               for (i=0;i<table->num_cols;i++) {
+                       fprintf(stdout, "column %d is %s\n", i+1, bound_values[i]);
+               }
+       }
+       for (i=0;i<table->num_cols;i++) {
+               g_free(bound_values[i]);
+       }
+}
+
+int mdb_is_fixed_col(MdbColumn *col)
+{
+       return col->is_fixed;
+}
+#if 0
+static char *mdb_data_to_hex(MdbHandle *mdb, char *text, int start, int size) 
+{
+int i;
+
+       for (i=start; i<start+size; i++) {
+               sprintf(&text[(i-start)*2],"%02x", mdb->pg_buf[i]);
+       }
+       text[(i-start)*2]='\0';
+
+       return text;
+}
+#endif
+int 
+mdb_ole_read_next(MdbHandle *mdb, MdbColumn *col, void *ole_ptr)
+{
+       guint16 ole_len;
+       guint16 ole_flags;
+       char *buf;
+       int pg_row, row_start;
+       int len;
+
+       ole_len = mdb_get_int16(ole_ptr, 0);
+       ole_flags = mdb_get_int16(ole_ptr, 2);
+
+       if (ole_flags == 0x8000) {
+               /* inline fields don't have a next */
+               return 0;
+       } else if (ole_flags == 0x4000) {
+               /* 0x4000 flagged ole's are contained on one page and thus 
+                * should be handled entirely with mdb_ole_read() */
+               return 0;
+       } else if (ole_flags == 0x0000) {
+               pg_row = (col->cur_blob_pg << 8) & col->cur_blob_row;
+               if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) {
+                       return 0;
+               }
+               if (col->bind_ptr)
+                       memcpy(col->bind_ptr, buf + row_start, len);
+               pg_row = mdb_get_int32(buf, row_start);
+               col->cur_blob_pg = pg_row >> 8;
+               col->cur_blob_row = pg_row & 0xff;
+
+               return len;
+       }
+       return 0;
+}
+int 
+mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, int chunk_size)
+{
+       guint16 ole_len;
+       guint16 ole_flags;
+       char *buf;
+       int pg_row, row_start;
+       int len;
+
+       ole_len = mdb_get_int16(ole_ptr, 0);
+       ole_flags = mdb_get_int16(ole_ptr, 2);
+       mdb_debug(MDB_DEBUG_OLE,"ole len = %d ole flags = %08x",
+               ole_len, ole_flags);
+
+       col->chunk_size = chunk_size;
+
+       if (ole_flags == 0x8000) {
+               /* inline ole field, if we can satisfy it, then do it */
+               len = col->cur_value_len - MDB_MEMO_OVERHEAD;
+               if (chunk_size >= len) {
+                       if (col->bind_ptr) 
+                               memcpy(col->bind_ptr, 
+                                       &mdb->pg_buf[col->cur_value_start + 
+                                               MDB_MEMO_OVERHEAD],
+                                       len);
+                       return len;
+               } else {
+                       return 0;
+               }
+       } else if (ole_flags == 0x4000) {
+               pg_row = mdb_get_int32(ole_ptr, 4);
+               col->cur_blob_pg = pg_row >> 8;
+               col->cur_blob_row = pg_row & 0xff;
+               mdb_debug(MDB_DEBUG_OLE,"ole row = %d ole pg = %ld",
+                       col->cur_blob_row, col->cur_blob_pg);
+
+               if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) {
+                       return 0;
+               }
+               mdb_debug(MDB_DEBUG_OLE,"start %d len %d", row_start, len);
+
+               if (col->bind_ptr) {
+                       memcpy(col->bind_ptr, buf + row_start, len);
+                       if (mdb_get_option(MDB_DEBUG_OLE))
+                               buffer_dump(col->bind_ptr, 0, 16);
+               }
+               return len;
+       } else if (ole_flags == 0x0000) {
+               pg_row = mdb_get_int32(ole_ptr, 4);
+               col->cur_blob_pg = pg_row >> 8;
+               col->cur_blob_row = pg_row & 0xff;
+
+               if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) {
+                       return 0;
+               }
+
+               if (col->bind_ptr) 
+                       memcpy(col->bind_ptr, buf + row_start, len);
+
+               pg_row = mdb_get_int32(buf, row_start);
+               col->cur_blob_pg = pg_row >> 8;
+               col->cur_blob_row = pg_row & 0xff;
+
+               return len;
+       } else {
+               fprintf(stderr,"Unhandled ole field flags = %04x\n", ole_flags);
+               return 0;
+       }
+}
+int mdb_copy_ole(MdbHandle *mdb, char *dest, int start, int size)
+{
+       guint16 ole_len;
+       guint16 ole_flags;
+       guint32 row_start, pg_row;
+       guint32 len;
+       char *buf;
+
+       if (size<MDB_MEMO_OVERHEAD) {
+               return 0;
+       } 
+
+       /* The 16 bit integer at offset 0 is the length of the memo field.
+        * The 32 bit integer at offset 4 contains page and row information.
+        */
+       ole_len = mdb_pg_get_int16(mdb, start);
+       ole_flags = mdb_pg_get_int16(mdb, start+2);
+
+       if (ole_flags == 0x8000) {
+               len = size - MDB_MEMO_OVERHEAD;
+               /* inline ole field */
+               if (dest) memcpy(dest, &mdb->pg_buf[start + MDB_MEMO_OVERHEAD],
+                       size - MDB_MEMO_OVERHEAD);
+               return len;
+       } else if (ole_flags == 0x4000) {
+               pg_row = mdb_get_int32(mdb->pg_buf, start+4);
+               mdb_debug(MDB_DEBUG_OLE,"Reading LVAL page %06x", pg_row >> 8);
+
+               if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) {
+                       return 0;
+               }
+               mdb_debug(MDB_DEBUG_OLE,"row num %d start %d len %d",
+                       pg_row & 0xff, row_start, len);
+
+               if (dest)
+                       memcpy(dest, buf + row_start, len);
+               return len;
+       } else if (ole_flags == 0x0000) {
+               int cur = 0;
+               pg_row = mdb_get_int32(mdb->pg_buf, start+4);
+               mdb_debug(MDB_DEBUG_OLE,"Reading LVAL page %06x", pg_row >> 8);
+               do {
+                       if (mdb_find_pg_row(mdb,pg_row,&buf,&row_start,&len)) {
+                               return 0;
+                       }
+
+                       mdb_debug(MDB_DEBUG_OLE,"row num %d start %d len %d",
+                               pg_row & 0xff, row_start, len);
+
+                       if (dest) 
+                               memcpy(dest+cur, buf + row_start + 4, len - 4);
+                       cur += len - 4;
+
+                       /* find next lval page */
+                       pg_row = mdb_get_int32(buf, row_start);
+               } while ((pg_row >> 8));
+               return cur;
+       } else {
+               fprintf(stderr,"Unhandled ole field flags = %04x\n", ole_flags);
+               return 0;
+       }
+}
+static char *mdb_memo_to_string(MdbHandle *mdb, int start, int size)
+{
+       guint16 memo_len;
+       static char text[MDB_BIND_SIZE];
+       guint16 memo_flags;
+       guint32 row_start, pg_row;
+       guint32 len;
+       char *buf;
+
+       if (size<MDB_MEMO_OVERHEAD) {
+               return "";
+       } 
+
+#if MDB_DEBUG
+       buffer_dump(mdb->pg_buf, start, start + 12);
+#endif
+
+       /* The 16 bit integer at offset 0 is the length of the memo field.
+        * The 32 bit integer at offset 4 contains page and row information.
+        */
+       memo_len = mdb_pg_get_int16(mdb, start);
+       memo_flags = mdb_pg_get_int16(mdb, start+2);
+
+       if (memo_flags & 0x8000) {
+               /* inline memo field */
+               strncpy(text, &mdb->pg_buf[start + MDB_MEMO_OVERHEAD],
+                       size - MDB_MEMO_OVERHEAD);
+               text[size - MDB_MEMO_OVERHEAD]='\0';
+               return text;
+       } else if (memo_flags & 0x4000) {
+               pg_row = mdb_get_int32(mdb->pg_buf, start+4);
+#if MDB_DEBUG
+               printf("Reading LVAL page %06x\n", pg_row >> 8);
+#endif
+               if (mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &len)) {
+                       return "";
+               }
+#if MDB_DEBUG
+               printf("row num %d start %d len %d\n",
+                       pg_row & 0xff, row_start, len);
+               buffer_dump(mdb->pg_buf, row_start, row_start + len);
+#endif
+               if (IS_JET3(mdb)) {
+                       strncpy(text, buf + row_start, len);
+                       text[len]='\0';
+               } else {
+                       mdb_unicode2ascii(mdb, buf, row_start, len, text);
+               }
+               return text;
+       } else { /* if (memo_flags == 0x0000) { */
+               pg_row = mdb_get_int32(mdb->pg_buf, start+4);
+#if MDB_DEBUG
+               printf("Reading LVAL page %06x\n", pg_row >> 8);
+#endif
+               text[0]='\0';
+               do {
+                       if (mdb_find_pg_row(mdb,pg_row,&buf,&row_start,&len)) {
+                               return "";
+                       }
+#if MDB_DEBUG
+                       printf("row num %d start %d len %d\n",
+                               pg_row & 0xff, row_start, len);
+#endif
+                       strncat(text, buf + row_start + 4, 
+                               strlen(text) + len - 4 > MDB_BIND_SIZE ?
+                               MDB_BIND_SIZE - strlen(text) : len - 4);
+
+                       /* find next lval page */
+                       pg_row = mdb_get_int32(mdb->pg_buf, row_start);
+               } while ((pg_row >> 8));
+               return text;
+/*
+       } else {
+               fprintf(stderr,"Unhandled memo field flags = %04x\n", memo_flags);
+               return "";
+*/
+       }
+}
+static char *
+mdb_num_to_string(MdbHandle *mdb, int start, int datatype, int prec, int scale)
+{
+       char *text;
+       gint32 l;
+
+       memcpy(&l, mdb->pg_buf+start+13, 4);
+
+       text = (char *) g_malloc(prec+2);
+       sprintf(text, "%0*" G_GINT32_FORMAT, prec, GINT32_FROM_LE(l));
+       if (scale) {
+               memmove(text+prec-scale, text+prec-scale+1, scale+1);
+               text[prec-scale] = '.';
+       }
+       return text;
+}
+
+static int trim_trailing_zeros(char * buff, int n)
+{
+       char * p = buff + n - 1;
+
+       while (p >= buff && *p == '0')
+               *p-- = '\0';
+
+       if (*p == '.')
+               *p = '\0';
+
+       return 0;
+}
+                               
+char *mdb_col_to_string(MdbHandle *mdb, unsigned char *buf, int start, int datatype, int size)
+{
+       /* FIX ME -- not thread safe */
+       static char text[MDB_BIND_SIZE];
+       time_t t;
+       int n;
+       float tf;
+       double td;
+
+       switch (datatype) {
+               case MDB_BOOL:
+                       /* shouldn't happen.  bools are handled specially
+                       ** by mdb_xfer_bound_bool() */
+               break;
+               case MDB_BYTE:
+                       sprintf(text,"%d",mdb_get_byte(buf, start));
+                       return text;
+               break;
+               case MDB_INT:
+                       sprintf(text,"%ld",(long)mdb_get_int16(buf, start));
+                       return text;
+               break;
+               case MDB_LONGINT:
+                       sprintf(text,"%ld",mdb_get_int32(buf, start));
+                       return text;
+               break;
+               case MDB_FLOAT:
+                       tf = mdb_get_single(mdb->pg_buf, start);
+                       n = sprintf(text,"%.*f",FLT_DIG - (int)ceil(log10(tf)), tf);
+                       trim_trailing_zeros(text, n);
+                       return text;
+               break;
+               case MDB_DOUBLE:
+                       td = mdb_get_double(mdb->pg_buf, start);
+                       n = sprintf(text,"%.*f",DBL_DIG - (int)ceil(log10(td)), td);
+                       trim_trailing_zeros(text, n);
+                       return text;
+               break;
+               case MDB_TEXT:
+                       if (size<0) {
+                               return "";
+                       }
+                       if (IS_JET4(mdb)) {
+/*
+                               int i;
+                               for (i=0;i<size;i++) {
+                                       fprintf(stdout, "%c %02x ", mdb->pg_buf[start+i], mdb->pg_buf[start+i]);
+                               } 
+                               fprintf(stdout, "\n");
+*/
+                               mdb_unicode2ascii(mdb, mdb->pg_buf, start, size, text);
+                       } else {
+                               strncpy(text, &buf[start], size);
+                               text[size]='\0';
+                       }
+                       return text;
+               break;
+               case MDB_SDATETIME:
+                       td = mdb_get_double(mdb->pg_buf, start);
+                       if (td > 1) {
+                               t = (long int)((td - 25569.0) * 86400.0);
+                       } else {
+                               t = (long int)(td * 86400.0);
+                       }
+                       strftime(text, MDB_BIND_SIZE, date_fmt, (struct tm*)gmtime(&t));
+                       return text;
+
+               break;
+               case MDB_MEMO:
+                       return mdb_memo_to_string(mdb, start, size);
+               break;
+               case MDB_MONEY:
+                       mdb_money_to_string(mdb, start, text);
+                       return text;
+               case MDB_NUMERIC:
+               break;
+               default:
+                       return "";
+               break;
+       }
+       return NULL;
+}
+int mdb_col_disp_size(MdbColumn *col)
+{
+       switch (col->col_type) {
+               case MDB_BOOL:
+                       return 1;
+               break;
+               case MDB_BYTE:
+                       return 4;
+               break;
+               case MDB_INT:
+                       return 6;
+               break;
+               case MDB_LONGINT:
+                       return 11;
+               break;
+               case MDB_FLOAT:
+                       return 10;
+               break;
+               case MDB_DOUBLE:
+                       return 10;
+               break;
+               case MDB_TEXT:
+                       return col->col_size;
+               break;
+               case MDB_SDATETIME:
+                       return 20;
+               break;
+               case MDB_MEMO:
+                       return 255; 
+               break;
+               case MDB_MONEY:
+                       return 21;
+               break;
+       }
+       return 0;
+}
+int mdb_col_fixed_size(MdbColumn *col)
+{
+       switch (col->col_type) {
+               case MDB_BOOL:
+                       return 1;
+               break;
+               case MDB_BYTE:
+                       return -1;
+               break;
+               case MDB_INT:
+                       return 2;
+               break;
+               case MDB_LONGINT:
+                       return 4;
+               break;
+               case MDB_FLOAT:
+                       return 4;
+               break;
+               case MDB_DOUBLE:
+                       return 8;
+               break;
+               case MDB_TEXT:
+                       return -1;
+               break;
+               case MDB_SDATETIME:
+                       return 4;
+               break;
+               case MDB_MEMO:
+                       return -1; 
+               break;
+               case MDB_MONEY:
+                       return 8;
+               break;
+       }
+       return 0;
+}
diff --git a/navit/map/poi_geodownload/libmdb/dump.c b/navit/map/poi_geodownload/libmdb/dump.c
new file mode 100644 (file)
index 0000000..7ee17f9
--- /dev/null
@@ -0,0 +1,39 @@
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+void buffer_dump(const unsigned char* buf, int start, int end)
+{
+       char asc[20];
+       int j, k;
+
+       memset(asc, 0, sizeof(asc));
+       k = 0;
+       for (j=start; j<=end; j++) {
+               if (k == 0) {
+                       fprintf(stdout, "%04x  ", j);
+               }
+               fprintf(stdout, "%02x ", buf[j]);
+               asc[k] = isprint(buf[j]) ? buf[j] : '.';
+               k++;
+               if (k == 8) {
+                       fprintf(stdout, " ");
+               }
+               if (k == 16) {
+                       fprintf(stdout, "  %s\n", asc);
+                       memset(asc, 0, sizeof(asc));
+                       k = 0;
+               }
+       }
+       for (j=k; j<16; j++) {
+               fprintf(stdout, "   ");
+       }
+       if (k < 8) {
+               fprintf(stdout, " ");
+       }
+       fprintf(stdout, "  %s\n", asc);
+}
diff --git a/navit/map/poi_geodownload/libmdb/file.c b/navit/map/poi_geodownload/libmdb/file.c
new file mode 100644 (file)
index 0000000..941830c
--- /dev/null
@@ -0,0 +1,376 @@
+/* MDB Tools - A library for reading MS Access database files
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+/*
+typedef struct {
+       int             pg_size;
+       guint16         row_count_offset; 
+       guint16         tab_num_rows_offset;
+       guint16         tab_num_cols_offset;
+       guint16         tab_num_idxs_offset;
+       guint16         tab_num_ridxs_offset;
+       guint16         tab_usage_map_offset;
+       guint16         tab_first_dpg_offset;
+       guint16         tab_cols_start_offset;
+       guint16         tab_ridx_entry_size;
+       guint16         col_fixed_offset;
+       guint16         col_size_offset;
+       guint16         col_num_offset;
+       guint16         tab_col_entry_size;
+       guint16         tab_free_map_offset;
+       guint16         tab_col_offset_var;
+       guint16         tab_col_offset_fixed;
+       guint16         tab_row_col_num_offset;
+} MdbFormatConstants; 
+*/
+MdbFormatConstants MdbJet4Constants = {
+       4096, 0x0c, 16, 45, 47, 51, 55, 56, 63, 12, 15, 23, 5, 25, 59, 7, 21, 9
+};
+MdbFormatConstants MdbJet3Constants = {
+       2048, 0x08, 12, 25, 27, 31, 35, 36, 43, 8, 13, 16, 1, 18, 39, 3, 14, 5 /* not sure on 5, need to check */
+};
+
+static ssize_t _mdb_read_pg(MdbHandle *mdb, unsigned char *pg_buf, unsigned long pg);
+
+/**
+ * mdb_find_file:
+ * @filename: path to MDB (database) file
+ *
+ * Finds and returns the absolute path to an MDB file.  Function will first try
+ * to fstat file as passed, then search through the $MDBPATH if not found.
+ *
+ * Return value: gchar pointer to absolute path. Caller is responsible for
+ * freeing.
+ **/
+
+static gchar *mdb_find_file(char *file_name)
+{
+       struct stat status;
+       gchar *mdbpath, **dir, *tmpfname;
+       unsigned int i = 0;
+
+       /* try the provided file name first */
+       if (!stat(file_name, &status)) {
+               return g_strdup(file_name);
+       }
+       
+       /* Now pull apart $MDBPATH and try those */
+       mdbpath = (gchar *) getenv("MDBPATH");
+       /* no path, can't find file */
+       if (!mdbpath || !strlen(mdbpath)) return NULL;
+
+       dir = g_strsplit(mdbpath, ":", 0); 
+       while (dir[i]) {
+               if (!strlen(dir[i])) continue;
+               tmpfname = g_strconcat(dir[i++], "/", file_name, NULL);
+               if (!stat(tmpfname, &status)) {
+                       g_strfreev(dir);
+                       return tmpfname;
+               }
+               g_free(tmpfname);
+       }
+       g_strfreev(dir);
+       return NULL;
+}
+/**
+ * mdb_open:
+ * @filename: path to MDB (database) file
+ * @flags: MDB_NOFLAGS for read-only, MDB_WRITABLE for read/write
+ *
+ * Opens an MDB file and returns an MdbHandle to it.  MDB File may be relative
+ * to the current directory, a full path to the file, or relative to a 
+ * component of $MDBPATH.
+ *
+ * Return value: pointer to MdbHandle structure.
+ **/
+MdbHandle *mdb_open(char *filename, MdbFileFlags flags)
+{
+       MdbHandle *mdb;
+
+       mdb = (MdbHandle *) g_malloc0(sizeof(MdbHandle));
+       mdb_set_default_backend(mdb, "access");
+       /* need something to bootstrap with, reassign after page 0 is read */
+       mdb->fmt = &MdbJet3Constants;
+       mdb->f = (MdbFile *) g_malloc0(sizeof(MdbFile));
+       mdb->f->refs = 1;
+       mdb->f->fd = -1;
+       mdb->f->filename = (char *) mdb_find_file(filename);
+       if (!mdb->f->filename) { 
+               fprintf(stderr, "Can't alloc filename\n");
+               mdb_close(mdb);
+               return NULL; 
+       }
+       if (flags & MDB_WRITABLE) {
+               mdb->f->writable = TRUE;
+               mdb->f->fd = open(mdb->f->filename,O_RDWR);
+       } else {
+               mdb->f->fd = open(mdb->f->filename,O_RDONLY);
+       }
+
+       if (mdb->f->fd==-1) {
+               fprintf(stderr,"Couldn't open file %s\n",mdb->f->filename); 
+               mdb_close(mdb);
+               return NULL;
+       }
+       if (!mdb_read_pg(mdb, 0)) {
+               fprintf(stderr,"Couldn't read first page.\n");
+               mdb_close(mdb);
+               return NULL;
+       }
+       if (mdb->pg_buf[0] != 0) {
+               mdb_close(mdb);
+               return NULL; 
+       }
+       mdb->f->jet_version = mdb_pg_get_int32(mdb, 0x14);
+       if (IS_JET4(mdb)) {
+               mdb->fmt = &MdbJet4Constants;
+       } else if (IS_JET3(mdb)) {
+               mdb->fmt = &MdbJet3Constants;
+       } else {
+               fprintf(stderr,"Unknown Jet version.\n");
+               mdb_close(mdb);
+               return NULL; 
+       }
+
+       return mdb;
+}
+
+/**
+ * mdb_close:
+ * @mdb: Handle to open MDB database file
+ *
+ * Dereferences MDB file, closes if reference count is 0, and destroys handle.
+ *
+ **/
+void 
+mdb_close(MdbHandle *mdb)
+{
+       if (!mdb) return;       
+       mdb_free_catalog(mdb);
+       g_free(mdb->stats);
+       g_free(mdb->backend_name);
+
+       if (mdb->f) {
+               if (mdb->f->refs > 1) {
+                       mdb->f->refs--;
+               } else {
+                       if (mdb->f->fd != -1) close(mdb->f->fd);
+                       g_free(mdb->f->filename);
+                       g_free(mdb->f);
+               }
+       }
+
+       g_free(mdb);
+}
+/**
+ * mdb_clone_handle:
+ * @mdb: Handle to open MDB database file
+ *
+ * Clones an existing database handle.  Cloned handle shares the file descriptor
+ * but has its own page buffer, page position, and similar internal variables.
+ *
+ * Return value: new handle to the database.
+ */
+MdbHandle *mdb_clone_handle(MdbHandle *mdb)
+{
+       MdbHandle *newmdb;
+       MdbCatalogEntry *entry, *data;
+       unsigned int i;
+
+       newmdb = (MdbHandle *) g_memdup(mdb, sizeof(MdbHandle));
+       newmdb->stats = NULL;
+       newmdb->catalog = g_ptr_array_new();
+       for (i=0;i<mdb->num_catalog;i++) {
+               entry = g_ptr_array_index(mdb->catalog,i);
+               data = g_memdup(entry,sizeof(MdbCatalogEntry));
+               g_ptr_array_add(newmdb->catalog, data);
+       }
+       mdb->backend_name = NULL;
+       if (mdb->f) {
+               mdb->f->refs++;
+       }
+       return newmdb;
+}
+
+/* 
+** mdb_read a wrapper for read that bails if anything is wrong 
+*/
+ssize_t mdb_read_pg(MdbHandle *mdb, unsigned long pg)
+{
+       ssize_t len;
+
+       if (pg && mdb->cur_pg == pg) return mdb->fmt->pg_size;
+
+       len = _mdb_read_pg(mdb, mdb->pg_buf, pg);
+       //fprintf(stderr, "read page %d type %02x\n", pg, mdb->pg_buf[0]);
+       mdb->cur_pg = pg;
+       /* kan - reset the cur_pos on a new page read */
+       mdb->cur_pos = 0; /* kan */
+       return len;
+}
+ssize_t mdb_read_alt_pg(MdbHandle *mdb, unsigned long pg)
+{
+       ssize_t len;
+
+       len = _mdb_read_pg(mdb, mdb->alt_pg_buf, pg);
+       return len;
+}
+static ssize_t _mdb_read_pg(MdbHandle *mdb, unsigned char *pg_buf, unsigned long pg)
+{
+       ssize_t len;
+       struct stat status;
+       off_t offset = pg * mdb->fmt->pg_size;
+
+        fstat(mdb->f->fd, &status);
+        if (status.st_size < offset) { 
+                fprintf(stderr,"offset %lu is beyond EOF\n",offset);
+                return 0;
+        }
+       if (mdb->stats && mdb->stats->collect) 
+               mdb->stats->pg_reads++;
+
+       lseek(mdb->f->fd, offset, SEEK_SET);
+       len = read(mdb->f->fd,pg_buf,mdb->fmt->pg_size);
+       if (len==-1) {
+               perror("read");
+               return 0;
+       }
+       else if (len<mdb->fmt->pg_size) {
+               /* fprintf(stderr,"EOF reached %d bytes returned.\n",len, mdb->fmt->pg_size); */
+               return 0;
+       } 
+       return len;
+}
+void mdb_swap_pgbuf(MdbHandle *mdb)
+{
+char tmpbuf[MDB_PGSIZE];
+
+       memcpy(tmpbuf,mdb->pg_buf, MDB_PGSIZE);
+       memcpy(mdb->pg_buf,mdb->alt_pg_buf, MDB_PGSIZE);
+       memcpy(mdb->alt_pg_buf,tmpbuf,MDB_PGSIZE);
+}
+
+
+/* really stupid, just here for consistancy */
+unsigned char mdb_get_byte(unsigned char *buf, int offset)
+{
+       return buf[offset];
+}
+unsigned char mdb_pg_get_byte(MdbHandle *mdb, int offset)
+{
+       if (offset < 0 || offset+1 > mdb->fmt->pg_size) return -1;
+       mdb->cur_pos++;
+       return mdb->pg_buf[offset];
+}
+
+int mdb_get_int16(unsigned char *buf, int offset)
+{
+       return buf[offset+1]*256+buf[offset];
+}
+int mdb_pg_get_int16(MdbHandle *mdb, int offset)
+{
+       if (offset < 0 || offset+2 > mdb->fmt->pg_size) return -1;
+       mdb->cur_pos+=2;
+       return mdb_get_int16(mdb->pg_buf, offset);
+}
+
+gint32 mdb_pg_get_int24_msb(MdbHandle *mdb, int offset)
+{
+       gint32 l = 0;
+       if (offset <0 || offset+3 > mdb->fmt->pg_size) return -1;
+       mdb->cur_pos+=3;
+       memcpy((char *)&l+1, &(mdb->pg_buf[offset]), 3);
+#if 0
+       printf("l=0x%08x 0x%08x\n",l,GINT32_FROM_BE(l));
+#endif
+       return GINT32_FROM_BE(l);
+}
+gint32 mdb_get_int24(unsigned char *buf, int offset)
+{
+       gint32 l = 0;
+       memcpy(&l, &buf[offset], 3);
+       return GINT32_FROM_LE(l);
+}
+gint32 mdb_pg_get_int24(MdbHandle *mdb, int offset)
+{
+       if (offset <0 || offset+3 > mdb->fmt->pg_size) return -1;
+       mdb->cur_pos+=3;
+       return mdb_get_int24(mdb->pg_buf, offset);
+}
+
+long mdb_get_int32(unsigned char *buf, int offset)
+{
+       guint32 l;
+       memcpy(&l, &buf[offset], 4);
+       return (long)GINT32_FROM_LE(l);
+}
+long mdb_pg_get_int32(MdbHandle *mdb, int offset)
+{
+       if (offset <0 || offset+4 > mdb->fmt->pg_size) return -1;
+       mdb->cur_pos+=4;
+       return mdb_get_int32(mdb->pg_buf, offset);
+}
+
+float mdb_get_single(unsigned char *buf, int offset)
+{
+       union {guint32 g; float f;} f;
+       memcpy(&f, &buf[offset], 4);
+       f.g = GUINT32_FROM_LE(f.g);
+       return f.f;
+}
+float mdb_pg_get_single(MdbHandle *mdb, int offset)
+{
+       if (offset <0 || offset+4 > mdb->fmt->pg_size) return -1;
+       mdb->cur_pos+=4;
+       return mdb_get_single(mdb->pg_buf, offset);
+}
+
+double mdb_get_double(unsigned char *buf, int offset)
+{
+       union {guint64 g; double d;} d;
+       memcpy(&d, &buf[offset], 8);
+       d.g = GUINT64_FROM_LE(d.g);
+       return d.d;
+}
+double mdb_pg_get_double(MdbHandle *mdb, int offset)
+{
+       if (offset <0 || offset+8 > mdb->fmt->pg_size) return -1;
+       mdb->cur_pos+=8;
+       return mdb_get_double(mdb->pg_buf, offset);
+}
+
+
+int 
+mdb_set_pos(MdbHandle *mdb, int pos)
+{
+       if (pos<0 || pos >= mdb->fmt->pg_size) return 0;
+
+       mdb->cur_pos=pos;
+       return pos;
+}
+int mdb_get_pos(MdbHandle *mdb)
+{
+       return mdb->cur_pos;
+}
diff --git a/navit/map/poi_geodownload/libmdb/iconv.c b/navit/map/poi_geodownload/libmdb/iconv.c
new file mode 100644 (file)
index 0000000..9f41afe
--- /dev/null
@@ -0,0 +1,63 @@
+/* MDB Tools - A library for reading MS Access database files
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+int
+mdb_unicode2ascii(MdbHandle *mdb, unsigned char *buf, int offset, unsigned int len, char *dest)
+{
+       unsigned int i;
+
+       if (buf[offset]==0xff && buf[offset+1]==0xfe) {
+               strncpy(dest, &buf[offset+2], len-2);
+               dest[len-2]='\0';
+       } else {
+               /* convert unicode to ascii, rather sloppily */
+               for (i=0;i<len;i+=2)
+                       dest[i/2] = buf[offset + i];
+               dest[len/2]='\0';
+       }
+       return len;
+}
+
+int
+mdb_ascii2unicode(MdbHandle *mdb, unsigned char *buf, int offset, unsigned int len, char *dest)
+{
+       unsigned int i = 0;
+
+       if (!buf) return 0;
+
+       if (IS_JET3(mdb)) {
+               strncpy(dest, &buf[offset], len);
+               dest[len]='\0';
+               return strlen(dest);
+       }
+
+       while (i<strlen(&buf[offset]) && (i*2+2)<len) {
+               dest[i*2] = buf[offset+i];
+               dest[i*2+1] = 0;
+               i++;
+       }
+
+       return (i*2);
+}
diff --git a/navit/map/poi_geodownload/libmdb/include/Makefile.am b/navit/map/poi_geodownload/libmdb/include/Makefile.am
new file mode 100644 (file)
index 0000000..084a754
--- /dev/null
@@ -0,0 +1 @@
+EXTRA_DIST = mdbtools.h
diff --git a/navit/map/poi_geodownload/libmdb/include/mdbtools.h b/navit/map/poi_geodownload/libmdb/include/mdbtools.h
new file mode 100644 (file)
index 0000000..b17df28
--- /dev/null
@@ -0,0 +1,536 @@
+/* MDB Tools - A library for reading MS Access database files
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef _mdbtools_h_
+#define _mdbtools_h_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <string.h>
+#include <glib.h>
+
+#ifdef HAVE_ICONV
+#include <iconv.h>
+#endif
+
+#define MDB_DEBUG 0
+
+#define MDB_PGSIZE 4096
+#define MDB_MAX_OBJ_NAME 256
+#define MDB_MAX_COLS 256
+#define MDB_MAX_IDX_COLS 10
+#define MDB_CATALOG_PG 18
+#define MDB_MEMO_OVERHEAD 12
+#define MDB_BIND_SIZE 16384
+
+enum {
+       MDB_PAGE_DB = 0,
+       MDB_PAGE_DATA,
+       MDB_PAGE_TABLE,
+       MDB_PAGE_INDEX,
+       MDB_PAGE_LEAF,
+       MDB_PAGE_MAP
+};
+enum {
+       MDB_VER_JET3 = 0,
+       MDB_VER_JET4 = 1
+};
+enum {
+       MDB_FORM = 0,
+       MDB_TABLE,
+       MDB_MACRO,
+       MDB_SYSTEM_TABLE,
+       MDB_REPORT,
+       MDB_QUERY,
+       MDB_LINKED_TABLE,
+       MDB_MODULE,
+       MDB_RELATIONSHIP,
+       MDB_UNKNOWN_09,
+       MDB_UNKNOWN_0A,
+       MDB_DATABASE_PROPERTY,
+       MDB_ANY = -1
+};
+enum {
+       MDB_BOOL = 0x01,
+       MDB_BYTE = 0x02,
+       MDB_INT = 0x03,
+       MDB_LONGINT = 0x04,
+       MDB_MONEY = 0x05,
+       MDB_FLOAT = 0x06,
+       MDB_DOUBLE = 0x07,
+       MDB_SDATETIME = 0x08,
+       MDB_TEXT = 0x0a,
+       MDB_OLE = 0x0b,
+       MDB_MEMO = 0x0c,
+       MDB_REPID = 0x0f,
+       MDB_NUMERIC = 0x10
+};
+
+/* SARG operators */
+enum {
+       MDB_OR = 1,
+       MDB_AND,
+       MDB_NOT,
+       MDB_EQUAL,
+       MDB_GT,
+       MDB_LT,
+       MDB_GTEQ,
+       MDB_LTEQ,
+       MDB_LIKE,
+       MDB_ISNULL,
+       MDB_NOTNULL
+};
+
+typedef enum {
+       MDB_TABLE_SCAN,
+       MDB_LEAF_SCAN,
+       MDB_INDEX_SCAN
+} MdbStrategy;
+
+typedef enum {
+       MDB_NOFLAGS = 0x00,
+       MDB_WRITABLE = 0x01
+} MdbFileFlags;
+
+enum {
+       MDB_DEBUG_LIKE = 0x0001,
+       MDB_DEBUG_WRITE = 0x0002,
+       MDB_DEBUG_USAGE = 0x0004,
+       MDB_DEBUG_OLE = 0x0008,
+       MDB_DEBUG_ROW = 0x0010,
+       MDB_USE_INDEX = 0x0020
+};
+
+#define mdb_is_logical_op(x) (x == MDB_OR || \
+                               x == MDB_AND || \
+                               x == MDB_NOT )
+
+#define mdb_is_relational_op(x) (x == MDB_EQUAL || \
+                               x == MDB_GT || \
+                               x == MDB_LT || \
+                               x == MDB_GTEQ || \
+                               x == MDB_LTEQ || \
+                               x == MDB_LIKE || \
+                               x == MDB_ISNULL || \
+                               x == MDB_NOTNULL )
+
+enum {
+       MDB_ASC,
+       MDB_DESC
+};
+
+enum {
+       MDB_IDX_UNIQUE = 0x01,
+       MDB_IDX_IGNORENULLS = 0x02,
+       MDB_IDX_REQUIRED = 0x08 
+};
+
+#define IS_JET4(mdb) (mdb->f->jet_version==MDB_VER_JET4)
+#define IS_JET3(mdb) (mdb->f->jet_version==MDB_VER_JET3)
+
+/* hash to store registered backends */
+/* extern GHashTable   *mdb_backends; */
+
+/* forward declarations */
+typedef struct mdbindex MdbIndex;
+typedef struct mdbsargtree MdbSargNode;
+
+typedef struct {
+       char *name;
+       unsigned char needs_length; /* or precision */
+       unsigned char needs_scale;
+       unsigned char needs_quotes;
+} MdbBackendType;
+               
+typedef struct {
+        MdbBackendType *types_table;
+} MdbBackend;
+
+typedef struct {
+       gboolean collect;
+       unsigned long pg_reads;
+} MdbStatistics;
+
+typedef struct {
+       int           fd;
+       gboolean      writable;
+       char          *filename;
+       guint32         jet_version;
+       guint32         db_key;
+       char            db_passwd[14];
+       MdbBackend      *default_backend;
+       char                    *backend_name;
+       MdbStatistics   *stats;
+       /* free map */
+       int  map_sz;
+       unsigned char *free_map;
+       /* reference count */
+       int refs;
+} MdbFile; 
+
+/* offset to row count on data pages...version dependant */
+typedef struct {
+       int             pg_size;
+       guint16         row_count_offset; 
+       guint16         tab_num_rows_offset;
+       guint16         tab_num_cols_offset;
+       guint16         tab_num_idxs_offset;
+       guint16         tab_num_ridxs_offset;
+       guint16         tab_usage_map_offset;
+       guint16         tab_first_dpg_offset;
+       guint16         tab_cols_start_offset;
+       guint16         tab_ridx_entry_size;
+       guint16         col_fixed_offset;
+       guint16         col_size_offset;
+       guint16         col_num_offset;
+       guint16         tab_col_entry_size;
+       guint16         tab_free_map_offset;
+       guint16         tab_col_offset_var;
+       guint16         tab_col_offset_fixed;
+       guint16         tab_row_col_num_offset;
+} MdbFormatConstants; 
+
+typedef struct {
+       MdbFile       *f;
+       guint32       cur_pg;
+       guint16       row_num;
+       unsigned int  cur_pos;
+       unsigned char pg_buf[MDB_PGSIZE];
+       unsigned char alt_pg_buf[MDB_PGSIZE];
+       unsigned int  num_catalog;
+       GPtrArray       *catalog;
+       MdbBackend      *default_backend;
+       char            *backend_name;
+       MdbFormatConstants *fmt;
+       MdbStatistics *stats;
+#ifdef HAVE_ICONV
+       iconv_t iconv_out;
+#endif
+} MdbHandle; 
+
+typedef struct {
+       MdbHandle       *mdb;
+       char           object_name[MDB_MAX_OBJ_NAME+1];
+       int            object_type;
+       unsigned long  table_pg; /* misnomer since object may not be a table */
+       unsigned long  kkd_pg;
+       unsigned int   kkd_rowid;
+       int                     num_props;
+       GArray          *props;
+       GArray          *columns;
+       int             flags;
+} MdbCatalogEntry;
+
+typedef struct {
+       gchar *name;
+       GHashTable      *hash;
+} MdbProperties;
+
+typedef union {
+       int     i;
+       double  d;
+       char    s[256];
+} MdbAny;
+
+typedef struct {
+       char            name[MDB_MAX_OBJ_NAME+1];
+       int             col_type;
+       int             col_size;
+       void    *bind_ptr;
+       int             *len_ptr;
+       GHashTable      *properties;
+       unsigned int    num_sargs;
+       GPtrArray       *sargs;
+       GPtrArray       *idx_sarg_cache;
+       unsigned char   is_fixed;
+       int             query_order;
+       /* col_num is the current column order, 
+        * does not include deletes */
+       int             col_num;        
+       int             cur_value_start;
+       int             cur_value_len;
+       /* MEMO/OLE readers */
+       guint32         cur_blob_pg;
+       int             cur_blob_row;
+       int             chunk_size;
+       /* numerics only */
+       int             col_prec;
+       int             col_scale;
+       MdbProperties   *props;
+       /* info needed for handling deleted/added columns */
+       int             fixed_offset;
+       int             var_col_num;
+       /* row_col_num is the row column number order, 
+        * including deleted columns */
+       int             row_col_num;
+} MdbColumn;
+
+struct mdbsargtree {
+       int       op;
+       MdbColumn *col;
+       MdbAny    value;
+       void      *parent;
+       MdbSargNode *left;
+       MdbSargNode *right;
+};
+
+typedef struct {
+       guint32 pg;
+       int start_pos;
+       int offset;
+       int len;
+       guint16 idx_starts[2000];       
+       unsigned char cache_value[256];
+} MdbIndexPage;
+
+typedef int (*MdbSargTreeFunc)(MdbSargNode *, gpointer *data);
+
+#define MDB_MAX_INDEX_DEPTH 10
+
+typedef struct {
+       int cur_depth;
+       guint32 last_leaf_found;
+       int clean_up_mode;
+       MdbIndexPage pages[MDB_MAX_INDEX_DEPTH];
+} MdbIndexChain;
+
+typedef struct {
+       MdbCatalogEntry *entry;
+       char    name[MDB_MAX_OBJ_NAME+1];
+       unsigned int    num_cols;
+       GPtrArray       *columns;
+       unsigned int    num_rows;
+       int     index_start;
+       unsigned int    num_real_idxs;
+       unsigned int    num_idxs;
+       GPtrArray       *indices;
+       guint32 first_data_pg;
+       guint32 cur_pg_num;
+       guint32 cur_phys_pg;
+       unsigned int    cur_row;
+       int  noskip_del;  /* don't skip deleted rows */
+       /* object allocation map */
+       guint32  map_base_pg;
+       unsigned int  map_sz;
+       unsigned char *usage_map;
+       /* pages with free space left */
+       guint32  freemap_base_pg;
+       unsigned int  freemap_sz;
+       unsigned char *free_usage_map;
+       /* query planner */
+       MdbSargNode *sarg_tree;
+       MdbStrategy strategy;
+       MdbIndex *scan_idx;
+       MdbHandle *mdbidx;
+       MdbIndexChain *chain;
+       MdbProperties   *props;
+       unsigned int num_var_cols;  /* to know if row has variable columns */
+       /* temp table */
+       unsigned int  is_temp_table;
+       GPtrArray     *temp_table_pages;
+} MdbTableDef;
+
+struct mdbindex {
+       int             index_num;
+       char            name[MDB_MAX_OBJ_NAME+1];
+       unsigned char   index_type;
+       guint32         first_pg;
+       int             num_rows;  /* number rows in index */
+       unsigned int    num_keys;
+       short   key_col_num[MDB_MAX_IDX_COLS];
+       unsigned char   key_col_order[MDB_MAX_IDX_COLS];
+       unsigned char   flags;
+       MdbTableDef     *table;
+};
+
+typedef struct {
+       char            name[MDB_MAX_OBJ_NAME+1];
+} MdbColumnProp;
+
+typedef struct {
+       void *value;
+       int siz;
+       int start;
+       unsigned char is_null;
+       unsigned char is_fixed;
+       int colnum;
+       int offset;
+} MdbField;
+
+typedef struct {
+       int     op;
+       MdbAny  value;
+} MdbSarg;
+
+/* mem.c */
+extern void mdb_init(void);
+extern void mdb_exit(void);
+
+/* file.c */
+extern ssize_t mdb_read_pg(MdbHandle *mdb, unsigned long pg);
+extern ssize_t mdb_read_alt_pg(MdbHandle *mdb, unsigned long pg);
+extern unsigned char mdb_get_byte(unsigned char *buf, int offset);
+extern int    mdb_get_int16(unsigned char *buf, int offset);
+extern gint32   mdb_get_int24(unsigned char *buf, int offset);
+extern long   mdb_get_int32(unsigned char *buf, int offset);
+extern float  mdb_get_single(unsigned char *buf, int offset);
+extern double mdb_get_double(unsigned char *buf, int offset);
+extern unsigned char mdb_pg_get_byte(MdbHandle *mdb, int offset);
+extern int    mdb_pg_get_int16(MdbHandle *mdb, int offset);
+extern gint32   mdb_pg_get_int24(MdbHandle *mdb, int offset);
+extern long   mdb_pg_get_int32(MdbHandle *mdb, int offset);
+extern float  mdb_pg_get_single(MdbHandle *mdb, int offset);
+extern double mdb_pg_get_double(MdbHandle *mdb, int offset);
+extern gint32 mdb_pg_get_int24_msb(MdbHandle *mdb, int offset);
+extern MdbHandle *mdb_open(char *filename, MdbFileFlags flags);
+extern void mdb_close(MdbHandle *mdb);
+extern MdbHandle *mdb_clone_handle(MdbHandle *mdb);
+extern void mdb_swap_pgbuf(MdbHandle *mdb);
+extern long _mdb_get_int32(unsigned char *buf, int offset);
+
+/* catalog.c */
+extern void mdb_free_catalog(MdbHandle *mdb);
+extern GPtrArray *mdb_read_catalog(MdbHandle *mdb, int obj_type);
+extern void mdb_dump_catalog(MdbHandle *mdb, int obj_type);
+extern char *mdb_get_objtype_string(int obj_type);
+
+/* table.c */
+extern MdbTableDef *mdb_alloc_tabledef(MdbCatalogEntry *entry);
+extern void mdb_free_tabledef(MdbTableDef *table);
+extern MdbTableDef *mdb_read_table(MdbCatalogEntry *entry);
+extern MdbTableDef *mdb_read_table_by_name(MdbHandle *mdb, gchar *table_name, int obj_type);
+extern void mdb_append_column(GPtrArray *columns, MdbColumn *in_col);
+extern void mdb_free_columns(GPtrArray *columns);
+extern GPtrArray *mdb_read_columns(MdbTableDef *table);
+extern void mdb_table_dump(MdbCatalogEntry *entry);
+extern guint16 read_pg_if_16(MdbHandle *mdb, int *cur_pos);
+extern guint32 read_pg_if_32(MdbHandle *mdb, int *cur_pos);
+extern int read_pg_if(MdbHandle *mdb, int *cur_pos, int offset);
+extern guint16 read_pg_if_n(MdbHandle *mdb, unsigned char *buf, int *cur_pos, int len);
+extern int mdb_is_user_table(MdbCatalogEntry *entry);
+extern int mdb_is_system_table(MdbCatalogEntry *entry);
+
+/* data.c */
+extern int mdb_bind_column_by_name(MdbTableDef *table, gchar *col_name, void *bind_ptr);
+extern void mdb_data_dump(MdbTableDef *table);
+extern void mdb_bind_column(MdbTableDef *table, int col_num, void *bind_ptr);
+extern int mdb_rewind_table(MdbTableDef *table);
+extern int mdb_fetch_row(MdbTableDef *table);
+extern int mdb_is_fixed_col(MdbColumn *col);
+extern char *mdb_col_to_string(MdbHandle *mdb, unsigned char *buf, int start, int datatype, int size);
+extern int mdb_find_pg_row(MdbHandle *mdb, int pg_row, char **buf, int *off, int *len);
+extern int mdb_find_end_of_row(MdbHandle *mdb, int row);
+extern int mdb_col_fixed_size(MdbColumn *col);
+extern int mdb_col_disp_size(MdbColumn *col);
+extern void mdb_bind_len(MdbTableDef *table, int col_num, int *len_ptr);
+extern int mdb_ole_read_next(MdbHandle *mdb, MdbColumn *col, void *ole_ptr);
+extern int mdb_ole_read(MdbHandle *mdb, MdbColumn *col, void *ole_ptr, int chunk_size);
+extern void mdb_set_date_fmt(const char *);
+extern int mdb_read_row(MdbTableDef *table, unsigned int row);
+
+/* dump.c */
+extern void buffer_dump(const unsigned char* buf, int start, int end);
+
+/* backend.c */
+extern char *mdb_get_coltype_string(MdbBackend *backend, int col_type);
+extern int  mdb_coltype_takes_length(MdbBackend *backend, int col_type);
+extern void mdb_init_backends(void);
+extern void mdb_register_backend(MdbBackendType *backend, char *backend_name);
+extern void mdb_remove_backends(void);
+extern int  mdb_set_default_backend(MdbHandle *mdb, char *backend_name);
+extern char *mdb_get_relationships(MdbHandle *mdb);
+
+/* sargs.c */
+extern int mdb_test_sargs(MdbTableDef *table, MdbField *fields, int num_fields);
+extern int mdb_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSargNode *node, MdbField *field);
+extern void mdb_sql_walk_tree(MdbSargNode *node, MdbSargTreeFunc func, gpointer data);
+extern int mdb_find_indexable_sargs(MdbSargNode *node, gpointer data);
+extern int mdb_add_sarg_by_name(MdbTableDef *table, char *colname, MdbSarg *in_sarg);
+extern int mdb_test_string(MdbSargNode *node, char *s);
+extern int mdb_test_int(MdbSargNode *node, gint32 i);
+extern int mdb_add_sarg(MdbColumn *col, MdbSarg *in_sarg);
+
+
+
+/* index.c */
+extern GPtrArray *mdb_read_indices(MdbTableDef *table);
+extern void mdb_index_dump(MdbTableDef *table, MdbIndex *idx);
+extern void mdb_index_scan_free(MdbTableDef *table);
+extern int mdb_index_find_next_on_page(MdbHandle *mdb, MdbIndexPage *ipg);
+extern int mdb_index_find_next(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 *pg, guint16 *row);
+extern void mdb_index_hash_text(guchar *text, guchar *hash);
+extern void mdb_index_scan_init(MdbHandle *mdb, MdbTableDef *table);
+extern int mdb_index_find_row(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 pg, guint16 row);
+extern void mdb_index_swap_n(unsigned char *src, int sz, unsigned char *dest);
+extern void mdb_free_indices(GPtrArray *indices);
+void mdb_index_page_reset(MdbIndexPage *ipg);
+extern MdbIndexPage *mdb_index_read_bottom_pg(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain);
+extern MdbIndexPage *mdb_index_unwind(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain);
+extern void mdb_index_page_init(MdbIndexPage *ipg);
+
+
+/* stats.c */
+extern void mdb_stats_on(MdbHandle *mdb);
+extern void mdb_stats_off(MdbHandle *mdb);
+extern void mdb_dump_stats(MdbHandle *mdb);
+
+/* like.c */
+extern int mdb_like_cmp(char *s, char *r);
+
+/* write.c */
+extern int mdb_crack_row(MdbTableDef *table, int row_start, int row_end, MdbField *fields);
+extern guint16 mdb_add_row_to_pg(MdbTableDef *table, unsigned char *row_buffer, int new_row_size);
+extern int mdb_update_index(MdbTableDef *table, MdbIndex *idx, unsigned int num_fields, MdbField *fields, guint32 pgnum, guint16 rownum);
+extern int mdb_pack_row(MdbTableDef *table, unsigned char *row_buffer, unsigned int num_fields, MdbField *fields);
+extern int mdb_replace_row(MdbTableDef *table, int row, unsigned char *new_row, int new_row_size);
+extern int mdb_pg_get_freespace(MdbHandle *mdb);
+extern int mdb_update_row(MdbTableDef *table);
+extern unsigned char *mdb_new_data_pg(MdbCatalogEntry *entry);
+
+/* map.c */
+extern guint32 mdb_map_find_next_freepage(MdbTableDef *table, int row_size);
+guint32 mdb_map_find_next(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg);
+
+/* props.c */
+extern GPtrArray *mdb_read_props_list(gchar *kkd, int len);
+extern void mdb_free_props(MdbProperties *props);
+extern MdbProperties *mdb_read_props(MdbHandle *mdb, GPtrArray *names, gchar *kkd, int len);
+
+/* worktable.c */
+extern MdbTableDef *mdb_create_temp_table(MdbHandle *mdb, char *name);
+extern void mdb_temp_table_add_col(MdbTableDef *table, MdbColumn *col);
+extern void mdb_fill_temp_col(MdbColumn *tcol, char *col_name, int col_size, int col_type, int is_fixed);
+extern void mdb_fill_temp_field(MdbField *field, void *value, int siz, int is_fixed, int is_null, int start, int column);
+extern void mdb_temp_columns_end(MdbTableDef *table);
+
+/* options.c */
+extern int mdb_get_option(unsigned long optnum);
+extern void mdb_debug(int klass, char *fmt, ...);
+
+/* iconv.c */
+extern int mdb_unicode2ascii(MdbHandle *mdb, unsigned char *buf, int offset, unsigned int len, char *dest);
+extern int mdb_ascii2unicode(MdbHandle *mdb, unsigned char *buf, int offset, unsigned int len, char *dest);
+
+#endif /* _mdbtools_h_ */
diff --git a/navit/map/poi_geodownload/libmdb/index.c b/navit/map/poi_geodownload/libmdb/index.c
new file mode 100644 (file)
index 0000000..e840536
--- /dev/null
@@ -0,0 +1,905 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000-2004 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+MdbIndexPage *mdb_index_read_bottom_pg(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain);
+MdbIndexPage *mdb_chain_add_page(MdbHandle *mdb, MdbIndexChain *chain, guint32 pg);
+
+char idx_to_text[] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0-7     0x00-0x07 */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8-15    0x09-0x0f */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 16-23   0x10-0x17 */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 24-31   0x19-0x1f */
+' ',  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 32-39   0x20-0x27 */
+0x00, 0x00, 0x00, 0x00, 0x00, ' ',  ' ',  0x00, /* 40-47   0x29-0x2f */
+'V',  'W',  'X',  'Y',  'Z',  '[',  '\\', ']',  /* 48-55   0x30-0x37 */
+'^',  '_',  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 56-63   0x39-0x3f */
+0x00, '`',  'a',  'b',  'd',  'f',  'g',  'h',  /* 64-71   0x40-0x47 */
+'i',  'j',  'k',  'l',  'm',  'o',  'p',  'r',  /* 72-79   0x49-0x4f  H */
+'s',  't',  'u',  'v',  'w',  'x',  'z',  '{',  /* 80-87   0x50-0x57  P */
+'|',  '}',  '~',  '5',  '6',  '7',  '8',  '9',  /* 88-95   0x59-0x5f */
+0x00, '`',  'a',  'b',  'd',  'f',  'g',  'h',  /* 96-103  0x60-0x67 */
+'i',  'j',  'k',  'l',  'm',  'o',  'p',  'r',  /* 014-111 0x69-0x6f  h */
+'s',  't',  'u',  'v',  'w',  'x',  'z',  '{',  /* 112-119 0x70-0x77  p */
+'|',  '}',  '~',  0x00, 0x00, 0x00, 0x00, 0x00, /* 120-127 0x78-0x7f */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128-135 0x80-0x87 */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */
+0x00, 0x00, 0x00, 0x00, 0x00, '`',  0x00, 0x00, /* 0xc0-0xc7 */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */
+0x00, '`',  0x00, '`',  '`',  '`',  0x00, 0x00, /* 0xe0-0xe7 */
+'f',  'f',  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */
+0x00, 0x00, 0x00, 'r',  0x00, 0x00, 'r',  0x00, /* 0xf0-0xf7 */
+0x81, 0x00, 0x00, 0x00, 'x',  0x00, 0x00, 0x00, /* 0xf8-0xff */
+};
+
+
+GPtrArray *
+mdb_read_indices(MdbTableDef *table)
+{
+       MdbCatalogEntry *entry = table->entry;
+       MdbHandle *mdb = entry->mdb;
+       MdbFormatConstants *fmt = mdb->fmt;
+       MdbIndex *pidx;
+       unsigned int i, j;
+       int idx_num, key_num, col_num;
+       int cur_pos, name_sz, idx2_sz, type_offset;
+       int index_start_pg = mdb->cur_pg;
+       gchar *tmpbuf;
+
+        table->indices = g_ptr_array_new();
+
+        if (IS_JET4(mdb)) {
+               cur_pos = table->index_start + 52 * table->num_real_idxs;
+               idx2_sz = 28;
+               type_offset = 23;
+       } else {
+               cur_pos = table->index_start + 39 * table->num_real_idxs;
+               idx2_sz = 20;
+               type_offset = 19;
+       }
+
+       tmpbuf = (gchar *) g_malloc(idx2_sz);
+       for (i=0;i<table->num_idxs;i++) {
+               read_pg_if_n(mdb, tmpbuf, &cur_pos, idx2_sz);
+               cur_pos += idx2_sz;
+               pidx = (MdbIndex *) g_malloc0(sizeof(MdbIndex));
+               pidx->table = table;
+               pidx->index_num = mdb_get_int16(tmpbuf, 4);
+               pidx->index_type = tmpbuf[type_offset]; 
+               g_ptr_array_add(table->indices, pidx);
+       }
+       g_free(tmpbuf);
+
+       for (i=0;i<table->num_idxs;i++) {
+               pidx = g_ptr_array_index (table->indices, i);
+               if (IS_JET4(mdb)) {
+                       name_sz=read_pg_if_16(mdb, &cur_pos);
+                       cur_pos += 2;
+                       tmpbuf = g_malloc(name_sz);
+                       read_pg_if_n(mdb, tmpbuf, &cur_pos, name_sz);
+                       cur_pos += name_sz;
+                       mdb_unicode2ascii(mdb, tmpbuf, 0, name_sz, pidx->name); 
+                       g_free(tmpbuf);
+               } else {
+                       read_pg_if(mdb, &cur_pos, 0);
+                       name_sz=mdb->pg_buf[cur_pos++];
+                       read_pg_if_n(mdb, pidx->name, &cur_pos, name_sz);
+                       cur_pos += name_sz;
+                       pidx->name[name_sz]='\0';               
+               }
+               //fprintf(stderr, "index name %s\n", pidx->name);
+       }
+
+       mdb_read_alt_pg(mdb, entry->table_pg);
+       mdb_read_pg(mdb, index_start_pg);
+       cur_pos = table->index_start;
+       idx_num=0;
+       for (i=0;i<table->num_real_idxs;i++) {
+               if (IS_JET4(mdb)) cur_pos += 4;
+               do {
+                       pidx = g_ptr_array_index (table->indices, idx_num++);
+               } while (pidx && pidx->index_type==2);
+
+               /* if there are more real indexes than index entries left after
+                  removing type 2's decrement real indexes and continue.  Happens
+                  on Northwind Orders table.
+               */
+               if (!pidx) {
+                       table->num_real_idxs--;
+                       continue;
+               }
+
+               pidx->num_rows = mdb_get_int32(mdb->alt_pg_buf, 
+                               fmt->tab_cols_start_offset +
+                               (i*fmt->tab_ridx_entry_size));
+
+               key_num=0;
+               for (j=0;j<MDB_MAX_IDX_COLS;j++) {
+                       col_num=read_pg_if_16(mdb,&cur_pos);
+                       cur_pos += 2;
+                       read_pg_if(mdb, &cur_pos, 0);
+                       cur_pos++;
+                       if (col_num == 0xFFFF)
+                               continue;
+                       /* set column number to a 1 based column number and store */
+                       pidx->key_col_num[key_num] = col_num + 1;
+                       pidx->key_col_order[key_num] =
+                               (mdb->pg_buf[cur_pos-1]) ? MDB_ASC : MDB_DESC;
+                       key_num++;
+               }
+               pidx->num_keys = key_num;
+
+               cur_pos += 4;
+               pidx->first_pg = read_pg_if_32(mdb, &cur_pos);
+               cur_pos += 4;
+               read_pg_if(mdb, &cur_pos, 0);
+               pidx->flags = mdb->pg_buf[cur_pos++];
+               if (IS_JET4(mdb)) cur_pos += 9;
+       }
+       return NULL;
+}
+void
+mdb_index_hash_text(guchar *text, guchar *hash)
+{
+       unsigned int k;
+
+       for (k=0;k<strlen(text);k++) {
+               hash[k] = idx_to_text[text[k]];
+               if (!(hash[k])) fprintf(stderr, 
+                               "No translation available for %02x %d\n", 
+                               text[k],text[k]);
+       }
+       hash[strlen(text)]=0;
+}
+void
+mdb_index_swap_n(unsigned char *src, int sz, unsigned char *dest)
+{
+       int i, j = 0;
+
+       for (i = sz; i > 0; i--) {
+               dest[j++] = src[i];
+       }
+}
+void 
+mdb_index_cache_sarg(MdbColumn *col, MdbSarg *sarg, MdbSarg *idx_sarg)
+{
+       //guint32 cache_int;
+       unsigned char *c;
+
+       switch (col->col_type) {
+               case MDB_TEXT:
+               mdb_index_hash_text(sarg->value.s, idx_sarg->value.s);
+               break;
+
+               case MDB_LONGINT:
+               idx_sarg->value.i = GUINT32_SWAP_LE_BE(sarg->value.i);
+               //cache_int = sarg->value.i * -1;
+               c = (unsigned char *) &(idx_sarg->value.i);
+               c[0] |= 0x80;
+               //printf("int %08x %02x %02x %02x %02x\n", sarg->value.i, c[0], c[1], c[2], c[3]);
+               break;  
+
+               case MDB_INT:
+               break;  
+
+               default:
+               break;  
+       }
+}
+#if 0
+int 
+mdb_index_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSarg *sarg, int offset, int len)
+{
+char tmpbuf[256];
+int lastchar;
+
+       switch (col->col_type) {
+               case MDB_BYTE:
+                       return mdb_test_int(sarg, mdb_pg_get_byte(mdb, offset));
+                       break;
+               case MDB_INT:
+                       return mdb_test_int(sarg, mdb_pg_get_int16(mdb, offset));
+                       break;
+               case MDB_LONGINT:
+                       return mdb_test_int(sarg, mdb_pg_get_int32(mdb, offset));
+                       break;
+               case MDB_TEXT:
+                       strncpy(tmpbuf, &mdb->pg_buf[offset],255);
+                       lastchar = len > 255 ? 255 : len;
+                       tmpbuf[lastchar]='\0';
+                       return mdb_test_string(sarg, tmpbuf);
+               default:
+                       fprintf(stderr, "Calling mdb_test_sarg on unknown type.  Add code to mdb_test_sarg() for type %d\n",col->col_type);
+                       break;
+       }
+       return 1;
+}
+#endif
+int
+mdb_index_test_sargs(MdbHandle *mdb, MdbIndex *idx, unsigned char *buf, int len)
+{
+       unsigned int i, j;
+       MdbColumn *col;
+       MdbTableDef *table = idx->table;
+       MdbSarg *idx_sarg;
+       MdbSarg *sarg;
+       MdbField field;
+       MdbSargNode node;
+       //int c_offset = 0, 
+       int c_len;
+
+#if 0
+       fprintf(stderr,"mdb_index_test_sargs called on ");
+       for (i=0;i<len;i++)
+               fprintf(stderr,"%02x ",buf[i]); //mdb->pg_buf[offset+i]);
+       fprintf(stderr,"\n");
+#endif
+       for (i=0;i<idx->num_keys;i++) {
+               //c_offset++; /* the per column null indicator/flags */
+               col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
+               /*
+                * This will go away eventually
+                */
+               if (col->col_type==MDB_TEXT) {
+                       //c_len = strlen(&mdb->pg_buf[offset + c_offset]);
+                       c_len = strlen(buf);
+               } else {
+                       c_len = col->col_size;
+                       //fprintf(stderr,"Only text types currently supported.  How did we get here?\n");
+               }
+               /*
+                * If we have no cached index values for this column, 
+                * create them.
+                */
+               if (col->num_sargs && !col->idx_sarg_cache) {
+                       col->idx_sarg_cache = g_ptr_array_new();
+                       for (j=0;j<col->num_sargs;j++) {
+                               sarg = g_ptr_array_index (col->sargs, j);
+                               idx_sarg = g_memdup(sarg,sizeof(MdbSarg));
+                               //printf("calling mdb_index_cache_sarg\n");
+                               mdb_index_cache_sarg(col, sarg, idx_sarg);
+                               g_ptr_array_add(col->idx_sarg_cache, idx_sarg);
+                       }
+               }
+
+               for (j=0;j<col->num_sargs;j++) {
+                       sarg = g_ptr_array_index (col->idx_sarg_cache, j);
+                       /* XXX - kludge */
+                       node.op = sarg->op;
+                       node.value = sarg->value;
+                       //field.value = &mdb->pg_buf[offset + c_offset];
+                       field.value = buf;
+                       field.siz = c_len;
+                       field.is_null = FALSE;
+                       if (!mdb_test_sarg(mdb, col, &node, &field)) {
+                               /* sarg didn't match, no sense going on */
+                               return 0;
+                       }
+               }
+       }
+       return 1;
+}
+/*
+ * pack the pages bitmap
+ */
+int
+mdb_index_pack_bitmap(MdbHandle *mdb, MdbIndexPage *ipg)
+{
+       int mask_bit = 0;
+       int mask_pos = 0x16;
+       int mask_byte = 0;
+       int elem = 0;
+       int len, start, i;
+
+       start = ipg->idx_starts[elem++];
+
+       while (start) {
+               len = ipg->idx_starts[elem] - start;
+               fprintf(stdout, "len is %d\n", len);
+               for (i=0; i < len; i++) {
+                       mask_bit++;
+                       if (mask_bit==8) {
+                               mask_bit=0;
+                               mdb->pg_buf[mask_pos++] = mask_byte;
+                               mask_byte = 0;
+                       }
+                       /* upon reaching the len, set the bit */
+               }
+               mask_byte = (1 << mask_bit) | mask_byte;
+               fprintf(stdout, "mask byte is %02x at %d\n", mask_byte, mask_pos);
+               start = ipg->idx_starts[elem++];
+       }
+       /* flush the last byte if any */
+       mdb->pg_buf[mask_pos++] = mask_byte;
+       /* remember to zero the rest of the bitmap */
+       for (i = mask_pos; i < 0xf8; i++) {
+               mdb->pg_buf[mask_pos++] = 0;
+       }
+       return 0;
+}
+/*
+ * unpack the pages bitmap
+ */
+int
+mdb_index_unpack_bitmap(MdbHandle *mdb, MdbIndexPage *ipg)
+{
+       int mask_bit = 0;
+       int mask_pos = 0x16;
+       int mask_byte;
+       int start = 0xf8;
+       int elem = 0;
+       int len = 0;
+
+       ipg->idx_starts[elem++]=start;
+
+#if 0
+       fprintf(stdout, "Unpacking index page %u\n", ipg->pg);
+#endif
+       do {
+               len = 0;
+               do {
+                       mask_bit++;
+                       if (mask_bit==8) {
+                               mask_bit=0;
+                               mask_pos++;
+                       }
+                       mask_byte = mdb->pg_buf[mask_pos];
+                       len++;
+               } while (mask_pos <= 0xf8 && !((1 << mask_bit) & mask_byte));
+               //fprintf(stdout, "%d %d %d %d\n", mask_pos, mask_bit, mask_byte, len);
+
+               start += len;
+               if (mask_pos < 0xf8) ipg->idx_starts[elem++]=start;
+
+       } while (mask_pos < 0xf8);
+
+       /* if we zero the next element, so we don't pick up the last pages starts*/
+       ipg->idx_starts[elem]=0;
+
+       return elem;
+}
+/*
+ * find the next entry on a page (either index or leaf). Uses state information
+ * stored in the MdbIndexPage across calls.
+ */
+int
+mdb_index_find_next_on_page(MdbHandle *mdb, MdbIndexPage *ipg)
+{
+       if (!ipg->pg) return 0;
+
+       /* if this page has not been unpacked to it */
+       if (!ipg->idx_starts[0]){
+               //fprintf(stdout, "Unpacking page %d\n", ipg->pg);
+               mdb_index_unpack_bitmap(mdb, ipg);
+       }
+
+       
+       if (ipg->idx_starts[ipg->start_pos + 1]==0) return 0; 
+       ipg->len = ipg->idx_starts[ipg->start_pos+1] - ipg->idx_starts[ipg->start_pos];
+       ipg->start_pos++;
+       //fprintf(stdout, "Start pos %d\n", ipg->start_pos);
+
+       return ipg->len;
+}
+void mdb_index_page_reset(MdbIndexPage *ipg)
+{
+       ipg->offset = 0xf8; /* start byte of the index entries */
+       ipg->start_pos=0;
+       ipg->len = 0; 
+       ipg->idx_starts[0]=0;
+}
+void mdb_index_page_init(MdbIndexPage *ipg)
+{
+       memset(ipg, 0, sizeof(MdbIndexPage));
+       mdb_index_page_reset(ipg);
+}
+/*
+ * find the next leaf page if any given a chain. Assumes any exhausted leaf 
+ * pages at the end of the chain have been peeled off before the call.
+ */
+MdbIndexPage *
+mdb_find_next_leaf(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
+{
+       MdbIndexPage *ipg, *newipg;
+       guint32 pg;
+       guint passed = 0;
+
+       ipg = mdb_index_read_bottom_pg(mdb, idx, chain);
+
+       /*
+        * If we are at the first page deep and it's not an index page then
+        * we are simply done. (there is no page to find
+        */
+
+       if (mdb->pg_buf[0]==MDB_PAGE_LEAF) {
+               /* Indexes can have leaves at the end that don't appear
+                * in the upper tree, stash the last index found so
+                * we can follow it at the end.  */
+               chain->last_leaf_found = ipg->pg;
+               return ipg;
+       }
+
+       /*
+        * apply sargs here, currently we don't
+        */
+       do {
+               ipg->len = 0;
+               //printf("finding next on pg %lu\n", ipg->pg);
+               if (!mdb_index_find_next_on_page(mdb, ipg)) {
+                       //printf("find_next_on_page returned 0\n");
+                       return 0;
+               }
+               pg = mdb_pg_get_int24_msb(mdb, ipg->offset + ipg->len - 3);
+               //printf("Looking at pg %lu at %lu %d\n", pg, ipg->offset, ipg->len);
+               ipg->offset += ipg->len;
+
+               /*
+                * add to the chain and call this function
+                * recursively.
+                */
+               newipg = mdb_chain_add_page(mdb, chain, pg);
+               newipg = mdb_find_next_leaf(mdb, idx, chain);
+               //printf("returning pg %lu\n",newipg->pg);
+               return newipg;
+       } while (!passed);
+       /* no more pages */
+       return NULL;
+
+}
+MdbIndexPage *
+mdb_chain_add_page(MdbHandle *mdb, MdbIndexChain *chain, guint32 pg)
+{
+       MdbIndexPage *ipg;
+
+       chain->cur_depth++;
+       if (chain->cur_depth > MDB_MAX_INDEX_DEPTH) {
+               fprintf(stderr,"Error! maximum index depth of %d exceeded.  This is probably due to a programming bug, If you are confident that your indexes really are this deep, adjust MDB_MAX_INDEX_DEPTH in mdbtools.h and recompile.\n", MDB_MAX_INDEX_DEPTH);
+               exit(1);
+       }
+       ipg = &(chain->pages[chain->cur_depth - 1]);
+       mdb_index_page_init(ipg);
+       ipg->pg = pg;
+
+       return ipg;
+}
+/*
+ * returns the bottom page of the IndexChain, if IndexChain is empty it 
+ * initializes it by reading idx->first_pg (the root page)
+ */
+MdbIndexPage *
+mdb_index_read_bottom_pg(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
+{
+       MdbIndexPage *ipg;
+
+       /*
+        * if it's new use the root index page (idx->first_pg)
+        */
+       if (!chain->cur_depth) {
+               ipg = &(chain->pages[0]);
+               mdb_index_page_init(ipg);
+               chain->cur_depth = 1;
+               ipg->pg = idx->first_pg;
+               if (!(ipg = mdb_find_next_leaf(mdb, idx, chain)))
+                       return 0;
+       } else {
+               ipg = &(chain->pages[chain->cur_depth - 1]);
+               ipg->len = 0; 
+       }
+
+       mdb_read_pg(mdb, ipg->pg);
+
+       return ipg;
+}
+/*
+ * unwind the stack and search for new leaf node
+ */
+MdbIndexPage *
+mdb_index_unwind(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
+{
+       MdbIndexPage *ipg;
+
+       //printf("page %lu finished\n",ipg->pg);
+       if (chain->cur_depth==1) {
+               //printf("cur_depth == 1 we're out\n");
+               return NULL;
+       }
+       /* 
+       * unwind the stack until we find something or reach 
+       * the top.
+       */
+       ipg = NULL;
+       while (chain->cur_depth>1 && ipg==NULL) {
+               //printf("chain depth %d\n", chain->cur_depth);
+               chain->cur_depth--;
+               ipg = mdb_find_next_leaf(mdb, idx, chain);
+               if (ipg) mdb_index_find_next_on_page(mdb, ipg);
+       }
+       if (chain->cur_depth==1) {
+               //printf("last leaf %lu\n", chain->last_leaf_found);
+               return NULL;
+       }
+       return ipg;
+}
+/*
+ * the main index function.
+ * caller provides an index chain which is the current traversal of index
+ * pages from the root page to the leaf.  Initially passed as blank, 
+ * mdb_index_find_next will store it's state information here. Each invocation
+ * then picks up where the last one left off, allowing us to scroll through
+ * the index one by one.
+ *
+ * Sargs are applied here but also need to be applied on the whole row b/c
+ * text columns may return false positives due to hashing and non-index
+ * columns with sarg values can't be tested here.
+ */
+int
+mdb_index_find_next(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 *pg, guint16 *row)
+{
+       MdbIndexPage *ipg;
+       int passed = 0;
+       int idx_sz;
+       int idx_start = 0;
+       MdbColumn *col;
+
+       ipg = mdb_index_read_bottom_pg(mdb, idx, chain);
+
+       /*
+        * loop while the sargs don't match
+        */
+       do {
+               ipg->len = 0;
+               /*
+                * if no more rows on this leaf, try to find a new leaf
+                */
+               if (!mdb_index_find_next_on_page(mdb, ipg)) {
+                       if (!chain->clean_up_mode) {
+                               if (!(ipg = mdb_index_unwind(mdb, idx, chain)))
+                                       chain->clean_up_mode = 1;
+                       }
+                       if (chain->clean_up_mode) {
+                               //fprintf(stdout,"in cleanup mode\n");
+
+                               if (!chain->last_leaf_found) return 0;
+                               mdb_read_pg(mdb, chain->last_leaf_found);
+                               chain->last_leaf_found = mdb_pg_get_int24(mdb, 0x0c);
+                               //printf("next leaf %lu\n", chain->last_leaf_found);
+                               mdb_read_pg(mdb, chain->last_leaf_found);
+                               /* reuse the chain for cleanup mode */
+                               chain->cur_depth = 1;
+                               ipg = &chain->pages[0];
+                               mdb_index_page_init(ipg);
+                               ipg->pg = chain->last_leaf_found;
+                               //printf("next on page %d\n",
+                               if (!mdb_index_find_next_on_page(mdb, ipg))
+                                       return 0;
+                       }
+               }
+               *row = mdb->pg_buf[ipg->offset + ipg->len - 1];
+#if 0
+               printf("page: ");
+               buffer_dump(mdb->pg_buf, ipg->offset+ipg->len-4, ipg->offset+ipg->len-2);
+#endif
+               *pg = mdb_pg_get_int24_msb(mdb, ipg->offset + ipg->len - 4);
+#if 0
+               printf("row = %d pg = %lu ipg->pg = %lu offset = %lu len = %d\n", *row, *pg, ipg->pg, ipg->offset, ipg->len);
+#endif
+               col=g_ptr_array_index(idx->table->columns,idx->key_col_num[0]-1);
+               idx_sz = mdb_col_fixed_size(col);
+               /* handle compressed indexes, single key indexes only? */
+               if (idx->num_keys==1 && idx_sz>0 && ipg->len - 4 < idx_sz) {
+#if 0
+                       printf("short index found\n");
+                       buffer_dump(ipg->cache_value, 0, idx_sz);
+#endif
+                       memcpy(&ipg->cache_value[idx_sz - (ipg->len - 4)], &mdb->pg_buf[ipg->offset], ipg->len);
+#if 0
+                       buffer_dump(ipg->cache_value, 0, idx_sz);
+#endif
+               } else {
+                       idx_start = ipg->offset + (ipg->len - 4 - idx_sz);
+                       memcpy(ipg->cache_value, &mdb->pg_buf[idx_start], idx_sz);
+               }
+
+               //idx_start = ipg->offset + (ipg->len - 4 - idx_sz);
+               passed = mdb_index_test_sargs(mdb, idx, ipg->cache_value, idx_sz);
+
+//             printf("passed=%d\n", passed);
+
+               buffer_dump(mdb->pg_buf, ipg->offset, ipg->offset+ipg->len-1);
+               ipg->offset += ipg->len;
+
+       } while (!passed);
+
+#if 0
+       fprintf(stdout,"len = %d pos %d\n", ipg->len, ipg->len);
+       buffer_dump(mdb->pg_buf, ipg->offset, ipg->offset+ipg->len-1);
+#endif
+
+       return ipg->len;
+}
+/*
+ * XXX - FIX ME
+ * This function is grossly inefficient.  It scans the entire index building 
+ * an IndexChain to a specific row.  We should be checking the index pages 
+ * for matches against the indexed fields to find the proper leaf page, but
+ * getting it working first and then make it fast!
+ */
+int 
+mdb_index_find_row(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain, guint32 pg, guint16 row)
+{
+       MdbIndexPage *ipg;
+       int passed = 0;
+       guint32 datapg;
+       guint16 datarow;
+
+       ipg = mdb_index_read_bottom_pg(mdb, idx, chain);
+
+       do {
+               ipg->len = 0;
+               /*
+                * if no more rows on this leaf, try to find a new leaf
+                */
+               if (!mdb_index_find_next_on_page(mdb, ipg)) {
+                       /* back to top? We're done */
+                       if (chain->cur_depth==1)
+                               return 0;
+
+                       /* 
+                        * unwind the stack until we find something or reach 
+                        * the top.
+                        */
+                       while (chain->cur_depth>1) {
+                               chain->cur_depth--;
+                               if (!(ipg = mdb_find_next_leaf(mdb, idx, chain)))
+                                       return 0;
+                               mdb_index_find_next_on_page(mdb, ipg);
+                       }
+                       if (chain->cur_depth==1)
+                               return 0;
+               }
+               /* test row and pg */
+               datarow = mdb->pg_buf[ipg->offset + ipg->len - 1];
+               datapg = mdb_pg_get_int24_msb(mdb, ipg->offset + ipg->len - 4);
+
+               if (datapg == pg && datarow == row) {
+                       passed = 1;
+               }
+               ipg->offset += ipg->len;
+       } while (!passed);
+
+       /* index chain from root to leaf should now be in "chain" */
+       return 1;
+}
+
+void mdb_index_walk(MdbTableDef *table, MdbIndex *idx)
+{
+MdbHandle *mdb = table->entry->mdb;
+int cur_pos = 0;
+unsigned char marker;
+MdbColumn *col;
+unsigned int i;
+
+       if (idx->num_keys!=1) return;
+
+       mdb_read_pg(mdb, idx->first_pg);
+       cur_pos = 0xf8;
+       
+       for (i=0;i<idx->num_keys;i++) {
+               marker = mdb->pg_buf[cur_pos++];
+               col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
+               //printf("column %d coltype %d col_size %d (%d)\n",i,col->col_type, mdb_col_fixed_size(col), col->col_size);
+       }
+}
+void 
+mdb_index_dump(MdbTableDef *table, MdbIndex *idx)
+{
+       unsigned int i;
+       MdbColumn *col;
+
+       fprintf(stdout,"index number     %d\n", idx->index_num);
+       fprintf(stdout,"index name       %s\n", idx->name);
+       fprintf(stdout,"index first page %d\n", idx->first_pg);
+       fprintf(stdout,"index rows       %d\n", idx->num_rows);
+       if (idx->index_type==1) fprintf(stdout,"index is a primary key\n");
+       for (i=0;i<idx->num_keys;i++) {
+               col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
+               fprintf(stdout,"Column %s(%d) Sorted %s Unique: %s\n", 
+                       col->name,
+                       idx->key_col_num[i], 
+                       idx->key_col_order[i]==MDB_ASC ? "ascending" : "descending",
+                       idx->flags & MDB_IDX_UNIQUE ? "Yes" : "No"
+                       );
+       }
+       mdb_index_walk(table, idx);
+}
+/*
+ * compute_cost tries to assign a cost to a given index using the sargs 
+ * available in this query.
+ *
+ * Indexes with no matching sargs are assigned 0
+ * Unique indexes are preferred over non-uniques
+ * Operator preference is equal, like, isnull, others 
+ */
+int mdb_index_compute_cost(MdbTableDef *table, MdbIndex *idx)
+{
+       unsigned int i;
+       MdbColumn *col;
+       MdbSarg *sarg = NULL;
+       int not_all_equal = 0;
+
+       if (!idx->num_keys) return 0;
+       if (idx->num_keys > 1) {
+               for (i=0;i<idx->num_keys;i++) {
+                       col=g_ptr_array_index(table->columns,idx->key_col_num[i]-1);
+                       if (col->sargs) sarg = g_ptr_array_index (col->sargs, 0);
+                       if (!sarg || sarg->op != MDB_EQUAL) not_all_equal++;
+               }
+       }
+
+       col=g_ptr_array_index(table->columns,idx->key_col_num[0]-1);
+       /* 
+        * if this is the first key column and there are no sargs,
+        * then this index is useless.
+        */
+       if (!col->num_sargs) return 0;
+
+       sarg = g_ptr_array_index (col->sargs, 0);
+
+       /*
+        * a like with a wild card first is useless as a sarg */
+       if (sarg->op == MDB_LIKE && sarg->value.s[0]=='%')
+               return 0;
+
+       /*
+        * this needs a lot of tweaking.
+        */
+       if (idx->flags & MDB_IDX_UNIQUE) {
+               if (idx->num_keys == 1) {
+                       //printf("op is %d\n", sarg->op);
+                       switch (sarg->op) {
+                               case MDB_EQUAL:
+                                       return 1; break;
+                               case MDB_LIKE:
+                                       return 4; break;
+                               case MDB_ISNULL:
+                                       return 12; break;
+                               default:
+                                       return 8; break;
+                       }
+               } else {
+                       switch (sarg->op) {
+                               case MDB_EQUAL:
+                                       if (not_all_equal) return 2; 
+                                       else return 1;
+                                       break;
+                               case MDB_LIKE:
+                                       return 6; break;
+                               case MDB_ISNULL:
+                                       return 12; break;
+                               default:
+                                       return 9; break;
+                       }
+               }
+       } else {
+               if (idx->num_keys == 1) {
+                       switch (sarg->op) {
+                               case MDB_EQUAL:
+                                       return 2; break;
+                               case MDB_LIKE:
+                                       return 5; break;
+                               case MDB_ISNULL:
+                                       return 12; break;
+                               default:
+                                       return 10; break;
+                       }
+               } else {
+                       switch (sarg->op) {
+                               case MDB_EQUAL:
+                                       if (not_all_equal) return 3; 
+                                       else return 2;
+                                       break;
+                               case MDB_LIKE:
+                                       return 7; break;
+                               case MDB_ISNULL:
+                                       return 12; break;
+                               default:
+                                       return 11; break;
+                       }
+               }
+       }
+       return 0;
+}
+/*
+ * choose_index runs mdb_index_compute_cost for each available index and picks
+ * the best.
+ *
+ * Returns strategy to use (table scan, or index scan)
+ */
+MdbStrategy 
+mdb_choose_index(MdbTableDef *table, int *choice)
+{
+       unsigned int i;
+       MdbIndex *idx;
+       int cost = 0;
+       int least = 99;
+
+       *choice = -1;
+       for (i=0;i<table->num_idxs;i++) {
+               idx = g_ptr_array_index (table->indices, i);
+               cost = mdb_index_compute_cost(table, idx);
+               //printf("cost for %s is %d\n", idx->name, cost);
+               if (cost && cost < least) {
+                       least = cost;
+                       *choice = i;
+               }
+       }
+       /* and the winner is: *choice */
+       if (least==99) return MDB_TABLE_SCAN;
+       return MDB_INDEX_SCAN;
+}
+void
+mdb_index_scan_init(MdbHandle *mdb, MdbTableDef *table)
+{
+       int i;
+
+       if (mdb_get_option(MDB_USE_INDEX) && mdb_choose_index(table, &i) == MDB_INDEX_SCAN) {
+               table->strategy = MDB_INDEX_SCAN;
+               table->scan_idx = g_ptr_array_index (table->indices, i);
+               table->chain = g_malloc0(sizeof(MdbIndexChain));
+               table->mdbidx = mdb_clone_handle(mdb);
+               mdb_read_pg(table->mdbidx, table->scan_idx->first_pg);
+               //printf("best index is %s\n",table->scan_idx->name);
+       }
+       //printf("TABLE SCAN? %d\n", table->strategy);
+}
+void 
+mdb_index_scan_free(MdbTableDef *table)
+{
+       if (table->chain) {
+               g_free(table->chain);
+               table->chain = NULL;
+       }
+       if (table->mdbidx) {
+               mdb_close(table->mdbidx);
+               table->mdbidx = NULL;
+       }
+}
+
+void mdb_free_indices(GPtrArray *indices)
+{
+       unsigned int i;
+
+       if (!indices) return;
+       for (i=0; i<indices->len; i++)
+               g_free (g_ptr_array_index(indices, i));
+       g_ptr_array_free(indices, TRUE);
+}
diff --git a/navit/map/poi_geodownload/libmdb/kkd.c b/navit/map/poi_geodownload/libmdb/kkd.c
new file mode 100644 (file)
index 0000000..ea72887
--- /dev/null
@@ -0,0 +1,149 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+
+/*
+** Note: This code is mostly garbage right now...just a test to parse out the
+**       KKD structures.
+*/
+
+GArray *mdb_get_column_props(MdbCatalogEntry *entry, int start)
+{
+int pos, cnt=0;
+int len, tmp, cplen;
+MdbColumnProp prop;
+MdbHandle *mdb = entry->mdb;
+
+       entry->props = g_array_new(FALSE,FALSE,sizeof(MdbColumnProp));
+       len = mdb_pg_get_int16(mdb,start);
+       pos = start + 6;
+       while (pos < start+len) {
+               tmp = mdb_pg_get_int16(mdb,pos); /* length of string */
+               pos += 2;
+               cplen = tmp > MDB_MAX_OBJ_NAME ? MDB_MAX_OBJ_NAME : tmp;
+               g_memmove(prop.name,&mdb->pg_buf[pos],cplen);
+               prop.name[cplen]='\0';
+               pos += tmp; 
+               g_array_append_val(entry->props, prop.name);
+               cnt++;
+       }
+       entry->num_props = cnt;
+       return entry->props;
+}
+
+GHashTable *mdb_get_column_def(MdbCatalogEntry *entry, int start)
+{
+GHashTable *hash = NULL;
+MdbHandle *mdb = entry->mdb;
+MdbColumnProp prop;
+int tmp, pos, col_num, val_len, i;
+int len, col_type;
+unsigned char c;
+int end;
+
+       fprintf(stdout,"\n data\n");
+       fprintf(stdout,"-------\n");
+       len = mdb_pg_get_int16(mdb,start);
+       fprintf(stdout,"length = %3d\n",len);
+       pos = start + 6;
+       end = start + len;
+       while (pos < end) {
+               fprintf(stdout,"pos = %3d\n",pos);
+               start = pos;
+               tmp = mdb_pg_get_int16(mdb,pos); /* length of field */
+               pos += 2;
+               col_type = mdb_pg_get_int16(mdb,pos); /* ??? */
+               pos += 2;
+               col_num = 0;
+               if (col_type) {
+                       col_num = mdb_pg_get_int16(mdb,pos); 
+                       pos += 2;
+               }
+               val_len = mdb_pg_get_int16(mdb,pos);
+               pos += 2;
+               fprintf(stdout,"length = %3d %04x %2d %2d ",tmp, col_type, col_num, val_len);
+               for (i=0;i<val_len;i++) {
+                       c = mdb->pg_buf[pos+i];
+                       if (isprint(c))
+                               fprintf(stdout,"  %c",c);
+                       else 
+                               fprintf(stdout," %02x",c);
+
+               }
+               pos = start + tmp; 
+               prop = g_array_index(entry->props,MdbColumnProp,col_num);
+               fprintf(stdout," Property %s",prop.name); 
+               fprintf(stdout,"\n");
+       }
+       return hash;
+}
+void mdb_kkd_dump(MdbCatalogEntry *entry)
+{
+int rows;
+int kkd_start, kkd_end;
+int i, tmp, pos, row_type, datapos=0;
+MdbColumnProp prop;
+MdbHandle *mdb = entry->mdb;
+int rowid = entry->kkd_rowid;
+
+
+       mdb_read_pg(mdb, entry->kkd_pg);
+       rows = mdb_pg_get_int16(mdb,8);
+       fprintf(stdout,"number of rows = %d\n",rows);
+       kkd_start = mdb_pg_get_int16(mdb,10+rowid*2);
+       fprintf(stdout,"kkd start = %d %04x\n",kkd_start,kkd_start);
+       kkd_end = mdb->fmt->pg_size;
+       for (i=0;i<rows;i++) {
+               tmp = mdb_pg_get_int16(mdb, 10+i*2);
+               if (tmp < mdb->fmt->pg_size &&
+                   tmp > kkd_start &&
+                   tmp < kkd_end) {
+                       kkd_end = tmp;
+               }
+       }
+       fprintf(stdout,"kkd end = %d %04x\n",kkd_end,kkd_end);
+       pos = kkd_start + 4; /* 4 = K K D \0 */
+       while (pos < kkd_end) {
+               tmp = mdb_pg_get_int16(mdb,pos);
+               row_type = mdb_pg_get_int16(mdb,pos+4);
+               fprintf(stdout,"row size = %3d type = 0x%02x\n",tmp,row_type);
+               if (row_type==0x80)  {
+                       fprintf(stdout,"\nColumn Properties\n");
+                       fprintf(stdout,"-----------------\n");
+                       mdb_get_column_props(entry,pos);
+                       for (i=0;i<entry->num_props;i++) {
+                               prop = g_array_index(entry->props,MdbColumnProp,i);
+                               fprintf(stdout,"%3d %s\n",i,prop.name); 
+                       }
+               }
+               if (row_type==0x01) datapos = pos;
+               pos += tmp;
+       }
+       
+       if (datapos) {
+               mdb_get_column_def(entry, datapos);
+       }
+}
+
diff --git a/navit/map/poi_geodownload/libmdb/like.c b/navit/map/poi_geodownload/libmdb/like.c
new file mode 100644 (file)
index 0000000..0a23d45
--- /dev/null
@@ -0,0 +1,78 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <mdbtools.h>
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+/**
+ * mdb_like_cmp
+ * @s: String to search within.
+ * @r: Search pattern.
+ *
+ * Tests the string @s to see if it matches the search pattern @r.  In the
+ * search pattern, a percent sign indicates matching on any number of
+ * characters, and an underscore indicates matching any single character.
+ *
+ * Returns: 1 if the string matches, 0 if the string does not match.
+ */
+int mdb_like_cmp(char *s, char *r)
+{
+       unsigned int i;
+       int ret;
+
+       mdb_debug(MDB_DEBUG_LIKE, "comparing %s and %s", s, r);
+       switch (r[0]) {
+               case '\0':
+                       if (s[0]=='\0') {
+                               return 1;
+                       } else {
+                               return 0;
+                       }
+               case '_':
+                       /* skip one character */
+                       return mdb_like_cmp(&s[1],&r[1]);
+               case '%':
+                       /* skip any number of characters */
+                       /* the strlen(s)+1 is important so the next call can */
+                       /* if there are trailing characters */
+                       for(i=0;i<strlen(s)+1;i++) {
+                               if (mdb_like_cmp(&s[i],&r[1])) {
+                                       return 1;
+                               }
+                       }
+                       return 0;
+               default:
+                       for(i=0;i<strlen(r);i++) {
+                               if (r[i]=='_' || r[i]=='%') break;
+                       }
+                       if (strncmp(s,r,i)) {
+                               return 0;
+                       } else {
+                               mdb_debug(MDB_DEBUG_LIKE, "at pos %d comparing %s and %s", i, &s[i], &r[i]);
+                               ret = mdb_like_cmp(&s[i],&r[i]);
+                               mdb_debug(MDB_DEBUG_LIKE, "returning %d (%s and %s)", ret, &s[i], &r[i]);
+                               return ret;
+                       }
+       }
+}
diff --git a/navit/map/poi_geodownload/libmdb/map.c b/navit/map/poi_geodownload/libmdb/map.c
new file mode 100644 (file)
index 0000000..1164b7b
--- /dev/null
@@ -0,0 +1,133 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+static guint32 
+mdb_map_find_next0(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg)
+{
+       guint32 pgnum, i, usage_bitlen;
+       unsigned char *usage_bitmap;
+
+       pgnum = mdb_get_int32(map, 1);
+       usage_bitmap = map + 5;
+       usage_bitlen = (map_sz - 5) * 8;
+
+       i = (start_pg >= pgnum) ? start_pg-pgnum+1 : 0;
+       for (; i<usage_bitlen; i++) {
+               if (usage_bitmap[i/8] & (1 << (i%8))) {
+                       return pgnum + i;
+               }
+       }
+       /* didn't find anything */
+       return 0;
+}
+static int 
+mdb_map_find_next1(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg)
+{
+       guint32 map_ind, max_map_pgs, offset, usage_bitlen;
+
+       /*
+       * start_pg will tell us where to (re)start the scan
+       * for the next data page.  each usage_map entry points to a
+       * 0x05 page which bitmaps (mdb->fmt->pg_size - 4) * 8 pages.
+       *
+       * map_ind gives us the starting usage_map entry
+       * offset gives us a page offset into the bitmap
+       */
+       usage_bitlen = (mdb->fmt->pg_size - 4) * 8;
+       max_map_pgs = (map_sz - 1) / 4;
+       map_ind = (start_pg + 1) / usage_bitlen;
+       offset = (start_pg + 1) % usage_bitlen;
+
+       for (; map_ind<max_map_pgs; map_ind++) {
+               unsigned char *usage_bitmap;
+               guint32 i, map_pg;
+
+               if (!(map_pg = mdb_get_int32(map, (map_ind*4)+1))) {
+                       continue;
+               }
+               if(mdb_read_alt_pg(mdb, map_pg) != mdb->fmt->pg_size) {
+                       fprintf(stderr, "Oops! didn't get a full page at %d\n", map_pg);
+                       exit(1);
+               } 
+
+               usage_bitmap = mdb->alt_pg_buf + 4;
+               for (i=offset; i<usage_bitlen; i++) {
+                       if (usage_bitmap[i/8] & (1 << (i%8))) {
+                               return map_ind*usage_bitlen + i;
+                       }
+               }
+               offset = 0;
+       }
+       /* didn't find anything */
+       return 0;
+}
+guint32 
+mdb_map_find_next(MdbHandle *mdb, unsigned char *map, unsigned int map_sz, guint32 start_pg)
+{
+       if (map[0] == 0) {
+               return mdb_map_find_next0(mdb, map, map_sz, start_pg);
+       } else if (map[0] == 1) {
+               return mdb_map_find_next1(mdb, map, map_sz, start_pg);
+       }
+
+       fprintf(stderr, "Warning: unrecognized usage map type: %d\n", map[0]);
+       return -1;
+}
+guint32
+mdb_alloc_page(MdbTableDef *table)
+{
+       printf("Allocating new page\n");
+       return 0;
+}
+guint32 
+mdb_map_find_next_freepage(MdbTableDef *table, int row_size)
+{
+       MdbCatalogEntry *entry = table->entry;
+       MdbHandle *mdb = entry->mdb;
+       guint32 pgnum;
+       guint32 cur_pg = 0;
+       int free_space;
+
+       do {
+               pgnum = mdb_map_find_next(mdb, 
+                               table->free_usage_map, 
+                               table->freemap_sz, cur_pg);
+               printf("looking at page %d\n", pgnum);
+               if (!pgnum) {
+                       /* allocate new page */
+                       pgnum = mdb_alloc_page(table);
+                       return pgnum;
+               }
+               cur_pg = pgnum;
+
+               mdb_read_pg(mdb, pgnum);
+               free_space = mdb_pg_get_freespace(mdb);
+               
+       } while (free_space < row_size);
+
+       printf("page %d has %d bytes left\n", pgnum, free_space);
+
+       return pgnum;
+}
diff --git a/navit/map/poi_geodownload/libmdb/mem.c b/navit/map/poi_geodownload/libmdb/mem.c
new file mode 100644 (file)
index 0000000..208757e
--- /dev/null
@@ -0,0 +1,50 @@
+/* MDB Tools - A library for reading MS Access database files
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+#include <locale.h>
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+/**
+ * mdb_init:
+ *
+ * Initializes the LibMDB library.  This function should be called exactly once
+ * by calling program and prior to any other function.
+ *
+ **/
+void mdb_init(void)
+{
+       mdb_init_backends();
+}
+
+/**
+ * mdb_exit:
+ *
+ * Cleans up the LibMDB library.  This function should be called exactly once
+ * by the calling program prior to exiting (or prior to final use of LibMDB 
+ * functions).
+ *
+ **/
+void mdb_exit(void)
+{
+       mdb_remove_backends();
+}
diff --git a/navit/map/poi_geodownload/libmdb/money.c b/navit/map/poi_geodownload/libmdb/money.c
new file mode 100644 (file)
index 0000000..7f2cf65
--- /dev/null
@@ -0,0 +1,139 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 1998-1999  Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+#define MAXPRECISION 20
+/* 
+** these routines are copied from the freetds project which does something
+** very similiar
+*/
+
+static int multiply_byte(unsigned char *product, int num, unsigned char *multiplier);
+static int do_carry(unsigned char *product);
+static char *array_to_string(unsigned char *array, int unsigned scale, char *s);
+
+/**
+ * mdb_money_to_string
+ * @mdb: Handle to open MDB database file
+ * @start: Offset of the field within the current page
+ * @s: String that will receieve the value
+ *
+ * Returns: the string that has received the value.
+ */
+char *mdb_money_to_string(MdbHandle *mdb, int start, char *s)
+{
+       int num_bytes = 8;
+       int i;
+       int neg=0;
+       unsigned char multiplier[MAXPRECISION], temp[MAXPRECISION];
+       unsigned char product[MAXPRECISION];
+       unsigned char money[num_bytes];
+
+       memset(multiplier,0,MAXPRECISION);
+       memset(product,0,MAXPRECISION);
+       multiplier[0]=1;
+       memcpy(money, mdb->pg_buf + start, num_bytes);
+
+       /* Perform two's complement for negative numbers */
+       if (money[7] & 0x80) {
+               neg = 1;
+               for (i=0;i<num_bytes;i++) {
+                       money[i] = ~money[i];
+               }
+               for (i=0; i<num_bytes; i++) {
+                       money[i] ++;
+                       if (money[i]!=0) break;
+               }
+       }
+
+       for (i=0;i<num_bytes;i++) {
+               /* product += multiplier * current byte */
+               multiply_byte(product, money[i], multiplier);
+
+               /* multiplier = multiplier * 256 */
+               memcpy(temp, multiplier, MAXPRECISION);
+               memset(multiplier,0,MAXPRECISION);
+               multiply_byte(multiplier, 256, temp);
+       }
+       if (neg) {
+               s[0]='-';
+               array_to_string(product, 4, &s[1]);
+       } else {
+               array_to_string(product, 4, s);
+       }
+       return s;
+}
+static int multiply_byte(unsigned char *product, int num, unsigned char *multiplier)
+{
+       unsigned char number[3];
+       unsigned int i, j;
+
+       number[0]=num%10;
+       number[1]=(num/10)%10;
+       number[2]=(num/100)%10;
+
+       for (i=0;i<MAXPRECISION;i++) {
+               if (multiplier[i] == 0) continue;
+               for (j=0;j<3;j++) {
+                       if (number[j] == 0) continue;
+                       product[i+j] += multiplier[i]*number[j];
+               }
+               do_carry(product);
+       }
+       return 0;
+}
+static int do_carry(unsigned char *product)
+{
+       unsigned int j;
+
+       for (j=0;j<MAXPRECISION-1;j++) {
+               if (product[j]>9) {
+                       product[j+1]+=product[j]/10;
+                       product[j]=product[j]%10;
+               }
+       }
+       if (product[j]>9) {
+               product[j]=product[j]%10;
+       }
+       return 0;
+}
+static char *array_to_string(unsigned char *array, unsigned int scale, char *s)
+{
+       unsigned int top, i, j=0;
+       
+       for (top=MAXPRECISION;(top>0) && (top-1>scale) && !array[top-1];top--);
+
+       if (top == 0) {
+               s[j++] = '0';
+       } else {
+               for (i=top; i>0; i--) {
+                       if (j == top-scale) s[j++]='.';
+                       s[j++]=array[i-1]+'0';
+               }
+       }
+       s[j]='\0';
+
+       return s;
+}
diff --git a/navit/map/poi_geodownload/libmdb/options.c b/navit/map/poi_geodownload/libmdb/options.c
new file mode 100644 (file)
index 0000000..cdbbc66
--- /dev/null
@@ -0,0 +1,86 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2004 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#include <mdbtools.h>
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+#define DEBUG 1
+
+static unsigned long opts;
+static int optset;
+
+static void load_options();
+
+void
+mdb_debug(int klass, char *fmt, ...)
+{
+#ifdef DEBUG
+       va_list ap;
+
+       if (!optset) load_options();
+       if (klass & opts) {     
+       va_start(ap, fmt);
+       vfprintf (stdout,fmt, ap);
+       va_end(ap);
+       fprintf(stdout,"\n");
+       }
+#endif
+}
+
+static void
+load_options()
+{
+       char *opt;
+       char *s;
+
+    if (!optset && (s=getenv("MDBOPTS"))) {
+               opt = strtok(s, ":");
+               do {
+               if (!strcmp(opt, "use_index")) opts |= MDB_USE_INDEX;
+               if (!strcmp(opt, "debug_like")) opts |= MDB_DEBUG_LIKE;
+               if (!strcmp(opt, "debug_write")) opts |= MDB_DEBUG_WRITE;
+               if (!strcmp(opt, "debug_usage")) opts |= MDB_DEBUG_USAGE;
+               if (!strcmp(opt, "debug_ole")) opts |= MDB_DEBUG_OLE;
+               if (!strcmp(opt, "debug_row")) opts |= MDB_DEBUG_ROW;
+               if (!strcmp(opt, "debug_all")) {
+                               opts |= MDB_DEBUG_LIKE;
+                               opts |= MDB_DEBUG_WRITE;
+                               opts |= MDB_DEBUG_USAGE;
+                               opts |= MDB_DEBUG_OLE;
+                               opts |= MDB_DEBUG_ROW;
+                       }
+                       opt = strtok(NULL,":");
+               } while (opt);
+    }
+       optset = 1;
+}
+int
+mdb_get_option(unsigned long optnum)
+{
+       if (!optset) load_options();
+       return ((opts & optnum) > 0);
+}
diff --git a/navit/map/poi_geodownload/libmdb/props.c b/navit/map/poi_geodownload/libmdb/props.c
new file mode 100644 (file)
index 0000000..61db9f5
--- /dev/null
@@ -0,0 +1,127 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000 Brian Bruns
+ *
+ *
+ * This library is free software; you can redistribute it and/or 
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+GPtrArray *
+mdb_read_props_list(gchar *kkd, int len)
+{
+       guint32 record_len;
+       int pos = 0;
+       gchar *name;
+       GPtrArray *names = NULL;
+       int i = 0;
+
+       names = g_ptr_array_new();
+#ifdef MDB_DEBUG
+       buffer_dump(kkd, 0, len - 1);
+#endif
+       pos = 0;
+       while (pos < len) {
+               record_len = mdb_get_int16(kkd, pos);
+               pos += 2;
+#ifdef MDB_DEBUG
+               printf("%02d ",i++);
+               buffer_dump(kkd, pos - 2, pos + record_len - 1);
+#endif
+               name = g_malloc(record_len + 1);
+               strncpy(name, &kkd[pos], record_len);
+               name[record_len] = '\0';
+               pos += record_len;
+               g_ptr_array_add(names, name);
+#ifdef MDB_DEBUG
+               printf("new len = %d\n", names->len);
+#endif
+       }
+       return names;
+}
+void
+mdb_free_props(MdbProperties *props)
+{
+       if (!props) return;
+
+       if (props->name) g_free(props->name);
+       g_free(props);
+}
+MdbProperties *
+mdb_alloc_props()
+{
+       MdbProperties *props;
+
+       props = g_malloc0(sizeof(MdbProperties));
+
+       return props;
+}
+MdbProperties * 
+mdb_read_props(MdbHandle *mdb, GPtrArray *names, gchar *kkd, int len)
+{
+       guint32 record_len, name_len;
+       int pos = 0;
+       int elem, dtype, dsize;
+       gchar *name, *value;
+       MdbProperties *props;
+       int i = 0;
+
+#ifdef MDB_DEBUG
+       buffer_dump(kkd, 0, len - 1);
+#endif
+       pos = 0;
+
+       /* skip the name record */
+       record_len = mdb_get_int16(kkd, pos);
+       pos += 4;
+       name_len = mdb_get_int16(kkd, pos);
+       pos += 2;
+       props = mdb_alloc_props();
+       if (name_len) {
+               props->name = g_malloc(name_len + 1);
+               strncpy(props->name, &kkd[pos], name_len);
+               props->name[name_len]='\0';
+       }
+       pos += name_len;
+
+       props->hash = g_hash_table_new(g_str_hash, g_str_equal);
+
+       while (pos < len) {
+               record_len = mdb_get_int16(kkd, pos);
+               elem = mdb_get_int16(kkd, pos + 4);
+               dtype = kkd[pos + 3];
+               dsize = mdb_get_int16(kkd, pos + 6);
+               value = g_malloc(dsize + 1);
+               strncpy(value, &kkd[pos + 8], dsize);
+               value[dsize] = '\0';
+               name = g_ptr_array_index(names,elem);
+#ifdef MDB_DEBUG
+               printf("%02d ",i++);
+               buffer_dump(kkd, pos, pos + record_len - 1);
+               printf("elem %d dsize %d dtype %d\n", elem, dsize, dtype);
+#endif
+               if (dtype == MDB_MEMO) dtype = MDB_TEXT;
+               if (dtype == MDB_BOOL) {
+                       g_hash_table_insert(props->hash, g_strdup(name), g_strdup(kkd[pos + 8] ? "yes" : "no"));
+               } else {
+                       g_hash_table_insert(props->hash, g_strdup(name), g_strdup(mdb_col_to_string(mdb, kkd, pos + 8, dtype, dsize)));
+               }
+               g_free(value);
+               pos += record_len;
+       }
+       return props;
+       
+}
diff --git a/navit/map/poi_geodownload/libmdb/sargs.c b/navit/map/poi_geodownload/libmdb/sargs.c
new file mode 100644 (file)
index 0000000..b14aaa9
--- /dev/null
@@ -0,0 +1,273 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * code for handling searchable arguments (sargs) used primary by the sql 
+ * engine to support where clause handling.  The sargs are configured in 
+ * a tree with AND/OR operators connecting the child nodes. NOT operations
+ * have only one child on the left side.  Logical operators (=,<,>,etc..)
+ * have no children.
+ *
+ * datatype support is a bit weak at this point.  To add more types create
+ * a mdb_test_[type]() function and invoke it from mdb_test_sarg()
+ */
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+void
+mdb_sql_walk_tree(MdbSargNode *node, MdbSargTreeFunc func, gpointer data)
+{
+       if (func(node, data))
+               return;
+       if (node->left) mdb_sql_walk_tree(node->left, func, data);
+       if (node->right) mdb_sql_walk_tree(node->right, func, data);
+}
+int 
+mdb_test_string(MdbSargNode *node, char *s)
+{
+int rc;
+
+       if (node->op == MDB_LIKE) {
+               return mdb_like_cmp(s,node->value.s);
+       }
+       rc = strncmp(node->value.s, s, 255);
+       switch (node->op) {
+               case MDB_EQUAL:
+                       if (rc==0) return 1;
+                       break;
+               case MDB_GT:
+                       if (rc<0) return 1;
+                       break;
+               case MDB_LT:
+                       if (rc>0) return 1;
+                       break;
+               case MDB_GTEQ:
+                       if (rc<=0) return 1;
+                       break;
+               case MDB_LTEQ:
+                       if (rc>=0) return 1;
+                       break;
+               default:
+                       fprintf(stderr, "Calling mdb_test_sarg on unknown operator.  Add code to mdb_test_string() for operator %d\n",node->op);
+                       break;
+       }
+       return 0;
+}
+int mdb_test_int(MdbSargNode *node, gint32 i)
+{
+       switch (node->op) {
+               case MDB_EQUAL:
+                       printf("comparing %x and %x %d\n", i, node->value.i, node->value.i == i);
+                       if (node->value.i == i) return 1;
+                       break;
+               case MDB_GT:
+                       if (node->value.i < i) return 1;
+                       break;
+               case MDB_LT:
+                       if (node->value.i > i) return 1;
+                       break;
+               case MDB_GTEQ:
+                       if (node->value.i <= i) return 1;
+                       break;
+               case MDB_LTEQ:
+                       if (node->value.i >= i) return 1;
+                       break;
+               default:
+                       fprintf(stderr, "Calling mdb_test_sarg on unknown operator.  Add code to mdb_test_int() for operator %d\n",node->op);
+                       break;
+       }
+       return 0;
+}
+#if 0
+#endif
+int
+mdb_find_indexable_sargs(MdbSargNode *node, gpointer data)
+{
+       MdbSarg sarg;
+
+       if (node->op == MDB_OR || node->op == MDB_NOT) return 1;
+
+       /* 
+        * right now all we do is look for sargs that are anded together from
+        * the root.  Later we may put together OR ops into a range, and then 
+        * range scan the leaf pages. That is col1 = 2 or col1 = 4 becomes
+        * col1 >= 2 and col1 <= 4 for the purpose of index scans, and then
+        * extra rows are thrown out when the row is tested against the main
+        * sarg tree.  range scans are generally only a bit better than table
+        * scanning anyway.
+        *
+        * also, later we should support the NOT operator, but it's generally
+        * a pretty worthless test for indexes, ie NOT col1 = 3, we are 
+        * probably better off table scanning.
+        */
+       if (mdb_is_relational_op(node->op) && node->col) {
+               //printf("op = %d value = %s\n", node->op, node->value.s);
+               sarg.op = node->op;
+               sarg.value = node->value;
+               mdb_add_sarg(node->col, &sarg);
+       }
+       return 0;
+}
+int 
+mdb_test_sarg(MdbHandle *mdb, MdbColumn *col, MdbSargNode *node, MdbField *field)
+{
+char tmpbuf[256];
+int lastchar;
+
+       if (node->op == MDB_ISNULL) {
+               if (field->is_null) return 0;
+               else return 1;
+       } else if (node->op == MDB_NOTNULL) {
+               if (field->is_null) return 1;
+               else return 0;
+       }
+       switch (col->col_type) {
+               case MDB_BOOL:
+                       return mdb_test_int(node, !field->is_null);
+                       break;
+               case MDB_BYTE:
+                       return mdb_test_int(node, (gint32)((char *)field->value)[0]);
+                       break;
+               case MDB_INT:
+                       return mdb_test_int(node, (gint32)mdb_get_int16(field->value, 0));
+                       break;
+               case MDB_LONGINT:
+                       return mdb_test_int(node, (gint32)mdb_get_int32(field->value, 0));
+                       break;
+               case MDB_TEXT:
+                       if (IS_JET4(mdb)) {
+                               mdb_unicode2ascii(mdb, field->value, 0, field->siz, tmpbuf);
+                       } else {
+                               strncpy(tmpbuf, field->value, 255);
+                               lastchar = field->siz > 255 ? 255 : field->siz;
+                               tmpbuf[lastchar]='\0';
+                       }
+                       return mdb_test_string(node, tmpbuf);
+               default:
+                       fprintf(stderr, "Calling mdb_test_sarg on unknown type.  Add code to mdb_test_sarg() for type %d\n",col->col_type);
+                       break;
+       }
+       return 1;
+}
+int
+mdb_find_field(int col_num, MdbField *fields, int num_fields)
+{
+       int i;
+
+       for (i=0;i<num_fields;i++) {
+               if (fields[i].colnum == col_num) return i;
+       }
+       return -1;
+}
+int
+mdb_test_sarg_node(MdbHandle *mdb, MdbSargNode *node, MdbField *fields, int num_fields)
+{
+       int elem;
+       MdbColumn *col;
+       int rc;
+
+       if (mdb_is_relational_op(node->op)) {
+               col = node->col;
+               /* for const = const expressions */
+               if (!col) {
+                       return (node->value.i);
+               }
+               elem = mdb_find_field(col->col_num, fields, num_fields);
+               if (!mdb_test_sarg(mdb, col, node, &fields[elem])) 
+                       return 0;
+       } else { /* logical op */
+               switch (node->op) {
+               case MDB_NOT:
+                       rc = mdb_test_sarg_node(mdb, node->left, fields, num_fields);
+                       return !rc;
+                       break;
+               case MDB_AND:
+                       if (!mdb_test_sarg_node(mdb, node->left, fields, num_fields))
+                               return 0;
+                       return mdb_test_sarg_node(mdb, node->right, fields, num_fields);
+                       break;
+               case MDB_OR:
+                       if (mdb_test_sarg_node(mdb, node->left, fields, num_fields))
+                               return 1;
+                       return mdb_test_sarg_node(mdb, node->right, fields, num_fields);
+                       break;
+               }
+       }
+       return 1;
+}
+int 
+mdb_test_sargs(MdbTableDef *table, MdbField *fields, int num_fields)
+{
+       MdbSargNode *node;
+       MdbCatalogEntry *entry = table->entry;
+       MdbHandle *mdb = entry->mdb;
+
+       node = table->sarg_tree;
+
+       /* there may not be a sarg tree */
+       if (!node) return 1;
+
+       return mdb_test_sarg_node(mdb, node, fields, num_fields);
+}
+#if 0
+int mdb_test_sargs(MdbHandle *mdb, MdbColumn *col, int offset, int len)
+{
+MdbSarg *sarg;
+int i;
+
+       for (i=0;i<col->num_sargs;i++) {
+               sarg = g_ptr_array_index (col->sargs, i);
+               if (!mdb_test_sarg(mdb, col, sarg, offset, len)) {
+                       /* sarg didn't match, no sense going on */
+                       return 0;       
+               }
+       }
+
+       return 1;
+}
+#endif
+int mdb_add_sarg(MdbColumn *col, MdbSarg *in_sarg)
+{
+MdbSarg *sarg;
+        if (!col->sargs) {
+               col->sargs = g_ptr_array_new();
+       }
+       sarg = g_memdup(in_sarg,sizeof(MdbSarg));
+        g_ptr_array_add(col->sargs, sarg);
+       col->num_sargs++;
+
+       return 1;
+}
+int mdb_add_sarg_by_name(MdbTableDef *table, char *colname, MdbSarg *in_sarg)
+{
+       MdbColumn *col;
+       unsigned int i;
+
+       for (i=0;i<table->num_cols;i++) {
+               col = g_ptr_array_index (table->columns, i);
+               if (!strcasecmp(col->name,colname)) {
+                       return mdb_add_sarg(col, in_sarg);
+               }
+       }
+       /* else didn't find the column return 0! */
+       return 0;
+}
diff --git a/navit/map/poi_geodownload/libmdb/stats.c b/navit/map/poi_geodownload/libmdb/stats.c
new file mode 100644 (file)
index 0000000..1abf285
--- /dev/null
@@ -0,0 +1,74 @@
+/* MDB Tools - A library for reading MS Access database files
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+/**
+ * mdb_stats_on:
+ * @mdb: Handle to the (open) MDB file to collect stats on.
+ *
+ * Begins collection of statistics on an MDBHandle.
+ *
+ * Statistics in LibMDB will track the number of reads from the MDB file.  The
+ * collection of statistics is started and stopped with the mdb_stats_on and
+ * mdb_stats_off functions.  Collected statistics are accessed by reading the
+ * MdbStatistics structure or calling mdb_dump_stats.
+ * 
+ */
+void
+mdb_stats_on(MdbHandle *mdb)
+{
+       if (!mdb->stats) 
+               mdb->stats = g_malloc0(sizeof(MdbStatistics));
+
+       mdb->stats->collect = TRUE;
+}
+/**
+ * mdb_stats_off:
+ * @mdb: pointer to handle of MDB file with active stats collection.
+ *
+ * Turns off statistics collection.
+ *
+ * If mdb_stats_off is not called, statistics will be turned off when handle
+ * is freed using mdb_close.
+ **/
+void
+mdb_stats_off(MdbHandle *mdb)
+{
+       if (!mdb->stats) return;
+
+       mdb->stats->collect = FALSE;
+}
+/**
+ * mdb_dump_stats:
+ * @mdb: pointer to handle of MDB file with active stats collection.
+ *
+ * Dumps current statistics to stdout.
+ **/
+void
+mdb_dump_stats(MdbHandle *mdb)
+{
+       if (!mdb->stats) return;
+
+       fprintf(stdout, "Physical Page Reads: %lu\n", mdb->stats->pg_reads);
+}
diff --git a/navit/map/poi_geodownload/libmdb/table.c b/navit/map/poi_geodownload/libmdb/table.c
new file mode 100644 (file)
index 0000000..52238ec
--- /dev/null
@@ -0,0 +1,368 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+
+static gint mdb_col_comparer(MdbColumn **a, MdbColumn **b)
+{
+       if ((*a)->col_num > (*b)->col_num)
+               return 1;
+       else if ((*a)->col_num < (*b)->col_num)
+               return -1;
+       else
+               return 0;
+}
+
+static unsigned char mdb_col_needs_size(int col_type)
+{
+       if (col_type == MDB_TEXT) {
+               return TRUE;
+       } else {
+               return FALSE;
+       }
+}
+
+MdbTableDef *mdb_alloc_tabledef(MdbCatalogEntry *entry)
+{
+       MdbTableDef *table;
+
+       table = (MdbTableDef *) g_malloc0(sizeof(MdbTableDef));
+       table->entry=entry;
+       strcpy(table->name, entry->object_name);
+
+       return table;   
+}
+void mdb_free_tabledef(MdbTableDef *table)
+{
+       if (!table) return;
+       if (table->is_temp_table) {
+               unsigned int i;
+               for (i=0; i<table->temp_table_pages->len; i++)
+                       g_free(g_ptr_array_index(table->temp_table_pages,i));
+               g_ptr_array_free(table->temp_table_pages, TRUE);
+       }
+       mdb_free_columns(table->columns);
+       mdb_free_indices(table->indices);
+       g_free(table->usage_map);
+       g_free(table->free_usage_map);
+       g_free(table);
+}
+MdbTableDef *mdb_read_table(MdbCatalogEntry *entry)
+{
+       MdbTableDef *table;
+       MdbHandle *mdb = entry->mdb;
+       MdbFormatConstants *fmt = mdb->fmt;
+       int len, row_start, pg_row;
+       char *buf;
+
+       table = mdb_alloc_tabledef(entry);
+
+       mdb_read_pg(mdb, entry->table_pg);
+       if (mdb->pg_buf[0] != 0x02) return NULL; /* not a valid table def page */
+
+       len = mdb_pg_get_int16(mdb,8);
+
+       table->num_rows = mdb_pg_get_int32(mdb, fmt->tab_num_rows_offset);
+       table->num_var_cols = mdb_pg_get_int16(mdb, fmt->tab_num_cols_offset-2);
+       table->num_cols = mdb_pg_get_int16(mdb, fmt->tab_num_cols_offset);
+       table->num_idxs = mdb_pg_get_int32(mdb, fmt->tab_num_idxs_offset); 
+       table->num_real_idxs = mdb_pg_get_int32(mdb, fmt->tab_num_ridxs_offset); 
+       /* grab a copy of the usage map */
+       pg_row = mdb_pg_get_int32(mdb, fmt->tab_usage_map_offset);
+       mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &(table->map_sz));
+       table->usage_map = g_memdup(buf + row_start, table->map_sz);
+       if (mdb_get_option(MDB_DEBUG_USAGE)) 
+               buffer_dump(buf, row_start, row_start+table->map_sz-1);
+       mdb_debug(MDB_DEBUG_USAGE,"usage map found on page %ld row %d start %d len %d",
+               pg_row >> 8, pg_row & 0xff, row_start, table->map_sz);
+
+       /* grab a copy of the free space page map */
+       pg_row = mdb_pg_get_int32(mdb, fmt->tab_free_map_offset);
+       mdb_find_pg_row(mdb, pg_row, &buf, &row_start, &(table->freemap_sz));
+       table->free_usage_map = g_memdup(buf + row_start, table->freemap_sz);
+       mdb_debug(MDB_DEBUG_USAGE,"free map found on page %ld row %d start %d len %d\n",
+               pg_row >> 8, pg_row & 0xff, row_start, table->freemap_sz);
+
+       table->first_data_pg = mdb_pg_get_int16(mdb, fmt->tab_first_dpg_offset);
+
+       return table;
+}
+MdbTableDef *mdb_read_table_by_name(MdbHandle *mdb, gchar *table_name, int obj_type)
+{
+       unsigned int i;
+       MdbCatalogEntry *entry;
+
+       mdb_read_catalog(mdb, obj_type);
+
+       for (i=0; i<mdb->num_catalog; i++) {
+               entry = g_ptr_array_index(mdb->catalog, i);
+               if (!strcasecmp(entry->object_name, table_name))
+                       return mdb_read_table(entry);
+       }
+
+       return NULL;
+}
+
+/*
+** read the next page if offset is > pg_size
+** return true if page was read
+*/ 
+int 
+read_pg_if(MdbHandle *mdb, int *cur_pos, int offset)
+{
+       if (*cur_pos + offset >= mdb->fmt->pg_size) {
+               mdb_read_pg(mdb, mdb_pg_get_int32(mdb,4));
+               *cur_pos = 8 - (mdb->fmt->pg_size - (*cur_pos));
+               return 1;
+       }
+       return 0;
+}
+guint32 
+read_pg_if_32(MdbHandle *mdb, int *cur_pos)
+{
+       unsigned char c[4];
+       int i, rc = 0;
+
+       for (i=0;i<4;i++) {
+               rc += read_pg_if(mdb, cur_pos, i);
+               c[i] = mdb->pg_buf[(*cur_pos) + i];
+       }
+       return mdb_get_int32(c, 0);
+}
+guint16 
+read_pg_if_16(MdbHandle *mdb, int *cur_pos)
+{
+       unsigned char low_byte, high_byte;
+       int rc = 0;
+
+       rc += read_pg_if(mdb, cur_pos, 0);
+       low_byte = mdb->pg_buf[*cur_pos];
+       rc += read_pg_if(mdb, cur_pos, 1);
+       high_byte = mdb->pg_buf[(*cur_pos) + 1];
+
+       return (high_byte * 256 + low_byte);
+}
+guint16 
+read_pg_if_n(MdbHandle *mdb, unsigned char *buf, int *cur_pos, int len)
+{
+       if (*cur_pos + len < mdb->fmt->pg_size) {
+               memcpy(buf, &mdb->pg_buf[*cur_pos], len);
+               return 0;
+       } else {
+               int half = mdb->fmt->pg_size - *cur_pos;
+               memcpy(buf, &mdb->pg_buf[*cur_pos], half);
+               mdb_read_pg(mdb, mdb_pg_get_int32(mdb,4));
+               memcpy(buf + half, &mdb->pg_buf[8], len - half);
+               *cur_pos = 8 - half;
+               return 1;
+       }
+}
+
+void mdb_append_column(GPtrArray *columns, MdbColumn *in_col)
+{
+       g_ptr_array_add(columns, g_memdup(in_col,sizeof(MdbColumn)));
+}
+void mdb_free_columns(GPtrArray *columns)
+{
+       unsigned int i;
+
+       if (!columns) return;
+       for (i=0; i<columns->len; i++)
+               g_free (g_ptr_array_index(columns, i));
+       g_ptr_array_free(columns, TRUE);
+}
+GPtrArray *mdb_read_columns(MdbTableDef *table)
+{
+       MdbHandle *mdb = table->entry->mdb;
+       MdbFormatConstants *fmt = mdb->fmt;
+       MdbColumn *pcol;
+       unsigned char *col;
+       unsigned int i;
+       int cur_pos, name_sz;
+       
+       table->columns = g_ptr_array_new();
+
+       col = (unsigned char *) g_malloc(fmt->tab_col_entry_size);
+
+       cur_pos = fmt->tab_cols_start_offset + 
+               (table->num_real_idxs * fmt->tab_ridx_entry_size);
+
+       /* new code based on patch submitted by Tim Nelson 2000.09.27 */
+
+       /* 
+       ** column attributes 
+       */
+       for (i=0;i<table->num_cols;i++) {
+#ifdef MDB_DEBUG
+       /* printf("column %d\n", i);
+       buffer_dump(mdb->pg_buf, cur_pos ,cur_pos + 18); */
+#endif
+               read_pg_if_n(mdb, col, &cur_pos, fmt->tab_col_entry_size);
+               cur_pos += fmt->tab_col_entry_size;
+               pcol = (MdbColumn *) g_malloc0(sizeof(MdbColumn));
+
+               pcol->col_type = col[0];
+
+               // col_num_offset == 1 or 5
+               pcol->col_num = col[fmt->col_num_offset];
+
+               //fprintf(stdout,"----- column %d -----\n",pcol->col_num);
+               // col_var == 3 or 7
+               pcol->var_col_num = mdb_get_int16(col, fmt->tab_col_offset_var);
+               //fprintf(stdout,"var column pos %d\n",pcol->var_col_num);
+
+               // col_var == 5 or 9
+               pcol->row_col_num = mdb_get_int16(col, fmt->tab_row_col_num_offset);
+               //fprintf(stdout,"row column num %d\n",pcol->row_col_num);
+
+               /* FIXME: can this be right in Jet3 and Jet4? */
+               if (pcol->col_type == MDB_NUMERIC) {
+                       pcol->col_prec = col[11];
+                       pcol->col_scale = col[12];
+               }
+
+               // col_fixed_offset == 13 or 15
+               pcol->is_fixed = col[fmt->col_fixed_offset] & 0x01 ? 1 : 0;
+
+               // col_fixed_offset == 13 or 15
+               pcol->fixed_offset = mdb_get_int16(col, fmt->tab_col_offset_fixed);
+               //fprintf(stdout,"fixed column offset %d\n",pcol->fixed_offset);
+               //fprintf(stdout,"col type %s\n",pcol->is_fixed ? "fixed" : "variable");
+
+               if (pcol->col_type != MDB_BOOL) {
+                       // col_size_offset == 16 or 23
+                       pcol->col_size = mdb_get_int16(col, fmt->col_size_offset);
+               } else {
+                       pcol->col_size=0;
+               }
+               
+               g_ptr_array_add(table->columns, pcol);
+       }
+
+       g_free (col);
+
+       /* 
+       ** column names - ordered the same as the column attributes table
+       */
+       for (i=0;i<table->num_cols;i++) {
+               pcol = g_ptr_array_index(table->columns, i);
+
+               if (IS_JET4(mdb)) {
+                       char *tmp_buf;
+                       name_sz = read_pg_if_16(mdb, &cur_pos);
+                       cur_pos += 2;
+                       tmp_buf = (char *) g_malloc(name_sz);
+                       read_pg_if_n(mdb, tmp_buf, &cur_pos, name_sz);
+                       mdb_unicode2ascii(mdb, tmp_buf, 0, name_sz, pcol->name);
+                       g_free(tmp_buf);
+                       cur_pos += name_sz;
+               } else if (IS_JET3(mdb)) {
+                       read_pg_if(mdb, &cur_pos, 0);
+                       name_sz = mdb->pg_buf[cur_pos];
+                       cur_pos++;
+                       read_pg_if_n(mdb, pcol->name, &cur_pos, name_sz);
+                       pcol->name[name_sz]='\0';
+                       cur_pos += name_sz;
+               } else {
+                       fprintf(stderr,"Unknown MDB version\n");
+               }
+       }
+
+       /* Sort the columns by col_num */
+       g_ptr_array_sort(table->columns, (GCompareFunc)mdb_col_comparer);
+
+       table->index_start = cur_pos;
+       return table->columns;
+}
+
+void mdb_table_dump(MdbCatalogEntry *entry)
+{
+MdbTableDef *table;
+MdbColumn *col;
+int coln;
+MdbIndex *idx;
+MdbHandle *mdb = entry->mdb;
+unsigned int i, bitn;
+guint32 pgnum;
+
+       table = mdb_read_table(entry);
+       fprintf(stdout,"definition page     = %lu\n",entry->table_pg);
+       fprintf(stdout,"number of datarows  = %d\n",table->num_rows);
+       fprintf(stdout,"number of columns   = %d\n",table->num_cols);
+       fprintf(stdout,"number of indices   = %d\n",table->num_real_idxs);
+
+       mdb_read_columns(table);
+       mdb_read_indices(table);
+
+       for (i=0;i<table->num_cols;i++) {
+               col = g_ptr_array_index(table->columns,i);
+       
+               fprintf(stdout,"column %d Name: %-20s Type: %s(%d)\n",
+                       i, col->name,
+                       mdb_get_coltype_string(mdb->default_backend, col->col_type),
+                       col->col_size);
+       }
+
+       for (i=0;i<table->num_idxs;i++) {
+               idx = g_ptr_array_index (table->indices, i);
+               mdb_index_dump(table, idx);
+       }
+       if (table->usage_map) {
+               printf("pages reserved by this object\n");
+               printf("usage map pg %" G_GUINT32_FORMAT "\n",
+                       table->map_base_pg);
+               printf("free map pg %" G_GUINT32_FORMAT "\n",
+                       table->freemap_base_pg);
+               pgnum = mdb_get_int32(table->usage_map,1);
+               /* the first 5 bytes of the usage map mean something */
+               coln = 0;
+               for (i=5;i<table->map_sz;i++) {
+                       for (bitn=0;bitn<8;bitn++) {
+                               if (table->usage_map[i] & 1 << bitn) {
+                                       coln++;
+                                       printf("%6" G_GUINT32_FORMAT, pgnum);
+                                       if (coln==10) {
+                                               printf("\n");
+                                               coln = 0;
+                                       } else {
+                                               printf(" ");
+                                       }
+                               }
+                               pgnum++;
+                       }
+               }
+               printf("\n");
+       }
+}
+
+int mdb_is_user_table(MdbCatalogEntry *entry)
+{
+       return ((entry->object_type == MDB_TABLE)
+        && !(entry->flags & 0x80000002)) ? 1 : 0;
+}
+int mdb_is_system_table(MdbCatalogEntry *entry)
+{
+       return ((entry->object_type == MDB_TABLE)
+        && (entry->flags & 0x80000002)) ? 1 : 0;
+}
diff --git a/navit/map/poi_geodownload/libmdb/worktable.c b/navit/map/poi_geodownload/libmdb/worktable.c
new file mode 100644 (file)
index 0000000..6f893dc
--- /dev/null
@@ -0,0 +1,99 @@
+/* MDB Tools - A library for reading MS Access database files
+ * Copyright (C) 2004 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+/*
+ * Temp table routines.  These are currently used to generate mock results for
+ * commands like "list tables" and "describe table"
+ */
+
+void
+mdb_fill_temp_col(MdbColumn *tcol, char *col_name, int col_size, int col_type, int is_fixed)
+{
+       memset(tcol,0,sizeof(MdbColumn));
+       strcpy(tcol->name, col_name);
+       tcol->col_type = col_type;
+       if ((col_type == MDB_TEXT) || (col_type == MDB_MEMO)) {
+               tcol->col_size = col_size;
+       } else {
+               tcol->col_size = mdb_col_fixed_size(tcol);
+       }
+       tcol->is_fixed = is_fixed;
+}
+void
+mdb_fill_temp_field(MdbField *field, void *value, int siz, int is_fixed, int is_null, int start, int colnum)
+{
+       field->value = value;
+       field->siz = siz;
+       field->is_fixed = is_fixed;
+       field->is_null = is_null;
+       field->start = start;
+       field->colnum = colnum;
+}
+MdbTableDef *
+mdb_create_temp_table(MdbHandle *mdb, char *name)
+{
+       MdbCatalogEntry *entry;
+       MdbTableDef *table;
+
+       /* dummy up a catalog entry */
+       entry = (MdbCatalogEntry *) g_malloc0(sizeof(MdbCatalogEntry));
+       entry->mdb = mdb;
+       entry->object_type = MDB_TABLE;
+       entry->table_pg = 0;
+       strcpy(entry->object_name, name);
+
+       table = mdb_alloc_tabledef(entry);
+       table->columns = g_ptr_array_new();
+       table->is_temp_table = 1;
+       table->temp_table_pages = g_ptr_array_new();
+
+       return table;
+}
+void
+mdb_temp_table_add_col(MdbTableDef *table, MdbColumn *col)
+{
+       col->col_num = table->num_cols;
+       if (!col->is_fixed)
+               col->var_col_num = table->num_var_cols++;
+       g_ptr_array_add(table->columns, g_memdup(col, sizeof(MdbColumn)));
+       table->num_cols++;
+}
+/*
+ * Should be called after setting up all temp table columns
+ */
+void mdb_temp_columns_end(MdbTableDef *table)
+{
+       MdbColumn *col;
+       unsigned int i;
+       unsigned int start = 0;
+
+       for (i=0; i<table->num_cols; i++) {
+               col = g_ptr_array_index(table->columns, i);
+               if (col->is_fixed) {
+                       col->fixed_offset = start;
+                       start += col->col_size;
+               }
+       }
+}
diff --git a/navit/map/poi_geodownload/libmdb/write.c b/navit/map/poi_geodownload/libmdb/write.c
new file mode 100644 (file)
index 0000000..1cff96a
--- /dev/null
@@ -0,0 +1,878 @@
+/* MDB Tools - A library for reading MS Access database file
+ * Copyright (C) 2000 Brian Bruns
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "mdbtools.h"
+#include "time.h"
+#include "math.h"
+
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+
+//static int mdb_copy_index_pg(MdbTableDef *table, MdbIndex *idx, MdbIndexPage *ipg);
+static int mdb_add_row_to_leaf_pg(MdbTableDef *table, MdbIndex *idx, MdbIndexPage *ipg, MdbField *idx_fields);
+
+void
+_mdb_put_int16(unsigned char *buf, guint32 offset, guint32 value)
+{
+       buf[offset] = value % 256;
+       value /= 256;
+       buf[offset+1] = value % 256;
+}
+void
+_mdb_put_int32(unsigned char *buf, guint32 offset, guint32 value)
+{
+       buf[offset] = value % 256;
+       value /= 256;
+       buf[offset+1] = value % 256;
+       value /= 256;
+       buf[offset+2] = value % 256;
+       value /= 256;
+       buf[offset+3] = value % 256;
+}
+ssize_t
+mdb_write_pg(MdbHandle *mdb, unsigned long pg)
+{
+       ssize_t len;
+       struct stat status;
+       off_t offset = pg * mdb->fmt->pg_size;
+
+       fstat(mdb->f->fd, &status);
+       /* is page beyond current size + 1 ? */
+       if (status.st_size < offset + mdb->fmt->pg_size) {
+               fprintf(stderr,"offset %lu is beyond EOF\n",offset);
+               return 0;
+       }
+       lseek(mdb->f->fd, offset, SEEK_SET);
+       len = write(mdb->f->fd,mdb->pg_buf,mdb->fmt->pg_size);
+       if (len==-1) {
+               perror("write");
+               return 0;
+       } else if (len<mdb->fmt->pg_size) {
+       /* fprintf(stderr,"EOF reached %d bytes returned.\n",len, mdb->pg_size); */
+               return 0;
+       }
+       mdb->cur_pos = 0;
+       return len;
+}
+
+static int 
+mdb_is_col_indexed(MdbTableDef *table, int colnum)
+{
+       unsigned int i, j;
+       MdbIndex *idx;
+
+       for (i=0;i<table->num_idxs;i++) {
+               idx = g_ptr_array_index (table->indices, i);
+               for (j=0;j<idx->num_keys;j++) {
+                       if (idx->key_col_num[j]==colnum) return 1;
+               }
+       }
+       return 0;
+}
+static int
+mdb_crack_row4(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
+{
+       MdbCatalogEntry *entry = table->entry;
+       MdbHandle *mdb = entry->mdb;
+       MdbColumn *col;
+       unsigned char *pg_buf = mdb->pg_buf;
+       unsigned int i;
+       unsigned int row_var_cols=0, row_fixed_cols, row_cols;
+       unsigned int fixed_cols_found;
+       unsigned int col_start;
+       unsigned char *nullmask;
+       unsigned int bitmask_sz;
+       unsigned int byte_num, bit_num;
+       unsigned int *var_col_offsets = NULL;
+
+       if (mdb_get_option(MDB_DEBUG_ROW)) {
+               buffer_dump(pg_buf, row_start, row_end);
+       }
+
+       row_cols = mdb_pg_get_int16(mdb, row_start);
+
+       bitmask_sz = (row_cols + 7) / 8;
+       nullmask = &pg_buf[row_end - bitmask_sz + 1];
+
+       /* read table of variable column locations */
+       if (table->num_var_cols > 0) {
+               row_var_cols = mdb_pg_get_int16(mdb, row_end - bitmask_sz - 1);
+               var_col_offsets = (int *)g_malloc((row_var_cols+1)*sizeof(int));
+               for (i=0; i<row_var_cols+1; i++) {
+                       var_col_offsets[i] = mdb_pg_get_int16(mdb,
+                               row_end - bitmask_sz - 3 - (i*2));
+               }
+       }
+       fixed_cols_found = 0;
+       row_fixed_cols = row_cols - row_var_cols;
+
+       /* read information into fields[] */
+       for (i=0;i<table->num_cols;i++) {
+               col = g_ptr_array_index(table->columns,i);
+               fields[i].colnum = i;
+               fields[i].is_fixed = (mdb_is_fixed_col(col)) ? 1 : 0;
+               byte_num = col->col_num / 8;
+               bit_num = col->col_num % 8;
+               /* logic on nulls is reverse, 1 is not null, 0 is null */
+               fields[i].is_null = nullmask[byte_num] & (1 << bit_num) ? 0 : 1;
+
+               if ((fields[i].is_fixed)
+                && (fixed_cols_found < row_fixed_cols)) {
+                       col_start = col->fixed_offset + 2;
+                       fields[i].start = row_start + col_start;
+                       fields[i].value = &pg_buf[row_start + col_start];
+                       fields[i].siz = col->col_size;
+                       fixed_cols_found++;
+               /* Use col->var_col_num because a deleted column is still
+                * present in the variable column offsets table for the row */
+               } else if ((!fields[i].is_fixed)
+                && (col->var_col_num < row_var_cols)) {
+                       col_start = var_col_offsets[col->var_col_num];
+                       fields[i].start = row_start + col_start;
+                       fields[i].value = &pg_buf[row_start + col_start];
+                       fields[i].siz = var_col_offsets[(col->var_col_num)+1] -
+                               col_start;
+               } else {
+                       fields[i].start = 0;
+                       fields[i].value = NULL;
+                       fields[i].siz = 0;
+                       fields[i].is_null = 1;
+               }
+       }
+       g_free(var_col_offsets);
+
+       return row_cols;
+}
+static int
+mdb_crack_row3(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
+{
+       MdbCatalogEntry *entry = table->entry;
+       MdbHandle *mdb = entry->mdb;
+       MdbColumn *col;
+       unsigned char *pg_buf = mdb->pg_buf;
+       unsigned int i;
+       unsigned int row_var_cols = 0, row_fixed_cols, row_cols;
+       unsigned int fixed_cols_found, var_cols_found;
+       unsigned int col_start;
+       unsigned char *nullmask;
+       unsigned int bitmask_sz;
+       unsigned int byte_num, bit_num;
+       unsigned int *var_col_offsets = NULL;
+       unsigned int num_jumps = 0, jumps_used = 0;
+       unsigned int col_ptr, row_len;
+
+       if (mdb_get_option(MDB_DEBUG_ROW)) {
+               buffer_dump(pg_buf, row_start, row_end);
+       }
+
+       row_cols = pg_buf[row_start];
+
+       bitmask_sz = (row_cols + 7) / 8;
+       nullmask = &pg_buf[row_end - bitmask_sz + 1];
+
+       /* read table of variable column locations */
+       if (table->num_var_cols > 0) {
+               row_var_cols = pg_buf[row_end - bitmask_sz];
+               row_len = row_end - row_start + 1;
+               num_jumps = (row_len - 1) / 256;
+               col_ptr = row_end - bitmask_sz - num_jumps - 1;
+               /* If last jump is a dummy value, ignore it */
+               if ((col_ptr-row_start-row_var_cols)/256 < num_jumps)
+                       num_jumps--;
+
+               var_col_offsets = (int *)g_malloc((row_var_cols+1)*sizeof(int));
+               jumps_used = 0;
+               for (i=0; i<row_var_cols+1; i++) {
+                       if ((jumps_used < num_jumps)
+                        && (i == pg_buf[row_end-bitmask_sz-jumps_used-1])) {
+                               jumps_used++;
+                       }
+                       var_col_offsets[i] = pg_buf[col_ptr-i]+(jumps_used*256);
+               }
+       }
+       fixed_cols_found = 0;
+       var_cols_found = 0;
+       row_fixed_cols = row_cols - row_var_cols;
+
+       if (mdb_get_option(MDB_DEBUG_ROW)) {
+               fprintf(stdout,"bitmask_sz %d num_jumps %d\n",bitmask_sz, num_jumps);
+               fprintf(stdout,"row_var_cols %d\n", row_var_cols);
+               fprintf(stdout,"row_fixed_cols %d\n", row_fixed_cols);
+       }
+
+       /* read information into fields[] */
+       for (i=0;i<table->num_cols;i++) {
+               col = g_ptr_array_index (table->columns, i);
+               fields[i].colnum = i;
+               fields[i].is_fixed = (mdb_is_fixed_col(col)) ? 1 : 0;
+               byte_num = col->col_num / 8;
+               bit_num = col->col_num % 8;
+               /* logic on nulls is reverse, 1 is not null, 0 is null */
+               fields[i].is_null = nullmask[byte_num] & (1 << bit_num) ? 0 : 1;
+
+               if ((fields[i].is_fixed)
+                && (fixed_cols_found < row_fixed_cols)) {
+                       col_start = col->fixed_offset + 1;
+                       fields[i].start = row_start + col_start;
+                       fields[i].value = &pg_buf[row_start + col_start];
+                       fields[i].siz = col->col_size;
+                       fixed_cols_found++;
+               } else if ((!fields[i].is_fixed)
+                  && (var_cols_found < row_var_cols)) {
+                       col_start = var_col_offsets[var_cols_found];
+                       fields[i].start = row_start + col_start;
+                       fields[i].value = &pg_buf[row_start + col_start];
+                       fields[i].siz = var_col_offsets[var_cols_found+1] -
+                               col_start;
+                       var_cols_found++;
+               } else {
+                       fields[i].start = 0;
+                       fields[i].value = NULL;
+                       fields[i].siz = 0;
+                       fields[i].is_null = 1;
+               }
+       }
+       g_free(var_col_offsets);
+
+       return row_cols;
+}
+/**
+ * mdb_crack_row:
+ * @table: Table that the row belongs to
+ * @row_start: offset to start of row on current page
+ * @row_end: offset to end of row on current page
+ * @fields: pointer to MdbField array to be popluated by mdb_crack_row
+ *
+ * Cracks a row buffer apart into its component fields.  
+ * 
+ * A row buffer is that portion of a data page which contains the values for
+ * that row.  Its beginning and end can be found in the row offset table.
+ *
+ * The resulting MdbField array contains pointers into the row for each field 
+ * present.  Be aware that by modifying field[]->value, you would be modifying 
+ * the row buffer itself, not a copy.
+ *
+ * This routine is mostly used internally by mdb_fetch_row() but may have some
+ * applicability for advanced application programs.
+ *
+ * Return value: number of fields present.
+ */
+int
+mdb_crack_row(MdbTableDef *table, int row_start, int row_end, MdbField *fields)
+{
+MdbCatalogEntry *entry = table->entry;
+MdbHandle *mdb = entry->mdb;
+
+       if (IS_JET4(mdb)) {
+               return mdb_crack_row4(table, row_start, row_end, fields);
+       } else {
+               return mdb_crack_row3(table, row_start, row_end, fields);
+       }
+}
+
+static int
+mdb_pack_null_mask(unsigned char *buffer, int num_fields, MdbField *fields)
+{
+       int pos = 0, bit = 0, byte = 0;
+       int i;
+
+       /* 'Not null' bitmap */
+       for (i=0; i<num_fields; i++) {
+               /* column is null if bit is clear (0) */
+               if (!fields[i].is_null) {
+                       byte |= 1 << bit;
+                       //printf("%d %d %d %d\n", i, bit, 1 << bit, byte);
+               }
+               bit++;
+               if (bit==8) {
+                       buffer[pos++] = byte;
+                       bit = byte = 0;
+               }
+       }
+       /* if we've written any bits to the current byte, flush it */
+       if (bit)
+               buffer[pos++] = byte;
+       
+       return pos;
+}
+/* fields must be ordered with fixed columns first, then vars, subsorted by 
+ * column number */
+static int
+mdb_pack_row4(MdbTableDef *table, unsigned char *row_buffer, unsigned int num_fields, MdbField *fields)
+{
+       unsigned int pos = 0;
+       unsigned int var_cols = 0;
+       unsigned int i;
+
+       row_buffer[pos++] = num_fields & 0xff;
+       row_buffer[pos++] = (num_fields >> 8) & 0xff; 
+
+       /* Fixed length columns */
+       for (i=0;i<num_fields;i++) {
+               if (fields[i].is_fixed) {
+                       fields[i].offset = pos;
+                       if (!fields[i].is_null) {
+                               memcpy(&row_buffer[pos], fields[i].value, fields[i].siz);
+                       }
+                       pos += fields[i].siz;
+               }
+       }
+       /* For tables without variable-length columns */
+       if (table->num_var_cols == 0) {
+               pos += mdb_pack_null_mask(&row_buffer[pos], num_fields, fields);
+               return pos;
+       }
+       /* Variable length columns */
+       for (i=0;i<num_fields;i++) {
+               if (!fields[i].is_fixed) {
+                       var_cols++;
+                       fields[i].offset = pos;
+                       if (! fields[i].is_null) {
+                               memcpy(&row_buffer[pos], fields[i].value, fields[i].siz);
+                               pos += fields[i].siz;
+                       }
+               }
+       }
+       /* EOD */
+       row_buffer[pos] = pos & 0xff;
+       row_buffer[pos+1] = (pos >> 8) & 0xff;
+       pos += 2;
+
+       /* Offsets of the variable-length columns */
+       for (i=num_fields; i>0; i--) {
+               if (!fields[i-1].is_fixed) {
+                       row_buffer[pos++] = fields[i-1].offset & 0xff;
+                       row_buffer[pos++] = (fields[i-1].offset >> 8) & 0xff;
+               }
+       }
+       /* Number of variable-length columns */
+       row_buffer[pos++] = var_cols & 0xff;
+       row_buffer[pos++] = (var_cols >> 8) & 0xff;
+
+       pos += mdb_pack_null_mask(&row_buffer[pos], num_fields, fields);
+       return pos;
+}
+
+static int
+mdb_pack_row3(MdbTableDef *table, unsigned char *row_buffer, unsigned int num_fields, MdbField *fields)
+{
+       unsigned int pos = 0;
+       unsigned int var_cols = 0;
+       unsigned int i, j;
+       unsigned char *offset_high;
+
+       row_buffer[pos++] = num_fields;
+
+       /* Fixed length columns */
+       for (i=0;i<num_fields;i++) {
+               if (fields[i].is_fixed) {
+                       fields[i].offset = pos;
+                       if (!fields[i].is_null) {
+                               memcpy(&row_buffer[pos], fields[i].value, fields[i].siz);
+                       }
+                       pos += fields[i].siz;
+               }
+       }
+       /* For tables without variable-length columns */
+       if (table->num_var_cols == 0) {
+               pos += mdb_pack_null_mask(&row_buffer[pos], num_fields, fields);
+               return pos;
+       }
+       /* Variable length columns */
+       for (i=0;i<num_fields;i++) {
+               if (!fields[i].is_fixed) {
+                       var_cols++;
+                       fields[i].offset = pos;
+                       if (! fields[i].is_null) {
+                               memcpy(&row_buffer[pos], fields[i].value, fields[i].siz);
+                               pos += fields[i].siz;
+                       }
+               }
+       }
+
+       offset_high = (unsigned char *) g_malloc(var_cols+1);
+       offset_high[0] = (pos << 8) & 0xff;
+       j = 1;
+       
+       /* EOD */
+       row_buffer[pos] = pos & 0xff;
+       pos++;
+
+       /* Variable length column offsets */
+       for (i=num_fields; i>0; i--) {
+               if (!fields[i-1].is_fixed) {
+                       row_buffer[pos++] = fields[i-1].offset & 0xff;
+                       offset_high[j++] = (fields[i-1].offset << 8) & 0xff;
+               }
+       }
+
+       /* Dummy jump table entry */
+       if (offset_high[0] < (pos+(num_fields+7)/8-1)/255) {
+               row_buffer[pos++] = 0xff;
+       }
+       /* Jump table */
+       for (i=0; i<var_cols; i++) {
+               if (offset_high[i] > offset_high[i+1]) {
+                       row_buffer[pos++] = var_cols-i;
+               }
+       }
+       g_free(offset_high);
+
+       row_buffer[pos++] = var_cols;
+
+       pos += mdb_pack_null_mask(&row_buffer[pos], num_fields, fields);
+       return pos;
+}
+int
+mdb_pack_row(MdbTableDef *table, unsigned char *row_buffer, int unsigned num_fields, MdbField *fields)
+{
+       if (table->is_temp_table) {
+               unsigned int i;
+               for (i=0; i<num_fields; i++) {
+                       MdbColumn *c = g_ptr_array_index(table->columns, i);
+                       fields[i].is_null = (fields[i].value) ? 0 : 1;
+                       fields[i].colnum = i;
+                       fields[i].is_fixed = c->is_fixed;
+                       if ((c->col_type != MDB_TEXT)
+                        && (c->col_type != MDB_MEMO)) {
+                               fields[i].siz = c->col_size;
+                       }
+               }
+       }
+       if (IS_JET4(table->entry->mdb)) {
+               return mdb_pack_row4(table, row_buffer, num_fields, fields);
+       } else {
+               return mdb_pack_row3(table, row_buffer, num_fields, fields);
+       }
+}
+int
+mdb_pg_get_freespace(MdbHandle *mdb)
+{
+       int rows, free_start, free_end;
+       int row_count_offset = mdb->fmt->row_count_offset;
+
+       rows = mdb_pg_get_int16(mdb, row_count_offset);
+       free_start = row_count_offset + 2 + (rows * 2);
+        free_end = mdb_pg_get_int16(mdb, row_count_offset + (rows * 2));
+       mdb_debug(MDB_DEBUG_WRITE,"free space left on page = %d", free_end - free_start);
+       return (free_end - free_start);
+}
+unsigned char *
+mdb_new_leaf_pg(MdbCatalogEntry *entry)
+{
+       MdbHandle *mdb = entry->mdb;
+       unsigned char *new_pg;
+
+       new_pg = (unsigned char *) g_malloc0(mdb->fmt->pg_size);
+               
+       new_pg[0]=0x04;
+       new_pg[1]=0x01;
+       _mdb_put_int32(new_pg, 4, entry->table_pg);
+       
+       return new_pg;
+}
+unsigned char *
+mdb_new_data_pg(MdbCatalogEntry *entry)
+{
+       MdbFormatConstants *fmt = entry->mdb->fmt;
+       unsigned char *new_pg;
+
+       new_pg = (unsigned char *) g_malloc0(fmt->pg_size);
+               
+       new_pg[0]=0x01;
+       new_pg[1]=0x01;
+       _mdb_put_int16(new_pg, 2, fmt->pg_size - fmt->row_count_offset - 2);
+       _mdb_put_int32(new_pg, 4, entry->table_pg);
+       
+       return new_pg;
+}
+
+int
+mdb_update_indexes(MdbTableDef *table, int num_fields, MdbField *fields, guint32 pgnum, guint16 rownum)
+{
+       unsigned int i;
+       MdbIndex *idx;
+       
+       for (i=0;i<table->num_idxs;i++) {
+               idx = g_ptr_array_index (table->indices, i);
+               mdb_debug(MDB_DEBUG_WRITE,"Updating %s (%d).", idx->name, idx->index_type);
+               if (idx->index_type==1) {
+                       mdb_update_index(table, idx, num_fields, fields, pgnum, rownum);
+               }
+       }
+       return 1;
+}
+
+int
+mdb_init_index_chain(MdbTableDef *table, MdbIndex *idx)
+{
+       MdbCatalogEntry *entry = table->entry;
+       MdbHandle *mdb = entry->mdb;
+
+       table->scan_idx = idx;
+       table->chain = g_malloc0(sizeof(MdbIndexChain));
+       table->mdbidx = mdb_clone_handle(mdb);
+       mdb_read_pg(table->mdbidx, table->scan_idx->first_pg);
+
+       return 1;
+}
+
+int
+mdb_update_index(MdbTableDef *table, MdbIndex *idx, unsigned int num_fields, MdbField *fields, guint32 pgnum, guint16 rownum)
+{
+       MdbCatalogEntry *entry = table->entry;
+       MdbHandle *mdb = entry->mdb;
+       int idx_xref[16];
+       unsigned int i, j;
+       MdbIndexChain *chain;
+       MdbField idx_fields[10];
+
+       for (i = 0; i < idx->num_keys; i++) {
+               for (j = 0; j < num_fields; j++) {
+                       // key_col_num is 1 based, can't remember why though
+                       if (fields[j].colnum == idx->key_col_num[i]-1) {
+                               idx_xref[i] = j;
+                               idx_fields[i] = fields[j];
+                       }
+               }
+       }
+       for (i = 0; i < idx->num_keys; i++) {
+               fprintf(stdout, "key col %d (%d) is mapped to field %d (%d %d)\n",
+                       i, idx->key_col_num[i], idx_xref[i], fields[idx_xref[i]].colnum, 
+                       fields[idx_xref[i]].siz);
+       }
+       for (i = 0; i < num_fields; i++) {
+               fprintf(stdout, "%d (%d %d)\n",
+                       i, fields[i].colnum, 
+                       fields[i].siz);
+       }
+
+       chain = g_malloc0(sizeof(MdbIndexChain));
+
+       mdb_index_find_row(mdb, idx, chain, pgnum, rownum);
+       printf("chain depth = %d\n", chain->cur_depth);
+       printf("pg = %" G_GUINT32_FORMAT "\n",
+               chain->pages[chain->cur_depth-1].pg);
+       //mdb_copy_index_pg(table, idx, &chain->pages[chain->cur_depth-1]);
+       mdb_add_row_to_leaf_pg(table, idx, &chain->pages[chain->cur_depth-1], idx_fields);
+       
+       return 1;
+}
+
+int
+mdb_insert_row(MdbTableDef *table, int num_fields, MdbField *fields)
+{
+       int new_row_size;
+       unsigned char row_buffer[4096];
+       MdbCatalogEntry *entry = table->entry;
+       MdbHandle *mdb = entry->mdb;
+       MdbFormatConstants *fmt = mdb->fmt;
+       guint32 pgnum;
+       guint16 rownum;
+
+       if (!mdb->f->writable) {
+               fprintf(stderr, "File is not open for writing\n");
+               return 0;
+       }
+       new_row_size = mdb_pack_row(table, row_buffer, num_fields, fields);
+       if (mdb_get_option(MDB_DEBUG_WRITE)) {
+               buffer_dump(row_buffer, 0, new_row_size-1);
+       }
+       pgnum = mdb_map_find_next_freepage(table, new_row_size);
+       if (!pgnum) {
+               fprintf(stderr, "Unable to allocate new page.\n");
+               return 0;
+       }
+
+       rownum = mdb_add_row_to_pg(table, row_buffer, new_row_size);
+
+       if (mdb_get_option(MDB_DEBUG_WRITE)) {
+               buffer_dump(mdb->pg_buf, 0, 39);
+               buffer_dump(mdb->pg_buf, fmt->pg_size - 160, fmt->pg_size-1);
+       }
+       mdb_debug(MDB_DEBUG_WRITE, "writing page %d", pgnum);
+       if (!mdb_write_pg(mdb, pgnum)) {
+               fprintf(stderr, "write failed! exiting...\n");
+               exit(1);
+       }
+
+       mdb_update_indexes(table, num_fields, fields, pgnum, rownum);
+       return 1;
+}
+/*
+ * Assumes caller has verfied space is available on page and adds the new 
+ * row to the current pg_buf.
+ */
+guint16
+mdb_add_row_to_pg(MdbTableDef *table, unsigned char *row_buffer, int new_row_size)
+{
+       unsigned char *new_pg;
+       int num_rows, i, pos, row_start, row_end, row_size;
+       MdbCatalogEntry *entry = table->entry;
+       MdbHandle *mdb = entry->mdb;
+       MdbFormatConstants *fmt = mdb->fmt;
+
+       if (table->is_temp_table) {
+               GPtrArray *pages = table->temp_table_pages;
+               if (pages->len == 0) {
+                       new_pg = mdb_new_data_pg(entry);
+                       g_ptr_array_add(pages, new_pg);
+               } else {
+                       new_pg = g_ptr_array_index(pages, pages->len - 1);
+                       if (mdb_get_int16(new_pg, 2) < new_row_size + 2) {
+                               new_pg = mdb_new_data_pg(entry);
+                               g_ptr_array_add(pages, new_pg);
+                       }
+               }
+
+               num_rows = mdb_get_int16(new_pg, fmt->row_count_offset);
+               pos = (num_rows == 0) ? fmt->pg_size :
+                       mdb_get_int16(new_pg, fmt->row_count_offset + (num_rows*2));
+       } else {  /* is not a temp table */
+               new_pg = mdb_new_data_pg(entry);
+
+               num_rows = mdb_pg_get_int16(mdb, fmt->row_count_offset);
+               pos = fmt->pg_size;
+
+               /* copy existing rows */
+               for (i=0;i<num_rows;i++) {
+                       row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (i*2));
+                       row_end = mdb_find_end_of_row(mdb, i);
+                       row_size = row_end - row_start + 1;
+                       pos -= row_size;
+                       memcpy(&new_pg[pos], &mdb->pg_buf[row_start], row_size);
+                       _mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (i*2), pos);
+               }
+       }
+
+       /* add our new row */
+       pos -= new_row_size;
+       memcpy(&new_pg[pos], row_buffer, new_row_size);
+       /* add row to the row offset table */
+       _mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (num_rows*2), pos);
+
+       /* update number rows on this page */
+       num_rows++;
+       _mdb_put_int16(new_pg, fmt->row_count_offset, num_rows);
+
+       /* update the freespace */
+       _mdb_put_int16(new_pg,2,pos - fmt->row_count_offset - 2 - (num_rows*2));
+
+       /* copy new page over old */
+       if (!table->is_temp_table) {
+               memcpy(mdb->pg_buf, new_pg, fmt->pg_size);
+               g_free(new_pg);
+       }
+
+       return num_rows;
+}
+int 
+mdb_update_row(MdbTableDef *table)
+{
+int row_start, row_end;
+unsigned int i;
+MdbColumn *col;
+MdbCatalogEntry *entry = table->entry;
+MdbHandle *mdb = entry->mdb;
+MdbFormatConstants *fmt = mdb->fmt;
+MdbField fields[256];
+unsigned char row_buffer[4096];
+int old_row_size, new_row_size, delta;
+unsigned int num_fields;
+
+       if (!mdb->f->writable) {
+               fprintf(stderr, "File is not open for writing\n");
+               return 0;
+       }
+       row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + ((table->cur_row-1)*2)); 
+       row_end = mdb_find_end_of_row(mdb, table->cur_row-1);
+       old_row_size = row_end - row_start;
+
+       row_start &= 0x0FFF; /* remove flags */
+
+       mdb_debug(MDB_DEBUG_WRITE,"page %lu row %d start %d end %d", (unsigned long) table->cur_phys_pg, table->cur_row-1, row_start, row_end);
+       if (mdb_get_option(MDB_DEBUG_LIKE))
+               buffer_dump(mdb->pg_buf, row_start, row_end);
+
+       for (i=0;i<table->num_cols;i++) {
+               col = g_ptr_array_index(table->columns,i);
+               if (col->bind_ptr && mdb_is_col_indexed(table,i)) {
+                       fprintf(stderr, "Attempting to update column that is part of an index\n");
+                       return 0;
+               }
+       }
+       num_fields = mdb_crack_row(table, row_start, row_end, fields);
+
+       if (mdb_get_option(MDB_DEBUG_WRITE)) {
+               for (i=0;i<num_fields;i++) {
+                       printf("col %d %d start %d siz %d\n", i, fields[i].colnum, fields[i].start, fields[i].siz);
+               }
+       }
+       for (i=0;i<table->num_cols;i++) {
+               col = g_ptr_array_index(table->columns,i);
+               if (col->bind_ptr) {
+                       printf("yes\n");
+                       fields[i].value = col->bind_ptr;
+                       fields[i].siz = *(col->len_ptr);
+               }
+       }
+
+       new_row_size = mdb_pack_row(table, row_buffer, num_fields, fields);
+       if (mdb_get_option(MDB_DEBUG_WRITE)) 
+               buffer_dump(row_buffer, 0, new_row_size-1);
+       delta = new_row_size - old_row_size;
+       if ((mdb_pg_get_freespace(mdb) - delta) < 0) {
+               fprintf(stderr, "No space left on this page, update will not occur\n");
+               return 0;
+       }
+       /* do it! */
+       mdb_replace_row(table, table->cur_row-1, row_buffer, new_row_size);
+       return 0;
+}
+int 
+mdb_replace_row(MdbTableDef *table, int row, unsigned char *new_row, int new_row_size)
+{
+MdbCatalogEntry *entry = table->entry;
+MdbHandle *mdb = entry->mdb;
+MdbFormatConstants *fmt = mdb->fmt;
+unsigned char *new_pg;
+guint16 num_rows;
+int row_start, row_end, row_size;
+int i, pos;
+
+       if (mdb_get_option(MDB_DEBUG_WRITE)) {
+               buffer_dump(mdb->pg_buf, 0, 39);
+               buffer_dump(mdb->pg_buf, fmt->pg_size - 160, fmt->pg_size-1);
+       }
+       mdb_debug(MDB_DEBUG_WRITE,"updating row %d on page %lu", row, (unsigned long) table->cur_phys_pg);
+       new_pg = mdb_new_data_pg(entry);
+
+       num_rows = mdb_pg_get_int16(mdb, fmt->row_count_offset);
+       _mdb_put_int16(new_pg, fmt->row_count_offset, num_rows);
+
+       pos = mdb->fmt->pg_size;
+
+       /* rows before */
+       for (i=0;i<row;i++) {
+               row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (i*2));
+               row_end = mdb_find_end_of_row(mdb, i);
+               row_size = row_end - row_start + 1;
+               pos -= row_size;
+               memcpy(&new_pg[pos], &mdb->pg_buf[row_start], row_size);
+               _mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (i*2), pos);
+       }
+       
+       /* our row */
+       pos -= new_row_size;
+       memcpy(&new_pg[pos], new_row, new_row_size);
+       _mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (row*2), pos);
+       
+       /* rows after */
+       for (i=row+1;i<num_rows;i++) {
+               row_start = mdb_pg_get_int16(mdb, (fmt->row_count_offset + 2) + (i*2));
+               row_end = mdb_find_end_of_row(mdb, i);
+               row_size = row_end - row_start + 1;
+               pos -= row_size;
+               memcpy(&new_pg[pos], &mdb->pg_buf[row_start], row_size);
+               _mdb_put_int16(new_pg, (fmt->row_count_offset + 2) + (i*2), pos);
+       }
+
+       /* almost done, copy page over current */
+       memcpy(mdb->pg_buf, new_pg, fmt->pg_size);
+
+       g_free(new_pg);
+
+       _mdb_put_int16(mdb->pg_buf, 2, mdb_pg_get_freespace(mdb));
+       if (mdb_get_option(MDB_DEBUG_WRITE)) {
+               buffer_dump(mdb->pg_buf, 0, 39);
+               buffer_dump(mdb->pg_buf, fmt->pg_size - 160, fmt->pg_size-1);
+       }
+       /* drum roll, please */
+       if (!mdb_write_pg(mdb, table->cur_phys_pg)) {
+               fprintf(stderr, "write failed! exiting...\n");
+               exit(1);
+       }
+       return 0;
+}
+static int
+mdb_add_row_to_leaf_pg(MdbTableDef *table, MdbIndex *idx, MdbIndexPage *ipg, MdbField *idx_fields) 
+/*,  guint32 pgnum, guint16 rownum) 
+static int
+mdb_copy_index_pg(MdbTableDef *table, MdbIndex *idx, MdbIndexPage *ipg)
+*/
+{
+       MdbCatalogEntry *entry = table->entry;
+       MdbHandle *mdb = entry->mdb;
+       MdbColumn *col;
+       guint32 pg;
+       guint16 row;
+       unsigned char *new_pg;
+       unsigned char key_hash[256];
+       unsigned char iflag;
+       int keycol;
+
+       new_pg = mdb_new_leaf_pg(entry);
+
+       mdb_index_page_reset(ipg);
+       mdb_read_pg(mdb, ipg->pg);
+
+       /* do we support this index type yet? */
+       if (idx->num_keys > 1) {
+               fprintf(stderr,"multikey indexes not yet supported, aborting\n");
+               return 0;
+       }
+       keycol = idx->key_col_num[0];
+       col = g_ptr_array_index (table->columns, keycol - 1);
+       printf("keycol = %d (%s)\n", keycol, col->name);
+       if (!mdb_is_fixed_col(col)) {
+               fprintf(stderr,"variable length key columns not yet supported, aborting\n");
+               return 0;
+       }
+       printf("col size = %d\n", col->col_size);
+
+       while (mdb_index_find_next_on_page(mdb, ipg)) {
+
+               /* check for compressed indexes.  */
+               if (ipg->len < col->col_size + 1) {
+                       fprintf(stderr,"compressed indexes not yet supported, aborting\n");
+                       return 0;
+               }
+
+               pg = mdb_pg_get_int24_msb(mdb, ipg->offset + ipg->len - 4);
+               row = mdb->pg_buf[ipg->offset + ipg->len - 1];
+               iflag = mdb->pg_buf[ipg->offset];
+               mdb_index_swap_n(&mdb->pg_buf[ipg->offset + 1], col->col_size, key_hash);
+               key_hash[col->col_size - 1] &= 0x7f;
+               printf("length = %d\n", ipg->len);
+               printf("iflag = %d pg = %" G_GUINT32_FORMAT
+                       " row = %" G_GUINT16_FORMAT "\n", iflag, pg, row);
+               buffer_dump(mdb->pg_buf, ipg->offset, ipg->offset + ipg->len - 1);
+               buffer_dump(mdb->pg_buf, ipg->offset + 1, ipg->offset + col->col_size);
+               buffer_dump(key_hash, 0, col->col_size - 1);
+               ipg->offset += ipg->len;
+               ipg->len = 0;
+               row++;
+       }
+       g_free(new_pg);
+
+       return ipg->len;
+}
diff --git a/navit/map/poi_geodownload/poi_geodownload.c b/navit/map/poi_geodownload/poi_geodownload.c
new file mode 100644 (file)
index 0000000..3545cde
--- /dev/null
@@ -0,0 +1,756 @@
+#include <mdbtools.h>
+#include "config.h"
+#include "debug.h"
+#include "coord.h"
+#include "projection.h"
+#include "item.h"
+#include "map.h"
+#include "plugin.h"
+
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <dirent.h>
+
+struct map_priv
+{
+       char *filename;
+       MdbHandle *h;
+       MdbHandle *h_idx;
+       MdbTableDef *table;
+       GPtrArray *table_col;
+       MdbColumn **cols;
+       MdbIndex *idx;
+       int idx_size;
+       enum item_type type;
+       int name_col;
+};
+
+struct map_rect_priv
+{
+       struct item item;
+       struct map_priv *m;
+       enum attr_type attr_next;
+       int cidx;
+       char buffer[4096];
+};
+
+#if 0
+struct index_data {
+       unsigned char data[15];
+};
+struct poi {
+       char filename[1024];
+       char icon[1024];
+       long pos;
+       MdbHandle *h;
+       MdbHandle *h_idx;
+       MdbTableDef *table;
+       GPtrArray *table_col;
+       MdbColumn **cols;
+       MdbIndex *idx;
+       int idx_size;
+       struct index_data index_data;
+       MdbIndexChain chain;
+       struct poi *next;
+} *poi_list;
+
+struct poi_data {
+       struct poi *poi;
+       int page;
+       int row;
+};
+
+       char poipath[256];
+       char poibmp[256];
+
+
+#endif
+
+static void
+print_col(MdbHandle *h, MdbColumn *col, char *buffer, int hex)
+{
+       char *s;
+       dbg(1,"type=%d\n", col->col_type);
+       switch (col->col_type) {
+       case MDB_BOOL:
+               strcpy(buffer, mdb_pg_get_byte(h, col->cur_value_start) ? "True" : "False");
+               break;
+       case MDB_BYTE:
+               sprintf(buffer, "%d", mdb_pg_get_byte(h, col->cur_value_start));
+               break;
+       case MDB_LONGINT:
+               if (hex)
+                       sprintf(buffer, "0x%lx", mdb_pg_get_int32(h, col->cur_value_start));
+               else
+                       sprintf(buffer, "%ld", mdb_pg_get_int32(h, col->cur_value_start));
+               break;
+       case MDB_DOUBLE:
+               sprintf(buffer, "%f", mdb_pg_get_double(h, col->cur_value_start));
+               break;
+       case MDB_TEXT:
+               dbg(1,"pg_buf %p start %d len %d\n", h->pg_buf, col->cur_value_start, col->cur_value_len);
+               if (col->cur_value_len) {
+                       s=mdb_col_to_string (h, h->pg_buf, col->cur_value_start, col->col_type, col->cur_value_len);
+                       dbg(1,"s=%p\n", s);
+                       sprintf(buffer, "%s", s);
+               }
+               break;
+       default:
+               sprintf(buffer, "unknown (%d)", col->col_type);
+       }
+}
+
+#if 0
+
+static void
+setup_idx_data(struct index_data *idx, struct coord *c, unsigned int geoflags, int size)
+{
+       /* 7f 80 1c 91 0a 7f 80 5c  f5 41 7f 80 00 00 05 */
+       idx->data[0]=0x7f;
+       idx->data[1]=(c->x >> 24) ^ 0x80;
+       idx->data[2]=c->x >> 16;
+       idx->data[3]=c->x >> 8;
+       idx->data[4]=c->x;
+       idx->data[5]=0x7f;
+       idx->data[6]=(c->y >> 24) ^ 0x80;
+       idx->data[7]=c->y >> 16;
+       idx->data[8]=c->y >> 8;
+       idx->data[9]=c->y;
+       idx->data[10]=0x7f;
+       if (size > 12) {
+               idx->data[11]=0x80 | (geoflags >> 24);
+               idx->data[12]=geoflags >> 16;
+               idx->data[13]=geoflags >> 8;
+               idx->data[14]=geoflags;
+       } else {
+               idx->data[11]=geoflags;
+       }
+}
+
+static void
+setup_idx_rect(struct coord *rect, struct index_data *idx, int size)
+{
+       struct coord r[2];
+       r[0].x=rect[0].x;
+       r[0].y=rect[1].y;
+       r[1].x=rect[1].x;
+       r[1].y=rect[0].y;
+#if 0
+       printf("low 0x%x 0%x\n", r[0].x, r[0].y);
+       printf("high 0x%x 0%x\n", r[1].x, r[1].y);
+#endif
+       setup_idx_data(idx, r, 0, size);
+       setup_idx_data(idx+1, r+1, 0xffffffff, size);
+}
+
+#endif
+
+static int
+load_row(struct map_priv *poi, int pg, int row)
+{
+       int row_start, row_end, offset;
+       unsigned int num_fields, i;
+       MdbField fields[256];
+       MdbFormatConstants *fmt;
+       int debug=0;
+
+       fmt=poi->h->fmt;
+       mdb_read_pg(poi->h, pg);
+       dbg(1, "enter poi=%p pg=%d row=%d\n", poi, pg, row);
+       dbg(1,"Page Type %d row_count_offset %d\n",poi->h->pg_buf[0], fmt->row_count_offset);
+       for (i = 0; i <= row; i++) {
+               offset=(fmt->row_count_offset + 2) + i * 2;
+               dbg(1,"row %d %d 0x%x\n", i, offset, mdb_pg_get_int16(poi->h, offset));
+       }
+       row_start = mdb_pg_get_int16(poi->h, (fmt->row_count_offset + 2) + row * 2);
+       if (row_start & 0x4000)
+               return 1;
+       row_end = mdb_find_end_of_row(poi->h, row);
+       if (debug) {
+               printf("start=0x%x end=0x%x\n", row_start, row_end);
+               buffer_dump(poi->h->pg_buf, row_start, row_end);
+       }
+
+       poi->h->cur_pos=row_start & 0x1fff;
+       poi->table->cur_row=row;
+       num_fields = mdb_crack_row(poi->table, row_start & 0x1fff, row_end, fields);
+       dbg(1,"num_fields=%d\n", num_fields);
+       for (i = 0; i < num_fields; i++) {
+               dbg(1,"i=%d/%d\n", i, num_fields);
+               poi->cols[i]->cur_value_start=fields[i].start;
+               poi->cols[i]->cur_value_len=fields[i].siz;
+       }
+       return 0;
+}
+
+#if 0
+
+static MdbIndexPage *
+index_next_row(MdbHandle *mdb, MdbIndex *idx, MdbIndexChain *chain)
+{
+       MdbIndexPage *ipg;
+
+       ipg = mdb_index_read_bottom_pg(mdb, idx, chain);
+       if (!mdb_index_find_next_on_page(mdb, ipg)) {
+#if 0
+               printf("no next\n");    
+#endif
+               if (!chain->clean_up_mode) {
+#if 0
+                       printf("no cleanup\n"); 
+#endif
+                       if (!(ipg = mdb_index_unwind(mdb, idx, chain)))
+                               chain->clean_up_mode = 1;
+               }
+               if (chain->clean_up_mode) {
+#if 0
+                       printf("cleanup\n");    
+#endif
+                       //fprintf(stdout,"in cleanup mode\n");
+
+                       if (!chain->last_leaf_found) {
+                               printf("no last_leaf_found\n");
+                               return NULL;
+                       }
+                       mdb_read_pg(mdb, chain->last_leaf_found);
+                       chain->last_leaf_found =
+                           mdb_pg_get_int24(mdb, 0x0c);
+                       //printf("next leaf %lu\n", chain->last_leaf_found);
+                       mdb_read_pg(mdb, chain->last_leaf_found);
+                       /* reuse the chain for cleanup mode */
+                       chain->cur_depth = 1;
+                       ipg = &chain->pages[0];
+                       mdb_index_page_init(ipg);
+                       ipg->pg = chain->last_leaf_found;
+                       //printf("next on page %d\n",
+                       if (!mdb_index_find_next_on_page(mdb, ipg)) {
+#if 0
+                               printf("no find_next_on_page\n");
+#endif
+                               return NULL;
+                       }
+               }
+       }
+       return ipg;
+}
+
+static int
+index_next(struct poi *poi, struct index_data *idx)
+{
+       MdbIndexPage *ipg;
+       MdbIndexChain *chain = &poi->chain;
+       int row;
+       int pg;
+       int offset;
+       char *cmp, *low, *high;
+       int debug=0;
+
+
+       for(;;) {
+       for(;;) {
+       ipg=index_next_row(poi->h_idx, poi->idx, chain);
+       if (! ipg)
+               return 0;
+       row = poi->h_idx->pg_buf[ipg->offset + ipg->len - 1];
+       pg = mdb_pg_get_int24_msb(poi->h_idx, ipg->offset + ipg->len - 4);
+
+       offset=poi->idx_size+4-ipg->len;
+       memcpy(poi->index_data.data+offset, poi->h_idx->pg_buf+ipg->offset, ipg->len - 4);
+       cmp=poi->index_data.data;
+       low=idx[0].data;
+       high=idx[1].data;
+       if (debug > 1) {
+               buffer_dump(low, 0, poi->idx_size-1);
+               buffer_dump(cmp, 0, poi->idx_size-1);
+               buffer_dump(high, 0, poi->idx_size-1);
+               printf("%d %d %d\n", memcmp(cmp, low, poi->idx_size), memcmp(cmp, high, poi->idx_size), offset);
+       }
+#if 0
+       buffer_dump(poi->h_idx->pg_buf, ipg->offset, ipg->offset+ipg->len-1);
+#endif
+       ipg->offset += ipg->len;
+       if (memcmp(cmp, low, poi->idx_size) >= 0) {
+               if (memcmp(cmp, high, poi->idx_size) <=0 ) {
+                       if (debug) {
+                               printf("match\n");
+                               buffer_dump(low, 0, poi->idx_size-1);
+                               buffer_dump(cmp, 0, poi->idx_size-1);
+                               buffer_dump(high, 0, poi->idx_size-1);
+                               printf("%d %d %d\n", memcmp(cmp, low, poi->idx_size), memcmp(cmp, high, poi->idx_size), offset);
+                       }
+                       break;
+               } else {
+                       return 0;
+               }
+       }
+       if (debug > 1)
+               printf("row=0x%x pg=0x%x len=%d\n", row, pg, ipg->len);
+       }
+       if (debug)
+               printf("match: row=0x%x pg=0x%x len=%d\n", row, pg, ipg->len);
+               if (!load_row(poi, pg, row))
+                       break;
+       }
+       return 1;
+}
+
+#endif
+
+static int
+load_poi_table(struct map_priv *m, MdbCatalogEntry *entry)
+{
+       int j;
+       MdbIndex *idx;
+
+       m->h_idx=NULL;
+       m->table = mdb_read_table(entry);
+       m->table_col = mdb_read_columns(m->table);
+       mdb_read_indices(m->table);
+       m->cols = (MdbColumn **) (m->table_col->pdata);
+       if (m->table_col->len < 4 || strcasecmp(m->cols[0]->name, "X") ||
+               strcasecmp(m->cols[1]->name, "Y") || strcasecmp(m->cols[3]->name, "GEOFLAGS")) 
+                       return 1;
+       m->name_col=-1;
+       for (j = 0; j < m->table_col->len ; j++) {
+               if (!strcasecmp(m->cols[j]->name, "NAME"))
+                       m->name_col=j;
+       }
+       for (j = 0; j < m->table->num_idxs; j++) {
+               idx = m->table->indices->pdata[j];
+               if (idx->num_keys == 3 && idx->key_col_num[0] == 1 &&
+                   idx->key_col_num[1] == 2 && idx->key_col_num[2] == 4) {
+                       m->idx = idx;
+                       m->idx_size=3+m->cols[0]->col_size+m->cols[1]->col_size+m->cols[3]->col_size;
+                       m->h_idx=mdb_clone_handle(m->h);
+               }
+       }
+       return 0;       
+}
+
+#if 0
+
+static void
+load_poi(char *filename, char *icon, int type)
+{
+       int i;
+       MdbCatalogEntry *entry;
+       GPtrArray *catalog;
+       struct poi *new = g_new0(struct poi, 1);
+
+       FILE *fp = fopen(filename,"r");
+       if( fp ) {
+              fclose(fp);
+       } else {
+               printf("ERR : POI file %s does not exists!\n",filename);
+               exit(0);
+               return -1;
+       }
+
+
+       fp = fopen(icon,"r");
+       if( fp ) {
+              fclose(fp);
+       } else {
+               printf("ERR : WARNING INCORRECT PICTURE! %s!\n",icon);
+               exit(0);
+               return -1;
+       }
+
+       strcpy(new->filename,filename);
+       strcpy(new->icon,icon);
+       new->type = type;
+
+
+       if (type == 0) {
+               new->h = mdb_open(filename, MDB_NOFLAGS);
+               catalog = mdb_read_catalog(new->h, MDB_TABLE);
+               for (i = 0; i < catalog->len; i++) {
+                       entry = catalog->pdata[i];
+                       if (!strcasecmp(entry->object_name, "_INDEXDATA")) {
+                               if (load_poi_table(new, entry)) {
+                                       printf("%s invalid\n", filename);
+                                       g_free(new);
+                                       new=NULL;
+                               }
+                       }
+               }
+               g_ptr_array_free(catalog, 1);
+       }
+       if (new) {
+               new->next = poi_list;
+               poi_list = new;
+       }
+}
+
+static void
+get_coord(struct poi *p, struct coord *c)
+{
+       c->x=mdb_pg_get_int32(p->h, p->cols[0]->cur_value_start);
+       c->y=mdb_pg_get_int32(p->h, p->cols[1]->cur_value_start);
+}
+
+static void
+poi_info(struct display_list *list, struct popup_item **popup)
+{
+       struct poi_data *data=list->data;
+       struct poi *poi=data->poi;
+       struct popup_item *popup_last, *popup_val_last;
+       char *text,buffer[4096];
+       int j;
+       MdbColumn *col;
+       char *v;
+
+       popup_last = *popup;
+
+       popup_val_last = NULL;
+       sprintf(buffer,"File:%s", poi->filename);
+       popup_item_new_text(&popup_val_last, buffer, 1);
+       sprintf(buffer,"Icon:%s", poi->icon);
+       popup_item_new_text(&popup_val_last, buffer, 2);
+       if (poi->type == 0) {
+               printf("poi_info pg=%d row=%d\n", data->page, data->row);
+               load_row(poi, data->page, data->row);
+               sprintf(buffer,"Page:%d", data->page);
+               popup_item_new_text(&popup_val_last, buffer, 3);
+               sprintf(buffer,"Row:%d", data->row);
+               popup_item_new_text(&popup_val_last, buffer, 4);
+               for (j = 0; j < poi->table_col->len; j++) {
+                       col = poi->table_col->pdata[j];
+       #if 0
+                       printf("start: %d type:%d\n", col->cur_value_start, col->col_type);
+       #endif
+                       sprintf(buffer, "%s:", col->name);
+                       v = buffer + strlen(buffer);
+                       if (!strcasecmp(col->name,"X") || !strcasecmp(col->name,"Y")) 
+                               print_col(poi->h, col, v, 1);
+                       else
+                               print_col(poi->h, col, v, 0);
+       #if 0
+                       printf("%s\n", buffer);
+       #endif
+                       text=g_convert(buffer,-1,"utf-8","iso8859-1",NULL,NULL,NULL);
+                       popup_item_new_text(&popup_val_last, buffer, j+10);
+                       g_free(text);
+               }
+       }
+       popup_item_new_text(&popup_last, "POI", 20)->submenu = popup_val_last;
+       *popup=popup_last;
+}
+
+static void
+draw_poi(struct poi *p, struct container *co, struct point *pnt)
+{
+       struct poi_data data;
+       data.poi=p;
+       if (p->type == 0) {
+               data.page=p->h->cur_pg;
+               data.row=p->table->cur_row-1;
+       }
+       if (p->type == 1) {
+               data.row=p->pos;
+       }
+       display_add(&co->disp[display_poi], 5, 0, p->icon, 1, pnt, poi_info, &data, sizeof(data));
+}
+
+static void
+plugin_draw(struct container *co)
+{
+       struct coord c;
+       struct point pnt;
+       struct poi *p;
+       struct index_data idx[2];
+       int use_index=0;
+       int debug=1;
+
+       p = poi_list;
+
+       if (co->trans->scale > 1024)
+               return; 
+       if (debug) {
+               printf("scale=%ld\n", co->trans->scale);
+               printf("rect 0x%lx,0%lx-0x%lx,0x%lx\n", co->trans->rect[0].x, co->trans->rect[0].y, co->trans->rect[1].x, co->trans->rect[1].y);
+       }
+       while (p) {
+               if (p->type == 0) {
+                       if (use_index)
+                               setup_idx_rect(co->trans->rect, idx, p->idx_size);
+                       if (! use_index) {
+                               printf("rewind %s %p\n", p->filename, p->table);
+                               mdb_rewind_table(p->table);
+                               while (mdb_fetch_row(p->table)) {
+                                       get_coord(p, &c);
+                                       if (transform(co->trans, &c, &pnt)) {
+                                               if (debug)
+                                                       printf("coord 0x%lx,0x%lx pg %d row %d\n", c.x, c.y, p->h->cur_pg, p->table->cur_row);
+                                               draw_poi(p, co, &pnt);
+                                       }
+                               }
+                       }  else {
+                               memset(&p->chain, 0, sizeof(p->chain));
+                               while (index_next(p, idx)) {
+                                       get_coord(p, &c);
+                                       if (transform(co->trans, &c, &pnt)) {
+                                               if (debug)
+                                                       printf("coord 0x%lx,0x%lx pg %d row %d\n", c.x, c.y, p->h->cur_pg, p->table->cur_row);
+                                               draw_poi(p, co, &pnt);
+                                       }
+                               }
+                       }
+               }
+               if (p->type == 1) {
+                       FILE *f;
+                       char line[1024];
+                       struct text_poi tpoi;
+                       if(!(f=fopen(p->filename, "r"))){
+                               printf("can't open poi file for drawing!\n");
+                               exit(0);
+                       }
+#if 0
+                       printf("opened poi file %s for drawing!\n",p->filename);
+#endif
+                       p->pos=ftell(f);
+                       fgets(line, 1024, f);
+                       while (!feof(f)) {
+                               if (strlen(line)) {
+                                       line[strlen(line)-1]='\0';
+                               }
+                               if (parse_text_poi(line, &tpoi)) {
+                                       transform_mercator(&tpoi.lat,&tpoi.lng,&c);
+//                                     printf("%ld %ld\n", c.x, c.y);
+                                       if (transform(co->trans, &c, &pnt)) {
+                                               draw_poi(p, co, &pnt);
+                                       }
+                               }
+                               p->pos=ftell(f);
+                               fgets(line, 1024, f);
+                       }
+                       fclose(f);                      
+               }
+               p = p->next;
+       }
+
+}
+
+#endif
+
+static void
+map_destroy_poi_geodownload(struct map_priv *m)
+{
+        dbg(1,"enter\n");
+        g_free(m);
+}
+
+static void
+poi_geodownload_coord_rewind(void *priv_data)
+{
+       struct map_rect_priv *mr=priv_data;
+       mr->cidx=0;
+}
+
+
+static int
+poi_geodownload_coord_get(void *priv_data, struct coord *c, int count)
+{
+       struct map_rect_priv *mr=priv_data;
+       dbg(1,"enter\n");
+       if (mr->cidx || !count)
+               return 0;
+       c->x=mdb_pg_get_int32(mr->m->h, mr->m->cols[0]->cur_value_start);
+       c->y=mdb_pg_get_int32(mr->m->h, mr->m->cols[1]->cur_value_start);
+       dbg(1,"x=0x%x y=0x%x\n", c->x, c->y);
+       return 1;
+}
+
+static void
+poi_geodownload_attr_rewind(void *priv_data)
+{
+       struct map_rect_priv *mr=priv_data;
+       mr->attr_next=attr_label;
+}
+
+static int
+poi_geodownload_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{
+       struct map_rect_priv *mr=priv_data;
+       struct map_priv *m=mr->m;
+       MdbColumn *col;
+       char *v;
+       int j;
+
+       dbg(1,"enter\n");
+       attr->type=attr_type;
+       switch (attr_type) {
+       case attr_any:
+               while (mr->attr_next != attr_none) {
+                       if (poi_geodownload_attr_get(mr, mr->attr_next, attr))
+                               return 1;
+                }
+                return 0;
+       case attr_label:
+               mr->attr_next=attr_debug;
+               if (m->name_col == -1)
+                       return 0;
+               col=m->cols[m->name_col];
+               if (col->cur_value_len) 
+                       attr->u.str=mdb_col_to_string (m->h, m->h->pg_buf, col->cur_value_start, col->col_type, col->cur_value_len);
+               else
+                       attr->u.str="";
+               return 1;
+       case attr_debug:
+               mr->attr_next=attr_none;
+               v=mr->buffer;
+               *v='\0';
+               for (j = 0; j < mr->m->table_col->len; j++) {
+                       col = mr->m->table_col->pdata[j];
+                       printf("start: %d type:%d\n", col->cur_value_start, col->col_type);
+                       sprintf(v, "%s:", col->name);
+                       v += strlen(v);
+                       if (!strcasecmp(col->name,"X") || !strcasecmp(col->name,"Y")) 
+                               print_col(mr->m->h, col, v, 1);
+                       else
+                               print_col(mr->m->h, col, v, 0);
+                       v += strlen(v);
+                       *v++='\n';
+                       *v='\0';
+               }
+               attr->u.str=mr->buffer;
+               return 1;
+       default:
+               break;
+       }
+       return 0;
+}
+
+static struct item_methods methods_poi_geodownload = {
+       poi_geodownload_coord_rewind,
+       poi_geodownload_coord_get,
+       poi_geodownload_attr_rewind,
+       poi_geodownload_attr_get,
+};
+
+
+static struct map_rect_priv *
+map_rect_new_poi_geodownload(struct map_priv *map, struct map_selection *sel)
+{
+        struct map_rect_priv *mr;
+
+        dbg(1,"enter\n");
+        mr=g_new0(struct map_rect_priv, 1);
+       mr->item.meth=&methods_poi_geodownload;
+       mr->item.id_hi=0;
+       mr->item.id_lo=0;
+       mr->item.priv_data=mr;
+       mr->item.type=map->type;
+       mr->m=map;
+       mdb_rewind_table(map->table);
+        return mr;
+}
+
+
+static void
+map_rect_destroy_poi_geodownload(struct map_rect_priv *mr)
+{
+       g_free(mr);
+}
+
+static struct item *
+map_rect_get_item_poi_geodownload(struct map_rect_priv *mr)
+{
+       dbg(1,"enter\n");
+       if (mdb_fetch_row(mr->m->table)) {
+               mr->item.id_hi=mr->m->table->cur_phys_pg;
+               mr->item.id_lo=mr->m->table->cur_row-1;
+               poi_geodownload_attr_rewind(mr);
+               return &mr->item;
+       }
+       return NULL;
+}
+
+static struct item *
+map_rect_get_item_byid_poi_geodownload(struct map_rect_priv *mr, int id_hi, int id_lo)
+{
+       char *v, buffer[4096];
+       int j;
+       MdbColumn *col;
+
+       dbg(1,"enter\n");
+       load_row(mr->m, id_hi, id_lo);
+       for (j = 0; j < mr->m->table_col->len; j++) {
+               col = mr->m->table_col->pdata[j];
+               printf("start: %d type:%d\n", col->cur_value_start, col->col_type);
+               sprintf(buffer, "%s:", col->name);
+               v = buffer + strlen(buffer);
+               if (!strcasecmp(col->name,"X") || !strcasecmp(col->name,"Y")) 
+                       print_col(mr->m->h, col, v, 1);
+               else
+                       print_col(mr->m->h, col, v, 0);
+               printf("%s\n", buffer);
+       }
+       dbg(1,"ret=%p\n", &mr->item);
+       poi_geodownload_attr_rewind(mr);
+       return &mr->item;
+}
+
+
+static struct map_methods map_methods_poi_geodownload = {
+       projection_mg,
+       "iso8859-1",
+       map_destroy_poi_geodownload,
+       map_rect_new_poi_geodownload,
+       map_rect_destroy_poi_geodownload,
+       map_rect_get_item_poi_geodownload,
+       map_rect_get_item_byid_poi_geodownload,
+};
+
+static struct map_priv *
+map_new_poi_geodownload(struct map_methods *meth, struct attr **attrs)
+{
+        struct map_priv *m;
+       MdbCatalogEntry *entry;
+       GPtrArray *catalog;
+       int i;
+       struct attr *attr;
+       struct attr *data=attr_search(attrs, NULL, attr_data);
+       char *filename;
+        if (! data)
+               return NULL;
+       filename=data->u.str;
+        dbg(1,"filename %s\n",filename);
+        *meth=map_methods_poi_geodownload;
+
+        m=g_new(struct map_priv, 1);
+        m->filename=g_strdup(filename);
+       m->h = mdb_open(m->filename, MDB_NOFLAGS);
+       m->type=type_none;
+       dbg(1,"attr_search\n");
+       attr=attr_search(attrs, NULL, attr_item_type);
+       dbg(1,"attr_search result %p\n", attr);
+       if (attr) 
+               m->type=attr->u.item_type;
+               
+       
+       catalog = mdb_read_catalog(m->h, MDB_TABLE);
+       for (i = 0; i < catalog->len; i++) {
+               entry = catalog->pdata[i];
+               dbg(1,"object name '%s'\n", entry->object_name);
+               if (!strcasecmp(entry->object_name, "_INDEXDATA")) {
+                       if (load_poi_table(m, entry)) {
+                               printf("%s invalid\n", filename);
+                               g_free(m);
+                               m=NULL;
+                       }
+               }
+       }
+       g_ptr_array_free(catalog, 1);
+        return m;
+}
+
+void
+plugin_init(void)
+{
+       dbg(1,"plugin_init\n");
+       plugin_register_map_type("poi_geodownload", map_new_poi_geodownload);
+       mdb_init();
+}
+
diff --git a/navit/map/textfile/Makefile.am b/navit/map/textfile/Makefile.am
new file mode 100644 (file)
index 0000000..486bc25
--- /dev/null
@@ -0,0 +1,8 @@
+include $(top_srcdir)/Makefile.inc
+AM_CPPFLAGS = @NAVIT_CFLAGS@ -I$(top_srcdir)/navit -DMODULE=map_textfile
+if PLUGINS
+  modulemap_LTLIBRARIES = libmap_textfile.la
+else
+  noinst_LTLIBRARIES = libmap_textfile.la
+endif
+libmap_textfile_la_SOURCES = textfile.c textfile.h
diff --git a/navit/map/textfile/textfile.c b/navit/map/textfile/textfile.c
new file mode 100644 (file)
index 0000000..aa2fa01
--- /dev/null
@@ -0,0 +1,395 @@
+/**
+ * Navit, a modular navigation system.
+ * Copyright (C) 2005-2008 Navit Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <glib.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "config.h"
+#include "debug.h"
+#include "plugin.h"
+#include "projection.h"
+#include "item.h"
+#include "map.h"
+#include "maptype.h"
+#include "attr.h"
+#include "transform.h"
+#include "file.h"
+
+#include "textfile.h"
+
+static int map_id;
+
+static int
+get_tag(char *line, char *name, int *pos, char *ret, char *name_ret)
+{
+       int len=0,quoted;
+       char *p,*e,*n;
+
+       dbg(1,"get_tag %s from %s\n", name, line); 
+       if (name)
+               len=strlen(name);
+       if (pos) 
+               p=line+*pos;
+       else
+               p=line;
+       for(;;) {
+               while (*p == ' ') {
+                       p++;
+               }
+               if (! *p)
+                       return 0;
+               n=p;
+               e=strchr(p,'=');
+               if (! e)
+                       return 0;
+               p=e+1;
+               quoted=0;
+               while (*p) {
+                       if (*p == ' ' && !quoted)
+                               break;
+                       if (*p == '"')
+                               quoted=1-quoted;
+                       p++;
+               }
+               if (name == NULL || (e-n == len && !strncmp(n, name, len))) {
+                       if (name_ret) {
+                               len=e-n;
+                               strncpy(name_ret, n, len);
+                               name_ret[len]='\0';
+                       }
+                       e++;
+                       len=p-e;
+                       if (e[0] == '"') {
+                               e++;
+                               len-=2;
+                       }
+                       strncpy(ret, e, len);
+                       ret[len]='\0';
+                       if (pos)
+                               *pos=p-line;
+                       return 1;
+               }
+       }       
+       return 0;
+}
+
+static void
+get_line(struct map_rect_priv *mr)
+{
+       if(mr->f) {
+               mr->pos=ftell(mr->f);
+               fgets(mr->line, SIZE, mr->f);
+               if (strlen(mr->line) >= SIZE-1) 
+                       printf("line too long\n");
+       }
+}
+
+static void
+map_destroy_textfile(struct map_priv *m)
+{
+       dbg(1,"map_destroy_textfile\n");
+       g_free(m);
+}
+
+static void
+textfile_coord_rewind(void *priv_data)
+{
+}
+
+static int
+parse_line(struct map_rect_priv *mr, int attr)
+{
+       int pos;
+
+       pos=coord_parse(mr->line, projection_mg, &mr->c);
+       if (pos < strlen(mr->line) && attr) {
+               strcpy(mr->attrs, mr->line+pos);
+       }
+       return pos;
+}
+
+static int
+textfile_coord_get(void *priv_data, struct coord *c, int count)
+{
+       struct map_rect_priv *mr=priv_data;
+       int ret=0;
+       dbg(1,"textfile_coord_get %d\n",count);
+       while (count--) {
+               if (mr->f && !feof(mr->f) && (!mr->item.id_hi || !mr->eoc) && parse_line(mr, mr->item.id_hi)) {
+                       *c=mr->c;
+                       dbg(1,"c=0x%x,0x%x\n", c->x, c->y);
+                       c++;
+                       ret++;          
+                       get_line(mr);
+                       if (mr->item.id_hi)
+                               mr->eoc=1;
+               } else {
+                       mr->more=0;
+                       break;
+               }
+       }
+       return ret;
+}
+
+static void
+textfile_attr_rewind(void *priv_data)
+{
+}
+
+static void
+textfile_encode_attr(char *attr_val, enum attr_type attr_type, struct attr *attr)
+{
+       if (attr_type >= attr_type_int_begin && attr_type <= attr_type_int_end) 
+               attr->u.num=atoi(attr_val);
+       else
+               attr->u.str=attr_val;
+}
+
+static int
+textfile_attr_get(void *priv_data, enum attr_type attr_type, struct attr *attr)
+{      
+       struct map_rect_priv *mr=priv_data;
+       char *str=NULL;
+       dbg(1,"textfile_attr_get mr=%p attrs='%s' ", mr, mr->attrs);
+       if (attr_type != mr->attr_last) {
+               dbg(1,"reset attr_pos\n");
+               mr->attr_pos=0;
+               mr->attr_last=attr_type;
+       }
+       if (attr_type == attr_any) {
+               dbg(1,"attr_any");
+               if (get_tag(mr->attrs,NULL,&mr->attr_pos,mr->attr, mr->attr_name)) {
+                       attr_type=attr_from_name(mr->attr_name);
+                       dbg(1,"found attr '%s' 0x%x\n", mr->attr_name, attr_type);
+                       attr->type=attr_type;
+                       textfile_encode_attr(mr->attr, attr_type, attr);
+                       return 1;
+               }
+       } else {
+               str=attr_to_name(attr_type);
+               dbg(1,"attr='%s' ",str);
+               if (get_tag(mr->attrs,str,&mr->attr_pos,mr->attr, NULL)) {
+                       textfile_encode_attr(mr->attr, attr_type, attr);
+                       dbg(1,"found\n");
+                       return 1;
+               }
+       }
+       dbg(1,"not found\n");
+       return 0;
+}
+
+static struct item_methods methods_textfile = {
+        textfile_coord_rewind,
+        textfile_coord_get,
+        textfile_attr_rewind,
+        textfile_attr_get,
+};
+
+static struct map_rect_priv *
+map_rect_new_textfile(struct map_priv *map, struct map_selection *sel)
+{
+       struct map_rect_priv *mr;
+
+       dbg(1,"map_rect_new_textfile\n");
+       mr=g_new0(struct map_rect_priv, 1);
+       mr->m=map;
+       mr->sel=sel;
+       mr->item.id_hi=0;
+       mr->item.id_lo=0;
+       mr->item.meth=&methods_textfile;
+       mr->item.priv_data=mr;
+       if (map->is_pipe) {
+               char *oargs,*args=g_strdup(map->filename),*sep=" ";
+               enum layer_type lay;
+               g_free(mr->args);
+               while (sel) {
+                       oargs=args;
+                       args=g_strdup_printf("%s 0x%x 0x%x 0x%x 0x%x", oargs, sel->u.c_rect.lu.x, sel->u.c_rect.lu.y, sel->u.c_rect.rl.x, sel->u.c_rect.rl.y);
+                       g_free(oargs);
+                       for (lay=layer_town ; lay < layer_end ; lay++) {
+                               oargs=args;
+                               args=g_strdup_printf("%s%s%d", oargs, sep, sel->order);
+                               g_free(oargs);
+                               sep=",";
+                       }
+                       sel=sel->next;
+               }
+               dbg(1,"popen args %s\n", args);
+               mr->args=args;
+               mr->f=popen(mr->args, "r");
+       } else {
+               mr->f=fopen(map->filename, "r");
+       }
+       if(!mr->f) {
+               printf("map_rect_new_textfile unable to open textfile %s\n",map->filename);
+       }
+       get_line(mr);
+       return mr;
+}
+
+
+static void
+map_rect_destroy_textfile(struct map_rect_priv *mr)
+{
+       if (mr->f) {
+               if (mr->m->is_pipe)
+                       pclose(mr->f);
+               else
+                       fclose(mr->f);
+       }
+        g_free(mr);
+}
+
+static struct item *
+map_rect_get_item_textfile(struct map_rect_priv *mr)
+{
+       char *p,type[SIZE];
+       dbg(1,"map_rect_get_item_textfile id_hi=%d line=%s", mr->item.id_hi, mr->line);
+       if (!mr->f) {
+               return NULL;
+       }
+       while (mr->more) {
+               struct coord c;
+               textfile_coord_get(mr, &c, 1);
+       }
+       for(;;) {
+               if (feof(mr->f)) {
+                       dbg(1,"map_rect_get_item_textfile: eof\n");
+                       if (mr->item.id_hi) {
+                               return NULL;
+                       }
+                       mr->item.id_hi++;
+                       if (mr->m->is_pipe) {
+                               pclose(mr->f);
+                               mr->f=popen(mr->args, "r");
+                       } else
+                               fseek(mr->f, 0, SEEK_SET);
+                       get_line(mr);
+               }
+               if ((p=strchr(mr->line,'\n'))) 
+                       *p='\0';
+               if (mr->item.id_hi) {
+                       mr->attrs[0]='\0';
+                       if (!parse_line(mr, 1)) {
+                               get_line(mr);
+                               continue;
+                       }
+                       dbg(1,"map_rect_get_item_textfile: point found\n");
+                       mr->eoc=0;
+                       mr->item.id_lo=mr->pos;
+               } else {
+                       if (parse_line(mr, 1)) {
+                               get_line(mr);
+                               continue;
+                       }
+                       dbg(1,"map_rect_get_item_textfile: line found\n");
+                       if (! mr->line[0]) {
+                               get_line(mr);
+                               continue;
+                       }
+                       mr->item.id_lo=mr->pos;
+                       strcpy(mr->attrs, mr->line);
+                       get_line(mr);
+                       dbg(1,"mr=%p attrs=%s\n", mr, mr->attrs);
+               }
+               dbg(1,"get_attrs %s\n", mr->attrs);
+               if (get_tag(mr->attrs,"type",NULL,type,NULL)) {
+                       dbg(1,"type='%s'\n", type);
+                       mr->item.type=item_from_name(type);
+                       if (mr->item.type == type_none) 
+                               printf("Warning: type '%s' unknown\n", type);
+               } else {
+                       get_line(mr);
+                       continue;
+               }
+               mr->attr_last=attr_none;
+               mr->more=1;
+               dbg(1,"return attr='%s'\n", mr->attrs);
+               return &mr->item;
+       }
+}
+
+static struct item *
+map_rect_get_item_byid_textfile(struct map_rect_priv *mr, int id_hi, int id_lo)
+{
+       if (mr->m->is_pipe) {
+               pclose(mr->f);
+               mr->f=popen(mr->args, "r");
+       } else
+               fseek(mr->f, id_lo, SEEK_SET);
+       get_line(mr);
+       mr->item.id_hi=id_hi;
+       return map_rect_get_item_textfile(mr);
+}
+
+static struct map_methods map_methods_textfile = {
+       projection_mg,
+       "iso8859-1",
+       map_destroy_textfile,
+       map_rect_new_textfile,
+       map_rect_destroy_textfile,
+       map_rect_get_item_textfile,
+       map_rect_get_item_byid_textfile,
+};
+
+static struct map_priv *
+map_new_textfile(struct map_methods *meth, struct attr **attrs)
+{
+       struct map_priv *m;
+       struct attr *data=attr_search(attrs, NULL, attr_data);
+       struct attr *charset=attr_search(attrs, NULL, attr_charset);
+       struct file_wordexp *wexp;
+       int len,is_pipe=0;
+       char *wdata;
+       char **wexp_data;
+       if (! data)
+               return NULL;
+       dbg(1,"map_new_textfile %s\n", data->u.str);    
+       wdata=g_strdup_printf(data->u.str);
+       len=strlen(wdata);
+       if (len && wdata[len-1] == '|') {
+               wdata[len-1]='\0';
+               is_pipe=1;
+       }
+       wexp=file_wordexp_new(wdata);
+       wexp_data=file_wordexp_get_array(wexp);
+       *meth=map_methods_textfile;
+
+       m=g_new0(struct map_priv, 1);
+       m->id=++map_id;
+       m->filename=g_strdup(wexp_data[0]);
+       m->is_pipe=is_pipe;
+       dbg(1,"map_new_textfile %s %s\n", m->filename, wdata);
+       if (charset) {
+               m->charset=g_strdup(charset->u.str);
+               meth->charset=m->charset;
+       }
+       file_wordexp_destroy(wexp);
+       return m;
+}
+
+void
+plugin_init(void)
+{
+       dbg(1,"textfile: plugin_init\n");
+       plugin_register_map_type("textfile", map_new_textfile);
+}
+
diff --git a/navit/map/textfile/textfile.h b/navit/map/textfile/textfile.h
new file mode 100644 (file)
index 0000000..b7a77be
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * Navit, a modular navigation system.
+ * Copyright (C) 2005-2008 Navit Team
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <stdio.h>
+#include "attr.h"
+#include "coord.h"
+struct map_priv {
+       int id;
+       char *filename;
+       char *charset;
+       int is_pipe;
+};
+
+#define SIZE 512
+
+struct map_rect_priv {
+       struct map_selection *sel;
+
+       FILE *f;
+       long pos;
+       char line[SIZE];
+       int attr_pos;
+       enum attr_type attr_last;
+       char attrs[SIZE];
+       char attr[SIZE];
+       char attr_name[SIZE];
+       struct coord c;
+       int eoc;
+       int more;
+       struct map_priv *m;
+       struct item item;
+       char *args;
+};
+
index 6496f74..8849bc1 100644 (file)
@@ -308,7 +308,7 @@ plugins_destroy(struct plugins *pls)
        void *
 plugin_get_type(enum plugin_type type, const char *type_name, const char *name)
 {
-       dbg(1, "type=\"%s\", name=\"%s\"\n", type_name, name);
+       dbg(0, "type=\"%s\", name=\"%s\"\n", type_name, name);
        GList *l,*lpls;
        struct name_val *nv;
        struct plugin *pl;
@@ -323,8 +323,6 @@ plugin_get_type(enum plugin_type type, const char *type_name, const char *name)
        if (!pls)
                return NULL;
        lpls=pls->list;
-       if(!g_ascii_strcasecmp(type_name, "map"))
-               type_name="data";
        filename=g_strjoin("", "lib", type_name, "_", name, NULL);
        corename=g_strjoin("", "lib", type_name, "_", "core", NULL);
        while (lpls) {