diff --git a/Makefile.am b/Makefile.am index 5e6405ee5..2203d04c4 100644 --- a/Makefile.am +++ b/Makefile.am @@ -31,7 +31,6 @@ osm2pgsql_SOURCES = osm2pgsql.cpp \ sanitizer.hpp \ sprompt.hpp \ table.hpp \ - text-tree.hpp \ util.hpp osm2pgsql_LDADD = libosm2pgsql.la @@ -71,7 +70,6 @@ libosm2pgsql_la_SOURCES = \ table.cpp \ taginfo.cpp \ tagtransform.cpp \ - text-tree.cpp \ util.cpp \ wildcmp.cpp diff --git a/geometry-processor.cpp b/geometry-processor.cpp index 71ebee711..16e302bae 100644 --- a/geometry-processor.cpp +++ b/geometry-processor.cpp @@ -91,7 +91,7 @@ relation_helper::~relation_helper() //clean up for(size_t i = 0; i < way_count; ++i) { - keyval::resetList(&(tags[i])); + tags[i].resetList(); free(nodes[i]); } } @@ -101,7 +101,7 @@ size_t& relation_helper::set(const member* member_list, const int member_list_le //clean up for(size_t i = 0; i < way_count; ++i) { - keyval::resetList(&(tags[i])); + tags[i].resetList(); free(nodes[i]); } diff --git a/keyvals.cpp b/keyvals.cpp index 92f98f383..8c5b9cd8e 100644 --- a/keyvals.cpp +++ b/keyvals.cpp @@ -13,75 +13,37 @@ #include -keyval::keyval() -{ - tree_ctx.reset(new text_tree()); - keyval::initList(this); -} -keyval::~keyval() +keyval::keyval(const keyval &other) { - //keyval::resetList(this); + key = other.key; + value = other.value; + // the list cannot be copied, so initialise as empty + next = this; + prev = this; + has_column = other.has_column; } -void keyval::initList(struct keyval *head) -{ - assert(head); - - head->next = head; - head->prev = head; - head->key = NULL; - head->value = NULL; - head->has_column = 0; -} -void keyval::freeItem(struct keyval *p) +unsigned int keyval::countList() const { - if (!p) - return; - - p->tree_ctx->text_release(p->key); - p->tree_ctx->text_release(p->value); - delete p; -} - - -unsigned int keyval::countList(const struct keyval *head) -{ - struct keyval *p; unsigned int count = 0; - if (!head) - return 0; - - p = head->next; - while(p != head) { + keyval *p = next; + while(p != this) { count++; p = p->next; } return count; } -int keyval::listHasData(struct keyval *head) -{ - if (!head) - return 0; - - return (head->next != head); -} - -char *keyval::getItem(const struct keyval *head, const char *name) +const std::string *keyval::getItem(const std::string &name) const { - struct keyval *p; - - if (!head) - return NULL; - - p = head->next; - while(p != head) { - if (!strcmp(p->key, name)) - return p->value; + keyval *p = next; + while(p != this) { + if (!p->key.compare(name)) + return &(p->value); p = p->next; } return NULL; @@ -91,112 +53,33 @@ char *keyval::getItem(const struct keyval *head, const char *name) list item which can be used to remove the tag from the linked list with the removeTag function */ -struct keyval *keyval::getTag(struct keyval *head, const char *name) +struct keyval *keyval::getTag(const std::string &name) { - struct keyval *p; - - if (!head) - return NULL; - - p = head->next; - while(p != head) { - if (!strcmp(p->key, name)) + keyval *p = next; + while(p != this) { + if (!p->key.compare(name)) return p; p = p->next; } return NULL; } -void keyval::removeTag(struct keyval *tag) +void keyval::removeTag() { - tag->prev->next=tag->next; - tag->next->prev=tag->prev; - freeItem(tag); + prev->next = next; + next->prev = prev; + delete(this); } -struct keyval *keyval::firstItem(struct keyval *head) -{ - if (head == NULL || head == head->next) - return NULL; - - return head->next; -} -struct keyval *keyval::nextItem(struct keyval *head, struct keyval *item) +struct keyval *keyval::popItem() { - if (item->next == head) + keyval *p = next; + if (p == this) return NULL; - return item->next; -} - -/* Pulls all items from list which match this prefix - * note: they are removed from the original list an returned in a new one - */ -struct keyval *keyval::getMatches(struct keyval *head, const char *name) -{ - struct keyval *out = NULL; - struct keyval *p; - - if (!head) - return NULL; - - //TODO: properly copy the tree_ctx from the keyval passed in - out = new keyval(); - if (!out) - return NULL; - - p = head->next; - while(p != head) { - struct keyval *next = p->next; - if (!strncmp(p->key, name, strlen(name))) { - p->next->prev = p->prev; - p->prev->next = p->next; - pushItem(out, p); - } - p = next; - } - - if (listHasData(out)) - return out; - - delete out; - return NULL; -} - -void keyval::updateItem(struct keyval *head, const char *name, const char *value) -{ - struct keyval *item; - - if (!head) - return; - - item = head->next; - while(item != head) { - if (!strcmp(item->key, name)) { - head->tree_ctx->text_release(item->value); - item->value = (char *)head->tree_ctx->text_get(value); - return; - } - item = item->next; - } - addItem(head, name, value, 0); -} - - -struct keyval *keyval::popItem(struct keyval *head) -{ - struct keyval *p; - - if (!head) - return NULL; - - p = head->next; - if (p == head) - return NULL; - - head->next = p->next; - p->next->prev = head; + next = p->next; + p->next->prev = this; p->next = NULL; p->prev = NULL; @@ -205,62 +88,57 @@ struct keyval *keyval::popItem(struct keyval *head) } -void keyval::pushItem(struct keyval *head, struct keyval *item) +void keyval::pushItem(struct keyval *item) { - - assert(head); assert(item); - item->next = head; - item->prev = head->prev; - head->prev->next = item; - head->prev = item; + item->next = this; + item->prev = prev; + prev->next = item; + prev = item; } -int keyval::addItem(struct keyval *head, const char *name, const char *value, int noDupe) +int keyval::addItem(const std::string &name, const std::string &value, bool noDupe) { - struct keyval *item; - - assert(head); - assert(name); - assert(value); - if (noDupe) { - item = head->next; - while (item != head) { - if (!strcmp(item->value, value) && !strcmp(item->key, name)) + keyval *item = next; + while (item != this) { + if (!value.compare(item->value) && !name.compare(item->key)) return 1; item = item->next; } } - //TODO: properly implement a copy constructor and do the - //shallow copy there instead of relying on implicit one? - item = new keyval(*head); - - item->key = (char *)head->tree_ctx->text_get(name); - item->value = (char *)head->tree_ctx->text_get(value); - item->has_column=0; + new keyval(name, value, this); - /* Add to head */ - item->next = head->next; - item->prev = head; - head->next->prev = item; - head->next = item; return 0; } -void keyval::resetList(struct keyval *head) +void keyval::resetList() { struct keyval *item; - while((item = popItem(head))) - freeItem(item); + while((item = popItem())) + delete(item); +} + +void keyval::cloneList(struct keyval *target) +{ + for(keyval *ptr = firstItem(); ptr; ptr = nextItem(ptr)) + target->addItem(ptr->key, ptr->value, false); } -void keyval::cloneList( struct keyval *target, struct keyval *source ) +void keyval::moveList(keyval *target) { - struct keyval *ptr; - for( ptr = source->next; ptr != source; ptr=ptr->next ) - addItem( target, ptr->key, ptr->value, 0 ); + target->resetList(); + + if (listHasData()) { + target->next = next; + target->prev = prev; + next->prev = target; + prev->next = target; + + next = this; + prev = this; + } } diff --git a/keyvals.hpp b/keyvals.hpp index 12db03721..2e631152b 100644 --- a/keyvals.hpp +++ b/keyvals.hpp @@ -8,42 +8,56 @@ #ifndef KEYVAL_H #define KEYVAL_H -#include "text-tree.hpp" - #include struct keyval { - char *key; - char *value; + std::string key; + std::string value; /* if a hstore column is requested we need a flag to store if a key has its own column because it should not be added to the hstore in this case */ int has_column; - struct keyval *next; - struct keyval *prev; - boost::shared_ptr tree_ctx; - - keyval(); - ~keyval(); - - static void initList(struct keyval *head); - static void freeItem(struct keyval *p); - static unsigned int countList(const struct keyval *head); - static int listHasData(struct keyval *head); - static char *getItem(const struct keyval *head, const char *name); - static struct keyval *getTag(struct keyval *head, const char *name); - static const struct keyval *getTag(const struct keyval *head, const char *name); - static void removeTag(struct keyval *tag); - static struct keyval *firstItem(struct keyval *head); - static struct keyval *nextItem(struct keyval *head, struct keyval *item); - static struct keyval *popItem(struct keyval *head); - static void pushItem(struct keyval *head, struct keyval *item); - static int addItem(struct keyval *head, const char *name, const char *value, int noDupe); - static void resetList(struct keyval *head); - static struct keyval *getMatches(struct keyval *head, const char *name); - static void updateItem(struct keyval *head, const char *name, const char *value); - static void cloneList( struct keyval *target, struct keyval *source ); +private: + keyval *next; + keyval *prev; + +public: + keyval() : has_column(0), next(this), prev(this) {} + + keyval(const std::string &name_, const std::string &value_) + : key(name_), value(value_), has_column(0), next(NULL), prev(NULL) + {} + + keyval(const keyval &other); + ~keyval() {} + + unsigned int countList() const; + bool listHasData() const { return next != this; } + const std::string *getItem(const std::string &name) const; + keyval *getTag(const std::string &name); + void removeTag(); + keyval *firstItem() const { return listHasData() ? next : NULL; } + keyval *nextItem(const keyval *item) const { + return item->next == this ? NULL : item->next; + } + keyval *popItem(); + void pushItem(keyval *item); + int addItem(const std::string &name, const std::string &value, bool noDupe); + void resetList(); + void cloneList(keyval *target); + void moveList(keyval *target); + +private: + keyval(const std::string &key_, const std::string &value_, keyval *after) + : key(key_), value(value_), has_column(0) + { + next = after->next; + prev = after; + after->next->prev = this; + after->next = this; + } + }; diff --git a/middle-pgsql.cpp b/middle-pgsql.cpp index d8ecc2abe..637704792 100644 --- a/middle-pgsql.cpp +++ b/middle-pgsql.cpp @@ -189,10 +189,9 @@ const char *pgsql_store_tags(const struct keyval *tags, const int& escape) static int buflen; char *ptr; - struct keyval *i; int first; - int countlist = keyval::countList(tags); + int countlist = tags->countList(); if( countlist == 0 ) { if( escape ) @@ -211,10 +210,10 @@ const char *pgsql_store_tags(const struct keyval *tags, const int& escape) ptr = buffer; first = 1; *ptr++ = '{'; - // The lists are circular, exit when we reach the head again */ - for( i=tags->next; i->key; i = i->next ) + + for(keyval* i = tags->firstItem(); i; i = tags->nextItem(i)) { - int maxlen = (strlen(i->key) + strlen(i->value)) * 4; + int maxlen = (i->key.length() + i->value.length()) * 4; if( (ptr+maxlen-buffer) > (buflen-20) ) // Almost overflowed? */ { buflen <<= 1; @@ -224,11 +223,11 @@ const char *pgsql_store_tags(const struct keyval *tags, const int& escape) } if( !first ) *ptr++ = ','; *ptr++ = '"'; - ptr = escape_tag( ptr, i->key, escape ); + ptr = escape_tag( ptr, i->key.c_str(), escape ); *ptr++ = '"'; *ptr++ = ','; *ptr++ = '"'; - ptr = escape_tag( ptr, i->value, escape ); + ptr = escape_tag( ptr, i->value.c_str(), escape ); *ptr++ = '"'; first=0; @@ -284,7 +283,7 @@ void pgsql_parse_tags( const char *string, struct keyval *tags ) string++; string = decode_upto( string, val ); // String points to the comma or closing '}' */ - keyval::addItem( tags, key, val, 0 ); + tags->addItem( key, val, false ); if( *string == ',' ) string++; } @@ -640,7 +639,6 @@ int middle_pgsql_t::ways_get_list(const osmid_t *ids, int way_count, osmid_t *wa // Match the list of ways coming from postgres in a different order // back to the list of ways given by the caller */ count = 0; - keyval::initList(&(tags[count])); for (i = 0; i < way_count; i++) { for (j = 0; j < countPG; j++) { if (ids[i] == wayidspg[j]) { @@ -655,11 +653,13 @@ int middle_pgsql_t::ways_get_list(const osmid_t *ids, int way_count, osmid_t *wa count_ptr[count] = nodes_get_list(nodes_ptr[count], list, num_nodes); count++; - keyval::initList(&(tags[count])); + break; } } } + assert(count<=way_count); + PQclear(res); free(tmp2); free(wayidspg); @@ -743,8 +743,6 @@ int middle_pgsql_t::relations_set(osmid_t id, struct member *members, int member way_parts.reserve(member_count); rel_parts.reserve(member_count); - keyval::initList( &member_list ); - for( i=0; i (length-10) ) { fprintf( stderr, "buffer overflow relation id %" PRIdOSMID "\n", id); return 1; } free(tag_buf); - keyval::resetList(&member_list); + member_list.resetList(); pgsql_CopyData(__FUNCTION__, rel_table->sql_conn, buffer); return 0; } @@ -796,7 +794,7 @@ int middle_pgsql_t::relations_set(osmid_t id, struct member *members, int member pgsql_execPrepared(rel_table->sql_conn, "insert_rel", 6, (const char * const *)paramValues, PGRES_COMMAND_OK); if( paramValues[4] ) free((void *)paramValues[4]); - keyval::resetList(&member_list); + member_list.resetList(); return 0; } @@ -812,7 +810,6 @@ int middle_pgsql_t::relations_get(osmid_t id, struct member **members, int *memb int num_members; struct member *list; int i=0; - struct keyval *item; // Make sure we're out of copy mode */ pgsql_endCopy( rel_table ); @@ -829,13 +826,13 @@ int middle_pgsql_t::relations_get(osmid_t id, struct member **members, int *memb } pgsql_parse_tags( PQgetvalue(res, 0, 1), tags ); - keyval::initList(&member_temp); pgsql_parse_tags( PQgetvalue(res, 0, 0), &member_temp ); num_members = strtol(PQgetvalue(res, 0, 2), NULL, 10); list = (struct member *)malloc( sizeof(struct member)*num_members ); - while( (item = keyval::popItem(&member_temp)) ) + keyval *item; + while((item = member_temp.popItem())) { if( i >= num_members ) { @@ -844,9 +841,9 @@ int middle_pgsql_t::relations_get(osmid_t id, struct member **members, int *memb } tag = item->key[0]; list[i].type = (tag == 'n')?OSMTYPE_NODE:(tag == 'w')?OSMTYPE_WAY:(tag == 'r')?OSMTYPE_RELATION:((OsmType)-1); - list[i].id = strtoosmid(item->key+1, NULL, 10 ); - list[i].role = strdup( item->value ); - keyval::freeItem(item); + list[i].id = strtoosmid(item->key.c_str()+1, NULL, 10 ); + list[i].role = strdup( item->value.c_str() ); + delete(item); i++; } *members = list; diff --git a/middle-ram.cpp b/middle-ram.cpp index 50c980dce..01deb43ae 100644 --- a/middle-ram.cpp +++ b/middle-ram.cpp @@ -89,11 +89,10 @@ int middle_ram_t::ways_set(osmid_t id, osmid_t *nds, int nd_count, struct keyval if (!ways[block][offset].tags) { ways[block][offset].tags = new keyval(); - keyval::initList(ways[block][offset].tags); } else - keyval::resetList(ways[block][offset].tags); + ways[block][offset].tags->resetList(); - keyval::cloneList(ways[block][offset].tags, tags); + tags->cloneList(ways[block][offset].tags); return 0; } @@ -113,11 +112,10 @@ int middle_ram_t::relations_set(osmid_t id, struct member *members, int member_c if (!rels[block][offset].tags) { rels[block][offset].tags = new keyval(); - keyval::initList(rels[block][offset].tags); } else - keyval::resetList(rels[block][offset].tags); + rels[block][offset].tags->resetList(); - keyval::cloneList(rels[block][offset].tags, tags); + tags->cloneList(rels[block][offset].tags); free( rels[block][offset].members ); rels[block][offset].members = NULL; @@ -188,7 +186,7 @@ void middle_ram_t::release_relations() if (rels[block][offset].members) { free(rels[block][offset].members); rels[block][offset].members = NULL; - keyval::resetList(rels[block][offset].tags); + rels[block][offset].tags->resetList(); delete rels[block][offset].tags; rels[block][offset].tags=NULL; } @@ -206,7 +204,7 @@ void middle_ram_t::release_ways() if (ways[i]) { for (j=0; jresetList(); delete ways[i][j].tags; } if (ways[i][j].ndids) @@ -236,7 +234,7 @@ int middle_ram_t::ways_get(osmid_t id, struct keyval *tags_ptr, struct osmNode * int ndCount = nodes_get_list(nodes, ways[block][offset].ndids+1, ways[block][offset].ndids[0]); if (ndCount) { - keyval::cloneList( tags_ptr, ways[block][offset].tags ); + ways[block][offset].tags->cloneList(tags_ptr); *nodes_ptr = nodes; *count_ptr = ndCount; return 0; @@ -250,13 +248,11 @@ int middle_ram_t::ways_get_list(const osmid_t *ids, int way_count, osmid_t *way_ int count = 0; int i; - keyval::initList(&(tag_ptr[count])); for (i = 0; i < way_count; i++) { if (ways_get(ids[i], &(tag_ptr[count]), &(node_ptr[count]), &(count_ptr[count])) == 0) { way_ids[count] = ids[i]; count++; - keyval::initList(&(tag_ptr[count])); } } return count; @@ -278,7 +274,7 @@ int middle_ram_t::relations_get(osmid_t id, struct member **members_ptr, int *me const size_t member_bytes = sizeof(struct member) * rels[block][offset].member_count; members = (struct member *)malloc(member_bytes); memcpy(members, rels[block][offset].members, member_bytes); - keyval::cloneList( tags_ptr, rels[block][offset].tags ); + rels[block][offset].tags->cloneList(tags_ptr); *members_ptr = members; *member_count = rels[block][offset].member_count; diff --git a/osm2pgsql.cpp b/osm2pgsql.cpp index 99a0f390f..59a191585 100644 --- a/osm2pgsql.cpp +++ b/osm2pgsql.cpp @@ -30,7 +30,6 @@ #include "output.hpp" #include "osmdata.hpp" #include "util.hpp" -#include "text-tree.hpp" #include #include diff --git a/output-gazetteer.cpp b/output-gazetteer.cpp index 552b517c0..d2d47579c 100644 --- a/output-gazetteer.cpp +++ b/output-gazetteer.cpp @@ -249,340 +249,334 @@ static int split_tags(struct keyval *tags, unsigned int flags, conscriptionnumber = 0; streetnumber = 0; - /* Initialise the result lists */ - keyval::initList(names); - keyval::initList(places); - keyval::initList(extratags); - /* Loop over the tags */ - while ((item = keyval::popItem(tags)) != NULL) + while ((item = tags->popItem()) != NULL) { /* If this is a name tag, add it to the name list */ - if (strcmp(item->key, "ref") == 0 || - strcmp(item->key, "int_ref") == 0 || - strcmp(item->key, "nat_ref") == 0 || - strcmp(item->key, "reg_ref") == 0 || - strcmp(item->key, "loc_ref") == 0 || - strcmp(item->key, "old_ref") == 0 || - strcmp(item->key, "ncn_ref") == 0 || - strcmp(item->key, "rcn_ref") == 0 || - strcmp(item->key, "lcn_ref") == 0 || - strcmp(item->key, "iata") == 0 || - strcmp(item->key, "icao") == 0 || - strcmp(item->key, "pcode:1") == 0 || - strcmp(item->key, "pcode:2") == 0 || - strcmp(item->key, "pcode:3") == 0 || - strcmp(item->key, "un:pcode:1") == 0 || - strcmp(item->key, "un:pcode:2") == 0 || - strcmp(item->key, "un:pcode:3") == 0 || - strcmp(item->key, "name") == 0 || - (strncmp(item->key, "name:", 5) == 0) || - strcmp(item->key, "int_name") == 0 || - (strncmp(item->key, "int_name:", 9) == 0) || - strcmp(item->key, "nat_name") == 0 || - (strncmp(item->key, "nat_name:", 9) == 0) || - strcmp(item->key, "reg_name") == 0 || - (strncmp(item->key, "reg_name:", 9) == 0) || - strcmp(item->key, "loc_name") == 0 || - (strncmp(item->key, "loc_name:", 9) == 0) || - strcmp(item->key, "old_name") == 0 || - (strncmp(item->key, "old_name:", 9) == 0) || - strcmp(item->key, "alt_name") == 0 || - (strncmp(item->key, "alt_name_", 9) == 0) || - (strncmp(item->key, "alt_name:", 9) == 0) || - strcmp(item->key, "official_name") == 0 || - (strncmp(item->key, "official_name:", 14) == 0) || - strcmp(item->key, "commonname") == 0 || - (strncmp(item->key, "commonname:", 11) == 0) || - strcmp(item->key, "common_name") == 0 || - (strncmp(item->key, "common_name:", 12) == 0) || - strcmp(item->key, "place_name") == 0 || - (strncmp(item->key, "place_name:", 11) == 0) || - strcmp(item->key, "short_name") == 0 || - (strncmp(item->key, "short_name:", 11) == 0) || - strcmp(item->key, "operator") == 0) /* operator is a bit of an oddity */ + if (item->key == "ref" || + item->key == "int_ref" || + item->key == "nat_ref" || + item->key == "reg_ref" || + item->key == "loc_ref" || + item->key == "old_ref" || + item->key == "ncn_ref" || + item->key == "rcn_ref" || + item->key == "lcn_ref" || + item->key == "iata" || + item->key == "icao" || + item->key == "pcode:1" || + item->key == "pcode:2" || + item->key == "pcode:3" || + item->key == "un:pcode:1" || + item->key == "un:pcode:2" || + item->key == "un:pcode:3" || + item->key == "name" || + (strncmp(item->key.c_str(), "name:", 5) == 0) || + item->key == "int_name" || + (strncmp(item->key.c_str(), "int_name:", 9) == 0) || + item->key == "nat_name" || + (strncmp(item->key.c_str(), "nat_name:", 9) == 0) || + item->key == "reg_name" || + (strncmp(item->key.c_str(), "reg_name:", 9) == 0) || + item->key == "loc_name" || + (strncmp(item->key.c_str(), "loc_name:", 9) == 0) || + item->key == "old_name" || + (strncmp(item->key.c_str(), "old_name:", 9) == 0) || + item->key == "alt_name" || + (strncmp(item->key.c_str(), "alt_name_", 9) == 0) || + (strncmp(item->key.c_str(), "alt_name:", 9) == 0) || + item->key == "official_name" || + (strncmp(item->key.c_str(), "official_name:", 14) == 0) || + item->key == "commonname" || + (strncmp(item->key.c_str(), "commonname:", 11) == 0) || + item->key == "common_name" || + (strncmp(item->key.c_str(), "common_name:", 12) == 0) || + item->key == "place_name" || + (strncmp(item->key.c_str(), "place_name:", 11) == 0) || + item->key == "short_name" || + (strncmp(item->key.c_str(), "short_name:", 11) == 0) || + item->key == "operator") /* operator is a bit of an oddity */ { - if (strcmp(item->key, "name:prefix") == 0) + if (item->key == "name:prefix") { - keyval::pushItem(extratags, item); + extratags->pushItem(item); } else { - keyval::pushItem(names, item); + names->pushItem(item); } } - else if (strcmp(item->key, "emergency") == 0 || - strcmp(item->key, "tourism") == 0 || - strcmp(item->key, "historic") == 0 || - strcmp(item->key, "military") == 0 || - strcmp(item->key, "natural") == 0) + else if (item->key == "emergency" || + item->key == "tourism" || + item->key == "historic" || + item->key == "military" || + item->key == "natural") { - if (strcmp(item->value, "no") && strcmp(item->value, "yes")) + if (item->value != "no" && item->value != "yes") { - keyval::pushItem(places, item); + places->pushItem(item); } else { - keyval::freeItem(item); + delete(item); } } - else if (strcmp(item->key, "highway") == 0) + else if (item->key == "highway") { - if (strcmp(item->value, "no") && - strcmp(item->value, "turning_circle") && - strcmp(item->value, "traffic_signals") && - strcmp(item->value, "mini_roundabout") && - strcmp(item->value, "noexit") && - strcmp(item->value, "crossing")) + if (item->value != "no" && + item->value != "turning_circle" && + item->value != "traffic_signals" && + item->value != "mini_roundabout" && + item->value != "noexit" && + item->value != "crossing") { - keyval::pushItem(places, item); + places->pushItem(item); } else { - keyval::freeItem(item); + delete(item); } } - else if (strcmp(item->key, "aerialway") == 0 || - strcmp(item->key, "aeroway") == 0 || - strcmp(item->key, "amenity") == 0 || - strcmp(item->key, "boundary") == 0 || - strcmp(item->key, "bridge") == 0 || - strcmp(item->key, "craft") == 0 || - strcmp(item->key, "leisure") == 0 || - strcmp(item->key, "office") == 0 || - strcmp(item->key, "railway") == 0 || - strcmp(item->key, "shop") == 0 || - strcmp(item->key, "tunnel") == 0 ) + else if (item->key == "aerialway" || + item->key == "aeroway" || + item->key == "amenity" || + item->key == "boundary" || + item->key == "bridge" || + item->key == "craft" || + item->key == "leisure" || + item->key == "office" || + item->key == "railway" || + item->key == "shop" || + item->key == "tunnel" ) { - if (strcmp(item->value, "no")) + if (item->value != "no") { - keyval::pushItem(places, item); - if (strcmp(item->key, "boundary") == 0 && strcmp(item->value, "administrative") == 0) + places->pushItem(item); + if (item->key == "boundary" && item->value == "administrative") { placeadmin = 1; } } else { - keyval::freeItem(item); + delete(item); } } - else if (strcmp(item->key, "waterway") == 0 && - strcmp(item->value, "riverbank") != 0) + else if (item->key == "waterway" && item->value != "riverbank") { - keyval::pushItem(places, item); + places->pushItem(item); } - else if (strcmp(item->key, "place") == 0) + else if (item->key == "place") { place = item; } - else if (strcmp(item->key, "addr:housename") == 0) + else if (item->key == "addr:housename") { - keyval::pushItem(names, item); + names->pushItem(item); placehouse = 1; } - else if (strcmp(item->key, "landuse") == 0) + else if (item->key == "landuse") { - if (strcmp(item->value, "cemetery") == 0) - keyval::pushItem(places, item); + if (item->value == "cemetery") + places->pushItem(item); else landuse = item; } - else if (strcmp(item->key, "postal_code") == 0 || - strcmp(item->key, "post_code") == 0 || - strcmp(item->key, "postcode") == 0 || - strcmp(item->key, "addr:postcode") == 0 || - strcmp(item->key, "tiger:zip_left") == 0 || - strcmp(item->key, "tiger:zip_right") == 0) + else if (item->key == "postal_code" || + item->key == "post_code" || + item->key == "postcode" || + item->key == "addr:postcode" || + item->key == "tiger:zip_left" || + item->key == "tiger:zip_right") { if (*postcode) - keyval::freeItem(item); + delete(item); else *postcode = item; } - else if (strcmp(item->key, "addr:street") == 0) + else if (item->key == "addr:street") { *street = item; } - else if (strcmp(item->key, "addr:place") == 0) + else if (item->key == "addr:place") { *addr_place = item; } - else if ((strcmp(item->key, "country_code_iso3166_1_alpha_2") == 0 || - strcmp(item->key, "country_code_iso3166_1") == 0 || - strcmp(item->key, "country_code_iso3166") == 0 || - strcmp(item->key, "country_code") == 0 || - strcmp(item->key, "iso3166-1:alpha2") == 0 || - strcmp(item->key, "iso3166-1") == 0 || - strcmp(item->key, "ISO3166-1") == 0 || - strcmp(item->key, "iso3166") == 0 || - strcmp(item->key, "is_in:country_code") == 0 || - strcmp(item->key, "addr:country") == 0 || - strcmp(item->key, "addr:country_code") == 0) - && strlen(item->value) == 2) + else if ((item->key == "country_code_iso3166_1_alpha_2" || + item->key == "country_code_iso3166_1" || + item->key == "country_code_iso3166" || + item->key == "country_code" || + item->key == "iso3166-1:alpha2" || + item->key == "iso3166-1" || + item->key == "ISO3166-1" || + item->key == "iso3166" || + item->key == "is_in:country_code" || + item->key == "addr:country" || + item->key == "addr:country_code") + && item->value.length() == 2) { *countrycode = item; } - else if (strcmp(item->key, "addr:housenumber") == 0) + else if (item->key == "addr:housenumber") { /* house number can be far more complex than just a single house number - leave for postgresql to deal with */ if (*housenumber) - keyval::freeItem(item); + delete(item); else { *housenumber = item; placehouse = 1; } } - else if (strcmp(item->key, "addr:conscriptionnumber") == 0) + else if (item->key == "addr:conscriptionnumber") { if (conscriptionnumber) - keyval::freeItem(item); + delete(item); else { conscriptionnumber = item; placehouse = 1; } } - else if (strcmp(item->key, "addr:streetnumber") == 0) + else if (item->key == "addr:streetnumber") { if (streetnumber) - keyval::freeItem(item); + delete(item); else { streetnumber = item; placehouse = 1; } } - else if (strcmp(item->key, "addr:interpolation") == 0) + else if (item->key == "addr:interpolation") { /* house number can be far more complex than just a single house number - leave for postgresql to deal with */ if (*housenumber) { - keyval::freeItem(item); + delete(item); } else { *housenumber = item; - keyval::addItem(places, "place", "houses", 1); + places->addItem("place", "houses", true); } } - else if (strcmp(item->key, "tiger:county") == 0) + else if (item->key == "tiger:county") { /* strip the state and replace it with a county suffix to ensure that the tag only matches against counties and not against some town with the same name. */ - subval = strcspn(item->value, ","); + subval = strcspn(item->value.c_str(), ","); *isin = (char *)realloc(*isin, isinsize + 9 + subval); *(*isin+isinsize) = ','; - strncpy(*isin+1+isinsize, item->value, subval); + strncpy(*isin+1+isinsize, item->value.c_str(), subval); strcpy(*isin+1+isinsize+subval, " county"); isinsize += 8 + subval; - keyval::freeItem(item); + delete(item); } - else if (strcmp(item->key, "is_in") == 0 || - (strncmp(item->key, "is_in:", 5) == 0) || - strcmp(item->key, "addr:suburb")== 0 || - strcmp(item->key, "addr:county")== 0 || - strcmp(item->key, "addr:city") == 0 || - strcmp(item->key, "addr:state_code") == 0 || - strcmp(item->key, "addr:state") == 0) + else if (item->key == "is_in" || + (strncmp(item->key.c_str(), "is_in:", 5) == 0) || + item->key == "addr:suburb" || + item->key == "addr:county" || + item->key == "addr:city" || + item->key == "addr:state_code" || + item->key == "addr:state") { - *isin = (char *)realloc(*isin, isinsize + 2 + strlen(item->value)); + *isin = (char *)realloc(*isin, isinsize + 2 + item->value.length()); *(*isin+isinsize) = ','; - strcpy(*isin+1+isinsize, item->value); - isinsize += 1 + strlen(item->value); - keyval::freeItem(item); + strcpy(*isin+1+isinsize, item->value.c_str()); + isinsize += 1 + item->value.length(); + delete(item); } - else if (strcmp(item->key, "admin_level") == 0) + else if (item->key == "admin_level") { - *admin_level = atoi(item->value); - keyval::freeItem(item); + *admin_level = atoi(item->value.c_str()); + delete(item); } - else if (strcmp(item->key, "tracktype") == 0 || - strcmp(item->key, "traffic_calming") == 0 || - strcmp(item->key, "service") == 0 || - strcmp(item->key, "cuisine") == 0 || - strcmp(item->key, "capital") == 0 || - strcmp(item->key, "dispensing") == 0 || - strcmp(item->key, "religion") == 0 || - strcmp(item->key, "denomination") == 0 || - strcmp(item->key, "sport") == 0 || - strcmp(item->key, "internet_access") == 0 || - strcmp(item->key, "lanes") == 0 || - strcmp(item->key, "surface") == 0 || - strcmp(item->key, "smoothness") == 0 || - strcmp(item->key, "width") == 0 || - strcmp(item->key, "est_width") == 0 || - strcmp(item->key, "incline") == 0 || - strcmp(item->key, "opening_hours") == 0 || - strcmp(item->key, "food_hours") == 0 || - strcmp(item->key, "collection_times") == 0 || - strcmp(item->key, "service_times") == 0 || - strcmp(item->key, "smoking_hours") == 0 || - strcmp(item->key, "disused") == 0 || - strcmp(item->key, "wheelchair") == 0 || - strcmp(item->key, "sac_scale") == 0 || - strcmp(item->key, "trail_visibility") == 0 || - strcmp(item->key, "mtb:scale") == 0 || - strcmp(item->key, "mtb:description") == 0 || - strcmp(item->key, "wood") == 0 || - strcmp(item->key, "drive_thru") == 0 || - strcmp(item->key, "drive_in") == 0 || - strcmp(item->key, "access") == 0 || - strcmp(item->key, "vehicle") == 0 || - strcmp(item->key, "bicyle") == 0 || - strcmp(item->key, "foot") == 0 || - strcmp(item->key, "goods") == 0 || - strcmp(item->key, "hgv") == 0 || - strcmp(item->key, "motor_vehicle") == 0 || - strcmp(item->key, "motor_car") == 0 || - (strncmp(item->key, "access:", 7) == 0) || - (strncmp(item->key, "contact:", 8) == 0) || - (strncmp(item->key, "drink:", 6) == 0) || - strcmp(item->key, "oneway") == 0 || - strcmp(item->key, "date_on") == 0 || - strcmp(item->key, "date_off") == 0 || - strcmp(item->key, "day_on") == 0 || - strcmp(item->key, "day_off") == 0 || - strcmp(item->key, "hour_on") == 0 || - strcmp(item->key, "hour_off") == 0 || - strcmp(item->key, "maxweight") == 0 || - strcmp(item->key, "maxheight") == 0 || - strcmp(item->key, "maxspeed") == 0 || - strcmp(item->key, "disused") == 0 || - strcmp(item->key, "toll") == 0 || - strcmp(item->key, "charge") == 0 || - strcmp(item->key, "population") == 0 || - strcmp(item->key, "description") == 0 || - strcmp(item->key, "image") == 0 || - strcmp(item->key, "attribution") == 0 || - strcmp(item->key, "fax") == 0 || - strcmp(item->key, "email") == 0 || - strcmp(item->key, "url") == 0 || - strcmp(item->key, "website") == 0 || - strcmp(item->key, "phone") == 0 || - strcmp(item->key, "tel") == 0 || - strcmp(item->key, "real_ale") == 0 || - strcmp(item->key, "smoking") == 0 || - strcmp(item->key, "food") == 0 || - strcmp(item->key, "camera") == 0 || - strcmp(item->key, "brewery") == 0 || - strcmp(item->key, "locality") == 0 || - strcmp(item->key, "wikipedia") == 0 || - (strncmp(item->key, "wikipedia:", 10) == 0) + else if (item->key == "tracktype" || + item->key == "traffic_calming" || + item->key == "service" || + item->key == "cuisine" || + item->key == "capital" || + item->key == "dispensing" || + item->key == "religion" || + item->key == "denomination" || + item->key == "sport" || + item->key == "internet_access" || + item->key == "lanes" || + item->key == "surface" || + item->key == "smoothness" || + item->key == "width" || + item->key == "est_width" || + item->key == "incline" || + item->key == "opening_hours" || + item->key == "food_hours" || + item->key == "collection_times" || + item->key == "service_times" || + item->key == "smoking_hours" || + item->key == "disused" || + item->key == "wheelchair" || + item->key == "sac_scale" || + item->key == "trail_visibility" || + item->key == "mtb:scale" || + item->key == "mtb:description" || + item->key == "wood" || + item->key == "drive_thru" || + item->key == "drive_in" || + item->key == "access" || + item->key == "vehicle" || + item->key == "bicyle" || + item->key == "foot" || + item->key == "goods" || + item->key == "hgv" || + item->key == "motor_vehicle" || + item->key == "motor_car" || + (strncmp(item->key.c_str(), "access:", 7) == 0) || + (strncmp(item->key.c_str(), "contact:", 8) == 0) || + (strncmp(item->key.c_str(), "drink:", 6) == 0) || + item->key == "oneway" || + item->key == "date_on" || + item->key == "date_off" || + item->key == "day_on" || + item->key == "day_off" || + item->key == "hour_on" || + item->key == "hour_off" || + item->key == "maxweight" || + item->key == "maxheight" || + item->key == "maxspeed" || + item->key == "disused" || + item->key == "toll" || + item->key == "charge" || + item->key == "population" || + item->key == "description" || + item->key == "image" || + item->key == "attribution" || + item->key == "fax" || + item->key == "email" || + item->key == "url" || + item->key == "website" || + item->key == "phone" || + item->key == "tel" || + item->key == "real_ale" || + item->key == "smoking" || + item->key == "food" || + item->key == "camera" || + item->key == "brewery" || + item->key == "locality" || + item->key == "wikipedia" || + (strncmp(item->key.c_str(), "wikipedia:", 10) == 0) ) { - keyval::pushItem(extratags, item); + extratags->pushItem(item); } - else if (strcmp(item->key, "building") == 0) + else if (item->key == "building") { placebuilding = 1; - keyval::freeItem(item); + delete(item); } - else if (strcmp(item->key, "mountain_pass") == 0) + else if (item->key == "mountain_pass") { - keyval::pushItem(places, item); + places->pushItem(item); } else { - keyval::freeItem(item); + delete(item); } } @@ -596,32 +590,27 @@ static int split_tags(struct keyval *tags, unsigned int flags, { if (*housenumber) { - keyval::freeItem(*housenumber); + delete(*housenumber); } if (!conscriptionnumber) { - keyval::addItem(tags, "addr:housenumber", streetnumber->value, 0); - keyval::freeItem(streetnumber); - *housenumber = keyval::popItem(tags); + streetnumber->key.assign("addr:housenumber"); + *housenumber = streetnumber; } if (!streetnumber) { - keyval::addItem(tags, "addr:housenumber", conscriptionnumber->value, 10); - keyval::freeItem(conscriptionnumber); - *housenumber = keyval::popItem(tags); + conscriptionnumber->key.assign("addr:housenumber"); + *housenumber = conscriptionnumber; } if (conscriptionnumber && streetnumber) { - char * completenumber = strdup(conscriptionnumber->value); - size_t completenumberlength = strlen(completenumber); - completenumber = (char *)realloc(completenumber, completenumberlength + 2 + strlen(streetnumber->value)); - *(completenumber + completenumberlength) = '/'; - strcpy(completenumber + completenumberlength + 1, streetnumber->value); - keyval::freeItem(conscriptionnumber); - keyval::freeItem(streetnumber); - keyval::addItem(tags, "addr:housenumber", completenumber, 0); - *housenumber = keyval::popItem(tags); - free(completenumber); + conscriptionnumber->key.assign("addr:housenumber"); + conscriptionnumber->value.reserve(conscriptionnumber->value.size() + 1 + + streetnumber->value.size()); + conscriptionnumber->value += '/'; + conscriptionnumber->value += streetnumber->value; + delete(streetnumber); + *housenumber = conscriptionnumber; } } @@ -629,40 +618,40 @@ static int split_tags(struct keyval *tags, unsigned int flags, { if (placeadmin) { - keyval::pushItem(extratags, place); + extratags->pushItem(place); } else { - keyval::pushItem(places, place); + places->pushItem(place); } } - if (placehouse && !keyval::listHasData(places)) + if (placehouse && !places->listHasData()) { - keyval::addItem(places, "place", "house", 1); + places->addItem("place", "house", false); } /* Fallback place types - only used if we didn't create something more specific already */ - if (placebuilding && !keyval::listHasData(places) && (keyval::listHasData(names) || *housenumber || *postcode)) + if (placebuilding && !places->listHasData() && (names->listHasData() || *housenumber || *postcode)) { - keyval::addItem(places, "building", "yes", 1); + places->addItem("building", "yes", false); } if (landuse) { - if (!keyval::listHasData(places) && keyval::listHasData(names)) + if (!places->listHasData() && names->listHasData()) { - keyval::pushItem(places, landuse); + places->pushItem(landuse); } else { - keyval::freeItem(landuse); + delete(landuse); } } - if (*postcode && !keyval::listHasData(places)) + if (*postcode && !places->listHasData()) { - keyval::addItem(places, "place", "postcode", 1); + places->addItem("place", "postcode", false); } /* Try to convert everything to an area */ @@ -719,7 +708,7 @@ void output_gazetteer_t::delete_unused_classes(char osm_type, osmid_t osm_id, st } else { for (i = 0; i < sz; i++) { cls = PQgetvalue(res, i, 0); - if (!keyval::getItem(places, cls)) { + if (!places->getItem(cls)) { if (!clslist) { clslist = (char *)malloc(strlen(cls)+3); sprintf(clslist, "'%s'", cls); @@ -745,7 +734,7 @@ void output_gazetteer_t::delete_unused_classes(char osm_type, osmid_t osm_id, st } } -void output_gazetteer_t::add_place(char osm_type, osmid_t osm_id, const char *key_class, const char *type, struct keyval *names, struct keyval *extratags, +void output_gazetteer_t::add_place(char osm_type, osmid_t osm_id, const std::string &key_class, const std::string &type, struct keyval *names, struct keyval *extratags, int adminlevel, struct keyval *housenumber, struct keyval *street, struct keyval *addr_place, const char *isin, struct keyval *postcode, struct keyval *countrycode, const char *wkt) { int first; @@ -756,31 +745,31 @@ void output_gazetteer_t::add_place(char osm_type, osmid_t osm_id, const char *ke sprintf(sql, "%c\t%" PRIdOSMID "\t", osm_type, osm_id); copy_data(sql); - escape(sql, sizeof(sql), key_class); + escape(sql, sizeof(sql), key_class.c_str()); copy_data(sql); copy_data("\t"); - escape(sql, sizeof(sql), type); + escape(sql, sizeof(sql), type.c_str()); copy_data(sql); copy_data("\t"); /* start name array */ - if (keyval::listHasData(names)) + if (names->listHasData()) { first = 1; - for (name = keyval::firstItem(names); name; name = keyval::nextItem(names, name)) + for (name = names->firstItem(); name; name = names->nextItem(name)) { if (first) first = 0; else copy_data(", "); copy_data("\""); - escape_array_record(sql, sizeof(sql), name->key); + escape_array_record(sql, sizeof(sql), name->key.c_str()); copy_data(sql); copy_data("\"=>\""); - escape_array_record(sql, sizeof(sql), name->value); + escape_array_record(sql, sizeof(sql), name->value.c_str()); copy_data(sql); copy_data("\""); @@ -797,7 +786,7 @@ void output_gazetteer_t::add_place(char osm_type, osmid_t osm_id, const char *ke if (housenumber) { - escape(sql, sizeof(sql), housenumber->value); + escape(sql, sizeof(sql), housenumber->value.c_str()); copy_data(sql); copy_data("\t"); } @@ -808,7 +797,7 @@ void output_gazetteer_t::add_place(char osm_type, osmid_t osm_id, const char *ke if (street) { - escape(sql, sizeof(sql), street->value); + escape(sql, sizeof(sql), street->value.c_str()); copy_data(sql); copy_data("\t"); } @@ -819,7 +808,7 @@ void output_gazetteer_t::add_place(char osm_type, osmid_t osm_id, const char *ke if (addr_place) { - escape(sql, sizeof(sql), addr_place->value); + escape(sql, sizeof(sql), addr_place->value.c_str()); copy_data(sql); copy_data("\t"); } @@ -842,7 +831,7 @@ void output_gazetteer_t::add_place(char osm_type, osmid_t osm_id, const char *ke if (postcode) { - escape(sql, sizeof(sql), postcode->value); + escape(sql, sizeof(sql), postcode->value.c_str()); copy_data(sql); copy_data("\t"); } @@ -853,7 +842,7 @@ void output_gazetteer_t::add_place(char osm_type, osmid_t osm_id, const char *ke if (countrycode) { - escape(sql, sizeof(sql), countrycode->value); + escape(sql, sizeof(sql), countrycode->value.c_str()); copy_data(sql); copy_data("\t"); } @@ -863,22 +852,22 @@ void output_gazetteer_t::add_place(char osm_type, osmid_t osm_id, const char *ke } /* extra tags array */ - if (keyval::listHasData(extratags)) + if (extratags->listHasData()) { first = 1; - for (name = keyval::firstItem(extratags); name; name = keyval::nextItem(extratags, name)) + for (name = extratags->firstItem(); name; name = extratags->nextItem(name)) { if (first) first = 0; else copy_data(", "); copy_data("\""); - escape_array_record(sql, sizeof(sql), name->key); + escape_array_record(sql, sizeof(sql), name->key.c_str()); copy_data(sql); copy_data("\"=>\""); - escape_array_record(sql, sizeof(sql), name->value); + escape_array_record(sql, sizeof(sql), name->value.c_str()); copy_data(sql); copy_data("\""); @@ -1122,26 +1111,26 @@ int output_gazetteer_t::gazetteer_process_node(osmid_t id, double lat, double lo delete_unused_classes('N', id, &places); /* Are we interested in this item? */ - if (keyval::listHasData(&places)) + if (places.listHasData()) { sprintf(wkt, "POINT(%.15g %.15g)", lon, lat); - for (place = keyval::firstItem(&places); place; place = keyval::nextItem(&places, place)) + for (place = places.firstItem(); place; place = places.nextItem(place)) { add_place('N', id, place->key, place->value, &names, &extratags, adminlevel, housenumber, street, addr_place, isin, postcode, countrycode, wkt); } } - if (housenumber) keyval::freeItem(housenumber); - if (street) keyval::freeItem(street); - if (addr_place) keyval::freeItem(addr_place); + if (housenumber) delete(housenumber); + if (street) delete(street); + if (addr_place) delete(addr_place); if (isin) free(isin); - if (postcode) keyval::freeItem(postcode); - if (countrycode) keyval::freeItem(countrycode); + if (postcode) delete(postcode); + if (countrycode) delete(countrycode); /* Free tag lists */ - keyval::resetList(&names); - keyval::resetList(&places); - keyval::resetList(&extratags); + names.resetList(); + places.resetList(); + extratags.resetList(); return 0; } @@ -1174,7 +1163,7 @@ int output_gazetteer_t::gazetteer_process_way(osmid_t id, osmid_t *ndv, int ndc, delete_unused_classes('W', id, &places); /* Are we interested in this item? */ - if (keyval::listHasData(&places)) + if (places.listHasData()) { struct osmNode *nodev; int nodec; @@ -1187,7 +1176,7 @@ int output_gazetteer_t::gazetteer_process_way(osmid_t id, osmid_t *ndv, int ndc, geometry_builder::maybe_wkt_t wkt = builder.get_wkt_simple(nodev, nodec, area); if (wkt) { - for (place = keyval::firstItem(&places); place; place = keyval::nextItem(&places, place)) + for (place = places.firstItem(); place; place = places.nextItem(place)) { add_place('W', id, place->key, place->value, &names, &extratags, adminlevel, housenumber, street, addr_place, isin, postcode, countrycode, wkt->geom.c_str()); @@ -1198,17 +1187,17 @@ int output_gazetteer_t::gazetteer_process_way(osmid_t id, osmid_t *ndv, int ndc, free(nodev); } - if (housenumber) keyval::freeItem(housenumber); - if (street) keyval::freeItem(street); - if (addr_place) keyval::freeItem(addr_place); + if (housenumber) delete(housenumber); + if (street) delete(street); + if (addr_place) delete(addr_place); if (isin) free(isin); - if (postcode) keyval::freeItem(postcode); - if (countrycode) keyval::freeItem(countrycode); + if (postcode) delete(postcode); + if (countrycode) delete(countrycode); /* Free tag lists */ - keyval::resetList(&names); - keyval::resetList(&places); - keyval::resetList(&extratags); + names.resetList(); + places.resetList(); + extratags.resetList(); return 0; } @@ -1231,24 +1220,23 @@ int output_gazetteer_t::gazetteer_process_relation(osmid_t id, struct member *me char * isin; struct keyval * postcode; struct keyval * countrycode; - const char *type; int cmp_waterway; - type = keyval::getItem(tags, "type"); + const std::string *type = tags->getItem("type"); if (!type) { if (delete_old) delete_unused_classes('R', id, 0); return 0; } - cmp_waterway = strcmp(type, "waterway"); + cmp_waterway = type->compare("waterway"); - if (!strcmp(type, "associatedStreet")) + if (!type->compare("associatedStreet")) { if (delete_old) delete_unused_classes('R', id, 0); return 0; } - if (strcmp(type, "boundary") && strcmp(type, "multipolygon") && cmp_waterway) { + if (type->compare("boundary") && type->compare("multipolygon") && cmp_waterway) { if (delete_old) delete_unused_classes('R', id, 0); return 0; } @@ -1264,7 +1252,7 @@ int output_gazetteer_t::gazetteer_process_relation(osmid_t id, struct member *me if (delete_old) delete_unused_classes('R', id, &places); - if (keyval::listHasData(&places)) + if (places.listHasData()) { /* get the boundary path (ways) */ int i, count; @@ -1306,7 +1294,7 @@ int output_gazetteer_t::gazetteer_process_relation(osmid_t id, struct member *me { if ((boost::starts_with(wkt->geom, "POLYGON") || boost::starts_with(wkt->geom, "MULTIPOLYGON"))) { - for (place = keyval::firstItem(&places); place; place = keyval::nextItem(&places, place)) + for (place = places.firstItem(); place; place = places.nextItem(place)) { add_place('R', id, place->key, place->value, &names, &extratags, adminlevel, housenumber, street, addr_place, isin, postcode, countrycode, wkt->geom.c_str()); @@ -1323,7 +1311,7 @@ int output_gazetteer_t::gazetteer_process_relation(osmid_t id, struct member *me geometry_builder::maybe_wkt_t wkt = builder.build_multilines(xnodes, xcount, id); if ((wkt->geom).length() > 0) { - for (place = keyval::firstItem(&places); place; place = keyval::nextItem(&places, place)) + for (place = places.firstItem(); place; place = places.nextItem(place)) { add_place('R', id, place->key, place->value, &names, &extratags, adminlevel, housenumber, street, addr_place, isin, postcode, countrycode, wkt->geom.c_str()); @@ -1332,7 +1320,7 @@ int output_gazetteer_t::gazetteer_process_relation(osmid_t id, struct member *me } for( i=0; iways_get(id, &tags_int, &nodes_int, &count_int)) { // Output the way ret = reprocess_way(id, nodes_int, count_int, &tags_int, exists); free(nodes_int); } - keyval::resetList(&tags_int); + tags_int.resetList(); return ret; } @@ -140,13 +139,12 @@ int output_multi_t::pending_relation(osmid_t id, int exists) { int count_int; int ret = 0; - keyval::initList(&tags_int); // Try to fetch the relation from the DB if (!m_mid->relations_get(id, &members_int, &count_int, &tags_int)) { ret = process_relation(id, members_int, count_int, &tags_int, exists); free(members_int); } - keyval::resetList(&tags_int); + tags_int.resetList(); return ret; } diff --git a/output-pgsql.cpp b/output-pgsql.cpp index f72d739a8..8add8a0ff 100644 --- a/output-pgsql.cpp +++ b/output-pgsql.cpp @@ -136,7 +136,7 @@ int output_pgsql_t::pgsql_out_way(osmid_t id, struct keyval *tags, const struct if ((wkt->area > 0.0) && m_enable_way_area) { char tmp[32]; snprintf(tmp, sizeof(tmp), "%g", wkt->area); - keyval::addItem(tags, "way_area", tmp, 0); + tags->addItem("way_area", tmp, false); } m_tables[t_poly]->write_wkt(id, tags, wkt->geom.c_str()); } else { @@ -192,7 +192,7 @@ int output_pgsql_t::pgsql_out_relation(osmid_t id, struct keyval *rel_tags, int if ((wkt->area > 0.0) && m_enable_way_area) { char tmp[32]; snprintf(tmp, sizeof(tmp), "%g", wkt->area); - keyval::addItem(rel_tags, "way_area", tmp, 0); + rel_tags->addItem("way_area", tmp, false); } m_tables[t_poly]->write_wkt(-id, rel_tags, wkt->geom.c_str()); } else { @@ -230,7 +230,7 @@ int output_pgsql_t::pgsql_out_relation(osmid_t id, struct keyval *rel_tags, int if ((wkt->area > 0.0) && m_enable_way_area) { char tmp[32]; snprintf(tmp, sizeof(tmp), "%g", wkt->area); - keyval::addItem(rel_tags, "way_area", tmp, 0); + rel_tags->addItem("way_area", tmp, false); } m_tables[t_poly]->write_wkt(-id, rel_tags, wkt->geom.c_str()); } @@ -292,7 +292,6 @@ int output_pgsql_t::pending_way(osmid_t id, int exists) { int count_int; int ret = 0; - keyval::initList(&tags_int); // Try to fetch the way from the DB if (!m_mid->ways_get(id, &tags_int, &nodes_int, &count_int)) { // Output the way @@ -300,7 +299,7 @@ int output_pgsql_t::pending_way(osmid_t id, int exists) { ret = pgsql_out_way(id, &tags_int, nodes_int, count_int, exists); free(nodes_int); } - keyval::resetList(&tags_int); + tags_int.resetList(); return ret; } @@ -340,13 +339,12 @@ int output_pgsql_t::pending_relation(osmid_t id, int exists) { int count_int; int ret = 0; - keyval::initList(&tags_int); // Try to fetch the relation from the DB if (!m_mid->relations_get(id, &members_int, &count_int, &tags_int)) { ret = pgsql_process_relation(id, members_int, count_int, &tags_int, exists, true); free(members_int); } - keyval::resetList(&tags_int); + tags_int.resetList(); return ret; } @@ -495,7 +493,7 @@ int output_pgsql_t::pgsql_process_relation(osmid_t id, const struct member *memb for( i=0; igetItem("type"); /* Must have a type field or we ignore it */ if (!type) return 0; /* Only a limited subset of type= is supported, ignore other */ - if ( (strcmp(type, "route") != 0) && (strcmp(type, "multipolygon") != 0) && (strcmp(type, "boundary") != 0)) + if ( (*type != "route") && (*type != "multipolygon") && (*type != "boundary")) return 0; diff --git a/parse-o5m.cpp b/parse-o5m.cpp index 17eb3783f..b6fc9de96 100644 --- a/parse-o5m.cpp +++ b/parse-o5m.cpp @@ -809,18 +809,18 @@ return 1; hisver= pbf_uint32(&bufp); uint32toa(hisver,tmpstr); - keyval::addItem(&(tags),"osm_version",tmpstr,0); + tags.addItem("osm_version",tmpstr,false); if(hisver!=0) { /* history information available */ histime= o5histime+= pbf_sint64(&bufp); createtimestamp(histime,tmpstr); - keyval::addItem(&(tags),"osm_timestamp",tmpstr, 0); + tags.addItem("osm_timestamp",tmpstr, false); if(histime!=0) { hiscset= o5hiscset+= pbf_sint32(&bufp); /* (not used) */ str_read(&bufp,&sp,&hisuser); hisuid= pbf_uint64((byte**)&sp); uint32toa(hisuid,tmpstr); - keyval::addItem(&(tags),"osm_uid",tmpstr,0); - keyval::addItem(&(tags),"osm_user",hisuser,0); + tags.addItem("osm_uid",tmpstr,false); + tags.addItem("osm_user",hisuser,false); } } /* end history information available */ } /* end read history */ @@ -841,7 +841,7 @@ return 1; break; default: ; } - keyval::resetList(&(tags)); + tags.resetList(); continue; /* end processing for this object */ } /* end delete request */ else { /* not a delete request */ @@ -858,7 +858,7 @@ return 1; node_lon= (double)(o5lon+= pbf_sint32(&bufp))/10000000; node_lat= (double)(o5lat+= pbf_sint32(&bufp))/10000000; if(!node_wanted(node_lat,node_lon)) { - keyval::resetList(&(tags)); + tags.resetList(); continue; } proj->reproject(&(node_lat),&(node_lon)); @@ -920,7 +920,7 @@ return 1; /* replace all blanks in key by underlines */ p++; } - keyval::addItem(&(tags),k,v,0); + tags.addItem(k,v,false); } } /* end for all tags of this object */ @@ -954,7 +954,7 @@ return 1; } /* reset temporary storage lists */ - keyval::resetList(&(tags)); + tags.resetList(); } /* end not a delete request */ diff --git a/parse-pbf.cpp b/parse-pbf.cpp index 348236a06..051894de6 100644 --- a/parse-pbf.cpp +++ b/parse-pbf.cpp @@ -172,27 +172,19 @@ static size_t uncompress_blob(Blob *bmsg, void *buf, int32_t max_size) int addProtobufItem(struct keyval *head, ProtobufCBinaryData key, ProtobufCBinaryData val, int noDupe) { - char *keystr, *valstr; - int retval; + std::string keystr((const char *) key.data, key.len); - keystr = (char *)calloc(key.len + 1, 1); - memcpy(keystr, key.data, key.len); + assert(keystr.find('\0') == std::string::npos); /* drop certain keys (matching parse-xml2) */ - if ((strcmp(keystr, "created_by") == 0) || (strcmp(keystr, "source") == 0)) { - free(keystr); + if ((keystr == "created_by") || (keystr == "source")) return 0; - } - - valstr = (char *)calloc(val.len + 1, 1); - memcpy(valstr, val.data, val.len); - retval = keyval::addItem(head, keystr, valstr, noDupe); + std::string valstr((const char *) val.data, val.len); - free(keystr); - free(valstr); + assert(valstr.find('\0') == std::string::npos); - return retval; + return head->addItem(keystr, valstr, noDupe); } int addIntItem(struct keyval *head, const char *key, int val, int noDupe) @@ -200,7 +192,7 @@ int addIntItem(struct keyval *head, const char *key, int val, int noDupe) char buf[100]; sprintf(buf, "%d", val); - return keyval::addItem(head, key, buf, noDupe); + return head->addItem(key, buf, noDupe); } int addInfoItems(struct keyval *head, Info *info, StringTable *string_table) @@ -221,7 +213,7 @@ int addInfoItems(struct keyval *head, Info *info, StringTable *string_table) username = (char *)calloc(user.len + 1, 1); memcpy(username, user.data, user.len); - keyval::addItem(head, "osm_user", username, 0); + head->addItem("osm_user", username, false); free(username); } @@ -250,7 +242,7 @@ int parse_pbf_t::processOsmDataNodes(struct osmdata_t *osmdata, PrimitiveGroup * Node *node = group->nodes[node_id]; double lat, lon; - keyval::resetList(&(tags)); + tags.resetList(); if (node->info && extra_attributes) { addInfoItems(&(tags), node->info, string_table); @@ -303,7 +295,7 @@ int parse_pbf_t::processOsmDataDenseNodes(struct osmdata_t *osmdata, PrimitiveGr DenseNodes *dense = group->dense; for (node_id = 0; node_id < dense->n_id; node_id++) { - keyval::resetList(&(tags)); + tags.resetList(); deltaid += dense->id[node_id]; deltalat += dense->lat[node_id]; @@ -325,7 +317,7 @@ int parse_pbf_t::processOsmDataDenseNodes(struct osmdata_t *osmdata, PrimitiveGr addIntItem(&(tags), "osm_uid", deltauid, 0); valstr = (char *)calloc(string_table->s[deltauser_sid].len + 1, 1); memcpy(valstr, string_table->s[deltauser_sid].data, string_table->s[deltauser_sid].len); - keyval::addItem(&(tags), "osm_user", valstr, 0); + tags.addItem("osm_user", valstr, false); free(valstr); } } @@ -373,7 +365,7 @@ int parse_pbf_t::processOsmDataWays(struct osmdata_t *osmdata, PrimitiveGroup *g Way *way = group->ways[way_id]; osmid_t deltaref = 0; - keyval::resetList(&(tags)); + tags.resetList(); if (way->info && extra_attributes) { addInfoItems(&(tags), way->info, string_table); @@ -424,7 +416,7 @@ int parse_pbf_t::processOsmDataRelations(struct osmdata_t *osmdata, PrimitiveGro Relation *relation = group->relations[rel_id]; osmid_t deltamemids = 0; - keyval::resetList(&(tags)); + tags.resetList(); member_count = 0; diff --git a/parse-xml2.cpp b/parse-xml2.cpp index fc118ae7e..2c4f58ddf 100644 --- a/parse-xml2.cpp +++ b/parse-xml2.cpp @@ -181,7 +181,7 @@ void parse_xml2_t::StartElement(xmlTextReaderPtr reader, const xmlChar *name, st while ((p = strchr(k, ' '))) *p = '_'; - keyval::addItem(&(tags), k, (char *)xv, 0); + tags.addItem(k, (char *)xv, 0); xmlFree(k); xmlFree(xv); } @@ -246,31 +246,31 @@ void parse_xml2_t::StartElement(xmlTextReaderPtr reader, const xmlChar *name, st xtmp = xmlTextReaderGetAttribute(reader, BAD_CAST "user"); if (xtmp) { - keyval::addItem(&(tags), "osm_user", (char *)xtmp, 0); + tags.addItem("osm_user", (char *)xtmp, false); xmlFree(xtmp); } xtmp = xmlTextReaderGetAttribute(reader, BAD_CAST "uid"); if (xtmp) { - keyval::addItem(&(tags), "osm_uid", (char *)xtmp, 0); + tags.addItem("osm_uid", (char *)xtmp, false); xmlFree(xtmp); } xtmp = xmlTextReaderGetAttribute(reader, BAD_CAST "version"); if (xtmp) { - keyval::addItem(&(tags), "osm_version", (char *)xtmp, 0); + tags.addItem("osm_version", (char *)xtmp, false); xmlFree(xtmp); } xtmp = xmlTextReaderGetAttribute(reader, BAD_CAST "timestamp"); if (xtmp) { - keyval::addItem(&(tags), "osm_timestamp", (char *)xtmp, 0); + tags.addItem("osm_timestamp", (char *)xtmp, false); xmlFree(xtmp); } xtmp = xmlTextReaderGetAttribute(reader, BAD_CAST "changeset"); if (xtmp) { - keyval::addItem(&(tags), "osm_changeset", (char *)xtmp, 0); + tags.addItem("osm_changeset", (char *)xtmp, false); xmlFree(xtmp); } } @@ -294,7 +294,7 @@ void parse_xml2_t::EndElement(const xmlChar *name, struct osmdata_t *osmdata) util::exit_nicely(); } } - keyval::resetList(&(tags)); + tags.resetList(); } else if (xmlStrEqual(name, BAD_CAST "way")) { if( action == ACTION_CREATE ) osmdata->way_add(osm_id, nds, nd_count, &(tags) ); @@ -307,7 +307,7 @@ void parse_xml2_t::EndElement(const xmlChar *name, struct osmdata_t *osmdata) fprintf( stderr, "Don't know action for way %" PRIdOSMID "\n", osm_id ); util::exit_nicely(); } - keyval::resetList(&(tags)); + tags.resetList(); } else if (xmlStrEqual(name, BAD_CAST "relation")) { if( action == ACTION_CREATE ) osmdata->relation_add(osm_id, members, member_count, &(tags)); @@ -320,7 +320,7 @@ void parse_xml2_t::EndElement(const xmlChar *name, struct osmdata_t *osmdata) fprintf( stderr, "Don't know action for relation %" PRIdOSMID "\n", osm_id ); util::exit_nicely(); } - keyval::resetList(&(tags)); + tags.resetList(); resetMembers(); } else if (xmlStrEqual(name, BAD_CAST "tag")) { /* ignore */ @@ -343,7 +343,7 @@ void parse_xml2_t::EndElement(const xmlChar *name, struct osmdata_t *osmdata) /* ignore */ } else if (xmlStrEqual(name, BAD_CAST "changeset")) { /* ignore */ - keyval::resetList(&(tags)); /* We may have accumulated some tags even if we ignored the changeset */ + tags.resetList(); /* We may have accumulated some tags even if we ignored the changeset */ } else if (xmlStrEqual(name, BAD_CAST "add")) { action = ACTION_NONE; } else if (xmlStrEqual(name, BAD_CAST "create")) { diff --git a/table.cpp b/table.cpp index 515dce2b3..7e40f7d7f 100644 --- a/table.cpp +++ b/table.cpp @@ -356,9 +356,9 @@ void table_t::write_columns(keyval *tags, string& values) for(columns_t::const_iterator column = columns.begin(); column != columns.end(); ++column) { keyval *tag = NULL; - if ((tag = keyval::getTag(tags, column->first.c_str()))) + if ((tag = tags->getTag(column->first))) { - escape_type(tag->value, column->second.c_str(), values); + escape_type(tag->value.c_str(), column->second.c_str(), values); //remember we already used this one so we cant use again later in the hstore column if (hstore_mode == HSTORE_NORM) tag->has_column = 1; @@ -373,18 +373,18 @@ void table_t::write_tags_column(keyval *tags, std::string& values) { //iterate through the list of tags, first one is always null bool added = false; - for (keyval* xtags = tags->next; xtags->key != NULL; xtags = xtags->next) + for (keyval* xtags = tags->firstItem(); xtags; xtags = tags->nextItem(xtags)) { //skip z_order tag and keys which have their own column - if ((xtags->has_column) || (strcmp("z_order", xtags->key) == 0)) + if (xtags->has_column || ("z_order" == xtags->key)) continue; //hstore ASCII representation looks like "key"=>"value" if(added) values.push_back(','); - escape4hstore(xtags->key, values); + escape4hstore(xtags->key.c_str(), values); values.append("=>"); - escape4hstore(xtags->value, values); + escape4hstore(xtags->value.c_str(), values); //we did at least one so we need commas from here on out added = true; @@ -400,17 +400,16 @@ void table_t::write_hstore_columns(keyval *tags, std::string& values) //iterate over all configured hstore columns in the options for(hstores_t::const_iterator hstore_column = hstore_columns.begin(); hstore_column != hstore_columns.end(); ++hstore_column) { - //a clone of the tags pointer bool added = false; //iterate through the list of tags, first one is always null - for (keyval* xtags = tags->next; xtags->key != NULL; xtags = xtags->next) + for (keyval* xtags = tags->firstItem(); xtags; xtags = tags->nextItem(xtags)) { //check if the tag's key starts with the name of the hstore column - if(hstore_column->find(xtags->key) == 0) + if(xtags->key.compare(0, hstore_column->size(), *hstore_column) == 0) { //generate the short key name, somehow pointer arithmetic works against this member of the keyval data structure... - char* shortkey = xtags->key + hstore_column->size(); + const char* shortkey = xtags->key.c_str() + hstore_column->size(); //and pack the shortkey with its value into the hstore //hstore ASCII representation looks like "key"=>"value" @@ -418,7 +417,7 @@ void table_t::write_hstore_columns(keyval *tags, std::string& values) values.push_back(','); escape4hstore(shortkey, values); values.append("=>"); - escape4hstore(xtags->value, values); + escape4hstore(xtags->value.c_str(), values); //we did at least one so we need commas from here on out added = true; diff --git a/tagtransform.cpp b/tagtransform.cpp index 119f4f29a..581f604d3 100644 --- a/tagtransform.cpp +++ b/tagtransform.cpp @@ -38,25 +38,23 @@ static const unsigned int nLayers = (sizeof(layers)/sizeof(*layers)); namespace { int add_z_order(keyval *tags, int *roads) { - const char *layer = keyval::getItem(tags, "layer"); - const char *highway = keyval::getItem(tags, "highway"); - const char *bridge = keyval::getItem(tags, "bridge"); - const char *tunnel = keyval::getItem(tags, "tunnel"); - const char *railway = keyval::getItem(tags, "railway"); - const char *boundary = keyval::getItem(tags, "boundary"); + const std::string *layer = tags->getItem("layer"); + const std::string *highway = tags->getItem("highway"); + const std::string *bridge = tags->getItem("bridge"); + const std::string *tunnel = tags->getItem("tunnel"); + const std::string *railway = tags->getItem("railway"); + const std::string *boundary = tags->getItem("boundary"); int z_order = 0; - int l; - unsigned int i; char z[13]; - l = layer ? strtol(layer, NULL, 10) : 0; + int l = layer ? strtol(layer->c_str(), NULL, 10) : 0; z_order = 10 * l; *roads = 0; if (highway) { - for (i = 0; i < nLayers; i++) { - if (!strcmp(layers[i].highway, highway)) { + for (unsigned i = 0; i < nLayers; i++) { + if (!strcmp(layers[i].highway, highway->c_str())) { z_order += layers[i].offset; *roads = layers[i].roads; break; @@ -64,26 +62,22 @@ int add_z_order(keyval *tags, int *roads) { } } - if (railway && strlen(railway)) { + if (railway && !railway->empty()) { z_order += 5; *roads = 1; } /* Administrative boundaries are rendered at low zooms so we prefer to use the roads table */ - if (boundary && !strcmp(boundary, "administrative")) + if (boundary && *boundary == "administrative") *roads = 1; - if (bridge - && (!strcmp(bridge, "true") || !strcmp(bridge, "yes") - || !strcmp(bridge, "1"))) + if (bridge && (*bridge == "true" || *bridge == "yes" || *bridge == "1")) z_order += 10; - if (tunnel - && (!strcmp(tunnel, "true") || !strcmp(tunnel, "yes") - || !strcmp(tunnel, "1"))) + if (tunnel && (*tunnel == "true" || *tunnel == "yes" || *tunnel == "1")) z_order -= 10; snprintf(z, sizeof(z), "%d", z_order); - keyval::addItem(tags, "z_order", z, 0); + tags->addItem("z_order", z, 0); return 0; } @@ -94,134 +88,95 @@ unsigned int c_filter_rel_member_tags( int * member_superseeded, int * make_boundary, int * make_polygon, int * roads, const export_list *exlist, bool allow_typeless) { - char *type; - struct keyval tags, *p, *q, *qq, poly_tags; - int i, j; + struct keyval tags, *q, poly_tags; int first_outerway, contains_tag; //if it has a relation figure out what kind it is - type = keyval::getItem(rel_tags, "type"); + const std::string *type = rel_tags->getItem("type"); bool is_route = false, is_boundary = false, is_multipolygon = false; - if(type) + if (type) { //what kind of relation is it - is_route = strcmp(type, "route") == 0; - is_boundary = strcmp(type, "boundary") == 0; - is_multipolygon = strcmp(type, "multipolygon") == 0; + is_route = *type == "route"; + is_boundary = *type == "boundary"; + is_multipolygon = *type == "multipolygon"; }//you didnt have a type and it was required - else if(!allow_typeless) + else if (!allow_typeless) { return 1; } /* Clone tags from relation */ - keyval::initList(&tags); - keyval::initList(&poly_tags); - p = rel_tags->next; - while (p != rel_tags) { + for (keyval *p = rel_tags->firstItem(); p; p = rel_tags->nextItem(p)) { //copy the name tag as "route_name" - if (is_route && (strcmp(p->key, "name") == 0)) - keyval::addItem(&tags, "route_name", p->value, 1); + if (is_route && (p->key == "name")) + tags.addItem("route_name", p->value, true); //copy all other tags except for "type" - else if (strcmp(p->key, "type")) - keyval::addItem(&tags, p->key, p->value, 1); - p = p->next; + else if (p->key != "type") + tags.addItem(p->key, p->value, true); } if (is_route) { - const char *state = keyval::getItem(rel_tags, "state"); - const char *netw = keyval::getItem(rel_tags, "network"); + const std::string *netw = rel_tags->getItem("network"); int networknr = -1; - if (state == NULL ) { - state = ""; - } - - if (netw != NULL ) { - if (strcmp(netw, "lcn") == 0) { + if (netw != NULL) { + const std::string *state = rel_tags->getItem("state"); + std::string statetype("yes"); + if (state) { + if (*state == "alternate") + statetype = "alternate"; + else if (*state == "connection") + statetype = "connection"; + } + if (*netw == "lcn") { networknr = 10; - if (strcmp(state, "alternate") == 0) { - keyval::addItem(&tags, "lcn", "alternate", 1); - } else if (strcmp(state, "connection") == 0) { - keyval::addItem(&tags, "lcn", "connection", 1); - } else { - keyval::addItem(&tags, "lcn", "yes", 1); - } - } else if (strcmp(netw, "rcn") == 0) { + tags.addItem("lcn", statetype, true); + } else if (*netw == "rcn") { networknr = 11; - if (strcmp(state, "alternate") == 0) { - keyval::addItem(&tags, "rcn", "alternate", 1); - } else if (strcmp(state, "connection") == 0) { - keyval::addItem(&tags, "rcn", "connection", 1); - } else { - keyval::addItem(&tags, "rcn", "yes", 1); - } - } else if (strcmp(netw, "ncn") == 0) { + tags.addItem("rcn", statetype, true); + } else if (*netw == "ncn") { networknr = 12; - if (strcmp(state, "alternate") == 0) { - keyval::addItem(&tags, "ncn", "alternate", 1); - } else if (strcmp(state, "connection") == 0) { - keyval::addItem(&tags, "ncn", "connection", 1); - } else { - keyval::addItem(&tags, "ncn", "yes", 1); - } - - } else if (strcmp(netw, "lwn") == 0) { + tags.addItem("ncn", statetype, true); + } else if (*netw == "lwn") { networknr = 20; - if (strcmp(state, "alternate") == 0) { - keyval::addItem(&tags, "lwn", "alternate", 1); - } else if (strcmp(state, "connection") == 0) { - keyval::addItem(&tags, "lwn", "connection", 1); - } else { - keyval::addItem(&tags, "lwn", "yes", 1); - } - } else if (strcmp(netw, "rwn") == 0) { + tags.addItem("lwn", statetype, true); + } else if (*netw == "rwn") { networknr = 21; - if (strcmp(state, "alternate") == 0) { - keyval::addItem(&tags, "rwn", "alternate", 1); - } else if (strcmp(state, "connection") == 0) { - keyval::addItem(&tags, "rwn", "connection", 1); - } else { - keyval::addItem(&tags, "rwn", "yes", 1); - } - } else if (strcmp(netw, "nwn") == 0) { + tags.addItem("rwn", statetype, true); + } else if (*netw == "nwn") { networknr = 22; - if (strcmp(state, "alternate") == 0) { - keyval::addItem(&tags, "nwn", "alternate", 1); - } else if (strcmp(state, "connection") == 0) { - keyval::addItem(&tags, "nwn", "connection", 1); - } else { - keyval::addItem(&tags, "nwn", "yes", 1); - } + tags.addItem("nwn", statetype, true); } } - if (keyval::getItem(rel_tags, "preferred_color") != NULL ) { - const char *a = keyval::getItem(rel_tags, "preferred_color"); - if (strcmp(a, "0") == 0 || strcmp(a, "1") == 0 - || strcmp(a, "2") == 0 || strcmp(a, "3") == 0 - || strcmp(a, "4") == 0) { - keyval::addItem(&tags, "route_pref_color", a, 1); + const std::string *prefcol = rel_tags->getItem("preferred_color"); + if (prefcol != NULL && prefcol->size() == 1) { + if ((*prefcol)[0] == '0' || (*prefcol)[0] == '1' + || (*prefcol)[0] == '2' || (*prefcol)[0] == '3' + || (*prefcol)[0] == '4') { + tags.addItem("route_pref_color", *prefcol, true); } else { - keyval::addItem(&tags, "route_pref_color", "0", 1); + tags.addItem("route_pref_color", "0", true); } } else { - keyval::addItem(&tags, "route_pref_color", "0", 1); + tags.addItem("route_pref_color", "0", true); } - if (keyval::getItem(rel_tags, "ref") != NULL ) { + const std::string *relref = rel_tags->getItem("ref"); + if (relref != NULL ) { if (networknr == 10) { - keyval::addItem(&tags, "lcn_ref", keyval::getItem(rel_tags, "ref"), 1); + tags.addItem("lcn_ref", *relref, true); } else if (networknr == 11) { - keyval::addItem(&tags, "rcn_ref", keyval::getItem(rel_tags, "ref"), 1); + tags.addItem("rcn_ref", *relref, true); } else if (networknr == 12) { - keyval::addItem(&tags, "ncn_ref", keyval::getItem(rel_tags, "ref"), 1); + tags.addItem("ncn_ref", *relref, true); } else if (networknr == 20) { - keyval::addItem(&tags, "lwn_ref", keyval::getItem(rel_tags, "ref"), 1); + tags.addItem("lwn_ref", *relref, true); } else if (networknr == 21) { - keyval::addItem(&tags, "rwn_ref", keyval::getItem(rel_tags, "ref"), 1); + tags.addItem("rwn_ref", *relref, true); } else if (networknr == 22) { - keyval::addItem(&tags, "nwn_ref", keyval::getItem(rel_tags, "ref"), 1); + tags.addItem("nwn_ref", *relref, true); } } } else if (is_boundary) { @@ -230,7 +185,7 @@ unsigned int c_filter_rel_member_tags( - Polygon features also go into the polygon table (useful for national_forests) The edges of the polygon also get treated as linear fetaures allowing these to be rendered seperately. */ *make_boundary = 1; - } else if (is_multipolygon && keyval::getItem(&tags, "boundary")) { + } else if (is_multipolygon && tags.getItem("boundary")) { /* Treat type=multipolygon exactly like type=boundary if it has a boundary tag. */ *make_boundary = 1; } else if (is_multipolygon) { @@ -238,53 +193,48 @@ unsigned int c_filter_rel_member_tags( /* Collect a list of polygon-like tags, these are used later to identify if an inner rings looks like it should be rendered separately */ - p = tags.next; - while (p != &tags) { - if (!strcmp(p->key, "area")) { - keyval::addItem(&poly_tags, p->key, p->value, 1); + for (keyval *p = tags.firstItem(); p; p = tags.nextItem(p)) { + if (p->key == "area") { + poly_tags.addItem(p->key, p->value, true); } else { const std::vector &infos = exlist->get(OSMTYPE_WAY); - for (i = 0; i < infos.size(); i++) { + for (unsigned i = 0; i < infos.size(); i++) { const taginfo &info = infos[i]; - if (strcmp(info.name.c_str(), p->key) == 0) { + if (info.name == p->key) { if (info.flags & FLAG_POLYGON) { - keyval::addItem(&poly_tags, p->key, p->value, 1); + poly_tags.addItem(p->key, p->value, true); } break; } } } - p = p->next; } /* Copy the tags from the outer way(s) if the relation is untagged (with * respect to tags that influence its polygon nature. Tags like name or fixme should be fine*/ - if (!keyval::listHasData(&poly_tags)) { + if (!poly_tags.listHasData()) { first_outerway = 1; - for (i = 0; i < member_count; i++) { + for (int i = 0; i < member_count; i++) { if (member_roles[i] && !strcmp(member_roles[i], "inner")) continue; /* insert all tags of the first outerway to the potential list of copied tags. */ if (first_outerway) { - p = member_tags[i].next; - while (p != &(member_tags[i])) { - keyval::addItem(&poly_tags, p->key, p->value, 1); - p = p->next; - } + for (keyval *p = member_tags[i].firstItem(); p; p = member_tags[i].nextItem(p)) + poly_tags.addItem(p->key, p->value, true); } else { /* Check if all of the tags in the list of potential tags are present on this way, otherwise remove from the list of potential tags. Tags need to be present on all outer ways to be copied over to the relation */ - q = poly_tags.next; - while (q != &poly_tags) { - p = keyval::getTag(&(member_tags[i]), q->key); - if ((p != NULL) && (strcmp(q->value, p->value) == 0)) { - q = q->next; + q = poly_tags.firstItem(); + while (q) { + const keyval *p = member_tags[i].getTag(q->key); + if ((p != NULL) && (p->value == q->value)) { + q = poly_tags.nextItem(q); } else { /* This tag is not present on all member outer ways, so don't copy it over to relation */ - qq = q->next; - keyval::removeTag(q); + keyval *qq = poly_tags.nextItem(q); + q->removeTag(); q = qq; } } @@ -292,20 +242,17 @@ unsigned int c_filter_rel_member_tags( first_outerway = 0; } /* Copy the list identified outer way tags over to the relation */ - q = poly_tags.next; - while (q != &poly_tags) { - keyval::addItem(&tags, q->key, q->value, 1); - q = q->next; - } + for (q = poly_tags.firstItem(); q; q = poly_tags.nextItem(q)) + tags.addItem(q->key, q->value, true); /* We need to re-check and only keep polygon tags in the list of polytags */ - q = poly_tags.next; - while (q != &poly_tags) { + q = poly_tags.firstItem(); + while (q) { contains_tag = 0; const std::vector &infos = exlist->get(OSMTYPE_WAY); - for (j = 0; j < infos.size(); j++) { + for (unsigned j = 0; j < infos.size(); j++) { const taginfo &info = infos[j]; - if (strcmp(info.name.c_str(), q->key) == 0) { + if (info.name == q->key) { if (info.flags & FLAG_POLYGON) { contains_tag = 1; break; @@ -313,25 +260,25 @@ unsigned int c_filter_rel_member_tags( } } if (contains_tag == 0) { - qq = q->next; - keyval::removeTag(q); + keyval *qq = poly_tags.nextItem(q); + q->removeTag(); q = qq; } else { - q = q->next; + q = poly_tags.nextItem(q); } } } - keyval::resetList(&poly_tags); + poly_tags.resetList(); } else if(!allow_typeless) { /* Unknown type, just exit */ - keyval::resetList(&tags); - keyval::resetList(&poly_tags); + tags.resetList(); + poly_tags.resetList(); return 1; } - if (!keyval::listHasData(&tags)) { - keyval::resetList(&tags); - keyval::resetList(&poly_tags); + if (!tags.listHasData()) { + tags.resetList(); + poly_tags.resetList(); return 1; } @@ -339,21 +286,19 @@ unsigned int c_filter_rel_member_tags( mark each member so that we can skip them during iterate_ways but only if the polygon-tags look the same as the outer ring */ if (make_polygon) { - for (i = 0; i < member_count; i++) { + for (int i = 0; i < member_count; i++) { int match = 1; - struct keyval *p = member_tags[i].next; - while (p != &(member_tags[i])) { - const char *v = keyval::getItem(&tags, p->key); - if (!v || strcmp(v, p->value)) { + for (const keyval *p = member_tags[i].firstItem(); p; p = member_tags[i].nextItem(p)) { + const std::string *v = tags.getItem(p->key); + if (!v || *v != p->value) { /* z_order and osm_ are automatically generated tags, so ignore them */ - if ((strcmp(p->key, "z_order") != 0) && (strcmp(p->key, "osm_user") != 0) && - (strcmp(p->key, "osm_version") != 0) && (strcmp(p->key, "osm_uid") != 0) && - (strcmp(p->key, "osm_changeset")) && (strcmp(p->key, "osm_timestamp") != 0)) { + if ((p->key != "z_order") && (p->key != "osm_user") && + (p->key != "osm_version") && (p->key != "osm_uid") && + (p->key != "osm_changeset") && (p->key != "osm_timestamp")) { match = 0; break; } } - p = p->next; } if (match) { member_superseeded[i] = 1; @@ -363,9 +308,7 @@ unsigned int c_filter_rel_member_tags( } } - keyval::resetList(rel_tags); - keyval::cloneList(rel_tags, &tags); - keyval::resetList(&tags); + tags.moveList(rel_tags); add_z_order(rel_tags, roads); @@ -387,11 +330,11 @@ unsigned int lua_filter_rel_member_tags(lua_State* L, const char* rel_mem_func, lua_newtable(L); /* relations key value table */ - while( (item = keyval::popItem(rel_tags)) != NULL ) { - lua_pushstring(L, item->key); - lua_pushstring(L, item->value); + while( (item = rel_tags->popItem()) != NULL ) { + lua_pushstring(L, item->key.c_str()); + lua_pushstring(L, item->value.c_str()); lua_rawset(L, -3); - keyval::freeItem(item); + delete(item); count++; } @@ -400,11 +343,11 @@ unsigned int lua_filter_rel_member_tags(lua_State* L, const char* rel_mem_func, for (i = 1; i <= member_count; i++) { lua_pushnumber(L, i); lua_newtable(L); /* member key value table */ - while( (item = keyval::popItem(&(member_tags[i - 1]))) != NULL ) { - lua_pushstring(L, item->key); - lua_pushstring(L, item->value); + while( (item = member_tags[i - 1].popItem()) != NULL ) { + lua_pushstring(L, item->key.c_str()); + lua_pushstring(L, item->value.c_str()); lua_rawset(L, -3); - keyval::freeItem(item); + delete(item); count++; } lua_rawset(L, -3); @@ -448,7 +391,7 @@ unsigned int lua_filter_rel_member_tags(lua_State* L, const char* rel_mem_func, while (lua_next(L,-2) != 0) { key = lua_tostring(L,-2); value = lua_tostring(L,-1); - keyval::addItem(rel_tags, key, value, 0); + rel_tags->addItem(key, value, false); lua_pop(L,1); } lua_pop(L,1); @@ -579,11 +522,11 @@ unsigned int tagtransform::lua_filter_basic_tags(const OsmType type, keyval *tag lua_newtable(L); /* key value table */ - while( (item = keyval::popItem(tags)) != NULL ) { - lua_pushstring(L, item->key); - lua_pushstring(L, item->value); + while( (item = tags->popItem()) != NULL ) { + lua_pushstring(L, item->key.c_str()); + lua_pushstring(L, item->value.c_str()); lua_rawset(L, -3); - keyval::freeItem(item); + delete(item); count++; } @@ -607,7 +550,7 @@ unsigned int tagtransform::lua_filter_basic_tags(const OsmType type, keyval *tag while (lua_next(L,-2) != 0) { key = lua_tostring(L,-2); value = lua_tostring(L,-1); - keyval::addItem(tags, key, value, 0); + tags->addItem(key, value, false); lua_pop(L,1); } @@ -635,7 +578,6 @@ unsigned int tagtransform::c_filter_basic_tags( //a place to keep the tags we like as we go struct keyval temp; - keyval::initList(&temp); enum OsmType export_type; if (type == OSMTYPE_RELATION) { @@ -647,25 +589,24 @@ unsigned int tagtransform::c_filter_basic_tags( /* We used to only go far enough to determine if it's a polygon or not, but now we go through and filter stuff we don't need */ //pop each tag off and keep it in the temp list if we like it struct keyval *item; - while ((item = keyval::popItem(tags)) != NULL ) { + while ((item = tags->popItem()) != NULL ) { //if we want to do more than the export list says if(!strict) { - if (type == OSMTYPE_RELATION && !strcmp("type", item->key)) { - keyval::pushItem(&temp, item); + if (type == OSMTYPE_RELATION && "type" == item->key) { + temp.pushItem(item); item = NULL; filter = 0; continue; } /* Allow named islands to appear as polygons */ - if (!strcmp("natural", item->key) - && !strcmp("coastline", item->value)) { + if ("natural" == item->key && "coastline" == item->value) { add_area_tag = 1; } /* Discard natural=coastline tags (we render these from a shapefile instead) */ - if (!options->keep_coastlines && !strcmp("natural", item->key) - && !strcmp("coastline", item->value)) { - keyval::freeItem(item); + if (!options->keep_coastlines && "natural" == item->key + && "coastline" == item->value) { + delete(item); item = NULL; continue; } @@ -676,9 +617,9 @@ unsigned int tagtransform::c_filter_basic_tags( size_t i = 0; for (; i < infos.size(); i++) { const taginfo &info = infos[i]; - if (wildMatch(info.name.c_str(), item->key)) { + if (wildMatch(info.name.c_str(), item->key.c_str())) { if (info.flags & FLAG_DELETE) { - keyval::freeItem(item); + delete(item); item = NULL; break; } @@ -686,7 +627,7 @@ unsigned int tagtransform::c_filter_basic_tags( filter = 0; flags |= info.flags; - keyval::pushItem(&temp, item); + temp.pushItem(item); item = NULL; break; } @@ -696,63 +637,62 @@ unsigned int tagtransform::c_filter_basic_tags( if (i == infos.size() && !strict) { if (options->hstore_mode != HSTORE_NONE) { /* with hstore, copy all tags... */ - keyval::pushItem(&temp, item); + temp.pushItem(item); /* ... but if hstore_match_only is set then don't take this as a reason for keeping the object */ - if (!options->hstore_match_only && strcmp("osm_uid", item->key) - && strcmp("osm_user", item->key) - && strcmp("osm_timestamp", item->key) - && strcmp("osm_version", item->key) - && strcmp("osm_changeset", item->key)) + if (!options->hstore_match_only && "osm_uid" != item->key + && "osm_user" != item->key + && "osm_timestamp" != item->key + && "osm_version" != item->key + && "osm_changeset" != item->key) filter = 0; } else if (options->hstore_columns.size() > 0) { /* does this column match any of the hstore column prefixes? */ size_t j = 0; for(; j < options->hstore_columns.size(); ++j) { - char *pos = strstr(item->key, options->hstore_columns[j].c_str()); - if (pos == item->key) { - keyval::pushItem(&temp, item); + size_t pos = item->key.find(options->hstore_columns[j]); + if (pos == 0) { + temp.pushItem(item); /* ... but if hstore_match_only is set then don't take this as a reason for keeping the object */ if (!options->hstore_match_only - && strcmp("osm_uid", item->key) - && strcmp("osm_user", item->key) - && strcmp("osm_timestamp", item->key) - && strcmp("osm_version", item->key) - && strcmp("osm_changeset", item->key)) + && "osm_uid" != item->key + && "osm_user" != item->key + && "osm_timestamp" != item->key + && "osm_version" != item->key + && "osm_changeset" != item->key) filter = 0; break; } } /* if not, skip the tag */ if (j == options->hstore_columns.size()) { - keyval::freeItem(item); + delete(item); } } else { - keyval::freeItem(item); + delete(item); } item = NULL; } } /* Move from temp list back to original list */ - while ((item = keyval::popItem(&temp)) != NULL ) - keyval::pushItem(tags, item); + while ((item = temp.popItem()) != NULL ) + tags->pushItem(item); *polygon = flags & FLAG_POLYGON; /* Special case allowing area= to override anything else */ - const char *area; - if ((area = keyval::getItem(tags, "area"))) { - if (!strcmp(area, "yes") || !strcmp(area, "true") || !strcmp(area, "1")) + const std::string *area; + if ((area = tags->getItem("area"))) { + if (*area == "yes" || *area == "true" || *area == "1") *polygon = 1; - else if (!strcmp(area, "no") || !strcmp(area, "false") - || !strcmp(area, "0")) + else if (*area == "no" || *area == "false" || *area == "0") *polygon = 0; } else { /* If we need to force this as a polygon, append an area tag */ if (add_area_tag) { - keyval::addItem(tags, "area", "yes", 0); + tags->addItem("area", "yes", false); *polygon = 1; } } diff --git a/tests/middle-tests.cpp b/tests/middle-tests.cpp index dc0df94ea..17be1c29d 100644 --- a/tests/middle-tests.cpp +++ b/tests/middle-tests.cpp @@ -43,7 +43,7 @@ int test_node_set(middle_t *mid) dynamic_cast(mid)->nodes_delete(id); } - keyval::resetList(&tags); + tags.resetList(); return 0; } @@ -78,8 +78,7 @@ int test_way_set(middle_t *mid) osmid_t way_id = 1; double lat = 12.3456789; double lon = 98.7654321; - struct keyval tags[2]; /* <-- this is needed because the ways_get_list method calls - * keyval::initList() on the `count + 1`th tags element. */ + struct keyval tags; struct osmNode *node_ptr = NULL; osmid_t way_ids_ptr; int node_count = 0; @@ -89,19 +88,19 @@ int test_way_set(middle_t *mid) // set the nodes for (int i = 0; i < nd_count; ++i) { - status = mid->nodes_set(nds[i], lat, lon, &tags[0]); + status = mid->nodes_set(nds[i], lat, lon, &tags); if (status != 0) { std::cerr << "ERROR: Unable to set node " << nds[i] << ".\n"; return 1; } } // set the way - status = mid->ways_set(way_id, nds, nd_count, &tags[0]); + status = mid->ways_set(way_id, nds, nd_count, &tags); if (status != 0) { std::cerr << "ERROR: Unable to set way.\n"; return 1; } // commit the setup data mid->commit(); // get it back - int way_count = mid->ways_get_list(&way_id, 1, &way_ids_ptr, &tags[0], &node_ptr, &node_count); + int way_count = mid->ways_get_list(&way_id, 1, &way_ids_ptr, &tags, &node_ptr, &node_count); if (way_count != 1) { std::cerr << "ERROR: Unable to get way list.\n"; return 1; } // check that it's the same @@ -156,7 +155,7 @@ int test_way_set(middle_t *mid) } } - keyval::resetList(&tags[0]); + tags.resetList(); free(node_ptr); // clean up for next test diff --git a/tests/test-output-multi-line.cpp b/tests/test-output-multi-line.cpp index 0681a5658..b740a978d 100644 --- a/tests/test-output-multi-line.cpp +++ b/tests/test-output-multi-line.cpp @@ -14,7 +14,6 @@ #include "middle-pgsql.hpp" #include "taginfo_impl.hpp" #include "parse.hpp" -#include "text-tree.hpp" #include #include diff --git a/tests/test-output-multi-point-multi-table.cpp b/tests/test-output-multi-point-multi-table.cpp index 0744a8f94..b90407509 100644 --- a/tests/test-output-multi-point-multi-table.cpp +++ b/tests/test-output-multi-point-multi-table.cpp @@ -14,7 +14,6 @@ #include "middle-pgsql.hpp" #include "taginfo_impl.hpp" #include "parse.hpp" -#include "text-tree.hpp" #include #include diff --git a/tests/test-output-multi-point.cpp b/tests/test-output-multi-point.cpp index 47d4cd847..809717d39 100644 --- a/tests/test-output-multi-point.cpp +++ b/tests/test-output-multi-point.cpp @@ -14,7 +14,6 @@ #include "middle-pgsql.hpp" #include "taginfo_impl.hpp" #include "parse.hpp" -#include "text-tree.hpp" #include #include diff --git a/tests/test-output-multi-polygon.cpp b/tests/test-output-multi-polygon.cpp index be3c48fdf..067e759a3 100644 --- a/tests/test-output-multi-polygon.cpp +++ b/tests/test-output-multi-polygon.cpp @@ -14,7 +14,6 @@ #include "middle-pgsql.hpp" #include "taginfo_impl.hpp" #include "parse.hpp" -#include "text-tree.hpp" #include #include diff --git a/tests/test-output-pgsql.cpp b/tests/test-output-pgsql.cpp index cf773cfbb..1ef7eba6a 100644 --- a/tests/test-output-pgsql.cpp +++ b/tests/test-output-pgsql.cpp @@ -15,7 +15,6 @@ #include "middle-ram.hpp" #include "taginfo_impl.hpp" #include "parse.hpp" -#include "text-tree.hpp" #include #include diff --git a/tests/test-parse-xml2.cpp b/tests/test-parse-xml2.cpp index 44ce7d9f7..52599f2fb 100644 --- a/tests/test-parse-xml2.cpp +++ b/tests/test-parse-xml2.cpp @@ -10,7 +10,6 @@ #include "parse-xml2.hpp" #include "output.hpp" #include "options.hpp" -#include "text-tree.hpp" #include "keyvals.hpp" void exit_nicely() diff --git a/text-tree.cpp b/text-tree.cpp deleted file mode 100644 index 36616b407..000000000 --- a/text-tree.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* text-tree.c - * - * Storage of reference counted text strings - * used by keyvals.c to store the key/value strings - */ - -#include -#include -#include -#include -#include "text-tree.hpp" - -namespace -{ - int text_compare(const void *pa, const void *pb, void *rb_param) - { - struct text_node *a = (struct text_node *)pa; - struct text_node *b = (struct text_node *)pb; - - rb_param = NULL; - return strcmp(a->str, b->str); - } - - void text_free(void *pa, void *rb_param) - { - struct text_node *a = (struct text_node *)pa; - rb_param = NULL; - free(a->str); - free(a); - } -} - -text_tree::text_tree() -{ - table = rb_create (text_compare, NULL, NULL); - assert(table); -} - -const char *text_tree::text_get(const char *text) -{ - struct text_node *node, *dupe; - - node = (struct text_node *)malloc(sizeof(*node)); - assert(node); - - node->str = strdup(text); - assert(node->str); - node->ref = 0; - dupe = (struct text_node *)rb_insert(table, (void *)node); - if (dupe) { - free(node->str); - free(node); - dupe->ref++; - return dupe->str; - } else { - node->ref++; - return node->str; - } -} - -void text_tree::text_release(const char *text) -{ - struct text_node *node, find; - - find.str = (char *)text; - find.ref = 0; - node = (struct text_node *)rb_find(table, (void *)&find); - if (!node) { - fprintf(stderr, "failed to find '%s'\n", text); - return; - } - node->ref--; - if (!node->ref) { - rb_delete (table, &find); - free(node->str); - free(node); - } -} - -text_tree::~text_tree() -{ - rb_destroy(table, text_free); -} -#if 0 -int main(int argc, char **argv) -{ - struct tree_context *ctx = text_init(); - - printf("%1$p %1$s\n", text_get(ctx, "Hello")); - printf("%1$p %1$s\n", text_get(ctx, "Hello")); - printf("%1$p %1$s\n", text_get(ctx, "World")); - - text_release(ctx,"Hello"); - text_release(ctx,"Hello"); - text_release(ctx,"World"); - text_release(ctx,"Hello"); - - text_exit(ctx); - return 0; -} -#endif diff --git a/text-tree.hpp b/text-tree.hpp deleted file mode 100644 index 51473d5d4..000000000 --- a/text-tree.hpp +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef TEXT_TREE_H -#define TEXT_TREE_H - -#include "rb.hpp" - -struct text_tree { - struct rb_table *table; - - text_tree(); - ~text_tree(); - const char *text_get(const char *text); - void text_release(const char *text); -}; - -struct text_node { - char *str; - int ref; -}; - - -#endif