Convert jsonpull to C++ with shared_ptr and std::vector/std::string

Replace the manual malloc/realloc/free memory management in jsonpull
with std::shared_ptr ownership. Each json_object now owns its children
through std::vector<json_object_ptr>; raw back-pointers to parent and
parser remain valid by structural invariant and are cleared on
json_disconnect so detached subtrees can outlive their parser.
Strings become std::string, child arrays become std::vector, and the
old union becomes a struct so non-trivial members can coexist while
preserving the existing o->value.xxx access paths.

The old jsonpull.c is replaced by jsonpull.cpp, json_stringify now
returns std::string, and all callers across tippecanoe, tile-join,
tippecanoe-decode, tippecanoe-json-tool, tippecanoe-overzoom and the
unit tests are updated to use json_object_ptr / json_pull_ptr.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Erica Fischer
2026-05-30 17:48:32 -07:00
co-authored by Cursor
parent 9381158165
commit 3da03c6075
25 changed files with 1295 additions and 531 deletions
+9 -12
View File
@@ -394,28 +394,25 @@ void readFeature(protozero::pbf_reader &pbf, size_t dim, double e, std::vector<s
auto tip = other.find("tippecanoe");
if (tip != other.end()) {
json_pull *jp = json_begin_string(tip->second.s.c_str());
json_object *o = json_read_tree(jp);
json_pull_ptr jp = json_begin_string(tip->second.s.c_str());
json_object_ptr o = json_read_tree(jp);
if (o != NULL) {
json_object *min = json_hash_get(o, "minzoom");
if (min != NULL && (min->type == JSON_NUMBER)) {
if (o != nullptr) {
json_object_ptr min = json_hash_get(o, "minzoom");
if (min != nullptr && (min->type == JSON_NUMBER)) {
sf.tippecanoe_minzoom = integer_zoom(sst->fname, milo::dtoa_milo(min->value.number.number));
}
json_object *max = json_hash_get(o, "maxzoom");
if (max != NULL && (max->type == JSON_NUMBER)) {
json_object_ptr max = json_hash_get(o, "maxzoom");
if (max != nullptr && (max->type == JSON_NUMBER)) {
sf.tippecanoe_maxzoom = integer_zoom(sst->fname, milo::dtoa_milo(max->value.number.number));
}
json_object *tlayer = json_hash_get(o, "layer");
if (tlayer != NULL && (tlayer->type == JSON_STRING)) {
json_object_ptr tlayer = json_hash_get(o, "layer");
if (tlayer != nullptr && (tlayer->type == JSON_STRING)) {
layername = tlayer->value.string.string;
}
}
json_free(o);
json_end(jp);
}
serialize_feature(sst, sf, layername);