mirror of
https://github.com/mapbox/tippecanoe.git
synced 2025-04-09 12:01:14 +00:00
Progress on converting jsonpull to more of a C++ idiom
This commit is contained in:
parent
9f1913bc37
commit
3f9dfdc452
@ -20,7 +20,7 @@
|
||||
#include "projection.hpp"
|
||||
#include "geometry.hpp"
|
||||
#include "write_json.hpp"
|
||||
#include "jsonpull/jsonpull.h"
|
||||
#include "jsonpull/jsonpull.hpp"
|
||||
#include "dirtiles.hpp"
|
||||
|
||||
int minzoom = 0;
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sqlite3.h>
|
||||
#include "jsonpull/jsonpull.h"
|
||||
#include "jsonpull/jsonpull.hpp"
|
||||
#include "dirtiles.hpp"
|
||||
|
||||
std::string dir_read_tile(std::string base, struct zxy tile) {
|
||||
@ -181,14 +181,14 @@ sqlite3 *dirmeta2tmp(const char *fname) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < o->length; i++) {
|
||||
for (size_t i = 0; i < o->keys.size(); i++) {
|
||||
if (o->keys[i]->type != JSON_STRING || o->values[i]->type != JSON_STRING) {
|
||||
fprintf(stderr, "%s: non-string in metadata\n", name.c_str());
|
||||
}
|
||||
|
||||
char *sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES (%Q, %Q);", o->keys[i]->string, o->values[i]->string);
|
||||
char *sql = sqlite3_mprintf("INSERT INTO metadata (name, value) VALUES (%Q, %Q);", o->keys[i]->string.c_str(), o->values[i]->string.c_str());
|
||||
if (sqlite3_exec(db, sql, NULL, NULL, &err) != SQLITE_OK) {
|
||||
fprintf(stderr, "set %s in metadata: %s\n", o->keys[i]->string, err);
|
||||
fprintf(stderr, "set %s in metadata: %s\n", o->keys[i]->string.c_str(), err);
|
||||
}
|
||||
sqlite3_free(sql);
|
||||
}
|
||||
|
120
evaluator.cpp
120
evaluator.cpp
@ -12,7 +12,7 @@ int compare(mvt_value one, json_object *two, bool &fail) {
|
||||
return false; // string vs non-string
|
||||
}
|
||||
|
||||
return strcmp(one.string_value.c_str(), two->string);
|
||||
return strcmp(one.string_value.c_str(), two->string.c_str());
|
||||
}
|
||||
|
||||
if (one.type == mvt_double || one.type == mvt_float || one.type == mvt_int || one.type == mvt_uint || one.type == mvt_sint) {
|
||||
@ -71,56 +71,56 @@ int compare(mvt_value one, json_object *two, bool &fail) {
|
||||
|
||||
bool eval(std::map<std::string, mvt_value> const &feature, json_object *f) {
|
||||
if (f == NULL || f->type != JSON_ARRAY) {
|
||||
fprintf(stderr, "Filter is not an array: %s\n", json_stringify(f));
|
||||
fprintf(stderr, "Filter is not an array: %s\n", json_stringify(f).c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (f->length < 1) {
|
||||
fprintf(stderr, "Array too small in filter: %s\n", json_stringify(f));
|
||||
if (f->array.size() < 1) {
|
||||
fprintf(stderr, "Array too small in filter: %s\n", json_stringify(f).c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (f->array[0]->type != JSON_STRING) {
|
||||
fprintf(stderr, "Filter operation is not a string: %s\n", json_stringify(f));
|
||||
fprintf(stderr, "Filter operation is not a string: %s\n", json_stringify(f).c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (strcmp(f->array[0]->string, "has") == 0 ||
|
||||
strcmp(f->array[0]->string, "!has") == 0) {
|
||||
if (f->length != 2) {
|
||||
fprintf(stderr, "Wrong number of array elements in filter: %s\n", json_stringify(f));
|
||||
if (f->array[0]->string == "has" ||
|
||||
f->array[0]->string == "!has") {
|
||||
if (f->array.size() != 2) {
|
||||
fprintf(stderr, "Wrong number of array elements in filter: %s\n", json_stringify(f).c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (strcmp(f->array[0]->string, "has") == 0) {
|
||||
if (f->array[0]->string == "has") {
|
||||
if (f->array[1]->type != JSON_STRING) {
|
||||
fprintf(stderr, "\"has\" key is not a string: %s\n", json_stringify(f));
|
||||
fprintf(stderr, "\"has\" key is not a string: %s\n", json_stringify(f).c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return feature.count(std::string(f->array[1]->string)) != 0;
|
||||
}
|
||||
|
||||
if (strcmp(f->array[0]->string, "!has") == 0) {
|
||||
if (f->array[0]->string == "!has") {
|
||||
if (f->array[1]->type != JSON_STRING) {
|
||||
fprintf(stderr, "\"!has\" key is not a string: %s\n", json_stringify(f));
|
||||
fprintf(stderr, "\"!has\" key is not a string: %s\n", json_stringify(f).c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
return feature.count(std::string(f->array[1]->string)) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(f->array[0]->string, "==") == 0 ||
|
||||
strcmp(f->array[0]->string, "!=") == 0 ||
|
||||
strcmp(f->array[0]->string, ">") == 0 ||
|
||||
strcmp(f->array[0]->string, ">=") == 0 ||
|
||||
strcmp(f->array[0]->string, "<") == 0 ||
|
||||
strcmp(f->array[0]->string, "<=") == 0) {
|
||||
if (f->length != 3) {
|
||||
fprintf(stderr, "Wrong number of array elements in filter: %s\n", json_stringify(f));
|
||||
if (f->array[0]->string == "==" ||
|
||||
f->array[0]->string == "!=" ||
|
||||
f->array[0]->string == ">" ||
|
||||
f->array[0]->string == ">=" ||
|
||||
f->array[0]->string == "<" ||
|
||||
f->array[0]->string == "<=") {
|
||||
if (f->array.size() != 3) {
|
||||
fprintf(stderr, "Wrong number of array elements in filter: %s\n", json_stringify(f).c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (f->array[1]->type != JSON_STRING) {
|
||||
fprintf(stderr, "\"!has\" key is not a string: %s\n", json_stringify(f));
|
||||
fprintf(stderr, "\"!has\" key is not a string: %s\n", json_stringify(f).c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@ -128,12 +128,11 @@ bool eval(std::map<std::string, mvt_value> const &feature, json_object *f) {
|
||||
if (ff == feature.end()) {
|
||||
static bool warned = false;
|
||||
if (!warned) {
|
||||
const char *s = json_stringify(f);
|
||||
fprintf(stderr, "Warning: attribute not found for comparison: %s\n", s);
|
||||
free((void *) s);
|
||||
std::string s = json_stringify(f);
|
||||
fprintf(stderr, "Warning: attribute not found for comparison: %s\n", s.c_str());
|
||||
warned = true;
|
||||
}
|
||||
if (strcmp(f->array[0]->string, "!=") == 0) {
|
||||
if (f->array[0]->string == "!=") {
|
||||
return true; // attributes that aren't found are not equal
|
||||
}
|
||||
return false; // not found: comparison is false
|
||||
@ -145,55 +144,54 @@ bool eval(std::map<std::string, mvt_value> const &feature, json_object *f) {
|
||||
if (fail) {
|
||||
static bool warned = false;
|
||||
if (!warned) {
|
||||
const char *s = json_stringify(f);
|
||||
fprintf(stderr, "Warning: mismatched type in comparison: %s\n", s);
|
||||
free((void *) s);
|
||||
std::string s = json_stringify(f);
|
||||
fprintf(stderr, "Warning: mismatched type in comparison: %s\n", s.c_str());
|
||||
warned = true;
|
||||
}
|
||||
if (strcmp(f->array[0]->string, "!=") == 0) {
|
||||
if (f->array[0]->string == "!=") {
|
||||
return true; // mismatched types are not equal
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (strcmp(f->array[0]->string, "==") == 0) {
|
||||
if (f->array[0]->string == "==") {
|
||||
return cmp == 0;
|
||||
}
|
||||
if (strcmp(f->array[0]->string, "!=") == 0) {
|
||||
if (f->array[0]->string == "!=") {
|
||||
return cmp != 0;
|
||||
}
|
||||
if (strcmp(f->array[0]->string, ">") == 0) {
|
||||
if (f->array[0]->string == ">") {
|
||||
return cmp > 0;
|
||||
}
|
||||
if (strcmp(f->array[0]->string, ">=") == 0) {
|
||||
if (f->array[0]->string == ">=") {
|
||||
return cmp >= 0;
|
||||
}
|
||||
if (strcmp(f->array[0]->string, "<") == 0) {
|
||||
if (f->array[0]->string == "<") {
|
||||
return cmp < 0;
|
||||
}
|
||||
if (strcmp(f->array[0]->string, "<=") == 0) {
|
||||
if (f->array[0]->string == "<=") {
|
||||
return cmp <= 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Internal error: can't happen: %s\n", json_stringify(f));
|
||||
fprintf(stderr, "Internal error: can't happen: %s\n", json_stringify(f).c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (strcmp(f->array[0]->string, "all") == 0 ||
|
||||
strcmp(f->array[0]->string, "any") == 0 ||
|
||||
strcmp(f->array[0]->string, "none") == 0) {
|
||||
if (f->array[0]->string == "all" ||
|
||||
f->array[0]->string == "any" ||
|
||||
f->array[0]->string == "none") {
|
||||
bool v;
|
||||
|
||||
if (strcmp(f->array[0]->string, "all") == 0) {
|
||||
if (f->array[0]->string == "all") {
|
||||
v = true;
|
||||
} else {
|
||||
v = false;
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < f->length; i++) {
|
||||
for (size_t i = 1; i < f->array.size(); i++) {
|
||||
bool out = eval(feature, f->array[i]);
|
||||
|
||||
if (strcmp(f->array[0]->string, "all") == 0) {
|
||||
if (f->array[0]->string == "all") {
|
||||
v = v && out;
|
||||
if (!v) {
|
||||
break;
|
||||
@ -206,22 +204,22 @@ bool eval(std::map<std::string, mvt_value> const &feature, json_object *f) {
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(f->array[0]->string, "none") == 0) {
|
||||
if (f->array[0]->string == "none") {
|
||||
return !v;
|
||||
} else {
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(f->array[0]->string, "in") == 0 ||
|
||||
strcmp(f->array[0]->string, "!in") == 0) {
|
||||
if (f->length < 2) {
|
||||
fprintf(stderr, "Array too small in filter: %s\n", json_stringify(f));
|
||||
if (f->array[0]->string == "in" ||
|
||||
f->array[0]->string == "!in") {
|
||||
if (f->array.size() < 2) {
|
||||
fprintf(stderr, "Array too small in filter: %s\n", json_stringify(f).c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (f->array[1]->type != JSON_STRING) {
|
||||
fprintf(stderr, "\"!has\" key is not a string: %s\n", json_stringify(f));
|
||||
fprintf(stderr, "\"!has\" key is not a string: %s\n", json_stringify(f).c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@ -229,28 +227,26 @@ bool eval(std::map<std::string, mvt_value> const &feature, json_object *f) {
|
||||
if (ff == feature.end()) {
|
||||
static bool warned = false;
|
||||
if (!warned) {
|
||||
const char *s = json_stringify(f);
|
||||
fprintf(stderr, "Warning: attribute not found for comparison: %s\n", s);
|
||||
free((void *) s);
|
||||
std::string s = json_stringify(f);
|
||||
fprintf(stderr, "Warning: attribute not found for comparison: %s\n", s.c_str());
|
||||
warned = true;
|
||||
}
|
||||
if (strcmp(f->array[0]->string, "!in") == 0) {
|
||||
if (f->array[0]->string == "!in") {
|
||||
return true; // attributes that aren't found are not in
|
||||
}
|
||||
return false; // not found: comparison is false
|
||||
}
|
||||
|
||||
bool found = false;
|
||||
for (size_t i = 2; i < f->length; i++) {
|
||||
for (size_t i = 2; i < f->array.size(); i++) {
|
||||
bool fail = false;
|
||||
int cmp = compare(ff->second, f->array[i], fail);
|
||||
|
||||
if (fail) {
|
||||
static bool warned = false;
|
||||
if (!warned) {
|
||||
const char *s = json_stringify(f);
|
||||
fprintf(stderr, "Warning: mismatched type in comparison: %s\n", s);
|
||||
free((void *) s);
|
||||
std::string s = json_stringify(f);
|
||||
fprintf(stderr, "Warning: mismatched type in comparison: %s\n", s.c_str());
|
||||
warned = true;
|
||||
}
|
||||
cmp = 1;
|
||||
@ -262,20 +258,20 @@ bool eval(std::map<std::string, mvt_value> const &feature, json_object *f) {
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(f->array[0]->string, "in") == 0) {
|
||||
if (f->array[0]->string == "in") {
|
||||
return found;
|
||||
} else {
|
||||
return !found;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "Unknown filter %s\n", json_stringify(f));
|
||||
fprintf(stderr, "Unknown filter %s\n", json_stringify(f).c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
bool evaluate(std::map<std::string, mvt_value> const &feature, std::string const &layer, json_object *filter) {
|
||||
if (filter == NULL || filter->type != JSON_HASH) {
|
||||
fprintf(stderr, "Error: filter is not a hash: %s\n", json_stringify(filter));
|
||||
fprintf(stderr, "Error: filter is not a hash: %s\n", json_stringify(filter).c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
@ -305,7 +301,7 @@ json_object *read_filter(const char *fname) {
|
||||
json_pull *jp = json_begin_file(fp);
|
||||
json_object *filter = json_read_tree(jp);
|
||||
if (filter == NULL) {
|
||||
fprintf(stderr, "%s: %s\n", fname, jp->error);
|
||||
fprintf(stderr, "%s: %s\n", fname, jp->error.c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
json_disconnect(filter);
|
||||
@ -319,7 +315,7 @@ json_object *parse_filter(const char *s) {
|
||||
json_object *filter = json_read_tree(jp);
|
||||
if (filter == NULL) {
|
||||
fprintf(stderr, "Could not parse filter %s\n", s);
|
||||
fprintf(stderr, "%s\n", jp->error);
|
||||
fprintf(stderr, "%s\n", jp->error.c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
json_disconnect(filter);
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "jsonpull/jsonpull.h"
|
||||
#include "jsonpull/jsonpull.hpp"
|
||||
#include "mvt.hpp"
|
||||
|
||||
bool evaluate(std::map<std::string, mvt_value> const &feature, std::string const &layer, json_object *filter);
|
||||
|
@ -12,7 +12,7 @@
|
||||
#include "protozero/pbf_reader.hpp"
|
||||
#include "protozero/pbf_writer.hpp"
|
||||
#include "milo/dtoa_milo.h"
|
||||
#include "jsonpull/jsonpull.h"
|
||||
#include "jsonpull/jsonpull.hpp"
|
||||
|
||||
#define POINT 0
|
||||
#define MULTIPOINT 1
|
||||
@ -397,13 +397,13 @@ void readFeature(protozero::pbf_reader &pbf, size_t dim, double e, std::vector<s
|
||||
json_object *min = json_hash_get(o, "minzoom");
|
||||
if (min != NULL && (min->type == JSON_STRING || min->type == JSON_NUMBER)) {
|
||||
sf.has_tippecanoe_minzoom = true;
|
||||
sf.tippecanoe_minzoom = atoi(min->string);
|
||||
sf.tippecanoe_minzoom = atoi(min->string.c_str());
|
||||
}
|
||||
|
||||
json_object *max = json_hash_get(o, "maxzoom");
|
||||
if (max != NULL && (max->type == JSON_STRING || max->type == JSON_NUMBER)) {
|
||||
sf.has_tippecanoe_maxzoom = true;
|
||||
sf.tippecanoe_maxzoom = atoi(max->string);
|
||||
sf.tippecanoe_maxzoom = atoi(max->string.c_str());
|
||||
}
|
||||
|
||||
json_object *tlayer = json_hash_get(o, "layer");
|
||||
|
51
geojson.cpp
51
geojson.cpp
@ -24,7 +24,7 @@
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "jsonpull/jsonpull.h"
|
||||
#include "jsonpull/jsonpull.hpp"
|
||||
#include "pool.hpp"
|
||||
#include "projection.hpp"
|
||||
#include "memfile.hpp"
|
||||
@ -66,12 +66,12 @@ int serialize_geojson_feature(struct serialization_state *sst, json_object *geom
|
||||
|
||||
int t;
|
||||
for (t = 0; t < GEOM_TYPES; t++) {
|
||||
if (strcmp(geometry_type->string, geometry_names[t]) == 0) {
|
||||
if (geometry_type->string == std::string(geometry_names[t])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (t >= GEOM_TYPES) {
|
||||
fprintf(stderr, "%s:%d: Can't handle geometry type %s\n", sst->fname, sst->line, geometry_type->string);
|
||||
fprintf(stderr, "%s:%d: Can't handle geometry type %s\n", sst->fname, sst->line, geometry_type->string.c_str());
|
||||
json_context(feature);
|
||||
return 0;
|
||||
}
|
||||
@ -86,7 +86,7 @@ int serialize_geojson_feature(struct serialization_state *sst, json_object *geom
|
||||
tippecanoe_minzoom = min->number;
|
||||
}
|
||||
if (min != NULL && min->type == JSON_STRING) {
|
||||
tippecanoe_minzoom = atoi(min->string);
|
||||
tippecanoe_minzoom = atoi(min->string.c_str());
|
||||
}
|
||||
|
||||
json_object *max = json_hash_get(tippecanoe, "maxzoom");
|
||||
@ -94,7 +94,7 @@ int serialize_geojson_feature(struct serialization_state *sst, json_object *geom
|
||||
tippecanoe_maxzoom = max->number;
|
||||
}
|
||||
if (max != NULL && max->type == JSON_STRING) {
|
||||
tippecanoe_maxzoom = atoi(max->string);
|
||||
tippecanoe_maxzoom = atoi(max->string.c_str());
|
||||
}
|
||||
|
||||
json_object *ln = json_hash_get(tippecanoe, "layer");
|
||||
@ -109,13 +109,13 @@ int serialize_geojson_feature(struct serialization_state *sst, json_object *geom
|
||||
if (id->type == JSON_NUMBER) {
|
||||
if (id->number >= 0) {
|
||||
char *err = NULL;
|
||||
id_value = strtoull(id->string, &err, 10);
|
||||
id_value = strtoull(id->string.c_str(), &err, 10);
|
||||
|
||||
if (err != NULL && *err != '\0') {
|
||||
static bool warned_frac = false;
|
||||
|
||||
if (!warned_frac) {
|
||||
fprintf(stderr, "Warning: Can't represent non-integer feature ID %s\n", id->string);
|
||||
fprintf(stderr, "Warning: Can't represent non-integer feature ID %s\n", id->string.c_str());
|
||||
warned_frac = true;
|
||||
}
|
||||
} else {
|
||||
@ -125,7 +125,7 @@ int serialize_geojson_feature(struct serialization_state *sst, json_object *geom
|
||||
static bool warned_neg = false;
|
||||
|
||||
if (!warned_neg) {
|
||||
fprintf(stderr, "Warning: Can't represent negative feature ID %s\n", id->string);
|
||||
fprintf(stderr, "Warning: Can't represent negative feature ID %s\n", id->string.c_str());
|
||||
warned_neg = true;
|
||||
}
|
||||
}
|
||||
@ -133,9 +133,8 @@ int serialize_geojson_feature(struct serialization_state *sst, json_object *geom
|
||||
static bool warned_nan = false;
|
||||
|
||||
if (!warned_nan) {
|
||||
char *s = json_stringify(id);
|
||||
fprintf(stderr, "Warning: Can't represent non-numeric feature ID %s\n", s);
|
||||
free(s); // stringify
|
||||
std::string s = json_stringify(id);
|
||||
fprintf(stderr, "Warning: Can't represent non-numeric feature ID %s\n", s.c_str());
|
||||
warned_nan = true;
|
||||
}
|
||||
}
|
||||
@ -143,10 +142,10 @@ int serialize_geojson_feature(struct serialization_state *sst, json_object *geom
|
||||
|
||||
size_t nprop = 0;
|
||||
if (properties != NULL && properties->type == JSON_HASH) {
|
||||
nprop = properties->length;
|
||||
nprop = properties->keys.size();
|
||||
}
|
||||
|
||||
std::vector<char *> metakey;
|
||||
std::vector<std::string> metakey;
|
||||
metakey.resize(nprop);
|
||||
|
||||
std::vector<std::string> metaval;
|
||||
@ -222,9 +221,9 @@ void check_crs(json_object *j, const char *reading) {
|
||||
if (properties != NULL) {
|
||||
json_object *name = json_hash_get(properties, "name");
|
||||
if (name->type == JSON_STRING) {
|
||||
if (strcmp(name->string, projection->alias) != 0) {
|
||||
if (name->string != std::string(projection->alias)) {
|
||||
if (!quiet) {
|
||||
fprintf(stderr, "%s: Warning: GeoJSON specified projection \"%s\", not the expected \"%s\".\n", reading, name->string, projection->alias);
|
||||
fprintf(stderr, "%s: Warning: GeoJSON specified projection \"%s\", not the expected \"%s\".\n", reading, name->string.c_str(), projection->alias);
|
||||
fprintf(stderr, "%s: If \"%s\" is not the expected projection, use -s to specify the right one.\n", reading, projection->alias);
|
||||
}
|
||||
}
|
||||
@ -241,8 +240,8 @@ void parse_json(struct serialization_state *sst, json_pull *jp, int layer, std::
|
||||
while (1) {
|
||||
json_object *j = json_read(jp);
|
||||
if (j == NULL) {
|
||||
if (jp->error != NULL) {
|
||||
fprintf(stderr, "%s:%d: %s\n", sst->fname, jp->line, jp->error);
|
||||
if (jp->error.size() != 0) {
|
||||
fprintf(stderr, "%s:%zu: %s\n", sst->fname, jp->line, jp->error.c_str());
|
||||
if (jp->root != NULL) {
|
||||
json_context(jp->root);
|
||||
}
|
||||
@ -256,7 +255,7 @@ void parse_json(struct serialization_state *sst, json_pull *jp, int layer, std::
|
||||
found_hashes++;
|
||||
|
||||
if (found_hashes == 50 && found_features == 0 && found_geometries == 0) {
|
||||
fprintf(stderr, "%s:%d: Warning: not finding any GeoJSON features or geometries in input yet after 50 objects.\n", sst->fname, jp->line);
|
||||
fprintf(stderr, "%s:%zu: Warning: not finding any GeoJSON features or geometries in input yet after 50 objects.\n", sst->fname, jp->line);
|
||||
}
|
||||
}
|
||||
|
||||
@ -269,7 +268,7 @@ void parse_json(struct serialization_state *sst, json_pull *jp, int layer, std::
|
||||
int i;
|
||||
int is_geometry = 0;
|
||||
for (i = 0; i < GEOM_TYPES; i++) {
|
||||
if (strcmp(type->string, geometry_names[i]) == 0) {
|
||||
if (type->string == std::string(geometry_names[i])) {
|
||||
is_geometry = 1;
|
||||
break;
|
||||
}
|
||||
@ -297,7 +296,7 @@ void parse_json(struct serialization_state *sst, json_pull *jp, int layer, std::
|
||||
|
||||
if (is_geometry) {
|
||||
if (found_features != 0 && found_geometries == 0) {
|
||||
fprintf(stderr, "%s:%d: Warning: found a mixture of features and bare geometries\n", sst->fname, jp->line);
|
||||
fprintf(stderr, "%s:%zu: Warning: found a mixture of features and bare geometries\n", sst->fname, jp->line);
|
||||
}
|
||||
found_geometries++;
|
||||
|
||||
@ -307,8 +306,8 @@ void parse_json(struct serialization_state *sst, json_pull *jp, int layer, std::
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(type->string, "Feature") != 0) {
|
||||
if (strcmp(type->string, "FeatureCollection") == 0) {
|
||||
if (type->string != std::string("Feature")) {
|
||||
if (type->string == std::string("FeatureCollection")) {
|
||||
check_crs(j, sst->fname);
|
||||
json_free(j);
|
||||
}
|
||||
@ -317,13 +316,13 @@ void parse_json(struct serialization_state *sst, json_pull *jp, int layer, std::
|
||||
}
|
||||
|
||||
if (found_features == 0 && found_geometries != 0) {
|
||||
fprintf(stderr, "%s:%d: Warning: found a mixture of features and bare geometries\n", sst->fname, jp->line);
|
||||
fprintf(stderr, "%s:%zu: Warning: found a mixture of features and bare geometries\n", sst->fname, jp->line);
|
||||
}
|
||||
found_features++;
|
||||
|
||||
json_object *geometry = json_hash_get(j, "geometry");
|
||||
if (geometry == NULL) {
|
||||
fprintf(stderr, "%s:%d: feature with no geometry\n", sst->fname, jp->line);
|
||||
fprintf(stderr, "%s:%zu: feature with no geometry\n", sst->fname, jp->line);
|
||||
json_context(j);
|
||||
json_free(j);
|
||||
continue;
|
||||
@ -331,7 +330,7 @@ void parse_json(struct serialization_state *sst, json_pull *jp, int layer, std::
|
||||
|
||||
json_object *properties = json_hash_get(j, "properties");
|
||||
if (properties == NULL || (properties->type != JSON_HASH && properties->type != JSON_NULL)) {
|
||||
fprintf(stderr, "%s:%d: feature without properties hash\n", sst->fname, jp->line);
|
||||
fprintf(stderr, "%s:%zu: feature without properties hash\n", sst->fname, jp->line);
|
||||
json_context(j);
|
||||
json_free(j);
|
||||
continue;
|
||||
@ -343,7 +342,7 @@ void parse_json(struct serialization_state *sst, json_pull *jp, int layer, std::
|
||||
json_object *geometries = json_hash_get(geometry, "geometries");
|
||||
if (geometries != NULL && geometries->type == JSON_ARRAY) {
|
||||
size_t g;
|
||||
for (g = 0; g < geometries->length; g++) {
|
||||
for (g = 0; g < geometries->array.size(); g++) {
|
||||
serialize_geojson_feature(sst, geometries->array[g], properties, id, layer, tippecanoe, j, layername);
|
||||
}
|
||||
} else {
|
||||
|
@ -6,7 +6,7 @@
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include "mbtiles.hpp"
|
||||
#include "jsonpull/jsonpull.h"
|
||||
#include "jsonpull/jsonpull.hpp"
|
||||
#include "serial.hpp"
|
||||
|
||||
struct parse_json_args {
|
||||
|
@ -4,18 +4,18 @@
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include "jsonpull.h"
|
||||
#include "jsonpull.hpp"
|
||||
|
||||
#define BUFFER 10000
|
||||
|
||||
json_pull *json_begin(ssize_t (*read)(struct json_pull *, char *buffer, size_t n), void *source) {
|
||||
json_pull *j = malloc(sizeof(json_pull));
|
||||
json_pull *j = new json_pull;
|
||||
if (j == NULL) {
|
||||
perror("Out of memory");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
j->error = NULL;
|
||||
j->error = "";
|
||||
j->line = 1;
|
||||
j->container = NULL;
|
||||
j->root = NULL;
|
||||
@ -25,11 +25,7 @@ json_pull *json_begin(ssize_t (*read)(struct json_pull *, char *buffer, size_t n
|
||||
j->buffer_head = 0;
|
||||
j->buffer_tail = 0;
|
||||
|
||||
j->buffer = malloc(BUFFER);
|
||||
if (j->buffer == NULL) {
|
||||
perror("Out of memory");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
j->buffer.resize(BUFFER);
|
||||
|
||||
return j;
|
||||
}
|
||||
@ -39,7 +35,7 @@ static inline int peek(json_pull *j) {
|
||||
return (unsigned char) j->buffer[j->buffer_head];
|
||||
} else {
|
||||
j->buffer_head = 0;
|
||||
j->buffer_tail = j->read(j, j->buffer, BUFFER);
|
||||
j->buffer_tail = j->read(j, (char *) j->buffer.c_str(), BUFFER);
|
||||
if (j->buffer_head >= j->buffer_tail) {
|
||||
return EOF;
|
||||
}
|
||||
@ -52,7 +48,7 @@ static inline int next(json_pull *j) {
|
||||
return (unsigned char) j->buffer[j->buffer_head++];
|
||||
} else {
|
||||
j->buffer_head = 0;
|
||||
j->buffer_tail = j->read(j, j->buffer, BUFFER);
|
||||
j->buffer_tail = j->read(j, (char *) j->buffer.c_str(), BUFFER);
|
||||
if (j->buffer_head >= j->buffer_tail) {
|
||||
return EOF;
|
||||
}
|
||||
@ -61,7 +57,7 @@ static inline int next(json_pull *j) {
|
||||
}
|
||||
|
||||
static ssize_t read_file(json_pull *j, char *buffer, size_t n) {
|
||||
return fread(buffer, 1, n, j->source);
|
||||
return fread(buffer, 1, n, (FILE *) j->source);
|
||||
}
|
||||
|
||||
json_pull *json_begin_file(FILE *f) {
|
||||
@ -69,7 +65,7 @@ json_pull *json_begin_file(FILE *f) {
|
||||
}
|
||||
|
||||
static ssize_t read_string(json_pull *j, char *buffer, size_t n) {
|
||||
const char *cp = j->source;
|
||||
const char *cp = (const char *) j->source;
|
||||
size_t out = 0;
|
||||
|
||||
while (out < n && cp[out] != '\0') {
|
||||
@ -87,8 +83,7 @@ json_pull *json_begin_string(const char *s) {
|
||||
|
||||
void json_end(json_pull *p) {
|
||||
json_free(p->root);
|
||||
free(p->buffer);
|
||||
free(p);
|
||||
delete p;
|
||||
}
|
||||
|
||||
static inline int read_wrap(json_pull *j) {
|
||||
@ -101,20 +96,14 @@ static inline int read_wrap(json_pull *j) {
|
||||
return c;
|
||||
}
|
||||
|
||||
#define SIZE_FOR(i, size) ((size_t)((((i) + 31) & ~31) * size))
|
||||
|
||||
static json_object *fabricate_object(json_pull *jp, json_object *parent, json_type type) {
|
||||
json_object *o = malloc(sizeof(struct json_object));
|
||||
json_object *o = new json_object;
|
||||
if (o == NULL) {
|
||||
perror("Out of memory");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
o->type = type;
|
||||
o->parent = parent;
|
||||
o->array = NULL;
|
||||
o->keys = NULL;
|
||||
o->values = NULL;
|
||||
o->length = 0;
|
||||
o->parser = jp;
|
||||
return o;
|
||||
}
|
||||
@ -126,56 +115,30 @@ static json_object *add_object(json_pull *j, json_type type) {
|
||||
if (c != NULL) {
|
||||
if (c->type == JSON_ARRAY) {
|
||||
if (c->expect == JSON_ITEM) {
|
||||
if (SIZE_FOR(c->length + 1, sizeof(json_object *)) != SIZE_FOR(c->length, sizeof(json_object *))) {
|
||||
if (SIZE_FOR(c->length + 1, sizeof(json_object *)) < SIZE_FOR(c->length, sizeof(json_object *))) {
|
||||
fprintf(stderr, "Array size overflow\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
c->array = realloc(c->array, SIZE_FOR(c->length + 1, sizeof(json_object *)));
|
||||
if (c->array == NULL) {
|
||||
perror("Out of memory");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
c->array[c->length++] = o;
|
||||
c->array.push_back(o);
|
||||
c->expect = JSON_COMMA;
|
||||
} else {
|
||||
j->error = "Expected a comma, not a list item";
|
||||
free(o);
|
||||
delete o;
|
||||
return NULL;
|
||||
}
|
||||
} else if (c->type == JSON_HASH) {
|
||||
if (c->expect == JSON_VALUE) {
|
||||
c->values[c->length - 1] = o;
|
||||
c->values[c->values.size() - 1] = o;
|
||||
c->expect = JSON_COMMA;
|
||||
} else if (c->expect == JSON_KEY) {
|
||||
if (type != JSON_STRING) {
|
||||
j->error = "Hash key is not a string";
|
||||
free(o);
|
||||
delete o;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (SIZE_FOR(c->length + 1, sizeof(json_object *)) != SIZE_FOR(c->length, sizeof(json_object *))) {
|
||||
if (SIZE_FOR(c->length + 1, sizeof(json_object *)) < SIZE_FOR(c->length, sizeof(json_object *))) {
|
||||
fprintf(stderr, "Hash size overflow\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
c->keys = realloc(c->keys, SIZE_FOR(c->length + 1, sizeof(json_object *)));
|
||||
c->values = realloc(c->values, SIZE_FOR(c->length + 1, sizeof(json_object *)));
|
||||
if (c->keys == NULL || c->values == NULL) {
|
||||
perror("Out of memory");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
c->keys[c->length] = o;
|
||||
c->values[c->length] = NULL;
|
||||
c->length++;
|
||||
c->keys.push_back(o);
|
||||
c->values.push_back(NULL);
|
||||
c->expect = JSON_COLON;
|
||||
} else {
|
||||
j->error = "Expected a comma or colon";
|
||||
free(o);
|
||||
delete o;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -190,15 +153,15 @@ static json_object *add_object(json_pull *j, json_type type) {
|
||||
return o;
|
||||
}
|
||||
|
||||
json_object *json_hash_get(json_object *o, const char *s) {
|
||||
json_object *json_hash_get(json_object *o, std::string const &s) {
|
||||
if (o == NULL || o->type != JSON_HASH) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < o->length; i++) {
|
||||
for (i = 0; i < o->keys.size(); i++) {
|
||||
if (o->keys[i] != NULL && o->keys[i]->type == JSON_STRING) {
|
||||
if (strcmp(o->keys[i]->string, s) == 0) {
|
||||
if (o->keys[i]->string == s) {
|
||||
return o->values[i];
|
||||
}
|
||||
}
|
||||
@ -207,70 +170,6 @@ json_object *json_hash_get(json_object *o, const char *s) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct string {
|
||||
char *buf;
|
||||
size_t n;
|
||||
size_t nalloc;
|
||||
};
|
||||
|
||||
static void string_init(struct string *s) {
|
||||
s->nalloc = 500;
|
||||
s->buf = malloc(s->nalloc);
|
||||
if (s->buf == NULL) {
|
||||
perror("Out of memory");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
s->n = 0;
|
||||
s->buf[0] = '\0';
|
||||
}
|
||||
|
||||
static void string_append(struct string *s, char c) {
|
||||
if (s->n + 2 >= s->nalloc) {
|
||||
size_t prev = s->nalloc;
|
||||
s->nalloc += 500;
|
||||
if (s->nalloc <= prev) {
|
||||
fprintf(stderr, "String size overflowed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
s->buf = realloc(s->buf, s->nalloc);
|
||||
if (s->buf == NULL) {
|
||||
perror("Out of memory");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
s->buf[s->n++] = c;
|
||||
s->buf[s->n] = '\0';
|
||||
}
|
||||
|
||||
static void string_append_string(struct string *s, char *add) {
|
||||
size_t len = strlen(add);
|
||||
|
||||
if (s->n + len + 1 >= s->nalloc) {
|
||||
size_t prev = s->nalloc;
|
||||
s->nalloc += 500 + len;
|
||||
if (s->nalloc <= prev) {
|
||||
fprintf(stderr, "String size overflowed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
s->buf = realloc(s->buf, s->nalloc);
|
||||
if (s->buf == NULL) {
|
||||
perror("Out of memory");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
for (; *add != '\0'; add++) {
|
||||
s->buf[s->n++] = *add;
|
||||
}
|
||||
|
||||
s->buf[s->n] = '\0';
|
||||
}
|
||||
|
||||
static void string_free(struct string *s) {
|
||||
free(s->buf);
|
||||
}
|
||||
|
||||
json_object *json_read_separators(json_pull *j, json_separator_callback cb, void *state) {
|
||||
int c;
|
||||
|
||||
@ -340,7 +239,7 @@ again:
|
||||
}
|
||||
|
||||
if (j->container->expect != JSON_COMMA) {
|
||||
if (!(j->container->expect == JSON_ITEM && j->container->length == 0)) {
|
||||
if (!(j->container->expect == JSON_ITEM && j->container->array.size() == 0)) {
|
||||
j->error = "Found ] without final element";
|
||||
return NULL;
|
||||
}
|
||||
@ -378,7 +277,7 @@ again:
|
||||
}
|
||||
|
||||
if (j->container->expect != JSON_COMMA) {
|
||||
if (!(j->container->expect == JSON_KEY && j->container->length == 0)) {
|
||||
if (!(j->container->expect == JSON_KEY && j->container->keys.size() == 0)) {
|
||||
j->error = "Found } without final element";
|
||||
return NULL;
|
||||
}
|
||||
@ -496,69 +395,63 @@ again:
|
||||
/////////////////////////// Numbers
|
||||
|
||||
if (c == '-' || (c >= '0' && c <= '9')) {
|
||||
struct string val;
|
||||
string_init(&val);
|
||||
std::string val;
|
||||
|
||||
if (c == '-') {
|
||||
string_append(&val, c);
|
||||
val.push_back(c);
|
||||
c = read_wrap(j);
|
||||
}
|
||||
|
||||
if (c == '0') {
|
||||
string_append(&val, c);
|
||||
val.push_back(c);
|
||||
} else if (c >= '1' && c <= '9') {
|
||||
string_append(&val, c);
|
||||
val.push_back(c);
|
||||
c = peek(j);
|
||||
|
||||
while (c >= '0' && c <= '9') {
|
||||
string_append(&val, read_wrap(j));
|
||||
val.push_back(read_wrap(j));
|
||||
c = peek(j);
|
||||
}
|
||||
}
|
||||
|
||||
if (peek(j) == '.') {
|
||||
string_append(&val, read_wrap(j));
|
||||
val.push_back(read_wrap(j));
|
||||
|
||||
c = peek(j);
|
||||
if (c < '0' || c > '9') {
|
||||
j->error = "Decimal point without digits";
|
||||
string_free(&val);
|
||||
return NULL;
|
||||
}
|
||||
while (c >= '0' && c <= '9') {
|
||||
string_append(&val, read_wrap(j));
|
||||
val.push_back(read_wrap(j));
|
||||
c = peek(j);
|
||||
}
|
||||
}
|
||||
|
||||
c = peek(j);
|
||||
if (c == 'e' || c == 'E') {
|
||||
string_append(&val, read_wrap(j));
|
||||
val.push_back(read_wrap(j));
|
||||
|
||||
c = peek(j);
|
||||
if (c == '+' || c == '-') {
|
||||
string_append(&val, read_wrap(j));
|
||||
val.push_back(read_wrap(j));
|
||||
}
|
||||
|
||||
c = peek(j);
|
||||
if (c < '0' || c > '9') {
|
||||
j->error = "Exponent without digits";
|
||||
string_free(&val);
|
||||
return NULL;
|
||||
}
|
||||
while (c >= '0' && c <= '9') {
|
||||
string_append(&val, read_wrap(j));
|
||||
val.push_back(read_wrap(j));
|
||||
c = peek(j);
|
||||
}
|
||||
}
|
||||
|
||||
json_object *n = add_object(j, JSON_NUMBER);
|
||||
if (n != NULL) {
|
||||
n->number = atof(val.buf);
|
||||
n->string = val.buf;
|
||||
n->length = val.n;
|
||||
} else {
|
||||
string_free(&val);
|
||||
n->number = atof(val.c_str());
|
||||
n->string = val;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
@ -566,16 +459,15 @@ again:
|
||||
/////////////////////////// Strings
|
||||
|
||||
if (c == '"') {
|
||||
struct string val;
|
||||
string_init(&val);
|
||||
std::string val;
|
||||
|
||||
int surrogate = -1;
|
||||
while ((c = read_wrap(j)) != EOF) {
|
||||
if (c == '"') {
|
||||
if (surrogate >= 0) {
|
||||
string_append(&val, 0xE0 | (surrogate >> 12));
|
||||
string_append(&val, 0x80 | ((surrogate >> 6) & 0x3F));
|
||||
string_append(&val, 0x80 | (surrogate & 0x3F));
|
||||
val.push_back(0xE0 | (surrogate >> 12));
|
||||
val.push_back(0x80 | ((surrogate >> 6) & 0x3F));
|
||||
val.push_back(0x80 | (surrogate & 0x3F));
|
||||
surrogate = -1;
|
||||
}
|
||||
|
||||
@ -590,7 +482,6 @@ again:
|
||||
hex[i] = read_wrap(j);
|
||||
if (hex[i] < '0' || (hex[i] > '9' && hex[i] < 'A') || (hex[i] > 'F' && hex[i] < 'a') || hex[i] > 'f') {
|
||||
j->error = "Invalid \\u hex character";
|
||||
string_free(&val);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
@ -602,9 +493,9 @@ again:
|
||||
} else {
|
||||
// Impossible surrogate, so output the first half,
|
||||
// keep what might be a legitimate new first half.
|
||||
string_append(&val, 0xE0 | (surrogate >> 12));
|
||||
string_append(&val, 0x80 | ((surrogate >> 6) & 0x3F));
|
||||
string_append(&val, 0x80 | (surrogate & 0x3F));
|
||||
val.push_back(0xE0 | (surrogate >> 12));
|
||||
val.push_back(0x80 | ((surrogate >> 6) & 0x3F));
|
||||
val.push_back(0x80 | (surrogate & 0x3F));
|
||||
surrogate = ch;
|
||||
}
|
||||
continue;
|
||||
@ -618,84 +509,78 @@ again:
|
||||
}
|
||||
|
||||
if (surrogate >= 0) {
|
||||
string_append(&val, 0xE0 | (surrogate >> 12));
|
||||
string_append(&val, 0x80 | ((surrogate >> 6) & 0x3F));
|
||||
string_append(&val, 0x80 | (surrogate & 0x3F));
|
||||
val.push_back(0xE0 | (surrogate >> 12));
|
||||
val.push_back(0x80 | ((surrogate >> 6) & 0x3F));
|
||||
val.push_back(0x80 | (surrogate & 0x3F));
|
||||
surrogate = -1;
|
||||
}
|
||||
|
||||
if (ch <= 0x7F) {
|
||||
string_append(&val, ch);
|
||||
val.push_back(ch);
|
||||
} else if (ch <= 0x7FF) {
|
||||
string_append(&val, 0xC0 | (ch >> 6));
|
||||
string_append(&val, 0x80 | (ch & 0x3F));
|
||||
val.push_back(0xC0 | (ch >> 6));
|
||||
val.push_back(0x80 | (ch & 0x3F));
|
||||
} else if (ch < 0xFFFF) {
|
||||
string_append(&val, 0xE0 | (ch >> 12));
|
||||
string_append(&val, 0x80 | ((ch >> 6) & 0x3F));
|
||||
string_append(&val, 0x80 | (ch & 0x3F));
|
||||
val.push_back(0xE0 | (ch >> 12));
|
||||
val.push_back(0x80 | ((ch >> 6) & 0x3F));
|
||||
val.push_back(0x80 | (ch & 0x3F));
|
||||
} else {
|
||||
string_append(&val, 0xF0 | (ch >> 18));
|
||||
string_append(&val, 0x80 | ((ch >> 12) & 0x3F));
|
||||
string_append(&val, 0x80 | ((ch >> 6) & 0x3F));
|
||||
string_append(&val, 0x80 | (ch & 0x3F));
|
||||
val.push_back(0xF0 | (ch >> 18));
|
||||
val.push_back(0x80 | ((ch >> 12) & 0x3F));
|
||||
val.push_back(0x80 | ((ch >> 6) & 0x3F));
|
||||
val.push_back(0x80 | (ch & 0x3F));
|
||||
}
|
||||
} else {
|
||||
if (surrogate >= 0) {
|
||||
string_append(&val, 0xE0 | (surrogate >> 12));
|
||||
string_append(&val, 0x80 | ((surrogate >> 6) & 0x3F));
|
||||
string_append(&val, 0x80 | (surrogate & 0x3F));
|
||||
val.push_back(0xE0 | (surrogate >> 12));
|
||||
val.push_back(0x80 | ((surrogate >> 6) & 0x3F));
|
||||
val.push_back(0x80 | (surrogate & 0x3F));
|
||||
surrogate = -1;
|
||||
}
|
||||
|
||||
if (c == '"') {
|
||||
string_append(&val, '"');
|
||||
val.push_back('"');
|
||||
} else if (c == '\\') {
|
||||
string_append(&val, '\\');
|
||||
val.push_back('\\');
|
||||
} else if (c == '/') {
|
||||
string_append(&val, '/');
|
||||
val.push_back('/');
|
||||
} else if (c == 'b') {
|
||||
string_append(&val, '\b');
|
||||
val.push_back('\b');
|
||||
} else if (c == 'f') {
|
||||
string_append(&val, '\f');
|
||||
val.push_back('\f');
|
||||
} else if (c == 'n') {
|
||||
string_append(&val, '\n');
|
||||
val.push_back('\n');
|
||||
} else if (c == 'r') {
|
||||
string_append(&val, '\r');
|
||||
val.push_back('\r');
|
||||
} else if (c == 't') {
|
||||
string_append(&val, '\t');
|
||||
val.push_back('\t');
|
||||
} else {
|
||||
j->error = "Found backslash followed by unknown character";
|
||||
string_free(&val);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
} else if (c < ' ') {
|
||||
j->error = "Found control character in string";
|
||||
string_free(&val);
|
||||
return NULL;
|
||||
} else {
|
||||
if (surrogate >= 0) {
|
||||
string_append(&val, 0xE0 | (surrogate >> 12));
|
||||
string_append(&val, 0x80 | ((surrogate >> 6) & 0x3F));
|
||||
string_append(&val, 0x80 | (surrogate & 0x3F));
|
||||
val.push_back(0xE0 | (surrogate >> 12));
|
||||
val.push_back(0x80 | ((surrogate >> 6) & 0x3F));
|
||||
val.push_back(0x80 | (surrogate & 0x3F));
|
||||
surrogate = -1;
|
||||
}
|
||||
|
||||
string_append(&val, c);
|
||||
val.push_back(c);
|
||||
}
|
||||
}
|
||||
if (c == EOF) {
|
||||
j->error = "String without closing quote mark";
|
||||
string_free(&val);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
json_object *s = add_object(j, JSON_STRING);
|
||||
if (s != NULL) {
|
||||
s->string = val.buf;
|
||||
s->length = val.n;
|
||||
} else {
|
||||
string_free(&val);
|
||||
s->string = val;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
@ -730,52 +615,43 @@ void json_free(json_object *o) {
|
||||
// Free any data linked from here
|
||||
|
||||
if (o->type == JSON_ARRAY) {
|
||||
json_object **a = o->array;
|
||||
size_t n = o->length;
|
||||
std::vector<json_object *> a = o->array;
|
||||
size_t n = o->array.size();
|
||||
|
||||
o->array = NULL;
|
||||
o->length = 0;
|
||||
o->array.resize(0);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
json_free(a[i]);
|
||||
}
|
||||
|
||||
free(a);
|
||||
} else if (o->type == JSON_HASH) {
|
||||
json_object **k = o->keys;
|
||||
json_object **v = o->values;
|
||||
size_t n = o->length;
|
||||
std::vector<json_object *> k = o->keys;
|
||||
std::vector<json_object *> v = o->values;
|
||||
size_t n = o->keys.size();
|
||||
|
||||
o->keys = NULL;
|
||||
o->values = NULL;
|
||||
o->length = 0;
|
||||
o->keys.resize(0);
|
||||
o->values.resize(0);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
json_free(k[i]);
|
||||
json_free(v[i]);
|
||||
}
|
||||
|
||||
free(k);
|
||||
free(v);
|
||||
} else if (o->type == JSON_STRING || o->type == JSON_NUMBER) {
|
||||
free(o->string);
|
||||
}
|
||||
|
||||
json_disconnect(o);
|
||||
|
||||
free(o);
|
||||
delete o;
|
||||
}
|
||||
|
||||
static void json_disconnect_parser(json_object *o) {
|
||||
if (o->type == JSON_HASH) {
|
||||
size_t i;
|
||||
for (i = 0; i < o->length; i++) {
|
||||
for (i = 0; i < o->keys.size(); i++) {
|
||||
json_disconnect_parser(o->keys[i]);
|
||||
json_disconnect_parser(o->values[i]);
|
||||
}
|
||||
} else if (o->type == JSON_ARRAY) {
|
||||
size_t i;
|
||||
for (i = 0; i < o->length; i++) {
|
||||
for (i = 0; i < o->array.size(); i++) {
|
||||
json_disconnect_parser(o->array[i]);
|
||||
}
|
||||
}
|
||||
@ -791,22 +667,21 @@ void json_disconnect(json_object *o) {
|
||||
if (o->parent->type == JSON_ARRAY) {
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < o->parent->length; i++) {
|
||||
for (i = 0; i < o->parent->array.size(); i++) {
|
||||
if (o->parent->array[i] == o) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < o->parent->length) {
|
||||
memmove(o->parent->array + i, o->parent->array + i + 1, o->parent->length - i - 1);
|
||||
o->parent->length--;
|
||||
if (i < o->parent->array.size()) {
|
||||
o->parent->array.erase(o->parent->array.begin() + i);
|
||||
}
|
||||
}
|
||||
|
||||
if (o->parent->type == JSON_HASH) {
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < o->parent->length; i++) {
|
||||
for (i = 0; i < o->parent->keys.size(); i++) {
|
||||
if (o->parent->keys[i] == o) {
|
||||
o->parent->keys[i] = fabricate_object(o->parser, o->parent, JSON_NULL);
|
||||
break;
|
||||
@ -817,15 +692,14 @@ void json_disconnect(json_object *o) {
|
||||
}
|
||||
}
|
||||
|
||||
if (i < o->parent->length) {
|
||||
if (i < o->parent->keys.size()) {
|
||||
if (o->parent->keys[i] != NULL && o->parent->keys[i]->type == JSON_NULL) {
|
||||
if (o->parent->values[i] != NULL && o->parent->values[i]->type == JSON_NULL) {
|
||||
free(o->parent->keys[i]);
|
||||
free(o->parent->values[i]);
|
||||
delete o->parent->keys[i];
|
||||
delete o->parent->values[i];
|
||||
|
||||
memmove(o->parent->keys + i, o->parent->keys + i + 1, o->parent->length - i - 1);
|
||||
memmove(o->parent->values + i, o->parent->values + i + 1, o->parent->length - i - 1);
|
||||
o->parent->length--;
|
||||
o->parent->keys.erase(o->parent->keys.begin() + i);
|
||||
o->parent->values.erase(o->parent->values.begin() + i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -840,80 +714,78 @@ void json_disconnect(json_object *o) {
|
||||
o->parent = NULL;
|
||||
}
|
||||
|
||||
static void json_print_one(struct string *val, json_object *o) {
|
||||
static void json_print_one(std::string &val, json_object *o) {
|
||||
if (o == NULL) {
|
||||
string_append_string(val, "...");
|
||||
val.append("...");
|
||||
} else if (o->type == JSON_STRING) {
|
||||
string_append(val, '\"');
|
||||
val.push_back('\"');
|
||||
|
||||
char *cp;
|
||||
for (cp = o->string; *cp != '\0'; cp++) {
|
||||
const char *cp;
|
||||
for (cp = o->string.c_str(); *cp != '\0'; cp++) {
|
||||
if (*cp == '\\' || *cp == '"') {
|
||||
string_append(val, '\\');
|
||||
string_append(val, *cp);
|
||||
val.push_back('\\');
|
||||
val.push_back(*cp);
|
||||
} else if (*cp >= 0 && *cp < ' ') {
|
||||
char *s;
|
||||
if (asprintf(&s, "\\u%04x", *cp) >= 0) {
|
||||
string_append_string(val, s);
|
||||
val.append(s);
|
||||
free(s);
|
||||
}
|
||||
} else {
|
||||
string_append(val, *cp);
|
||||
val.push_back(*cp);
|
||||
}
|
||||
}
|
||||
|
||||
string_append(val, '\"');
|
||||
val.push_back('\"');
|
||||
} else if (o->type == JSON_NUMBER) {
|
||||
string_append_string(val, o->string);
|
||||
val.append(o->string);
|
||||
} else if (o->type == JSON_NULL) {
|
||||
string_append_string(val, "null");
|
||||
val.append("null");
|
||||
} else if (o->type == JSON_TRUE) {
|
||||
string_append_string(val, "true");
|
||||
val.append("true");
|
||||
} else if (o->type == JSON_FALSE) {
|
||||
string_append_string(val, "false");
|
||||
val.append("false");
|
||||
} else if (o->type == JSON_HASH) {
|
||||
string_append(val, '}');
|
||||
val.push_back('}');
|
||||
} else if (o->type == JSON_ARRAY) {
|
||||
string_append(val, ']');
|
||||
val.push_back(']');
|
||||
}
|
||||
}
|
||||
|
||||
static void json_print(struct string *val, json_object *o) {
|
||||
static void json_print(std::string &val, json_object *o) {
|
||||
if (o == NULL) {
|
||||
// Hash value in incompletely read hash
|
||||
string_append_string(val, "...");
|
||||
val.append("...");
|
||||
} else if (o->type == JSON_HASH) {
|
||||
string_append(val, '{');
|
||||
val.push_back('{');
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < o->length; i++) {
|
||||
for (i = 0; i < o->keys.size(); i++) {
|
||||
json_print(val, o->keys[i]);
|
||||
string_append(val, ':');
|
||||
val.push_back(':');
|
||||
json_print(val, o->values[i]);
|
||||
if (i + 1 < o->length) {
|
||||
string_append(val, ',');
|
||||
if (i + 1 < o->keys.size()) {
|
||||
val.push_back(',');
|
||||
}
|
||||
}
|
||||
string_append(val, '}');
|
||||
val.push_back('}');
|
||||
} else if (o->type == JSON_ARRAY) {
|
||||
string_append(val, '[');
|
||||
val.push_back('[');
|
||||
size_t i;
|
||||
for (i = 0; i < o->length; i++) {
|
||||
for (i = 0; i < o->array.size(); i++) {
|
||||
json_print(val, o->array[i]);
|
||||
if (i + 1 < o->length) {
|
||||
string_append(val, ',');
|
||||
if (i + 1 < o->array.size()) {
|
||||
val.push_back(',');
|
||||
}
|
||||
}
|
||||
string_append(val, ']');
|
||||
val.push_back(']');
|
||||
} else {
|
||||
json_print_one(val, o);
|
||||
}
|
||||
}
|
||||
|
||||
char *json_stringify(json_object *o) {
|
||||
struct string val;
|
||||
string_init(&val);
|
||||
json_print(&val, o);
|
||||
|
||||
return val.buf;
|
||||
std::string json_stringify(json_object *o) {
|
||||
std::string val;
|
||||
json_print(val, o);
|
||||
return val;
|
||||
}
|
@ -1,9 +1,8 @@
|
||||
#ifndef JSONPULL_H
|
||||
#define JSONPULL_H
|
||||
#ifndef JSONPULL_HPP
|
||||
#define JSONPULL_HPP
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
typedef enum json_type {
|
||||
// These types can be returned by json_read()
|
||||
@ -25,29 +24,30 @@ typedef enum json_type {
|
||||
JSON_VALUE,
|
||||
} json_type;
|
||||
|
||||
typedef struct json_object {
|
||||
struct json_object;
|
||||
|
||||
struct json_object {
|
||||
json_type type;
|
||||
struct json_object *parent;
|
||||
struct json_pull *parser;
|
||||
|
||||
char *string;
|
||||
std::string string;
|
||||
double number;
|
||||
|
||||
struct json_object **array;
|
||||
struct json_object **keys;
|
||||
struct json_object **values;
|
||||
size_t length;
|
||||
std::vector<json_object *> array;
|
||||
std::vector<json_object *> keys;
|
||||
std::vector<json_object *> values;
|
||||
|
||||
int expect;
|
||||
} json_object;
|
||||
};
|
||||
|
||||
typedef struct json_pull {
|
||||
char *error;
|
||||
int line;
|
||||
std::string error;
|
||||
size_t line;
|
||||
|
||||
ssize_t (*read)(struct json_pull *, char *buf, size_t n);
|
||||
void *source;
|
||||
char *buffer;
|
||||
std::string buffer;
|
||||
ssize_t buffer_tail;
|
||||
ssize_t buffer_head;
|
||||
|
||||
@ -69,12 +69,8 @@ json_object *json_read_separators(json_pull *j, json_separator_callback cb, void
|
||||
void json_free(json_object *j);
|
||||
void json_disconnect(json_object *j);
|
||||
|
||||
json_object *json_hash_get(json_object *o, const char *s);
|
||||
json_object *json_hash_get(json_object *o, std::string const &key);
|
||||
|
||||
char *json_stringify(json_object *o);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
std::string json_stringify(json_object *o);
|
||||
|
||||
#endif
|
72
jsontool.cpp
72
jsontool.cpp
@ -7,7 +7,7 @@
|
||||
#include <string>
|
||||
#include <getopt.h>
|
||||
#include <vector>
|
||||
#include "jsonpull/jsonpull.h"
|
||||
#include "jsonpull/jsonpull.hpp"
|
||||
#include "csv.hpp"
|
||||
#include "text.hpp"
|
||||
|
||||
@ -145,14 +145,13 @@ void out(std::string const &s, int type, json_object *properties) {
|
||||
if (o != NULL) {
|
||||
found = true;
|
||||
if (o->type == JSON_STRING || o->type == JSON_NUMBER) {
|
||||
extracted = sort_quote(o->string);
|
||||
extracted = sort_quote(o->string.c_str());
|
||||
} else {
|
||||
// Don't really know what to do about sort quoting
|
||||
// for arbitrary objects
|
||||
|
||||
const char *out = json_stringify(o);
|
||||
extracted = sort_quote(out);
|
||||
free((void *) out);
|
||||
std::string out = json_stringify(o);
|
||||
extracted = sort_quote(out.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
@ -247,9 +246,8 @@ void join_csv(json_object *j) {
|
||||
if (key->type == JSON_STRING || key->type == JSON_NUMBER) {
|
||||
joinkey = key->string;
|
||||
} else {
|
||||
const char *s = json_stringify(key);
|
||||
std::string s = json_stringify(key);
|
||||
joinkey = s;
|
||||
free((void *) s);
|
||||
}
|
||||
|
||||
if (joinkey < prev_joinkey) {
|
||||
@ -300,12 +298,6 @@ void join_csv(json_object *j) {
|
||||
|
||||
if (fields.size() > 0 && joinkey == fields[0]) {
|
||||
// This knows more about the structure of JSON objects than it ought to
|
||||
properties->keys = (json_object **) realloc((void *) properties->keys, (properties->length + 32 + fields.size()) * sizeof(json_object *));
|
||||
properties->values = (json_object **) realloc((void *) properties->values, (properties->length + 32 + fields.size()) * sizeof(json_object *));
|
||||
if (properties->keys == NULL || properties->values == NULL) {
|
||||
perror("realloc");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (size_t i = 1; i < fields.size(); i++) {
|
||||
std::string k = header[i];
|
||||
@ -323,8 +315,8 @@ void join_csv(json_object *j) {
|
||||
{
|
||||
// This knows more about the structure of JSON objects than it ought to
|
||||
|
||||
json_object *ko = (json_object *) malloc(sizeof(json_object));
|
||||
json_object *vo = (json_object *) malloc(sizeof(json_object));
|
||||
json_object *ko = new json_object;
|
||||
json_object *vo = new json_object;
|
||||
if (ko == NULL || vo == NULL) {
|
||||
perror("malloc");
|
||||
exit(EXIT_FAILURE);
|
||||
@ -334,26 +326,14 @@ void join_csv(json_object *j) {
|
||||
vo->type = attr_type;
|
||||
|
||||
ko->parent = vo->parent = properties;
|
||||
ko->array = vo->array = NULL;
|
||||
ko->keys = vo->keys = NULL;
|
||||
ko->values = vo->values = NULL;
|
||||
ko->parser = vo->parser = properties->parser;
|
||||
|
||||
ko->string = strdup(k.c_str());
|
||||
vo->string = strdup(v.c_str());
|
||||
ko->string = k;
|
||||
vo->string = v;
|
||||
vo->number = atof(vo->string.c_str());
|
||||
|
||||
if (ko->string == NULL || vo->string == NULL) {
|
||||
perror("strdup");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ko->length = strlen(ko->string);
|
||||
vo->length = strlen(vo->string);
|
||||
vo->number = atof(vo->string);
|
||||
|
||||
properties->keys[properties->length] = ko;
|
||||
properties->values[properties->length] = vo;
|
||||
properties->length++;
|
||||
properties->keys.push_back(ko);
|
||||
properties->values.push_back(vo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -365,8 +345,8 @@ void process(FILE *fp, const char *fname) {
|
||||
while (1) {
|
||||
json_object *j = json_read(jp);
|
||||
if (j == NULL) {
|
||||
if (jp->error != NULL) {
|
||||
fprintf(stderr, "%s:%d: %s\n", fname, jp->line, jp->error);
|
||||
if (jp->error.size() != 0) {
|
||||
fprintf(stderr, "%s:%zu: %s\n", fname, jp->line, jp->error.c_str());
|
||||
}
|
||||
|
||||
json_free(jp->root);
|
||||
@ -378,20 +358,19 @@ void process(FILE *fp, const char *fname) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strcmp(type->string, "Feature") == 0) {
|
||||
if (type->string == "Feature") {
|
||||
if (csvfile != NULL) {
|
||||
join_csv(j);
|
||||
}
|
||||
|
||||
char *s = json_stringify(j);
|
||||
out(s, 1, json_hash_get(j, "properties"));
|
||||
free(s);
|
||||
std::string s = json_stringify(j);
|
||||
out(s.c_str(), 1, json_hash_get(j, "properties"));
|
||||
json_free(j);
|
||||
} else if (strcmp(type->string, "Point") == 0 ||
|
||||
strcmp(type->string, "MultiPoint") == 0 ||
|
||||
strcmp(type->string, "LineString") == 0 ||
|
||||
strcmp(type->string, "MultiLineString") == 0 ||
|
||||
strcmp(type->string, "MultiPolygon") == 0) {
|
||||
} else if (type->string == "Point" ||
|
||||
type->string == "MultiPoint" ||
|
||||
type->string == "LineString" ||
|
||||
type->string == "MultiLineString" ||
|
||||
type->string == "MultiPolygon") {
|
||||
int is_geometry = 1;
|
||||
|
||||
if (j->parent != NULL) {
|
||||
@ -413,12 +392,11 @@ void process(FILE *fp, const char *fname) {
|
||||
}
|
||||
|
||||
if (is_geometry) {
|
||||
char *s = json_stringify(j);
|
||||
out(s, 2, NULL);
|
||||
free(s);
|
||||
std::string s = json_stringify(j);
|
||||
out(s.c_str(), 2, NULL);
|
||||
json_free(j);
|
||||
}
|
||||
} else if (strcmp(type->string, "FeatureCollection") == 0) {
|
||||
} else if (type->string == "FeatureCollection") {
|
||||
json_free(j);
|
||||
}
|
||||
}
|
||||
|
4
main.cpp
4
main.cpp
@ -43,7 +43,7 @@
|
||||
#include <sys/statfs.h>
|
||||
#endif
|
||||
|
||||
#include "jsonpull/jsonpull.h"
|
||||
#include "jsonpull/jsonpull.hpp"
|
||||
#include "mbtiles.hpp"
|
||||
#include "tile.hpp"
|
||||
#include "pool.hpp"
|
||||
@ -2379,7 +2379,7 @@ void parse_json_source(const char *arg, struct source &src) {
|
||||
json_object *o = json_read_tree(jp);
|
||||
|
||||
if (o == NULL) {
|
||||
fprintf(stderr, "%s: -L%s: %s\n", *av, arg, jp->error);
|
||||
fprintf(stderr, "%s: -L%s: %s\n", *av, arg, jp->error.c_str());
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
50
plugin.cpp
50
plugin.cpp
@ -26,7 +26,7 @@
|
||||
#include "serial.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "jsonpull/jsonpull.h"
|
||||
#include "jsonpull/jsonpull.hpp"
|
||||
}
|
||||
|
||||
#include "plugin.hpp"
|
||||
@ -97,8 +97,8 @@ std::vector<mvt_layer> parse_layers(int fd, int z, unsigned x, unsigned y, std::
|
||||
while (1) {
|
||||
json_object *j = json_read(jp);
|
||||
if (j == NULL) {
|
||||
if (jp->error != NULL) {
|
||||
fprintf(stderr, "Filter output:%d: %s\n", jp->line, jp->error);
|
||||
if (jp->error.size() != 0) {
|
||||
fprintf(stderr, "Filter output:%zu: %s\n", jp->line, jp->error.c_str());
|
||||
if (jp->root != NULL) {
|
||||
json_context(jp->root);
|
||||
}
|
||||
@ -113,13 +113,13 @@ std::vector<mvt_layer> parse_layers(int fd, int z, unsigned x, unsigned y, std::
|
||||
if (type == NULL || type->type != JSON_STRING) {
|
||||
continue;
|
||||
}
|
||||
if (strcmp(type->string, "Feature") != 0) {
|
||||
if (type->string != std::string("Feature")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
json_object *geometry = json_hash_get(j, "geometry");
|
||||
if (geometry == NULL) {
|
||||
fprintf(stderr, "Filter output:%d: filtered feature with no geometry\n", jp->line);
|
||||
fprintf(stderr, "Filter output:%zu: filtered feature with no geometry\n", jp->line);
|
||||
json_context(j);
|
||||
json_free(j);
|
||||
exit(EXIT_FAILURE);
|
||||
@ -127,7 +127,7 @@ std::vector<mvt_layer> parse_layers(int fd, int z, unsigned x, unsigned y, std::
|
||||
|
||||
json_object *properties = json_hash_get(j, "properties");
|
||||
if (properties == NULL || (properties->type != JSON_HASH && properties->type != JSON_NULL)) {
|
||||
fprintf(stderr, "Filter output:%d: feature without properties hash\n", jp->line);
|
||||
fprintf(stderr, "Filter output:%zu: feature without properties hash\n", jp->line);
|
||||
json_context(j);
|
||||
json_free(j);
|
||||
exit(EXIT_FAILURE);
|
||||
@ -135,32 +135,32 @@ std::vector<mvt_layer> parse_layers(int fd, int z, unsigned x, unsigned y, std::
|
||||
|
||||
json_object *geometry_type = json_hash_get(geometry, "type");
|
||||
if (geometry_type == NULL) {
|
||||
fprintf(stderr, "Filter output:%d: null geometry (additional not reported)\n", jp->line);
|
||||
fprintf(stderr, "Filter output:%zu: null geometry (additional not reported)\n", jp->line);
|
||||
json_context(j);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (geometry_type->type != JSON_STRING) {
|
||||
fprintf(stderr, "Filter output:%d: geometry type is not a string\n", jp->line);
|
||||
fprintf(stderr, "Filter output:%zu: geometry type is not a string\n", jp->line);
|
||||
json_context(j);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
json_object *coordinates = json_hash_get(geometry, "coordinates");
|
||||
if (coordinates == NULL || coordinates->type != JSON_ARRAY) {
|
||||
fprintf(stderr, "Filter output:%d: feature without coordinates array\n", jp->line);
|
||||
fprintf(stderr, "Filter output:%zu: feature without coordinates array\n", jp->line);
|
||||
json_context(j);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int t;
|
||||
for (t = 0; t < GEOM_TYPES; t++) {
|
||||
if (strcmp(geometry_type->string, geometry_names[t]) == 0) {
|
||||
if (geometry_type->string == std::string(geometry_names[t])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (t >= GEOM_TYPES) {
|
||||
fprintf(stderr, "Filter output:%d: Can't handle geometry type %s\n", jp->line, geometry_type->string);
|
||||
fprintf(stderr, "Filter output:%zu: Can't handle geometry type %s\n", jp->line, geometry_type->string.c_str());
|
||||
json_context(j);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@ -216,7 +216,7 @@ std::vector<mvt_layer> parse_layers(int fd, int z, unsigned x, unsigned y, std::
|
||||
|
||||
json_object *id = json_hash_get(j, "id");
|
||||
if (id != NULL) {
|
||||
feature.id = atoll(id->string);
|
||||
feature.id = atoll(id->string.c_str());
|
||||
feature.has_id = true;
|
||||
}
|
||||
|
||||
@ -254,7 +254,7 @@ std::vector<mvt_layer> parse_layers(int fd, int z, unsigned x, unsigned y, std::
|
||||
fk->second.polygons++;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < properties->length; i++) {
|
||||
for (size_t i = 0; i < properties->keys.size(); i++) {
|
||||
int tp = -1;
|
||||
std::string s;
|
||||
|
||||
@ -301,8 +301,8 @@ serial_feature parse_feature(json_pull *jp, int z, unsigned x, unsigned y, std::
|
||||
while (1) {
|
||||
json_object *j = json_read(jp);
|
||||
if (j == NULL) {
|
||||
if (jp->error != NULL) {
|
||||
fprintf(stderr, "Filter output:%d: %s\n", jp->line, jp->error);
|
||||
if (jp->error.size() != 0) {
|
||||
fprintf(stderr, "Filter output:%zu: %s\n", jp->line, jp->error.c_str());
|
||||
if (jp->root != NULL) {
|
||||
json_context(jp->root);
|
||||
}
|
||||
@ -318,13 +318,13 @@ serial_feature parse_feature(json_pull *jp, int z, unsigned x, unsigned y, std::
|
||||
if (type == NULL || type->type != JSON_STRING) {
|
||||
continue;
|
||||
}
|
||||
if (strcmp(type->string, "Feature") != 0) {
|
||||
if (type->string != std::string("Feature")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
json_object *geometry = json_hash_get(j, "geometry");
|
||||
if (geometry == NULL) {
|
||||
fprintf(stderr, "Filter output:%d: filtered feature with no geometry\n", jp->line);
|
||||
fprintf(stderr, "Filter output:%zu: filtered feature with no geometry\n", jp->line);
|
||||
json_context(j);
|
||||
json_free(j);
|
||||
exit(EXIT_FAILURE);
|
||||
@ -332,7 +332,7 @@ serial_feature parse_feature(json_pull *jp, int z, unsigned x, unsigned y, std::
|
||||
|
||||
json_object *properties = json_hash_get(j, "properties");
|
||||
if (properties == NULL || (properties->type != JSON_HASH && properties->type != JSON_NULL)) {
|
||||
fprintf(stderr, "Filter output:%d: feature without properties hash\n", jp->line);
|
||||
fprintf(stderr, "Filter output:%zu: feature without properties hash\n", jp->line);
|
||||
json_context(j);
|
||||
json_free(j);
|
||||
exit(EXIT_FAILURE);
|
||||
@ -340,32 +340,32 @@ serial_feature parse_feature(json_pull *jp, int z, unsigned x, unsigned y, std::
|
||||
|
||||
json_object *geometry_type = json_hash_get(geometry, "type");
|
||||
if (geometry_type == NULL) {
|
||||
fprintf(stderr, "Filter output:%d: null geometry (additional not reported)\n", jp->line);
|
||||
fprintf(stderr, "Filter output:%zu: null geometry (additional not reported)\n", jp->line);
|
||||
json_context(j);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (geometry_type->type != JSON_STRING) {
|
||||
fprintf(stderr, "Filter output:%d: geometry type is not a string\n", jp->line);
|
||||
fprintf(stderr, "Filter output:%zu: geometry type is not a string\n", jp->line);
|
||||
json_context(j);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
json_object *coordinates = json_hash_get(geometry, "coordinates");
|
||||
if (coordinates == NULL || coordinates->type != JSON_ARRAY) {
|
||||
fprintf(stderr, "Filter output:%d: feature without coordinates array\n", jp->line);
|
||||
fprintf(stderr, "Filter output:%zu: feature without coordinates array\n", jp->line);
|
||||
json_context(j);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int t;
|
||||
for (t = 0; t < GEOM_TYPES; t++) {
|
||||
if (strcmp(geometry_type->string, geometry_names[t]) == 0) {
|
||||
if (geometry_type->string == std::string(geometry_names[t])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (t >= GEOM_TYPES) {
|
||||
fprintf(stderr, "Filter output:%d: Can't handle geometry type %s\n", jp->line, geometry_type->string);
|
||||
fprintf(stderr, "Filter output:%zu: Can't handle geometry type %s\n", jp->line, geometry_type->string.c_str());
|
||||
json_context(j);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
@ -448,7 +448,7 @@ serial_feature parse_feature(json_pull *jp, int z, unsigned x, unsigned y, std::
|
||||
|
||||
json_object *id = json_hash_get(j, "id");
|
||||
if (id != NULL) {
|
||||
sf.id = atoll(id->string);
|
||||
sf.id = atoll(id->string.c_str());
|
||||
sf.has_id = true;
|
||||
}
|
||||
|
||||
@ -491,7 +491,7 @@ serial_feature parse_feature(json_pull *jp, int z, unsigned x, unsigned y, std::
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < properties->length; i++) {
|
||||
for (size_t i = 0; i < properties->keys.size(); i++) {
|
||||
serial_val v;
|
||||
v.type = -1;
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include "jsonpull/jsonpull.h"
|
||||
#include "jsonpull/jsonpull.hpp"
|
||||
#include "geometry.hpp"
|
||||
#include "projection.hpp"
|
||||
#include "read_json.hpp"
|
||||
@ -31,14 +31,14 @@ int mb_geometry[GEOM_TYPES] = {
|
||||
};
|
||||
|
||||
void json_context(json_object *j) {
|
||||
char *s = json_stringify(j);
|
||||
std::string s = json_stringify(j);
|
||||
|
||||
if (strlen(s) >= 500) {
|
||||
sprintf(s + 497, "...");
|
||||
if (s.size() >= 500) {
|
||||
s.resize(497);
|
||||
s.append("...");
|
||||
}
|
||||
|
||||
fprintf(stderr, "In JSON object %s\n", s);
|
||||
free(s); // stringify
|
||||
fprintf(stderr, "In JSON object %s\n", s.c_str());
|
||||
}
|
||||
|
||||
void parse_geometry(int t, json_object *j, drawvec &out, int op, const char *fname, int line, json_object *feature) {
|
||||
@ -51,7 +51,7 @@ void parse_geometry(int t, json_object *j, drawvec &out, int op, const char *fna
|
||||
int within = geometry_within[t];
|
||||
if (within >= 0) {
|
||||
size_t i;
|
||||
for (i = 0; i < j->length; i++) {
|
||||
for (i = 0; i < j->array.size(); i++) {
|
||||
if (within == GEOM_POINT) {
|
||||
if (i == 0 || mb_geometry[t] == GEOM_MULTIPOINT) {
|
||||
op = VT_MOVETO;
|
||||
@ -63,13 +63,13 @@ void parse_geometry(int t, json_object *j, drawvec &out, int op, const char *fna
|
||||
parse_geometry(within, j->array[i], out, op, fname, line, feature);
|
||||
}
|
||||
} else {
|
||||
if (j->length >= 2 && j->array[0]->type == JSON_NUMBER && j->array[1]->type == JSON_NUMBER) {
|
||||
if (j->array.size() >= 2 && j->array[0]->type == JSON_NUMBER && j->array[1]->type == JSON_NUMBER) {
|
||||
long long x, y;
|
||||
double lon = j->array[0]->number;
|
||||
double lat = j->array[1]->number;
|
||||
projection->project(lon, lat, 32, &x, &y);
|
||||
|
||||
if (j->length > 2) {
|
||||
if (j->array.size() > 2) {
|
||||
static int warned = 0;
|
||||
|
||||
if (!warned) {
|
||||
@ -109,21 +109,20 @@ void canonicalize(json_object *o) {
|
||||
long long v;
|
||||
unsigned long long uv;
|
||||
|
||||
if (is_integer(o->string, &v)) {
|
||||
if (is_integer(o->string.c_str(), &v)) {
|
||||
s = std::to_string(v);
|
||||
} else if (is_unsigned_integer(o->string, &uv)) {
|
||||
} else if (is_unsigned_integer(o->string.c_str(), &uv)) {
|
||||
s = std::to_string(uv);
|
||||
} else {
|
||||
s = milo::dtoa_milo(o->number);
|
||||
}
|
||||
free(o->string);
|
||||
o->string = strdup(s.c_str());
|
||||
o->string = s;
|
||||
} else if (o->type == JSON_HASH) {
|
||||
for (size_t i = 0; i < o->length; i++) {
|
||||
for (size_t i = 0; i < o->keys.size(); i++) {
|
||||
canonicalize(o->values[i]);
|
||||
}
|
||||
} else if (o->type == JSON_ARRAY) {
|
||||
for (size_t i = 0; i < o->length; i++) {
|
||||
for (size_t i = 0; i < o->array.size(); i++) {
|
||||
canonicalize(o->array[i]);
|
||||
}
|
||||
}
|
||||
@ -144,9 +143,7 @@ void stringify_value(json_object *value, int &type, std::string &stringified, co
|
||||
val = "null";
|
||||
} else {
|
||||
canonicalize(value);
|
||||
const char *v = json_stringify(value);
|
||||
val = std::string(v);
|
||||
free((void *) v); // stringify
|
||||
val = json_stringify(value);
|
||||
}
|
||||
|
||||
if (vt == JSON_STRING) {
|
||||
@ -164,9 +161,9 @@ void stringify_value(json_object *value, int &type, std::string &stringified, co
|
||||
long long v;
|
||||
unsigned long long uv;
|
||||
|
||||
if (is_integer(value->string, &v)) {
|
||||
if (is_integer(value->string.c_str(), &v)) {
|
||||
stringified = std::to_string(v);
|
||||
} else if (is_unsigned_integer(value->string, &uv)) {
|
||||
} else if (is_unsigned_integer(value->string.c_str(), &uv)) {
|
||||
stringified = std::to_string(uv);
|
||||
} else {
|
||||
stringified = milo::dtoa_milo(value->number);
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include "geometry.hpp"
|
||||
#include "mbtiles.hpp"
|
||||
#include "jsonpull/jsonpull.h"
|
||||
#include "jsonpull/jsonpull.hpp"
|
||||
|
||||
size_t fwrite_check(const void *ptr, size_t size, size_t nitems, FILE *stream, const char *fname);
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include <sstream>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include "jsonpull/jsonpull.h"
|
||||
#include "jsonpull/jsonpull.hpp"
|
||||
#include "milo/dtoa_milo.h"
|
||||
|
||||
int pk = false;
|
||||
@ -575,7 +575,7 @@ void handle_tasks(std::map<zxy, std::vector<std::string>> &tasks, std::vector<st
|
||||
|
||||
void handle_vector_layers(json_object *vector_layers, std::map<std::string, layermap_entry> &layermap, std::map<std::string, std::string> &attribute_descriptions) {
|
||||
if (vector_layers != NULL && vector_layers->type == JSON_ARRAY) {
|
||||
for (size_t i = 0; i < vector_layers->length; i++) {
|
||||
for (size_t i = 0; i < vector_layers->array.size(); i++) {
|
||||
if (vector_layers->array[i]->type == JSON_HASH) {
|
||||
json_object *id = json_hash_get(vector_layers->array[i], "id");
|
||||
json_object *desc = json_hash_get(vector_layers->array[i], "description");
|
||||
@ -594,14 +594,14 @@ void handle_vector_layers(json_object *vector_layers, std::map<std::string, laye
|
||||
|
||||
json_object *fields = json_hash_get(vector_layers->array[i], "fields");
|
||||
if (fields != NULL && fields->type == JSON_HASH) {
|
||||
for (size_t j = 0; j < fields->length; j++) {
|
||||
for (size_t j = 0; j < fields->keys.size(); j++) {
|
||||
if (fields->keys[j]->type == JSON_STRING && fields->values[j]->type) {
|
||||
const char *desc2 = fields->values[j]->string;
|
||||
std::string desc2 = fields->values[j]->string;
|
||||
|
||||
if (strcmp(desc2, "Number") != 0 &&
|
||||
strcmp(desc2, "String") != 0 &&
|
||||
strcmp(desc2, "Boolean") != 0 &&
|
||||
strcmp(desc2, "Mixed") != 0) {
|
||||
if (desc2 != "Number" &&
|
||||
desc2 != "String" &&
|
||||
desc2 != "Boolean" &&
|
||||
desc2 != "Mixed") {
|
||||
attribute_descriptions.insert(std::pair<std::string, std::string>(fields->keys[j]->string, desc2));
|
||||
}
|
||||
}
|
||||
|
2
tile.cpp
2
tile.cpp
@ -41,7 +41,7 @@
|
||||
#include "evaluator.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include "jsonpull/jsonpull.h"
|
||||
#include "jsonpull/jsonpull.hpp"
|
||||
}
|
||||
|
||||
#include "plugin.hpp"
|
||||
|
Loading…
x
Reference in New Issue
Block a user