From 271ec3d154e7d0a9126a8e3f7e2cafb711c47e3a Mon Sep 17 00:00:00 2001 From: Eric Fischer Date: Tue, 3 May 2016 10:52:49 -0700 Subject: [PATCH] Stop using malloc for layer names --- main.cpp | 48 +++++++++++++++++++----------------------------- mbtiles.cpp | 4 ++-- mbtiles.hpp | 2 +- tile-join.cpp | 23 ++++++----------------- tile.cpp | 17 +++++++---------- tile.hpp | 2 +- 6 files changed, 36 insertions(+), 60 deletions(-) diff --git a/main.cpp b/main.cpp index 727e82f..5b2a194 100644 --- a/main.cpp +++ b/main.cpp @@ -1177,14 +1177,10 @@ int read_input(std::vector &sources, char *fname, const char *layername, } } - char *layernames[nlayers]; + std::vector layernames; for (i = 0; i < nlayers; i++) { if (layername != NULL) { - layernames[i] = strdup(layername); - if (layernames[i] == NULL) { - perror("Out of memory"); - exit(EXIT_FAILURE); - } + layernames.push_back(std::string(layername)); } else { const char *src; if (sources.size() < 1) { @@ -1195,39 +1191,37 @@ int read_input(std::vector &sources, char *fname, const char *layername, src = sources[i].file.c_str(); } - char *trunc = layernames[i] = (char *) malloc(strlen(src) + 1); - if (trunc == NULL) { - perror("Out of memory"); - exit(EXIT_FAILURE); - } - + // Find the last component of the pathname const char *ocp, *use = src; for (ocp = src; *ocp; ocp++) { if (*ocp == '/' && ocp[1] != '\0') { use = ocp + 1; } } - strcpy(trunc, use); + std::string trunc = std::string(use); - char *cp = strstr(trunc, ".json"); - if (cp != NULL) { - *cp = '\0'; + // Trim .json or .mbtiles from the name + ssize_t cp; + cp = trunc.find(".json"); + if (cp >= 0) { + trunc = trunc.substr(0, cp); } - cp = strstr(trunc, ".mbtiles"); - if (cp != NULL) { - *cp = '\0'; + cp = trunc.find(".mbtiles"); + if (cp >= 0) { + trunc = trunc.substr(0, cp); } - char *out = trunc; - for (cp = trunc; *cp; cp++) { - if (isalpha(*cp) || isdigit(*cp) || *cp == '_') { - *out++ = *cp; + // Trim out characters that can't be part of selector + std::string out; + for (cp = 0; cp < trunc.size(); cp++) { + if (isalpha(trunc[cp]) || isdigit(trunc[cp]) || trunc[cp] == '_') { + out.append(trunc, cp, 1); } } - *out = '\0'; + layernames.push_back(out); if (!quiet) { - fprintf(stderr, "For layer %d, using name \"%s\"\n", i, trunc); + fprintf(stderr, "For layer %d, using name \"%s\"\n", i, out.c_str()); } } } @@ -1692,10 +1686,6 @@ int read_input(std::vector &sources, char *fname, const char *layername, mbtiles_write_metadata(outdb, fname, layernames, minzoom, maxzoom, minlat, minlon, maxlat, maxlon, midlat, midlon, file_keys, nlayers, forcetable, attribution); - for (i = 0; i < nlayers; i++) { - free(layernames[i]); - } - return ret; } diff --git a/mbtiles.cpp b/mbtiles.cpp index 97318f5..fecaafc 100644 --- a/mbtiles.cpp +++ b/mbtiles.cpp @@ -132,7 +132,7 @@ bool type_and_string::operator<(const type_and_string &o) const { return false; } -void mbtiles_write_metadata(sqlite3 *outdb, const char *fname, char **layername, int minzoom, int maxzoom, double minlat, double minlon, double maxlat, double maxlon, double midlat, double midlon, std::vector > &file_keys, int nlayers, int forcetable, const char *attribution) { +void mbtiles_write_metadata(sqlite3 *outdb, const char *fname, std::vector &layername, int minzoom, int maxzoom, double minlat, double minlon, double maxlat, double maxlon, double midlat, double midlon, std::vector > &file_keys, int nlayers, int forcetable, const char *attribution) { char *sql, *err; sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES ('name', %Q);", fname); @@ -237,7 +237,7 @@ void mbtiles_write_metadata(sqlite3 *outdb, const char *fname, char **layername, } aprintf(&buf, "{ \"id\": \""); - quote(&buf, layername[i]); + quote(&buf, layername[i].c_str()); aprintf(&buf, "\", \"description\": \"\", \"minzoom\": %d, \"maxzoom\": %d, \"fields\": {", minzoom, maxzoom); std::set::iterator j; diff --git a/mbtiles.hpp b/mbtiles.hpp index 1d15abb..3a535b1 100644 --- a/mbtiles.hpp +++ b/mbtiles.hpp @@ -9,6 +9,6 @@ sqlite3 *mbtiles_open(char *dbname, char **argv, int forcetable); void mbtiles_write_tile(sqlite3 *outdb, int z, int tx, int ty, const char *data, int size); -void mbtiles_write_metadata(sqlite3 *outdb, const char *fname, char **layername, int minzoom, int maxzoom, double minlat, double minlon, double maxlat, double maxlon, double midlat, double midlon, std::vector > &file_keys, int nlayers, int forcetable, const char *attribution); +void mbtiles_write_metadata(sqlite3 *outdb, const char *fname, std::vector &layername, int minzoom, int maxzoom, double minlat, double minlon, double maxlat, double maxlon, double midlat, double midlon, std::vector > &file_keys, int nlayers, int forcetable, const char *attribution); void mbtiles_close(sqlite3 *outdb, char **argv); diff --git a/tile-join.cpp b/tile-join.cpp index 596d087..64ed4c7 100644 --- a/tile-join.cpp +++ b/tile-join.cpp @@ -25,7 +25,7 @@ struct stats { double minlat, minlon, maxlat, maxlon; }; -void handle(std::string message, int z, unsigned x, unsigned y, std::vector > &file_keys, char ***layernames, int *nlayers, sqlite3 *outdb, std::vector &header, std::map > &mapping, std::set &exclude, int ifmatched) { +void handle(std::string message, int z, unsigned x, unsigned y, std::vector > &file_keys, std::vector &layernames, int *nlayers, sqlite3 *outdb, std::vector &header, std::map > &mapping, std::set &exclude, int ifmatched) { mvt_tile tile; mvt_tile outtile; int features_added = 0; @@ -47,24 +47,13 @@ void handle(std::string message, int z, unsigned x, unsigned y, std::vector()); - *layernames = (char **) realloc(*layernames, (ll + 1) * sizeof(char *)); - - if (*layernames == NULL) { - perror("realloc layernames"); - exit(EXIT_FAILURE); - } - - (*layernames)[ll] = strdup(ln); - if ((*layernames)[ll] == NULL) { - perror("Out of memory"); - exit(EXIT_FAILURE); - } + layernames.push_back(std::string(ln)); *nlayers = ll + 1; } @@ -215,7 +204,7 @@ double max(double a, double b) { } } -void decode(char *fname, char *map, std::vector > &file_keys, char ***layernames, int *nlayers, sqlite3 *outdb, struct stats *st, std::vector &header, std::map > &mapping, std::set &exclude, int ifmatched, char **attribution) { +void decode(char *fname, char *map, std::vector > &file_keys, std::vector &layernames, int *nlayers, sqlite3 *outdb, struct stats *st, std::vector &header, std::map > &mapping, std::set &exclude, int ifmatched, char **attribution) { sqlite3 *db; if (sqlite3_open(fname, &db) != SQLITE_OK) { @@ -434,12 +423,12 @@ int main(int argc, char **argv) { st.maxzoom = st.maxlat = st.maxlon = INT_MIN; std::vector > file_keys; - char **layernames = NULL; + std::vector layernames; int nlayers = 0; char *attribution = NULL; for (i = optind; i < argc; i++) { - decode(argv[i], csv, file_keys, &layernames, &nlayers, outdb, &st, header, mapping, exclude, ifmatched, &attribution); + decode(argv[i], csv, file_keys, layernames, &nlayers, outdb, &st, header, mapping, exclude, ifmatched, &attribution); } mbtiles_write_metadata(outdb, outfile, layernames, st.minzoom, st.maxzoom, st.minlat, st.minlon, st.maxlat, st.maxlon, st.midlat, st.midlon, file_keys, nlayers, 0, attribution); diff --git a/tile.cpp b/tile.cpp index 1fa4332..291bff1 100644 --- a/tile.cpp +++ b/tile.cpp @@ -506,7 +506,7 @@ int manage_gap(unsigned long long index, unsigned long long *previndex, double s return 0; } -long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *stringpool, int z, unsigned tx, unsigned ty, int detail, int min_detail, int basezoom, char **layernames, sqlite3 *outdb, double droprate, int buffer, const char *fname, FILE **geomfile, int minzoom, int maxzoom, double todo, volatile long long *along, double gamma, int nlayers, int *prevent, int *additional, int child_shards, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y, volatile int *running) { +long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *stringpool, int z, unsigned tx, unsigned ty, int detail, int min_detail, int basezoom, std::vector *layernames, sqlite3 *outdb, double droprate, int buffer, const char *fname, FILE **geomfile, int minzoom, int maxzoom, double todo, volatile long long *along, double gamma, int nlayers, int *prevent, int *additional, int child_shards, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y, volatile int *running) { int line_detail; double fraction = 1; @@ -901,7 +901,7 @@ long long write_tile(FILE *geoms, long long *geompos_in, char *metabase, char *s for (size_t j = 0; j < features.size(); j++) { mvt_layer layer; - layer.name = layernames[j]; + layer.name = (*layernames)[j]; layer.version = 2; layer.extent = 1 << line_detail; @@ -994,7 +994,7 @@ struct write_tile_args { char *stringpool; int min_detail; int basezoom; - char **layernames; + std::vector *layernames; sqlite3 *outdb; double droprate; int buffer; @@ -1021,6 +1021,7 @@ struct write_tile_args { unsigned *initial_x; unsigned *initial_y; volatile int *running; + int err; }; void *run_thread(void *vargs) { @@ -1064,11 +1065,7 @@ void *run_thread(void *vargs) { long long len = write_tile(geom, &geompos, arg->metabase, arg->stringpool, z, x, y, z == arg->maxzoom ? arg->full_detail : arg->low_detail, arg->min_detail, arg->basezoom, arg->layernames, arg->outdb, arg->droprate, arg->buffer, arg->fname, arg->geomfile, arg->minzoom, arg->maxzoom, arg->todo, arg->along, arg->gamma, arg->nlayers, arg->prevent, arg->additional, arg->child_shards, arg->meta_off, arg->pool_off, arg->initial_x, arg->initial_y, arg->running); if (len < 0) { - int *err = (int *) malloc(sizeof(int)); - if (err == NULL) { - perror("Out of memory"); - exit(EXIT_FAILURE); - } + int *err = &arg->err; *err = z - 1; return err; } @@ -1116,7 +1113,7 @@ void *run_thread(void *vargs) { return NULL; } -int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, unsigned *midx, unsigned *midy, char **layernames, int maxzoom, int minzoom, int basezoom, sqlite3 *outdb, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int nlayers, int *prevent, int *additional, int full_detail, int low_detail, int min_detail, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y) { +int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, unsigned *midx, unsigned *midy, std::vector &layernames, int maxzoom, int minzoom, int basezoom, sqlite3 *outdb, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int nlayers, int *prevent, int *additional, int full_detail, int low_detail, int min_detail, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y) { int i; for (i = 0; i <= maxzoom; i++) { long long most = 0; @@ -1226,7 +1223,7 @@ int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpo args[thread].stringpool = stringpool; args[thread].min_detail = min_detail; args[thread].basezoom = basezoom; - args[thread].layernames = layernames; + args[thread].layernames = &layernames; args[thread].outdb = outdb; // locked with db_lock args[thread].droprate = droprate; args[thread].buffer = buffer; diff --git a/tile.hpp b/tile.hpp index c7bddc7..144f0a6 100644 --- a/tile.hpp +++ b/tile.hpp @@ -1,5 +1,5 @@ long long write_tile(char **geom, char *metabase, char *stringpool, unsigned *file_bbox, int z, unsigned x, unsigned y, int detail, int min_detail, int basezoom, char **layernames, sqlite3 *outdb, double droprate, int buffer, const char *fname, FILE **geomfile, int file_minzoom, int file_maxzoom, double todo, char *geomstart, long long along, double gamma, int nlayers, int *prevent, int *additional); -int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, unsigned *midx, unsigned *midy, char **layernames, int maxzoom, int minzoom, int basezoom, sqlite3 *outdb, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int nlayers, int *prevent, int *additional, int full_detail, int low_detail, int min_detail, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y); +int traverse_zooms(int *geomfd, off_t *geom_size, char *metabase, char *stringpool, unsigned *midx, unsigned *midy, std::vector &layernames, int maxzoom, int minzoom, int basezoom, sqlite3 *outdb, double droprate, int buffer, const char *fname, const char *tmpdir, double gamma, int nlayers, int *prevent, int *additional, int full_detail, int low_detail, int min_detail, long long *meta_off, long long *pool_off, unsigned *initial_x, unsigned *initial_y); int manage_gap(unsigned long long index, unsigned long long *previndex, double scale, double gamma, double *gap);