/* * Navit, a modular navigation system. * Copyright (C) 2005-2011 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 #include #include #ifdef _MSC_VER #define atoll _atoi64 #else #include #endif #include "maptool.h" int osm_xml_get_attribute(char *xml, char *attribute, char *buffer, int buffer_size) { int len=strlen(attribute); char *pos,*i,s,*attr; attr=g_alloca(len+2); strcpy(attr, attribute); strcpy(attr+len, "="); pos=strstr(xml, attr); if (! pos) return 0; pos+=len+1; s=*pos++; if (! s) return 0; i=strchr(pos, s); if (! i) return 0; if (i - pos > buffer_size) { fprintf(stderr,"Buffer overflow %ld vs %d\n", (long)(i-pos), buffer_size); return 0; } strncpy(buffer, pos, i-pos); buffer[i-pos]='\0'; return 1; } static struct entity { char *entity; char c; } entities[]= { {""",'"'}, {"'",'\''}, {"&",'&'}, {"<",'<'}, {">",'>'}, {""",'"'}, {"'",'\''}, {"&",'&'}, {"<",'<'}, {">",'>'}, {"{",'{'}, {"}",'}'}, }; void osm_xml_decode_entities(char *buffer) { char *pos=buffer; int i,len; while ((pos=strchr(pos, '&'))) { for (i = 0 ; i < sizeof(entities)/sizeof(struct entity); i++) { len=strlen(entities[i].entity); if (!strncmp(pos, entities[i].entity, len)) { *pos=entities[i].c; memmove(pos+1, pos+len, strlen(pos+len)+1); break; } } pos++; } } static int parse_tag(char *p) { char k_buffer[BUFFER_SIZE]; char v_buffer[BUFFER_SIZE]; if (!osm_xml_get_attribute(p, "k", k_buffer, BUFFER_SIZE)) return 0; if (!osm_xml_get_attribute(p, "v", v_buffer, BUFFER_SIZE)) return 0; osm_xml_decode_entities(v_buffer); osm_add_tag(k_buffer, v_buffer); return 1; } static int parse_node(char *p) { char id_buffer[BUFFER_SIZE]; char lat_buffer[BUFFER_SIZE]; char lon_buffer[BUFFER_SIZE]; if (!osm_xml_get_attribute(p, "id", id_buffer, BUFFER_SIZE)) return 0; if (!osm_xml_get_attribute(p, "lat", lat_buffer, BUFFER_SIZE)) return 0; if (!osm_xml_get_attribute(p, "lon", lon_buffer, BUFFER_SIZE)) return 0; osm_add_node(atoll(id_buffer), atof(lat_buffer), atof(lon_buffer)); return 1; } static int parse_way(char *p) { char id_buffer[BUFFER_SIZE]; if (!osm_xml_get_attribute(p, "id", id_buffer, BUFFER_SIZE)) return 0; osm_add_way(atoll(id_buffer)); return 1; } static int parse_relation(char *p) { char id_buffer[BUFFER_SIZE]; if (!osm_xml_get_attribute(p, "id", id_buffer, BUFFER_SIZE)) return 0; osm_add_relation(atoll(id_buffer)); return 1; } static int parse_member(char *p) { char type_buffer[BUFFER_SIZE]; char ref_buffer[BUFFER_SIZE]; char role_buffer[BUFFER_SIZE]; enum relation_member_type type; if (!osm_xml_get_attribute(p, "type", type_buffer, BUFFER_SIZE)) return 0; if (!osm_xml_get_attribute(p, "ref", ref_buffer, BUFFER_SIZE)) return 0; if (!osm_xml_get_attribute(p, "role", role_buffer, BUFFER_SIZE)) return 0; if (!g_strcmp0(type_buffer,"node")) type=rel_member_node; else if (!g_strcmp0(type_buffer,"way")) type=rel_member_way; else if (!g_strcmp0(type_buffer,"relation")) type=rel_member_relation; else { fprintf(stderr,"Unknown type '%s'\n",type_buffer); return 0; } osm_add_member(type, atoll(ref_buffer), role_buffer); return 1; } static int parse_nd(char *p) { char ref_buffer[BUFFER_SIZE]; if (!osm_xml_get_attribute(p, "ref", ref_buffer, BUFFER_SIZE)) return 0; osm_add_nd(atoll(ref_buffer)); return 1; } static int xml_declaration_in_line(char* buffer) { return !strncmp(buffer, "",12)) { } else if (!strncmp(p, "",7)) { osm_end_node(osm); } else if (!strncmp(p, "",6)) { osm_end_way(osm); } else if (!strncmp(p, "",11)) { osm_end_relation(osm); } else if (!strncmp(p, "",6)) { } else { fprintf(stderr,"WARNING: unknown tag in %s\n", buffer); } } sig_alrm(0); sig_alrm_end(); return 1; }