From 0696fa46699875fe43708d78602244fd6f257ee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Mar=C3=ADn?= Date: Thu, 23 Apr 2020 18:37:04 +0200 Subject: [PATCH] Optimize varlena returning functions Closes #4623 Closes https://github.com/postgis/postgis/pull/541 --- NEWS | 5 +- liblwgeom/bytebuffer.c | 25 +- liblwgeom/bytebuffer.h | 5 +- liblwgeom/cunit/cu_algorithm.c | 20 +- liblwgeom/cunit/cu_gserialized2.c | 4 +- liblwgeom/cunit/cu_in_twkb.c | 12 +- liblwgeom/cunit/cu_in_wkb.c | 13 +- liblwgeom/cunit/cu_out_encoded_polyline.c | 14 +- liblwgeom/cunit/cu_out_geojson.c | 29 +- liblwgeom/cunit/cu_out_gml.c | 136 +++++--- liblwgeom/cunit/cu_out_kml.c | 44 ++- liblwgeom/cunit/cu_out_svg.c | 29 +- liblwgeom/cunit/cu_out_twkb.c | 14 +- liblwgeom/cunit/cu_out_wkb.c | 5 +- liblwgeom/cunit/cu_out_x3d.c | 29 +- liblwgeom/cunit/cu_surface.c | 14 +- liblwgeom/cunit/cu_tester.h | 13 - liblwgeom/gserialized.c | 4 +- liblwgeom/gserialized.txt | 2 +- liblwgeom/gserialized1.c | 12 +- liblwgeom/gserialized2.c | 12 +- liblwgeom/liblwgeom.h.in | 67 +--- liblwgeom/liblwgeom_internal.h | 17 +- liblwgeom/lwalgorithm.c | 16 +- liblwgeom/lwout_encoded_polyline.c | 38 +-- liblwgeom/lwout_geojson.c | 121 ++++--- liblwgeom/lwout_gml.c | 393 +++++++++++----------- liblwgeom/lwout_kml.c | 7 +- liblwgeom/lwout_svg.c | 131 +++++--- liblwgeom/lwout_twkb.c | 26 +- liblwgeom/lwout_wkb.c | 134 ++++---- liblwgeom/lwout_wkt.c | 47 +-- liblwgeom/lwout_x3d.c | 17 +- liblwgeom/stringbuffer.c | 11 - liblwgeom/stringbuffer.h | 1 - loader/shp2pgsql-core.c | 8 +- postgis/geography_inout.c | 94 ++++-- postgis/lwgeom_dump.c | 6 +- postgis/lwgeom_export.c | 77 ++++- postgis/lwgeom_functions_basic.c | 36 +- postgis/lwgeom_geos.c | 2 +- postgis/lwgeom_inout.c | 109 +++++- postgis/lwgeom_ogc.c | 43 ++- postgis/lwgeom_transform.c | 16 +- raster/rt_core/rt_geometry.c | 6 +- raster/rt_pg/rtpg_geometry.c | 37 +- raster/rt_pg/rtpg_mapalgebra.c | 38 +-- raster/rt_pg/rtpg_pixel.c | 38 +-- topology/postgis_topology.c | 42 ++- 49 files changed, 1167 insertions(+), 852 deletions(-) diff --git a/NEWS b/NEWS index 94ed614a6..fe49bcec9 100644 --- a/NEWS +++ b/NEWS @@ -10,8 +10,9 @@ Only tickets not included in 3.1.0alpha1 - #4656, Cast a geojson_text::geometry for implicit GeoJSON ingestion (Raúl Marín) * Enhancements * - - #4651: ST_Simplify: Don't copy if nothing is removed (Raúl Marín) - - #4657: Avoid De-TOASTing where possible (Paul Ramsey) + - #4651, ST_Simplify: Don't copy if nothing is removed (Raúl Marín) + - #4657, Avoid De-TOASTing where possible (Paul Ramsey) + - #4623, Optimize varlena returning functions (Raúl Marín) * Bug fixes * - #4652, Fix several memory related bugs in ST_GeomFromGML (Raúl Marín) diff --git a/liblwgeom/bytebuffer.c b/liblwgeom/bytebuffer.c index fc1fa5c08..2d1435317 100644 --- a/liblwgeom/bytebuffer.c +++ b/liblwgeom/bytebuffer.c @@ -101,14 +101,15 @@ bytebuffer_makeroom(bytebuffer_t *s, size_t size_to_add) } /** Returns a copy of the internal buffer */ -lwvarlena_t * -bytebuffer_get_buffer_varlena(const bytebuffer_t *s) +uint8_t* +bytebuffer_get_buffer_copy(const bytebuffer_t *s, size_t *buffer_length) { size_t bufsz = bytebuffer_getlength(s); - lwvarlena_t *v = lwalloc(bufsz + LWVARHDRSZ); - memcpy(v->data, s->buf_start, bufsz); - LWSIZE_SET(v->size, bufsz + LWVARHDRSZ); - return v; + uint8_t *buf = lwalloc(bufsz); + memcpy(buf, s->buf_start, bufsz); + if ( buffer_length ) + *buffer_length = bufsz; + return buf; } /** Returns a read-only reference to the internal buffer */ @@ -181,18 +182,6 @@ bytebuffer_getlength(const bytebuffer_t *s) /* Unused functions */ #if 0 -/** Returns a copy of the internal buffer */ -uint8_t* -bytebuffer_get_buffer_copy(const bytebuffer_t *s, size_t *buffer_length) -{ - size_t bufsz = bytebuffer_getlength(s); - uint8_t *buf = lwalloc(bufsz); - memcpy(buf, s->buf_start, bufsz); - if ( buffer_length ) - *buffer_length = bufsz; - return buf; -} - /** * Allocate a new bytebuffer_t. Use bytebuffer_destroy to free. */ diff --git a/liblwgeom/bytebuffer.h b/liblwgeom/bytebuffer.h index bf00f8f6f..08594822d 100644 --- a/liblwgeom/bytebuffer.h +++ b/liblwgeom/bytebuffer.h @@ -31,9 +31,7 @@ #include #include "varint.h" -#include "liblwgeom_internal.h" #include "lwgeom_log.h" - #define BYTEBUFFER_STARTSIZE 512 #define BYTEBUFFER_STATICSIZE 1024 @@ -54,7 +52,7 @@ void bytebuffer_append_bytebuffer(bytebuffer_t *write_to, bytebuffer_t *write_fr void bytebuffer_append_varint(bytebuffer_t *s, const int64_t val); void bytebuffer_append_uvarint(bytebuffer_t *s, const uint64_t val); size_t bytebuffer_getlength(const bytebuffer_t *s); -lwvarlena_t *bytebuffer_get_buffer_varlena(const bytebuffer_t *s); +uint8_t* bytebuffer_get_buffer_copy(const bytebuffer_t *s, size_t *buffer_length); const uint8_t* bytebuffer_get_buffer(const bytebuffer_t *s, size_t *buffer_length); /* Unused functions */ @@ -63,7 +61,6 @@ void bytebuffer_destroy(bytebuffer_t *s); bytebuffer_t *bytebuffer_create_with_size(size_t size); bytebuffer_t *bytebuffer_create(void); void bytebuffer_clear(bytebuffer_t *s); -uint8_t* bytebuffer_get_buffer_copy(const bytebuffer_t *s, size_t *buffer_length); uint64_t bytebuffer_read_uvarint(bytebuffer_t *s); int64_t bytebuffer_read_varint(bytebuffer_t *s); bytebuffer_t* bytebuffer_merge(bytebuffer_t **buff_array, int nbuffers); diff --git a/liblwgeom/cunit/cu_algorithm.c b/liblwgeom/cunit/cu_algorithm.c index cdd1f37da..4d31a6234 100644 --- a/liblwgeom/cunit/cu_algorithm.c +++ b/liblwgeom/cunit/cu_algorithm.c @@ -951,21 +951,21 @@ static void test_geohash_precision(void) static void test_geohash_point(void) { - lwvarlena_t *geohash; + char *geohash; geohash = geohash_point(0, 0, 16); //printf("\ngeohash %s\n",geohash); - ASSERT_VARLENA_EQUAL(geohash, "s000000000000000"); + ASSERT_STRING_EQUAL(geohash, "s000000000000000"); lwfree(geohash); geohash = geohash_point(90, 0, 16); //printf("\ngeohash %s\n",geohash); - ASSERT_VARLENA_EQUAL(geohash, "w000000000000000"); + ASSERT_STRING_EQUAL(geohash, "w000000000000000"); lwfree(geohash); geohash = geohash_point(20.012345, -20.012345, 15); //printf("\ngeohash %s\n",geohash); - ASSERT_VARLENA_EQUAL(geohash, "kkqnpkue9ktbpe5"); + ASSERT_STRING_EQUAL(geohash, "kkqnpkue9ktbpe5"); lwfree(geohash); } @@ -975,40 +975,40 @@ static void test_geohash(void) LWPOINT *lwpoint = NULL; LWLINE *lwline = NULL; LWMLINE *lwmline = NULL; - lwvarlena_t *geohash = NULL; + char *geohash = NULL; lwpoint = (LWPOINT*)lwgeom_from_wkt("POINT(23.0 25.2)", LW_PARSER_CHECK_NONE); geohash = lwgeom_geohash((LWGEOM*)lwpoint,0); //printf("\ngeohash %s\n",geohash); - ASSERT_VARLENA_EQUAL(geohash, "ss2r77s0du7p2ewb8hmx"); + ASSERT_STRING_EQUAL(geohash, "ss2r77s0du7p2ewb8hmx"); lwpoint_free(lwpoint); lwfree(geohash); lwpoint = (LWPOINT*)lwgeom_from_wkt("POINT(23.0 25.2 2.0)", LW_PARSER_CHECK_NONE); geohash = lwgeom_geohash((LWGEOM*)lwpoint,0); //printf("geohash %s\n",geohash); - ASSERT_VARLENA_EQUAL(geohash, "ss2r77s0du7p2ewb8hmx"); + ASSERT_STRING_EQUAL(geohash, "ss2r77s0du7p2ewb8hmx"); lwpoint_free(lwpoint); lwfree(geohash); lwline = (LWLINE*)lwgeom_from_wkt("LINESTRING(23.0 23.0,23.1 23.1)", LW_PARSER_CHECK_NONE); geohash = lwgeom_geohash((LWGEOM*)lwline,0); //printf("geohash %s\n",geohash); - ASSERT_VARLENA_EQUAL(geohash, "ss0"); + ASSERT_STRING_EQUAL(geohash, "ss0"); lwline_free(lwline); lwfree(geohash); lwline = (LWLINE*)lwgeom_from_wkt("LINESTRING(23.0 23.0,23.001 23.001)", LW_PARSER_CHECK_NONE); geohash = lwgeom_geohash((LWGEOM*)lwline,0); //printf("geohash %s\n",geohash); - ASSERT_VARLENA_EQUAL(geohash, "ss06g7h"); + ASSERT_STRING_EQUAL(geohash, "ss06g7h"); lwline_free(lwline); lwfree(geohash); lwmline = (LWMLINE*)lwgeom_from_wkt("MULTILINESTRING((23.0 23.0,23.1 23.1),(23.0 23.0,23.1 23.1))", LW_PARSER_CHECK_NONE); geohash = lwgeom_geohash((LWGEOM*)lwmline,0); //printf("geohash %s\n",geohash); - ASSERT_VARLENA_EQUAL(geohash, "ss0"); + ASSERT_STRING_EQUAL(geohash, "ss0"); lwmline_free(lwmline); lwfree(geohash); } diff --git a/liblwgeom/cunit/cu_gserialized2.c b/liblwgeom/cunit/cu_gserialized2.c index 1f86dd080..f88c74d00 100644 --- a/liblwgeom/cunit/cu_gserialized2.c +++ b/liblwgeom/cunit/cu_gserialized2.c @@ -251,11 +251,11 @@ static void test_lwgeom_from_gserialized2(void) size1 = gserialized2_from_lwgeom_size(geom1); g1 = gserialized2_from_lwgeom(geom1, &size2); CU_ASSERT_EQUAL(size1, size2); - CU_ASSERT_EQUAL(LWSIZE_GET(g1->size), size2); + CU_ASSERT_EQUAL(SIZE_GET(g1->size), size2); geom2 = lwgeom_from_gserialized2(g1); CU_ASSERT_EQUAL(geom1->flags, geom2->flags); g2 = gserialized2_from_lwgeom(geom2, &size2); - CU_ASSERT_EQUAL(LWSIZE_GET(g2->size), size2); + CU_ASSERT_EQUAL(SIZE_GET(g2->size), size2); CU_ASSERT_EQUAL(g1->gflags, g2->gflags); CU_ASSERT_EQUAL(FLAGS_GET_SOLID(geom2->flags), 1); lwfree(g1); diff --git a/liblwgeom/cunit/cu_in_twkb.c b/liblwgeom/cunit/cu_in_twkb.c index 6dcc39a96..43542b217 100644 --- a/liblwgeom/cunit/cu_in_twkb.c +++ b/liblwgeom/cunit/cu_in_twkb.c @@ -54,6 +54,8 @@ static void cu_twkb_in(char *wkt) { LWGEOM_PARSER_RESULT pr; LWGEOM *g_a, *g_b; + uint8_t *twkb_a, *twkb_b; + size_t twkb_size_a, twkb_size_b; /* int i; char *hex; */ /* Turn WKT into geom */ @@ -69,23 +71,23 @@ static void cu_twkb_in(char *wkt) g_a = pr.geom; /* Turn geom into TWKB */ - lwvarlena_t *twkb_a = lwgeom_to_twkb(g_a, variant, precision, precision, precision); + twkb_a = lwgeom_to_twkb(g_a, variant, precision, precision, precision, &twkb_size_a); // printf("\n Size: %ld\n", twkb_size_a); /* Turn TWKB back into geom */ - g_b = lwgeom_from_twkb((uint8_t *)twkb_a->data, LWSIZE_GET(twkb_a->size) - LWVARHDRSZ, LW_PARSER_CHECK_NONE); + g_b = lwgeom_from_twkb(twkb_a, twkb_size_a, LW_PARSER_CHECK_NONE); // printf("\n Org: %s\n 1st: %s\n 2nd: %s\n", wkt, lwgeom_to_ewkt(g_a), lwgeom_to_ewkt(g_b)); /* Turn geom to TWKB again */ - lwvarlena_t *twkb_b = lwgeom_to_twkb(g_b, variant, precision, precision, precision); + twkb_b = lwgeom_to_twkb(g_b, variant, precision, precision, precision, &twkb_size_b); /* Turn TWKB into hex for comparisons */ if ( hex_a ) lwfree(hex_a); if ( hex_b ) lwfree(hex_b); - hex_a = hexbytes_from_bytes((uint8_t *)twkb_a->data, LWSIZE_GET(twkb_a->size) - LWVARHDRSZ); - hex_b = hexbytes_from_bytes((uint8_t *)twkb_b->data, LWSIZE_GET(twkb_b->size) - LWVARHDRSZ); + hex_a = hexbytes_from_bytes(twkb_a, twkb_size_a); + hex_b = hexbytes_from_bytes(twkb_b, twkb_size_b); /* Clean up */ lwfree(twkb_a); diff --git a/liblwgeom/cunit/cu_in_wkb.c b/liblwgeom/cunit/cu_in_wkb.c index 40039257f..4bd9bd590 100644 --- a/liblwgeom/cunit/cu_in_wkb.c +++ b/liblwgeom/cunit/cu_in_wkb.c @@ -63,7 +63,8 @@ static void cu_wkb_in(char *wkt) { LWGEOM_PARSER_RESULT pr; LWGEOM *g_a, *g_b; - lwvarlena_t *wkb_a, *wkb_b; + uint8_t *wkb_a, *wkb_b; + size_t wkb_size_a, wkb_size_b; /* int i; char *hex; */ if ( hex_a ) free(hex_a); @@ -82,17 +83,17 @@ static void cu_wkb_in(char *wkt) g_a = pr.geom; /* Turn geom into WKB */ - wkb_a = lwgeom_to_wkb_varlena(g_a, WKB_NDR | WKB_EXTENDED); + wkb_a = lwgeom_to_wkb(g_a, WKB_NDR | WKB_EXTENDED, &wkb_size_a); /* Turn WKB back into geom */ - g_b = lwgeom_from_wkb((uint8_t *)wkb_a->data, LWSIZE_GET(wkb_a->size) - LWVARHDRSZ, LW_PARSER_CHECK_NONE); + g_b = lwgeom_from_wkb(wkb_a, wkb_size_a, LW_PARSER_CHECK_NONE); /* Turn geom to WKB again */ - wkb_b = lwgeom_to_wkb_varlena(g_b, WKB_NDR | WKB_EXTENDED); + wkb_b = lwgeom_to_wkb(g_b, WKB_NDR | WKB_EXTENDED, &wkb_size_b); /* Turn geoms into WKB for comparisons */ - hex_a = hexbytes_from_bytes((uint8_t *)wkb_a->data, LWSIZE_GET(wkb_a->size) - LWVARHDRSZ); - hex_b = hexbytes_from_bytes((uint8_t *)wkb_b->data, LWSIZE_GET(wkb_b->size) - LWVARHDRSZ); + hex_a = hexbytes_from_bytes(wkb_a, wkb_size_a); + hex_b = hexbytes_from_bytes(wkb_b, wkb_size_b); /* Clean up */ lwfree(wkb_a); diff --git a/liblwgeom/cunit/cu_out_encoded_polyline.c b/liblwgeom/cunit/cu_out_encoded_polyline.c index 608b0ae71..0cdcc1f59 100644 --- a/liblwgeom/cunit/cu_out_encoded_polyline.c +++ b/liblwgeom/cunit/cu_out_encoded_polyline.c @@ -22,13 +22,19 @@ static void do_encoded_polyline_test(char* in, int precision, char* out) { - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_to_encoded_polyline(g, precision); + LWGEOM* g; + char* h; - ASSERT_VARLENA_EQUAL(v, out); + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_to_encoded_polyline(g, precision); + + if (strcmp(h, out)) + fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", in, h, out); + + CU_ASSERT_STRING_EQUAL(h, out); lwgeom_free(g); - lwfree(v); + lwfree(h); } static void diff --git a/liblwgeom/cunit/cu_out_geojson.c b/liblwgeom/cunit/cu_out_geojson.c index fe63c9238..4bdfbe2f3 100644 --- a/liblwgeom/cunit/cu_out_geojson.c +++ b/liblwgeom/cunit/cu_out_geojson.c @@ -19,25 +19,38 @@ static void do_geojson_test(char * in, char * out, char * srs, int precision, int has_bbox) { - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_to_geojson(g, srs, precision, has_bbox); + LWGEOM *g; + char * h; - ASSERT_VARLENA_EQUAL(v, out); + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_to_geojson(g, srs, precision, has_bbox); + + if (strcmp(h, out)) + fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", in, h, out); + + CU_ASSERT_STRING_EQUAL(h, out); lwgeom_free(g); - lwfree(v); + lwfree(h); } static void do_geojson_unsupported(char * in, char * out) { - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_to_geojson(g, NULL, 0, 0); + LWGEOM *g; + char *h; - ASSERT_STRING_EQUAL(out, cu_error_msg); + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_to_geojson(g, NULL, 0, 0); + + if (strcmp(cu_error_msg, out)) + fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", + in, cu_error_msg, out); + + CU_ASSERT_STRING_EQUAL(out, cu_error_msg); cu_error_msg_reset(); - lwfree(v); + lwfree(h); lwgeom_free(g); } diff --git a/liblwgeom/cunit/cu_out_gml.c b/liblwgeom/cunit/cu_out_gml.c index fdd1631a9..a4e84fc2e 100644 --- a/liblwgeom/cunit/cu_out_gml.c +++ b/liblwgeom/cunit/cu_out_gml.c @@ -20,121 +20,171 @@ static void do_gml2_test(char * in, char * out, char * srs, int precision) { - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_to_gml2(g, srs, precision, "gml:"); + LWGEOM *g; + char *h; - ASSERT_VARLENA_EQUAL(v, out); + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_to_gml2(g, srs, precision, "gml:"); + + if (strcmp(h, out)) + fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", in, h, out); + + CU_ASSERT_STRING_EQUAL(h, out); lwgeom_free(g); - lwfree(v); + lwfree(h); } static void do_gml2_test_prefix(char * in, char * out, char * srs, int precision, const char *prefix) { - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_to_gml2(g, srs, precision, prefix); + LWGEOM *g; + char *h; - ASSERT_VARLENA_EQUAL(v, out); + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_to_gml2(g, srs, precision, prefix); + + if (strcmp(h, out)) + fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", in, h, out); + + CU_ASSERT_STRING_EQUAL(h, out); lwgeom_free(g); - lwfree(v); + lwfree(h); } static void do_gml3_test_opts(char * in, char * out, char * srs, int precision, int opts) { - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_to_gml3(g, srs, precision, opts, "gml:", NULL); + LWGEOM *g; + char *h; - ASSERT_VARLENA_EQUAL(v, out); + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_to_gml3(g, srs, precision, opts, "gml:", NULL); + + if (strcmp(h, out)) + fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", in, h, out); + + CU_ASSERT_STRING_EQUAL(h, out); lwgeom_free(g); - lwfree(v); + lwfree(h); } static void do_gml3_test(char * in, char * out, char * srs, int precision, int is_geodetic) { + LWGEOM *g; + char *h; int opts = LW_GML_IS_DIMS; if ( is_geodetic ) opts |= LW_GML_IS_DEGREE; - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_to_gml3(g, srs, precision, opts, "gml:", NULL); + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_to_gml3(g, srs, precision, opts, "gml:", NULL); - ASSERT_VARLENA_EQUAL(v, out); + if (strcmp(h, out)) + fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", in, h, out); + + CU_ASSERT_STRING_EQUAL(h, out); lwgeom_free(g); - lwfree(v); + lwfree(h); } static void do_gml3_test_prefix(char * in, char * out, char * srs, int precision, int is_geodetic, const char *prefix) { + LWGEOM *g; + char *h; int opts = LW_GML_IS_DIMS; + if ( is_geodetic ) opts |= LW_GML_IS_DEGREE; - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_to_gml3(g, srs, precision, opts, prefix, NULL); + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_to_gml3(g, srs, precision, opts, prefix, NULL); - ASSERT_VARLENA_EQUAL(v, out); + if (strcmp(h, out)) + fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", in, h, out); + + CU_ASSERT_STRING_EQUAL(h, out); lwgeom_free(g); - lwfree(v); + lwfree(h); } static void do_gml3_test_nodims(char * in, char * out, char * srs, int precision, int is_geodetic, int is_dims, const char *prefix) { + LWGEOM *g; + char *h; int opts = 0; + if ( is_geodetic ) opts |= LW_GML_IS_DEGREE; if ( is_dims ) opts |= LW_GML_IS_DIMS; - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_to_gml3(g, srs, precision, opts, prefix, NULL); + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_to_gml3(g, srs, precision, opts, prefix, NULL); - ASSERT_VARLENA_EQUAL(v, out); + if (strcmp(h, out)) + fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", in, h, out); + + CU_ASSERT_STRING_EQUAL(h, out); lwgeom_free(g); - lwfree(v); + lwfree(h); } static void do_gml2_unsupported(char * in, char * out) { - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_to_gml2(g, NULL, 0, ""); + LWGEOM *g; + char *h; - ASSERT_STRING_EQUAL(out, cu_error_msg); + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_to_gml2(g, NULL, 0, ""); + + if (strcmp(cu_error_msg, out)) + fprintf(stderr, "\nGML 2 - In: %s\nOut: %s\nTheo: %s\n", + in, cu_error_msg, out); + CU_ASSERT_STRING_EQUAL(out, cu_error_msg); cu_error_msg_reset(); - lwfree(v); + lwfree(h); lwgeom_free(g); } static void do_gml2_extent_test(char * in, char * out, char * srs, double precision, char * prefix) { - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_extent_to_gml2(g, srs, precision, prefix); - if (!v) - { - ASSERT_STRING_EQUAL(in, cu_error_msg); - } - else - { - ASSERT_VARLENA_EQUAL(v, out); - } + LWGEOM *g; + char *h; + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_extent_to_gml2(g, srs, precision, prefix); + if ( ! h ) h = strdup(cu_error_msg); + + if (strcmp(h, out)) + fprintf(stderr, "\nEXT GML 2 - In: %s\nObt: %s\nExp: %s\n", + in, h, out); + CU_ASSERT_STRING_EQUAL(out, h); cu_error_msg_reset(); - lwfree(v); + + lwfree(h); lwgeom_free(g); } static void do_gml3_extent_test(char * in, char * out, char * srs, double precision, int opts, char* prefix) { - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_extent_to_gml3(g, srs, precision, opts, prefix); + LWGEOM *g; + char *h; - ASSERT_VARLENA_EQUAL(v, out); + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_extent_to_gml3(g, srs, precision, opts, prefix); + if ( ! h ) h = strdup(cu_error_msg); + if (strcmp(h, out)) + fprintf(stderr, "\nEXT GML 3 - In: %s\nObt: %s\nExp: %s\n", + in, h, out); + CU_ASSERT_STRING_EQUAL(out, h); + cu_error_msg_reset(); + + lwfree(h); lwgeom_free(g); - lwfree(v); } static void out_gml_test_precision(void) diff --git a/liblwgeom/cunit/cu_out_kml.c b/liblwgeom/cunit/cu_out_kml.c index d886ddd88..45682fd71 100644 --- a/liblwgeom/cunit/cu_out_kml.c +++ b/liblwgeom/cunit/cu_out_kml.c @@ -19,38 +19,58 @@ static void do_kml_test(char * in, char * out, int precision) { - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_to_kml2(g, precision, ""); + LWGEOM *g; + char * h; - ASSERT_VARLENA_EQUAL(v, out); + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_to_kml2(g, precision, ""); + + if (strcmp(h, out)) + fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", in, h, out); + + CU_ASSERT_STRING_EQUAL(h, out); lwgeom_free(g); - lwfree(v); + lwfree(h); } static void do_kml_unsupported(char * in, char * out) { - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_to_kml2(g, 0, ""); + LWGEOM *g; + char *h; - ASSERT_STRING_EQUAL(cu_error_msg, out); + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_to_kml2(g, 0, ""); + + if (strcmp(cu_error_msg, out)) + fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", + in, cu_error_msg, out); + + CU_ASSERT_STRING_EQUAL(out, cu_error_msg); cu_error_msg_reset(); - lwfree(v); + lwfree(h); lwgeom_free(g); } static void do_kml_test_prefix(char * in, char * out, int precision, const char *prefix) { - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_to_kml2(g, precision, prefix); + LWGEOM *g; + char * h; - ASSERT_VARLENA_EQUAL(v, out); + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_to_kml2(g, precision, prefix); + + if (strcmp(h, out)) + fprintf(stderr, "\nPrefix: %s\nIn: %s\nOut: %s\nTheo: %s\n", + prefix, in, h, out); + + CU_ASSERT_STRING_EQUAL(h, out); lwgeom_free(g); - lwfree(v); + lwfree(h); } diff --git a/liblwgeom/cunit/cu_out_svg.c b/liblwgeom/cunit/cu_out_svg.c index bb60303bb..cf929dfa3 100644 --- a/liblwgeom/cunit/cu_out_svg.c +++ b/liblwgeom/cunit/cu_out_svg.c @@ -19,26 +19,39 @@ static void do_svg_test(char * in, char * out, int precision, int relative) { - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_to_svg(g, precision, relative); + LWGEOM *g; + char * h; - ASSERT_VARLENA_EQUAL(v, out); + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_to_svg(g, precision, relative); + + if (strcmp(h, out)) + fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", in, h, out); + + CU_ASSERT_STRING_EQUAL(h, out); lwgeom_free(g); - lwfree(v); + lwfree(h); } static void do_svg_unsupported(char * in, char * out) { - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_to_svg(g, 0, 0); + LWGEOM *g; + char *h; - ASSERT_STRING_EQUAL(cu_error_msg, out); + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_to_svg(g, 0, 0); + + if (strcmp(cu_error_msg, out)) + fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", + in, cu_error_msg, out); + + CU_ASSERT_STRING_EQUAL(out, cu_error_msg); cu_error_msg_reset(); + lwfree(h); lwgeom_free(g); - lwfree(v); } diff --git a/liblwgeom/cunit/cu_out_twkb.c b/liblwgeom/cunit/cu_out_twkb.c index 5c2602e53..3609416db 100644 --- a/liblwgeom/cunit/cu_out_twkb.c +++ b/liblwgeom/cunit/cu_out_twkb.c @@ -55,11 +55,13 @@ static int clean_twkb_out_suite(void) static void cu_twkb(char *wkt, int8_t prec_xy, int8_t prec_z, int8_t prec_m, uint8_t variant) { LWGEOM *g = lwgeom_from_wkt(wkt, LW_PARSER_CHECK_NONE); + size_t twkb_size; + uint8_t *twkb; if ( ! g ) lwnotice("input wkt is invalid: %s", wkt); - lwvarlena_t *twkb = lwgeom_to_twkb(g, variant, prec_xy, prec_z, prec_m); + twkb = lwgeom_to_twkb(g, variant, prec_xy, prec_z, prec_m, &twkb_size); lwgeom_free(g); if ( s ) free(s); - s = hexbytes_from_bytes((uint8_t *)twkb->data, LWSIZE_GET(twkb->size) - LWVARHDRSZ); + s = hexbytes_from_bytes(twkb, twkb_size); free(twkb); } @@ -71,13 +73,15 @@ static void cu_twkb_idlist(char *wkt, int64_t *idlist, int8_t prec_xy, int8_t pr { LWGEOM *g = lwgeom_from_wkt(wkt, LW_PARSER_CHECK_NONE); LWGEOM *g_b; + size_t twkb_size; + uint8_t *twkb; if ( ! g ) lwnotice("input wkt is invalid: %s", wkt); - lwvarlena_t *twkb = lwgeom_to_twkb_with_idlist(g, idlist, variant, prec_xy, prec_z, prec_m); + twkb = lwgeom_to_twkb_with_idlist(g, idlist, variant, prec_xy, prec_z, prec_m, &twkb_size); lwgeom_free(g); if ( s ) free(s); if ( w ) free(w); - s = hexbytes_from_bytes((uint8_t *)twkb->data, LWSIZE_GET(twkb->size) - LWVARHDRSZ); - g_b = lwgeom_from_twkb((uint8_t *)twkb->data, LWSIZE_GET(twkb->size) - LWVARHDRSZ, LW_PARSER_CHECK_NONE); + s = hexbytes_from_bytes(twkb, twkb_size); + g_b = lwgeom_from_twkb(twkb, twkb_size, LW_PARSER_CHECK_NONE); w = lwgeom_to_ewkt(g_b); lwgeom_free(g_b); free(twkb); diff --git a/liblwgeom/cunit/cu_out_wkb.c b/liblwgeom/cunit/cu_out_wkb.c index 236c53aff..7b23fe634 100644 --- a/liblwgeom/cunit/cu_out_wkb.c +++ b/liblwgeom/cunit/cu_out_wkb.c @@ -21,6 +21,7 @@ ** Global variable to hold hex WKB strings */ static char *s; +static size_t s_size; /* ** The suite initialization function. @@ -50,7 +51,7 @@ static void cu_wkb_from_hexwkb(char *hexwkb) { LWGEOM *g = lwgeom_from_hexwkb(hexwkb, LW_PARSER_CHECK_NONE); if ( s ) free(s); - s = (char *)lwgeom_to_wkb_buffer(g, WKB_HEX | WKB_XDR | WKB_EXTENDED); + s = (char*)lwgeom_to_wkb(g, WKB_HEX | WKB_XDR | WKB_EXTENDED, 0); lwgeom_free(g); } @@ -61,7 +62,7 @@ static void cu_wkb(char *wkt) { LWGEOM *g = lwgeom_from_wkt(wkt, LW_PARSER_CHECK_NONE); if ( s ) free(s); - s = (char *)lwgeom_to_wkb_buffer(g, WKB_HEX | WKB_XDR | WKB_EXTENDED); + s = (char*)lwgeom_to_wkb(g, WKB_HEX | WKB_XDR | WKB_EXTENDED, &s_size); lwgeom_free(g); } diff --git a/liblwgeom/cunit/cu_out_x3d.c b/liblwgeom/cunit/cu_out_x3d.c index 3e10d35a8..49f63f5a2 100644 --- a/liblwgeom/cunit/cu_out_x3d.c +++ b/liblwgeom/cunit/cu_out_x3d.c @@ -19,25 +19,38 @@ static void do_x3d3_test(char * in, char * out, char * srs, int precision, int option) { - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_to_x3d3(g, srs, precision, option, ""); + LWGEOM *g; + char * h; - ASSERT_VARLENA_EQUAL(v, out); + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_to_x3d3(g, srs, precision, option, ""); + + if (strcmp(h, out)) + fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", in, h, out); + + CU_ASSERT_STRING_EQUAL(h, out); lwgeom_free(g); - lwfree(v); + lwfree(h); } static void do_x3d3_unsupported(char * in, char * out) { - LWGEOM *g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); - lwvarlena_t *v = lwgeom_to_x3d3(g, NULL, 0, 0, ""); + LWGEOM *g; + char *h; - ASSERT_STRING_EQUAL(out, cu_error_msg); + g = lwgeom_from_wkt(in, LW_PARSER_CHECK_NONE); + h = lwgeom_to_x3d3(g, NULL, 0, 0, ""); + + if (strcmp(cu_error_msg, out)) + fprintf(stderr, "\nIn: %s\nOut: %s\nTheo: %s\n", + in, cu_error_msg, out); + + CU_ASSERT_STRING_EQUAL(out, cu_error_msg); cu_error_msg_reset(); - lwfree(v); + lwfree(h); lwgeom_free(g); } diff --git a/liblwgeom/cunit/cu_surface.c b/liblwgeom/cunit/cu_surface.c index ce9db5274..90507318c 100644 --- a/liblwgeom/cunit/cu_surface.c +++ b/liblwgeom/cunit/cu_surface.c @@ -244,7 +244,7 @@ void polyhedralsurface_parse(void) geom = lwgeom_from_wkt("POLYHEDRALSURFACE(((0 1,2 3,4 5,0 1)))", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE); - tmp = lwgeom_to_hexwkb_buffer(geom, WKB_NDR | WKB_EXTENDED); + tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0); CU_ASSERT_STRING_EQUAL("010F00000001000000010300000001000000040000000000000000000000000000000000F03F00000000000000400000000000000840000000000000104000000000000014400000000000000000000000000000F03F", tmp); lwfree(tmp); tmp = lwgeom_to_ewkt(geom); @@ -259,7 +259,7 @@ void polyhedralsurface_parse(void) tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACEM(((0 1 2,3 4 5,6 7 8,0 1 2)))", tmp); lwfree(tmp); - tmp = lwgeom_to_hexwkb_buffer(geom, WKB_NDR | WKB_EXTENDED); + tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0); CU_ASSERT_STRING_EQUAL("010F00004001000000010300004001000000040000000000000000000000000000000000F03F000000000000004000000000000008400000000000001040000000000000144000000000000018400000000000001C4000000000000020400000000000000000000000000000F03F0000000000000040", tmp); lwfree(tmp); lwgeom_free(geom); @@ -277,7 +277,7 @@ void polyhedralsurface_parse(void) tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACE(((0 1 2,3 4 5,6 7 8,0 1 2),(9 10 11,12 13 14,15 16 17,9 10 11)))", tmp); lwfree(tmp); - tmp = lwgeom_to_hexwkb_buffer(geom, WKB_NDR | WKB_EXTENDED); + tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0); CU_ASSERT_STRING_EQUAL("010F00008001000000010300008002000000040000000000000000000000000000000000F03F000000000000004000000000000008400000000000001040000000000000144000000000000018400000000000001C4000000000000020400000000000000000000000000000F03F00000000000000400400000000000000000022400000000000002440000000000000264000000000000028400000000000002A400000000000002C400000000000002E4000000000000030400000000000003140000000000000224000000000000024400000000000002640", tmp); lwfree(tmp); lwgeom_free(geom); @@ -310,7 +310,7 @@ void polyhedralsurface_parse(void) geom = lwgeom_from_wkt("POLYHEDRALSURFACE EMPTY", LW_PARSER_CHECK_NONE); CU_ASSERT_EQUAL(strlen(cu_error_msg), 0); CU_ASSERT_EQUAL(geom->type, POLYHEDRALSURFACETYPE); - tmp = (char *)lwgeom_to_hexwkb_buffer(geom, WKB_HEX | WKB_ISO | WKB_NDR); + tmp = (char *)lwgeom_to_wkb(geom, WKB_HEX | WKB_ISO | WKB_NDR, 0); CU_ASSERT_STRING_EQUAL("010F00000000000000", tmp); lwfree(tmp); tmp = lwgeom_to_ewkt(geom); @@ -326,7 +326,7 @@ void polyhedralsurface_parse(void) tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACE(((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((1 0 0,0 1 0,0 0 1,1 0 0)))", tmp); lwfree(tmp); - tmp = lwgeom_to_hexwkb_buffer(geom, WKB_NDR | WKB_EXTENDED); + tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0); CU_ASSERT_STRING_EQUAL("010F000080040000000103000080010000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000010300008001000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000000001030000800100000004000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000F03F00000000000000000000000000000000000000000000000001030000800100000004000000000000000000F03F000000000000000000000000000000000000000000000000000000000000F03F000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F00000000000000000000000000000000", tmp); lwfree(tmp); lwgeom_free(geom); @@ -340,7 +340,7 @@ void polyhedralsurface_parse(void) tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("POLYHEDRALSURFACE(((0 0 0 0,0 0 1 0,0 1 0 2,0 0 0 0)),((0 0 0 0,0 1 0 0,1 0 0 4,0 0 0 0)),((0 0 0 0,1 0 0 0,0 0 1 6,0 0 0 0)),((1 0 0 0,0 1 0 0,0 0 1 0,1 0 0 0)))", tmp); lwfree(tmp); - tmp = lwgeom_to_hexwkb_buffer(geom, WKB_NDR | WKB_EXTENDED); + tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0); CU_ASSERT_STRING_EQUAL("010F0000C00400000001030000C00100000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F00000000000000000000000000000000000000000000F03F00000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000001030000C0010000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F00000000000000000000000000000000000000000000F03F000000000000000000000000000000000000000000001040000000000000000000000000000000000000000000000000000000000000000001030000C001000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000001840000000000000000000000000000000000000000000000000000000000000000001030000C00100000004000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F000000000000000000000000000000000000000000000000", tmp); lwfree(tmp); lwgeom_free(geom); @@ -354,7 +354,7 @@ void polyhedralsurface_parse(void) tmp = lwgeom_to_ewkt(geom); CU_ASSERT_STRING_EQUAL("SRID=4326;POLYHEDRALSURFACE(((0 0 0,0 0 1,0 1 0,0 0 0)),((0 0 0,0 1 0,1 0 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((1 0 0,0 1 0,0 0 1,1 0 0)))", tmp); lwfree(tmp); - tmp = lwgeom_to_hexwkb_buffer(geom, WKB_NDR | WKB_EXTENDED); + tmp = lwgeom_to_hexwkb(geom, WKB_NDR | WKB_EXTENDED, 0); CU_ASSERT_STRING_EQUAL("010F0000A0E6100000040000000103000080010000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000010300008001000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000000001030000800100000004000000000000000000000000000000000000000000000000000000000000000000F03F0000000000000000000000000000000000000000000000000000000000000000000000000000F03F00000000000000000000000000000000000000000000000001030000800100000004000000000000000000F03F000000000000000000000000000000000000000000000000000000000000F03F000000000000000000000000000000000000000000000000000000000000F03F000000000000F03F00000000000000000000000000000000", tmp); lwfree(tmp); lwgeom_free(geom); diff --git a/liblwgeom/cunit/cu_tester.h b/liblwgeom/cunit/cu_tester.h index baa5e627a..862bc09e3 100644 --- a/liblwgeom/cunit/cu_tester.h +++ b/liblwgeom/cunit/cu_tester.h @@ -46,19 +46,6 @@ typedef void (*PG_SuiteSetup)(void); CU_ASSERT_STRING_EQUAL(o,e); \ } while (0); -#define ASSERT_VARLENA_EQUAL(v, s) \ - do \ - { \ - if (strncmp(v->data, s, LWSIZE_GET(v->size) - LWVARHDRSZ) != 0) \ - { \ - fprintf( \ - stderr, "[%s:%d]\n Expected: %s\n Obtained: %s\n", __FILE__, __LINE__, (s), (v->data)); \ - CU_FAIL(); \ - } \ - else \ - CU_PASS(); \ - } while (0); - #define ASSERT_LWGEOM_EQUAL(o, e) do { \ if ( !lwgeom_same(o, e) ) { \ char* wkt_o = lwgeom_to_ewkt(o); \ diff --git a/liblwgeom/gserialized.c b/liblwgeom/gserialized.c index e90a6d4e1..7492bc1ac 100644 --- a/liblwgeom/gserialized.c +++ b/liblwgeom/gserialized.c @@ -314,8 +314,8 @@ int gserialized_cmp(const GSERIALIZED *g1, const GSERIALIZED *g2) { GBOX box1, box2; uint64_t hash1, hash2; - size_t sz1 = LWSIZE_GET(g1->size); - size_t sz2 = LWSIZE_GET(g2->size); + size_t sz1 = SIZE_GET(g1->size); + size_t sz2 = SIZE_GET(g2->size); size_t hsz1 = gserialized_header_size(g1); size_t hsz2 = gserialized_header_size(g2); uint8_t *b1 = (uint8_t*)g1 + hsz1; diff --git a/liblwgeom/gserialized.txt b/liblwgeom/gserialized.txt index d774226f3..1e8377745 100644 --- a/liblwgeom/gserialized.txt +++ b/liblwgeom/gserialized.txt @@ -35,7 +35,7 @@ flags area. Or some combination of the above. typedef struct { - uint32 size; /* Use LWSIZE_SET() and LWSIZE_GET() macros to manipulate. */ + uint32 size; /* Use SIZE_SET() and SIZE_GET() macros to manipulate. */ uchar srid[3]; /* 21 bits of SRID (and 3 spare bits) */ uchar flags; /* High priority information */ uchar data[1]; /* See gserialized.txt */ diff --git a/liblwgeom/gserialized1.c b/liblwgeom/gserialized1.c index 1a87ccf52..728c00530 100644 --- a/liblwgeom/gserialized1.c +++ b/liblwgeom/gserialized1.c @@ -232,7 +232,7 @@ gserialized1_hash(const GSERIALIZED *g1) size_t hsz1 = gserialized1_header_size(g1); uint8_t *b1 = (uint8_t*)g1 + hsz1; /* Calculate size of type/coordinate buffer */ - size_t sz1 = LWSIZE_GET(g1->size); + size_t sz1 = SIZE_GET(g1->size); size_t bsz1 = sz1 - hsz1; /* Calculate size of srid/type/coordinate buffer */ int32_t srid = gserialized1_get_srid(g1); @@ -1533,7 +1533,7 @@ GSERIALIZED* gserialized1_set_gbox(GSERIALIZED *g, GBOX *gbox) */ else { - size_t varsize_new = LWSIZE_GET(g->size) + box_size; + size_t varsize_new = SIZE_GET(g->size) + box_size; uint8_t *ptr; g_out = lwalloc(varsize_new); /* Copy the head of g into place */ @@ -1541,9 +1541,9 @@ GSERIALIZED* gserialized1_set_gbox(GSERIALIZED *g, GBOX *gbox) /* Copy the body of g into place after leaving space for the box */ ptr = g_out->data; ptr += box_size; - memcpy(ptr, g->data, LWSIZE_GET(g->size) - 8); + memcpy(ptr, g->data, SIZE_GET(g->size) - 8); G1FLAGS_SET_BBOX(g_out->gflags, 1); - LWSIZE_SET(g_out->size, varsize_new); + SIZE_SET(g_out->size, varsize_new); } /* Move bounds to nearest float values */ @@ -1579,7 +1579,7 @@ GSERIALIZED* gserialized1_drop_gbox(GSERIALIZED *g) { int g_ndims = G1FLAGS_NDIMS_BOX(g->gflags); size_t box_size = 2 * g_ndims * sizeof(float); - size_t g_out_size = LWSIZE_GET(g->size) - box_size; + size_t g_out_size = SIZE_GET(g->size) - box_size; GSERIALIZED *g_out = lwalloc(g_out_size); /* Copy the contents while omitting the box */ @@ -1594,7 +1594,7 @@ GSERIALIZED* gserialized1_drop_gbox(GSERIALIZED *g) /* Copy parts after the box into place */ memcpy(outptr, inptr, g_out_size - 8); G1FLAGS_SET_BBOX(g_out->gflags, 0); - LWSIZE_SET(g_out->size, g_out_size); + SIZE_SET(g_out->size, g_out_size); } /* No box? Nothing to do but copy and return. */ else diff --git a/liblwgeom/gserialized2.c b/liblwgeom/gserialized2.c index f141157c9..7967704b7 100644 --- a/liblwgeom/gserialized2.c +++ b/liblwgeom/gserialized2.c @@ -274,7 +274,7 @@ gserialized2_hash(const GSERIALIZED *g1) size_t hsz1 = gserialized2_header_size(g1); uint8_t *b1 = (uint8_t *)g1 + hsz1; /* Calculate size of type/coordinate buffer */ - size_t sz1 = LWSIZE_GET(g1->size); + size_t sz1 = SIZE_GET(g1->size); size_t bsz1 = sz1 - hsz1; /* Calculate size of srid/type/coordinate buffer */ int32_t srid = gserialized2_get_srid(g1); @@ -1195,7 +1195,7 @@ GSERIALIZED* gserialized2_from_lwgeom(LWGEOM *geom, size_t *size) ** We are aping PgSQL code here, PostGIS code should use ** VARSIZE to set this for real. */ - LWSIZE_SET(g->size, expected_size); + SIZE_SET(g->size, expected_size); g->gflags = lwflags_get_g2flags(geom->flags); /* Move write head past size, srid and flags. */ @@ -1605,7 +1605,7 @@ GSERIALIZED* gserialized2_set_gbox(GSERIALIZED *g, GBOX *gbox) */ else { - size_t varsize_in = LWSIZE_GET(g->size); + size_t varsize_in = SIZE_GET(g->size); size_t varsize_out = varsize_in + box_size; uint8_t *ptr_out, *ptr_in, *ptr; g_out = lwalloc(varsize_out); @@ -1622,7 +1622,7 @@ GSERIALIZED* gserialized2_set_gbox(GSERIALIZED *g, GBOX *gbox) ptr_out += box_size; memcpy(ptr_out, ptr_in, varsize_in - (ptr_in - ptr)); G2FLAGS_SET_BBOX(g_out->gflags, 1); - LWSIZE_SET(g_out->size, varsize_out); + SIZE_SET(g_out->size, varsize_out); } /* Move bounds to nearest float values */ @@ -1658,7 +1658,7 @@ GSERIALIZED* gserialized2_drop_gbox(GSERIALIZED *g) { int g_ndims = G2FLAGS_NDIMS_BOX(g->gflags); size_t box_size = 2 * g_ndims * sizeof(float); - size_t g_out_size = LWSIZE_GET(g->size) - box_size; + size_t g_out_size = SIZE_GET(g->size) - box_size; GSERIALIZED *g_out = lwalloc(g_out_size); /* Copy the contents while omitting the box */ @@ -1678,7 +1678,7 @@ GSERIALIZED* gserialized2_drop_gbox(GSERIALIZED *g) /* Copy parts after the box into place */ memcpy(outptr, inptr, g_out_size - 8); G2FLAGS_SET_BBOX(g_out->gflags, 0); - LWSIZE_SET(g_out->size, g_out_size); + SIZE_SET(g_out->size, g_out_size); } /* No box? Nothing to do but copy and return. */ else diff --git a/liblwgeom/liblwgeom.h.in b/liblwgeom/liblwgeom.h.in index aa7f74ca7..b6c4475ec 100644 --- a/liblwgeom/liblwgeom.h.in +++ b/liblwgeom/liblwgeom.h.in @@ -312,34 +312,6 @@ extern lwinterrupt_callback *lwgeom_register_interrupt_callback(lwinterrupt_call */ typedef uint16_t lwflags_t; -/****************************************************************** -* LWGEOM varlena equivalent type that contains both the size and -* data(see Postgresql c.h) -*/ -typedef struct lwvarlena_t -{ - uint32_t size; /* Do not touch this field directly! */ - char data[]; /* Data content is here */ -} lwvarlena_t; - -#define LWVARHDRSZ ((int32_t) sizeof(int32_t)) - -/** -* Macro for reading the size from the GSERIALIZED size attribute. -* Cribbed from PgSQL, top 30 bits are size. Use VARSIZE() when working -* internally with PgSQL. See SET_VARSIZE_4B / VARSIZE_4B in -* PGSRC/src/include/postgres.h for details. -*/ -#ifdef WORDS_BIGENDIAN -#define LWSIZE_GET(varsize) ((varsize) & 0x3FFFFFFF) -#define LWSIZE_SET(varsize, len) ((varsize) = ((len) & 0x3FFFFFFF)) -#define IS_BIG_ENDIAN 1 -#else -#define LWSIZE_GET(varsize) (((varsize) >> 2) & 0x3FFFFFFF) -#define LWSIZE_SET(varsize, len) ((varsize) = (((uint32_t)(len)) << 2)) -#define IS_BIG_ENDIAN 0 -#endif - /******************************************************************/ typedef struct { @@ -1635,7 +1607,7 @@ extern LWPOINT* lwmpoint_median(const LWMPOINT *g, double tol, uint32_t maxiter, /** * Calculate the GeoHash (http://geohash.org) string for a geometry. Caller must free. */ -lwvarlena_t *lwgeom_geohash(const LWGEOM *lwgeom, int precision); +char *lwgeom_geohash(const LWGEOM *lwgeom, int precision); unsigned int geohash_point_as_int(POINT2D *pt); @@ -1691,18 +1663,18 @@ LWCOLLECTION* lwgeom_clip_to_ordinate_range(const LWGEOM *lwin, char ordinate, d -extern lwvarlena_t* lwgeom_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix); -extern lwvarlena_t* lwgeom_extent_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix); +extern char* lwgeom_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix); +extern char* lwgeom_extent_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix); /** * @param opts output options bitfield, see LW_GML macros for meaning */ -extern lwvarlena_t* lwgeom_extent_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix); -extern lwvarlena_t* lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix, const char *id); -extern lwvarlena_t* lwgeom_to_kml2(const LWGEOM *geom, int precision, const char *prefix); -extern lwvarlena_t* lwgeom_to_geojson(const LWGEOM *geo, char *srs, int precision, int has_bbox); -extern lwvarlena_t* lwgeom_to_x3d3(const LWGEOM *geom, char *srs, int precision, int opts, const char *defid); -extern lwvarlena_t* lwgeom_to_svg(const LWGEOM *geom, int precision, int relative); -extern lwvarlena_t* lwgeom_to_encoded_polyline(const LWGEOM *geom, int precision); +extern char* lwgeom_extent_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix); +extern char* lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix, const char *id); +extern char* lwgeom_to_kml2(const LWGEOM *geom, int precision, const char *prefix); +extern char* lwgeom_to_geojson(const LWGEOM *geo, char *srs, int precision, int has_bbox); +extern char* lwgeom_to_svg(const LWGEOM *geom, int precision, int relative); +extern char* lwgeom_to_x3d3(const LWGEOM *geom, char *srs, int precision, int opts, const char *defid); +extern char* lwgeom_to_encoded_polyline(const LWGEOM *geom, int precision); /** * Create an LWGEOM object from a GeoJSON representation @@ -2171,25 +2143,17 @@ LWGEOM_UNPARSER_RESULT; /** * @param geom geometry to convert to WKT * @param variant output format to use (WKT_ISO, WKT_SFSQL, WKT_EXTENDED) -* @param precision Double precision * @param size_out (Out parameter) size of the buffer */ extern char* lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out); /** * @param geom geometry to convert to WKT -* @param variant output format to use (WKT_ISO, WKT_SFSQL, WKT_EXTENDED) -* @param precision Double precision -*/ -extern lwvarlena_t* lwgeom_to_wkt_varlena(const LWGEOM *geom, uint8_t variant, int precision); - -/** -* @param geom geometry to convert to WKB * @param variant output format to use * (WKB_ISO, WKB_SFSQL, WKB_EXTENDED, WKB_NDR, WKB_XDR) +* @param size_out (Out parameter) size of the buffer */ -extern uint8_t* lwgeom_to_wkb_buffer(const LWGEOM *geom, uint8_t variant); -extern lwvarlena_t* lwgeom_to_wkb_varlena(const LWGEOM *geom, uint8_t variant); +extern uint8_t* lwgeom_to_wkb(const LWGEOM *geom, uint8_t variant, size_t *size_out); /** * @param geom geometry to convert to HEXWKB @@ -2197,8 +2161,7 @@ extern lwvarlena_t* lwgeom_to_wkb_varlena(const LWGEOM *geom, uint8_t variant); * (WKB_ISO, WKB_SFSQL, WKB_EXTENDED, WKB_NDR, WKB_XDR) * @param size_out (Out parameter) size of the buffer */ -extern char* lwgeom_to_hexwkb_buffer(const LWGEOM *geom, uint8_t variant); -extern lwvarlena_t* lwgeom_to_hexwkb_varlena(const LWGEOM *geom, uint8_t variant); +extern char* lwgeom_to_hexwkb(const LWGEOM *geom, uint8_t variant, size_t *size_out); /** * @param lwgeom geometry to convert to EWKT @@ -2259,9 +2222,9 @@ extern LWGEOM* lwgeom_from_twkb(const uint8_t *twkb, size_t twkb_size, char chec * @param variant what variations on TWKB are requested? * @param twkb_size returns the length of the output TWKB in bytes if set */ -extern lwvarlena_t* lwgeom_to_twkb(const LWGEOM *geom, uint8_t variant, int8_t precision_xy, int8_t precision_z, int8_t precision_m); +extern uint8_t* lwgeom_to_twkb(const LWGEOM *geom, uint8_t variant, int8_t precision_xy, int8_t precision_z, int8_t precision_m, size_t *twkb_size); -extern lwvarlena_t* lwgeom_to_twkb_with_idlist(const LWGEOM *geom, int64_t *idlist, uint8_t variant, int8_t precision_xy, int8_t precision_z, int8_t precision_m); +extern uint8_t* lwgeom_to_twkb_with_idlist(const LWGEOM *geom, int64_t *idlist, uint8_t variant, int8_t precision_xy, int8_t precision_z, int8_t precision_m, size_t *twkb_size); /** * Trim the bits of an LWGEOM in place, to optimize it for compression. diff --git a/liblwgeom/liblwgeom_internal.h b/liblwgeom/liblwgeom_internal.h index 44bcbfb22..e47d6d4ca 100644 --- a/liblwgeom/liblwgeom_internal.h +++ b/liblwgeom/liblwgeom_internal.h @@ -114,6 +114,21 @@ #define WKB_TIN_TYPE 16 #define WKB_TRIANGLE_TYPE 17 +/** +* Macro for reading the size from the GSERIALIZED size attribute. +* Cribbed from PgSQL, top 30 bits are size. Use VARSIZE() when working +* internally with PgSQL. See SET_VARSIZE_4B / VARSIZE_4B in +* PGSRC/src/include/postgres.h for details. +*/ +#ifdef WORDS_BIGENDIAN +#define SIZE_GET(varsize) ((varsize) & 0x3FFFFFFF) +#define SIZE_SET(varsize, len) ((varsize) = ((len) & 0x3FFFFFFF)) +#define IS_BIG_ENDIAN 1 +#else +#define SIZE_GET(varsize) (((varsize) >> 2) & 0x3FFFFFFF) +#define SIZE_SET(varsize, len) ((varsize) = (((uint32_t)(len)) << 2)) +#define IS_BIG_ENDIAN 0 +#endif /** * Macro that returns: @@ -239,7 +254,7 @@ int point_interpolate(const POINT4D *p1, const POINT4D *p2, POINT4D *p, int hasz * Geohash */ int lwgeom_geohash_precision(GBOX bbox, GBOX *bounds); -lwvarlena_t *geohash_point(double longitude, double latitude, int precision); +char *geohash_point(double longitude, double latitude, int precision); void decode_geohash_bbox(char *geohash, double *lat, double *lon, int precision); /* diff --git a/liblwgeom/lwalgorithm.c b/liblwgeom/lwalgorithm.c index dcd6f147e..1a2b8237a 100644 --- a/liblwgeom/lwalgorithm.c +++ b/liblwgeom/lwalgorithm.c @@ -589,16 +589,15 @@ static char *base32 = "0123456789bcdefghjkmnpqrstuvwxyz"; ** From geohash-native.c, (c) 2008 David Troy ** Released under the MIT License. */ -lwvarlena_t * -geohash_point(double longitude, double latitude, int precision) +char *geohash_point(double longitude, double latitude, int precision) { int is_even=1, i=0; double lat[2], lon[2], mid; char bits[] = {16,8,4,2,1}; int bit=0, ch=0; - lwvarlena_t *v = lwalloc(precision + LWVARHDRSZ); - LWSIZE_SET(v->size, precision + LWVARHDRSZ); - char *geohash = v->data; + char *geohash = NULL; + + geohash = lwalloc(precision + 1); lat[0] = -90.0; lat[1] = 90.0; @@ -646,8 +645,8 @@ geohash_point(double longitude, double latitude, int precision) ch = 0; } } - - return v; + geohash[i] = 0; + return geohash; } @@ -854,8 +853,7 @@ int lwgeom_geohash_precision(GBOX bbox, GBOX *bounds) ** bounds of the feature. Big features have loose precision. ** Small features have tight precision. */ -lwvarlena_t * -lwgeom_geohash(const LWGEOM *lwgeom, int precision) +char *lwgeom_geohash(const LWGEOM *lwgeom, int precision) { GBOX gbox; GBOX gbox_bounds; diff --git a/liblwgeom/lwout_encoded_polyline.c b/liblwgeom/lwout_encoded_polyline.c index e5afdd44b..20bf27238 100644 --- a/liblwgeom/lwout_encoded_polyline.c +++ b/liblwgeom/lwout_encoded_polyline.c @@ -26,13 +26,13 @@ #include "stringbuffer.h" #include "liblwgeom_internal.h" -static lwvarlena_t *lwline_to_encoded_polyline(const LWLINE *, int precision); -static lwvarlena_t *lwmmpoint_to_encoded_polyline(const LWMPOINT *, int precision); -static lwvarlena_t *pointarray_to_encoded_polyline(const POINTARRAY *, int precision); +static char* lwline_to_encoded_polyline(const LWLINE*, int precision); +static char* lwmmpoint_to_encoded_polyline(const LWMPOINT*, int precision); +static char* pointarray_to_encoded_polyline(const POINTARRAY*, int precision); /* takes a GEOMETRY and returns an Encoded Polyline representation */ -extern lwvarlena_t * -lwgeom_to_encoded_polyline(const LWGEOM *geom, int precision) +extern char* +lwgeom_to_encoded_polyline(const LWGEOM* geom, int precision) { int type = geom->type; switch (type) @@ -48,37 +48,37 @@ lwgeom_to_encoded_polyline(const LWGEOM *geom, int precision) } } -static lwvarlena_t * -lwline_to_encoded_polyline(const LWLINE *line, int precision) +static char* +lwline_to_encoded_polyline(const LWLINE* line, int precision) { return pointarray_to_encoded_polyline(line->points, precision); } -static lwvarlena_t * -lwmmpoint_to_encoded_polyline(const LWMPOINT *mpoint, int precision) +static char* +lwmmpoint_to_encoded_polyline(const LWMPOINT* mpoint, int precision) { LWLINE* line = lwline_from_lwmpoint(mpoint->srid, mpoint); - lwvarlena_t *encoded_polyline = lwline_to_encoded_polyline(line, precision); + char* encoded_polyline = lwline_to_encoded_polyline(line, precision); lwline_free(line); return encoded_polyline; } -static lwvarlena_t * -pointarray_to_encoded_polyline(const POINTARRAY *pa, int precision) +static char* +pointarray_to_encoded_polyline(const POINTARRAY* pa, int precision) { uint32_t i; const POINT2D* prevPoint; int* delta; + char* encoded_polyline = NULL; stringbuffer_t* sb; double scale = pow(10, precision); /* Empty input is empty string */ - if (pa->npoints == 0) - { - lwvarlena_t *v = lwalloc(LWVARHDRSZ); - LWSIZE_SET(v->size, LWVARHDRSZ); - return v; + if (pa->npoints == 0) { + encoded_polyline = lwalloc(1 * sizeof(char)); + encoded_polyline[0] = 0; + return encoded_polyline; } delta = lwalloc(2 * sizeof(int) * pa->npoints); @@ -132,8 +132,8 @@ pointarray_to_encoded_polyline(const POINTARRAY *pa, int precision) } lwfree(delta); - lwvarlena_t *v = stringbuffer_getvarlenacopy(sb); + encoded_polyline = stringbuffer_getstringcopy(sb); stringbuffer_destroy(sb); - return v; + return encoded_polyline; } diff --git a/liblwgeom/lwout_geojson.c b/liblwgeom/lwout_geojson.c index 3b53f838d..c9c788882 100644 --- a/liblwgeom/lwout_geojson.c +++ b/liblwgeom/lwout_geojson.c @@ -28,14 +28,14 @@ #include /* strlen */ #include -static lwvarlena_t *asgeojson_point(const LWPOINT *point, char *srs, GBOX *bbox, int precision); -static lwvarlena_t *asgeojson_line(const LWLINE *line, char *srs, GBOX *bbox, int precision); -static lwvarlena_t *asgeojson_triangle(const LWTRIANGLE *tri, char *srs, GBOX *bbox, int precision); -static lwvarlena_t *asgeojson_poly(const LWPOLY *poly, char *srs, GBOX *bbox, int precision); -static lwvarlena_t *asgeojson_multipoint(const LWMPOINT *mpoint, char *srs, GBOX *bbox, int precision); -static lwvarlena_t *asgeojson_multiline(const LWMLINE *mline, char *srs, GBOX *bbox, int precision); -static lwvarlena_t *asgeojson_multipolygon(const LWMPOLY *mpoly, char *srs, GBOX *bbox, int precision); -static lwvarlena_t *asgeojson_collection(const LWCOLLECTION *col, char *srs, GBOX *bbox, int precision); +static char *asgeojson_point(const LWPOINT *point, char *srs, GBOX *bbox, int precision); +static char *asgeojson_line(const LWLINE *line, char *srs, GBOX *bbox, int precision); +static char *asgeojson_triangle(const LWTRIANGLE *tri, char *srs, GBOX *bbox, int precision); +static char *asgeojson_poly(const LWPOLY *poly, char *srs, GBOX *bbox, int precision); +static char *asgeojson_multipoint(const LWMPOINT *mpoint, char *srs, GBOX *bbox, int precision); +static char *asgeojson_multiline(const LWMLINE *mline, char *srs, GBOX *bbox, int precision); +static char *asgeojson_multipolygon(const LWMPOLY *mpoly, char *srs, GBOX *bbox, int precision); +static char *asgeojson_collection(const LWCOLLECTION *col, char *srs, GBOX *bbox, int precision); static size_t asgeojson_geom_size(const LWGEOM *geom, GBOX *bbox, int precision); static size_t asgeojson_geom_buf(const LWGEOM *geom, char *output, GBOX *bbox, int precision); @@ -45,7 +45,7 @@ static size_t pointArray_geojson_size(POINTARRAY *pa, int precision); /** * Takes a GEOMETRY and returns a GeoJson representation */ -lwvarlena_t * +char * lwgeom_to_geojson(const LWGEOM *geom, char *srs, int precision, int has_bbox) { int type = geom->type; @@ -201,13 +201,15 @@ asgeojson_point_buf(const LWPOINT *point, char *srs, char *output, GBOX *bbox, i return (ptr-output); } -static lwvarlena_t * +static char * asgeojson_point(const LWPOINT *point, char *srs, GBOX *bbox, int precision) { - uint32_t size = asgeojson_point_size(point, srs, bbox, precision); - lwvarlena_t *output = (lwvarlena_t *)lwalloc(size + LWVARHDRSZ); - size = asgeojson_point_buf(point, srs, output->data, bbox, precision); - LWSIZE_SET(output->size, size + LWVARHDRSZ); + char *output; + int size; + + size = asgeojson_point_size(point, srs, bbox, precision); + output = lwalloc(size); + asgeojson_point_buf(point, srs, output, bbox, precision); return output; } @@ -248,13 +250,16 @@ asgeojson_triangle_buf(const LWTRIANGLE *tri, char *srs, char *output, GBOX *bbo return (ptr - output); } -static lwvarlena_t * +static char * asgeojson_triangle(const LWTRIANGLE *tri, char *srs, GBOX *bbox, int precision) { - uint32_t size = asgeojson_triangle_size(tri, srs, bbox, precision); - lwvarlena_t *output = (lwvarlena_t *)lwalloc(size + LWVARHDRSZ); - size = asgeojson_triangle_buf(tri, srs, output->data, bbox, precision); - LWSIZE_SET(output->size, size + LWVARHDRSZ); + char *output; + int size; + + size = asgeojson_triangle_size(tri, srs, bbox, precision); + output = lwalloc(size); + asgeojson_triangle_buf(tri, srs, output, bbox, precision); + return output; } @@ -291,13 +296,16 @@ asgeojson_line_buf(const LWLINE *line, char *srs, char *output, GBOX *bbox, int return (ptr-output); } -static lwvarlena_t * +static char * asgeojson_line(const LWLINE *line, char *srs, GBOX *bbox, int precision) { - uint32_t size = asgeojson_line_size(line, srs, bbox, precision); - lwvarlena_t *output = (lwvarlena_t *)lwalloc(size + LWVARHDRSZ); - size = asgeojson_line_buf(line, srs, output->data, bbox, precision); - LWSIZE_SET(output->size, size + LWVARHDRSZ); + char *output; + int size; + + size = asgeojson_line_size(line, srs, bbox, precision); + output = lwalloc(size); + asgeojson_line_buf(line, srs, output, bbox, precision); + return output; } @@ -351,13 +359,16 @@ asgeojson_poly_buf(const LWPOLY *poly, char *srs, char *output, GBOX *bbox, int return (ptr-output); } -static lwvarlena_t * +static char * asgeojson_poly(const LWPOLY *poly, char *srs, GBOX *bbox, int precision) { - uint32_t size = asgeojson_poly_size(poly, srs, bbox, precision); - lwvarlena_t *output = (lwvarlena_t *)lwalloc(size + LWVARHDRSZ); - size = asgeojson_poly_buf(poly, srs, output->data, bbox, precision); - LWSIZE_SET(output->size, size + LWVARHDRSZ); + char *output; + int size; + + size = asgeojson_poly_size(poly, srs, bbox, precision); + output = lwalloc(size); + asgeojson_poly_buf(poly, srs, output, bbox, precision); + return output; } @@ -412,13 +423,16 @@ asgeojson_multipoint_buf(const LWMPOINT *mpoint, char *srs, char *output, GBOX * return (ptr - output); } -static lwvarlena_t * +static char * asgeojson_multipoint(const LWMPOINT *mpoint, char *srs, GBOX *bbox, int precision) { - uint32_t size = asgeojson_multipoint_size(mpoint, srs, bbox, precision); - lwvarlena_t *output = (lwvarlena_t *)lwalloc(size + LWVARHDRSZ); - size = asgeojson_multipoint_buf(mpoint, srs, output->data, bbox, precision); - LWSIZE_SET(output->size, size + LWVARHDRSZ); + char *output; + int size; + + size = asgeojson_multipoint_size(mpoint, srs, bbox, precision); + output = lwalloc(size); + asgeojson_multipoint_buf(mpoint, srs, output, bbox, precision); + return output; } @@ -477,13 +491,16 @@ asgeojson_multiline_buf(const LWMLINE *mline, char *srs, char *output, GBOX *bbo return (ptr - output); } -static lwvarlena_t * +static char * asgeojson_multiline(const LWMLINE *mline, char *srs, GBOX *bbox, int precision) { - uint32_t size = asgeojson_multiline_size(mline, srs, bbox, precision); - lwvarlena_t *output = (lwvarlena_t *)lwalloc(size + LWVARHDRSZ); - size = asgeojson_multiline_buf(mline, srs, output->data, bbox, precision); - LWSIZE_SET(output->size, size + LWVARHDRSZ); + char *output; + int size; + + size = asgeojson_multiline_size(mline, srs, bbox, precision); + output = lwalloc(size); + asgeojson_multiline_buf(mline, srs, output, bbox, precision); + return output; } @@ -551,13 +568,16 @@ asgeojson_multipolygon_buf(const LWMPOLY *mpoly, char *srs, char *output, GBOX * return (ptr - output); } -static lwvarlena_t * +static char * asgeojson_multipolygon(const LWMPOLY *mpoly, char *srs, GBOX *bbox, int precision) { - uint32_t size = asgeojson_multipolygon_size(mpoly, srs, bbox, precision); - lwvarlena_t *output = (lwvarlena_t *)lwalloc(size + LWVARHDRSZ); - size = asgeojson_multipolygon_buf(mpoly, srs, output->data, bbox, precision); - LWSIZE_SET(output->size, size + LWVARHDRSZ); + char *output; + int size; + + size = asgeojson_multipolygon_size(mpoly, srs, bbox, precision); + output = lwalloc(size); + asgeojson_multipolygon_buf(mpoly, srs, output, bbox, precision); + return output; } @@ -614,13 +634,16 @@ asgeojson_collection_buf(const LWCOLLECTION *col, char *srs, char *output, GBOX return (ptr - output); } -static lwvarlena_t * +static char * asgeojson_collection(const LWCOLLECTION *col, char *srs, GBOX *bbox, int precision) { - uint32_t size = asgeojson_collection_size(col, srs, bbox, precision); - lwvarlena_t *output = (lwvarlena_t *)lwalloc(size + LWVARHDRSZ); - size = asgeojson_collection_buf(col, srs, output->data, bbox, precision); - LWSIZE_SET(output->size, size + LWVARHDRSZ); + char *output; + int size; + + size = asgeojson_collection_size(col, srs, bbox, precision); + output = lwalloc(size); + asgeojson_collection_buf(col, srs, output, bbox, precision); + return output; } diff --git a/liblwgeom/lwout_gml.c b/liblwgeom/lwout_gml.c index 308727fdc..d55d6dc19 100644 --- a/liblwgeom/lwout_gml.c +++ b/liblwgeom/lwout_gml.c @@ -33,79 +33,45 @@ #include #include "liblwgeom_internal.h" -#include "liblwgeom.h" + static size_t asgml2_point_size(const LWPOINT *point, const char *srs, int precision, const char *prefix); -static lwvarlena_t *asgml2_point(const LWPOINT *point, const char *srs, int precision, const char *prefix); +static char *asgml2_point(const LWPOINT *point, const char *srs, int precision, const char *prefix); static size_t asgml2_line_size(const LWLINE *line, const char *srs, int precision, const char *prefix); -static lwvarlena_t *asgml2_line(const LWLINE *line, const char *srs, int precision, const char *prefix); +static char *asgml2_line(const LWLINE *line, const char *srs, int precision, const char *prefix); static size_t asgml2_poly_size(const LWPOLY *poly, const char *srs, int precision, const char *prefix); -static lwvarlena_t *asgml2_poly(const LWPOLY *poly, const char *srs, int precision, const char *prefix); +static char *asgml2_poly(const LWPOLY *poly, const char *srs, int precision, const char *prefix); static size_t asgml2_multi_size(const LWCOLLECTION *col, const char *srs, int precision, const char *prefix); -static lwvarlena_t *asgml2_multi(const LWCOLLECTION *col, const char *srs, int precision, const char *prefix); +static char *asgml2_multi(const LWCOLLECTION *col, const char *srs, int precision, const char *prefix); static size_t asgml2_collection_size(const LWCOLLECTION *col, const char *srs, int precision, const char *prefix); -static lwvarlena_t *asgml2_collection(const LWCOLLECTION *col, const char *srs, int precision, const char *prefix); +static char *asgml2_collection(const LWCOLLECTION *col, const char *srs, int precision, const char *prefix); static size_t pointArray_toGML2(POINTARRAY *pa, char *buf, int precision); static size_t asgml3_point_size(const LWPOINT *point, const char *srs, int precision, int opts, const char *prefix, const char *id); -static lwvarlena_t * -asgml3_point(const LWPOINT *point, const char *srs, int precision, int opts, const char *prefix, const char *id); +static char *asgml3_point(const LWPOINT *point, const char *srs, int precision, int opts, const char *prefix, const char *id); static size_t asgml3_line_size(const LWLINE *line, const char *srs, int precision, int opts, const char *prefix, const char *id); -static lwvarlena_t * -asgml3_line(const LWLINE *line, const char *srs, int precision, int opts, const char *prefix, const char *id); -static lwvarlena_t *asgml3_circstring(const LWCIRCSTRING *circ, - const char *srs, - int precision, - int opts, - const char *prefix, - const char *id); +static char *asgml3_line(const LWLINE *line, const char *srs, int precision, int opts, const char *prefix, const char *id); +static char *asgml3_circstring( const LWCIRCSTRING *circ, const char *srs, int precision, int opts, const char *prefix, const char *id ); static size_t asgml3_poly_size(const LWPOLY *poly, const char *srs, int precision, int opts, const char *prefix, const char *id); -static lwvarlena_t *asgml3_poly(const LWPOLY *poly, - const char *srs, - int precision, - int opts, - int is_patch, - const char *prefix, - const char *id); -static lwvarlena_t * -asgml3_curvepoly(const LWCURVEPOLY *poly, const char *srs, int precision, int opts, const char *prefix, const char *id); +static char *asgml3_poly(const LWPOLY *poly, const char *srs, int precision, int opts, int is_patch, const char *prefix, const char *id); +static char * asgml3_curvepoly(const LWCURVEPOLY* poly, const char *srs, int precision, int opts, const char *prefix, const char *id); static size_t asgml3_triangle_size(const LWTRIANGLE *triangle, const char *srs, int precision, int opts, const char *prefix, const char *id); -static lwvarlena_t *asgml3_triangle(const LWTRIANGLE *triangle, - const char *srs, - int precision, - int opts, - const char *prefix, - const char *id); +static char *asgml3_triangle(const LWTRIANGLE *triangle, const char *srs, int precision, int opts, const char *prefix, const char *id); static size_t asgml3_multi_size(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id); -static lwvarlena_t * -asgml3_multi(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id); -static lwvarlena_t * -asgml3_psurface(const LWPSURFACE *psur, const char *srs, int precision, int opts, const char *prefix, const char *id); -static lwvarlena_t * -asgml3_tin(const LWTIN *tin, const char *srs, int precision, int opts, const char *prefix, const char *id); +static char *asgml3_multi(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id); +static char *asgml3_psurface(const LWPSURFACE *psur, const char *srs, int precision, int opts, const char *prefix, const char *id); +static char *asgml3_tin(const LWTIN *tin, const char *srs, int precision, int opts, const char *prefix, const char *id); static size_t asgml3_collection_size(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id); -static lwvarlena_t *asgml3_collection(const LWCOLLECTION *col, - const char *srs, - int precision, - int opts, - const char *prefix, - const char *id); -static lwvarlena_t * -asgml3_compound(const LWCOMPOUND *col, const char *srs, int precision, int opts, const char *prefix, const char *id); -static lwvarlena_t * -asgml3_multicurve(const LWMCURVE *cur, const char *srs, int precision, int opts, const char *prefix, const char *id); -static lwvarlena_t *asgml3_multisurface(const LWMSURFACE *sur, - const char *srs, - int precision, - int opts, - const char *prefix, - const char *id); +static char *asgml3_collection(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id); +static char *asgml3_compound(const LWCOMPOUND *col, const char *srs, int precision, int opts, const char *prefix, const char *id ); +static char *asgml3_multicurve( const LWMCURVE* cur, const char *srs, int precision, int opts, const char *prefix, const char *id ); +static char *asgml3_multisurface(const LWMSURFACE *sur, const char *srs, int precision, int opts, const char *prefix, const char *id); static size_t pointArray_toGML3(POINTARRAY *pa, char *buf, int precision, int opts); static size_t pointArray_GMLsize(POINTARRAY *pa, int precision); -static lwvarlena_t * +static char * gbox_to_gml2(const GBOX *bbox, const char *srs, int precision, const char *prefix) { int size; @@ -119,8 +85,7 @@ gbox_to_gml2(const GBOX *bbox, const char *srs, int precision, const char *prefi size = ( sizeof("/") + (prefixlen*2) ) * 2; if ( srs ) size += strlen(srs) + sizeof(" srsName=.."); - lwvarlena_t *v = lwalloc(size + LWVARHDRSZ); - ptr = output = v->data; + ptr = output = lwalloc(size); ptr += sprintf(ptr, "<%sBox", prefix); @@ -128,9 +93,7 @@ gbox_to_gml2(const GBOX *bbox, const char *srs, int precision, const char *prefi ptr += sprintf(ptr, "/>"); - LWSIZE_SET(v->size, ptr - output + LWVARHDRSZ); - - return v; + return output; } pa = ptarray_construct_empty(FLAGS_GET_Z(bbox->flags), 0, 2); @@ -149,8 +112,7 @@ gbox_to_gml2(const GBOX *bbox, const char *srs, int precision, const char *prefi size += ( sizeof("/") + (prefixlen*2) ) * 2; if ( srs ) size += strlen(srs) + sizeof(" srsName=.."); - lwvarlena_t *v = lwalloc(size + LWVARHDRSZ); - ptr = output = v->data; + ptr = output = lwalloc(size); if ( srs ) ptr += sprintf(ptr, "<%sBox srsName=\"%s\">", prefix, srs); else ptr += sprintf(ptr, "<%sBox>", prefix); @@ -160,12 +122,11 @@ gbox_to_gml2(const GBOX *bbox, const char *srs, int precision, const char *prefi ptr += sprintf(ptr, "", prefix, prefix); ptarray_free(pa); - LWSIZE_SET(v->size, ptr - output + LWVARHDRSZ); - return v; + return output; } -static lwvarlena_t * +static char * gbox_to_gml3(const GBOX *bbox, const char *srs, int precision, int opts, const char *prefix) { int size; @@ -180,16 +141,14 @@ gbox_to_gml3(const GBOX *bbox, const char *srs, int precision, int opts, const c size = ( sizeof("/") + (prefixlen*2) ) * 2; if ( srs ) size += strlen(srs) + sizeof(" srsName=.."); - lwvarlena_t *v = lwalloc(size + LWVARHDRSZ); - ptr = output = v->data; + ptr = output = lwalloc(size); ptr += sprintf(ptr, "<%sEnvelope", prefix); if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs); ptr += sprintf(ptr, "/>"); - LWSIZE_SET(v->size, ptr - output + LWVARHDRSZ); - return v; + return output; } if (FLAGS_GET_Z(bbox->flags)) dimension = 3; @@ -206,8 +165,7 @@ gbox_to_gml3(const GBOX *bbox, const char *srs, int precision, int opts, const c if ( srs ) size += strlen(srs) + sizeof(" srsName=.."); if ( IS_DIMS(opts) ) size += sizeof(" srsDimension=. ."); - lwvarlena_t *v = lwalloc(size + LWVARHDRSZ); - ptr = output = v->data; + ptr = output = lwalloc(size); ptr += sprintf(ptr, "<%sEnvelope", prefix); if ( srs ) ptr += sprintf(ptr, " srsName=\"%s\"", srs); @@ -232,21 +190,35 @@ gbox_to_gml3(const GBOX *bbox, const char *srs, int precision, int opts, const c ptarray_free(pa); - LWSIZE_SET(v->size, ptr - output + LWVARHDRSZ); - return v; + return output; } -extern lwvarlena_t * + +extern char * lwgeom_extent_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix) { const GBOX* bbox = lwgeom_get_bbox(geom); - return gbox_to_gml2(bbox, srs, precision, prefix); + /* + if ( ! bbox ) { + lwerror("lwgeom_extent_to_gml2: empty geometry doesn't have a bounding box"); + return NULL; + } + */ + char *ret = gbox_to_gml2(bbox, srs, precision, prefix); + return ret; } -extern lwvarlena_t * + +extern char * lwgeom_extent_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix) { const GBOX* bbox = lwgeom_get_bbox(geom); + /* + if ( ! bbox ) { + lwerror("lwgeom_extent_to_gml3: empty geometry doesn't have a bounding box"); + return NULL; + } + */ return gbox_to_gml3(bbox, srs, precision, opts, prefix); } @@ -255,8 +227,8 @@ lwgeom_extent_to_gml3(const LWGEOM *geom, const char *srs, int precision, int op * @brief VERSION GML 2 * takes a GEOMETRY and returns a GML2 representation */ -extern lwvarlena_t * -lwgeom_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char *prefix) +extern char * +lwgeom_to_gml2(const LWGEOM *geom, const char *srs, int precision, const char* prefix) { int type = geom->type; @@ -327,13 +299,15 @@ asgml2_point_buf(const LWPOINT *point, const char *srs, char *output, int precis return (ptr-output); } -static lwvarlena_t * +static char * asgml2_point(const LWPOINT *point, const char *srs, int precision, const char *prefix) { - int size = asgml2_point_size(point, srs, precision, prefix); - lwvarlena_t *output = lwalloc(LWVARHDRSZ + size); - size = asgml2_point_buf(point, srs, output->data, precision, prefix); - LWSIZE_SET(output->size, size + LWVARHDRSZ); + char *output; + int size; + + size = asgml2_point_size(point, srs, precision, prefix); + output = lwalloc(size); + asgml2_point_buf(point, srs, output, precision, prefix); return output; } @@ -372,13 +346,15 @@ asgml2_line_buf(const LWLINE *line, const char *srs, char *output, int precision return (ptr-output); } -static lwvarlena_t * +static char * asgml2_line(const LWLINE *line, const char *srs, int precision, const char *prefix) { - int size = asgml2_line_size(line, srs, precision, prefix); - lwvarlena_t *output = lwalloc(LWVARHDRSZ + size); - size = asgml2_line_buf(line, srs, output->data, precision, prefix); - LWSIZE_SET(output->size, size + LWVARHDRSZ); + char *output; + int size; + + size = asgml2_line_size(line, srs, precision, prefix); + output = lwalloc(size); + asgml2_line_buf(line, srs, output, precision, prefix); return output; } @@ -432,13 +408,15 @@ asgml2_poly_buf(const LWPOLY *poly, const char *srs, char *output, int precision return (ptr-output); } -static lwvarlena_t * +static char * asgml2_poly(const LWPOLY *poly, const char *srs, int precision, const char *prefix) { - int size = asgml2_poly_size(poly, srs, precision, prefix); - lwvarlena_t *output = lwalloc(LWVARHDRSZ + size); - size = asgml2_poly_buf(poly, srs, output->data, precision, prefix); - LWSIZE_SET(output->size, size + LWVARHDRSZ); + char *output; + int size; + + size = asgml2_poly_size(poly, srs, precision, prefix); + output = lwalloc(size); + asgml2_poly_buf(poly, srs, output, precision, prefix); return output; } @@ -547,14 +525,17 @@ asgml2_multi_buf(const LWCOLLECTION *col, const char *srs, char *output, /* * Don't call this with single-geoms inspected! */ -static lwvarlena_t * -asgml2_multi(const LWCOLLECTION *col, const char *srs, int precision, const char *prefix) +static char * +asgml2_multi(const LWCOLLECTION *col, const char *srs, int precision, + const char *prefix) { - int size = asgml2_multi_size(col, srs, precision, prefix); - lwvarlena_t *output = lwalloc(LWVARHDRSZ + size); - size = asgml2_multi_buf(col, srs, output->data, precision, prefix); - LWSIZE_SET(output->size, size + LWVARHDRSZ); - return output; + char *gml; + size_t size; + + size = asgml2_multi_size(col, srs, precision, prefix); + gml = lwalloc(size); + asgml2_multi_buf(col, srs, gml, precision, prefix); + return gml; } @@ -663,14 +644,17 @@ asgml2_collection_buf(const LWCOLLECTION *col, const char *srs, char *output, in /* * Don't call this with single-geoms inspected! */ -static lwvarlena_t * -asgml2_collection(const LWCOLLECTION *col, const char *srs, int precision, const char *prefix) +static char * +asgml2_collection(const LWCOLLECTION *col, const char *srs, int precision, + const char *prefix) { - int size = asgml2_collection_size(col, srs, precision, prefix); - lwvarlena_t *output = lwalloc(LWVARHDRSZ + size); - size = asgml2_collection_buf(col, srs, output->data, precision, prefix); - LWSIZE_SET(output->size, size + LWVARHDRSZ); - return output; + char *gml; + size_t size; + + size = asgml2_collection_size(col, srs, precision, prefix); + gml = lwalloc(size); + asgml2_collection_buf(col, srs, gml, precision, prefix); + return gml; } @@ -728,7 +712,7 @@ pointArray_toGML2(POINTARRAY *pa, char *output, int precision) /* takes a GEOMETRY and returns a GML representation */ -extern lwvarlena_t * +extern char * lwgeom_to_gml3(const LWGEOM *geom, const char *srs, int precision, int opts, const char *prefix, const char *id) { int type = geom->type; @@ -826,13 +810,15 @@ asgml3_point_buf(const LWPOINT *point, const char *srs, char *output, int precis return (ptr-output); } -static lwvarlena_t * +static char * asgml3_point(const LWPOINT *point, const char *srs, int precision, int opts, const char *prefix, const char *id) { - size_t size = asgml3_point_size(point, srs, precision, opts, prefix, id); - lwvarlena_t *output = lwalloc(LWVARHDRSZ + size); - size = asgml3_point_buf(point, srs, output->data, precision, opts, prefix, id); - LWSIZE_SET(output->size, size + LWVARHDRSZ); + char *output; + int size; + + size = asgml3_point_size(point, srs, precision, opts, prefix, id); + output = lwalloc(size); + asgml3_point_buf(point, srs, output, precision, opts, prefix, id); return output; } @@ -926,13 +912,15 @@ asgml3_line_buf(const LWLINE *line, const char *srs, char *output, int precision return (ptr-output); } -static lwvarlena_t * +static char * asgml3_line(const LWLINE *line, const char *srs, int precision, int opts, const char *prefix, const char *id) { - size_t size = asgml3_line_size(line, srs, precision, opts, prefix, id); - lwvarlena_t *output = lwalloc(LWVARHDRSZ + size); - size = asgml3_line_buf(line, srs, output->data, precision, opts, prefix, id); - LWSIZE_SET(output->size, size + LWVARHDRSZ); + char *output; + int size; + + size = asgml3_line_size(line, srs, precision, opts, prefix, id); + output = lwalloc(size); + asgml3_line_buf(line, srs, output, precision, opts, prefix, id); return output; } @@ -989,18 +977,15 @@ asgml3_circstring_buf(const LWCIRCSTRING *circ, const char *srs, char *output, i return (ptr-output); } -static lwvarlena_t * -asgml3_circstring(const LWCIRCSTRING *circ, - const char *srs, - int precision, - int opts, - const char *prefix, - const char *id) +static char * +asgml3_circstring( const LWCIRCSTRING *circ, const char *srs, int precision, int opts, const char *prefix, const char *id ) { - size_t size = asgml3_circstring_size(circ, srs, precision, opts, prefix, id); - lwvarlena_t *output = lwalloc(LWVARHDRSZ + size); - size = asgml3_circstring_buf(circ, srs, output->data, precision, opts, prefix, id); - LWSIZE_SET(output->size, size + LWVARHDRSZ); + char *output; + int size; + + size = asgml3_circstring_size(circ, srs, precision, opts, prefix, id); + output = lwalloc( size ); + asgml3_circstring_buf(circ, srs, output, precision, opts, prefix, id); return output; } @@ -1075,19 +1060,15 @@ asgml3_poly_buf(const LWPOLY *poly, const char *srs, char *output, int precision return (ptr-output); } -static lwvarlena_t * -asgml3_poly(const LWPOLY *poly, - const char *srs, - int precision, - int opts, - int is_patch, - const char *prefix, - const char *id) +static char * +asgml3_poly(const LWPOLY *poly, const char *srs, int precision, int opts, int is_patch, const char *prefix, const char *id) { - size_t size = asgml3_poly_size(poly, srs, precision, opts, prefix, id); - lwvarlena_t *output = lwalloc(LWVARHDRSZ + size); - size = asgml3_poly_buf(poly, srs, output->data, precision, opts, is_patch, prefix, id); - LWSIZE_SET(output->size, size + LWVARHDRSZ); + char *output; + int size; + + size = asgml3_poly_size(poly, srs, precision, opts, prefix, id); + output = lwalloc(size); + asgml3_poly_buf(poly, srs, output, precision, opts, is_patch, prefix, id); return output; } @@ -1195,14 +1176,16 @@ asgml3_compound_buf(const LWCOMPOUND *col, const char *srs, char *output, int pr return ( ptr - output ); } -static lwvarlena_t * -asgml3_compound(const LWCOMPOUND *col, const char *srs, int precision, int opts, const char *prefix, const char *id) +static char * +asgml3_compound(const LWCOMPOUND *col, const char *srs, int precision, int opts, const char *prefix, const char *id ) { - size_t size = asgml3_compound_size(col, srs, precision, opts, prefix, id); - lwvarlena_t *output = lwalloc(LWVARHDRSZ + size); - size = asgml3_compound_buf(col, srs, output->data, precision, opts, prefix, id); - LWSIZE_SET(output->size, size + LWVARHDRSZ); - return output; + char* gml; + size_t size; + + size = asgml3_compound_size( col, srs, precision, opts, prefix, id ); + gml = lwalloc( size ); + asgml3_compound_buf( col, srs, gml, precision, opts, prefix, id ); + return gml; } static size_t asgml3_curvepoly_size(const LWCURVEPOLY* poly, const char *srs, int precision, int opts, const char *prefix, const char *id) @@ -1331,14 +1314,15 @@ static size_t asgml3_curvepoly_buf(const LWCURVEPOLY* poly, const char *srs, cha return (ptr - output); } -static lwvarlena_t * -asgml3_curvepoly(const LWCURVEPOLY *poly, const char *srs, int precision, int opts, const char *prefix, const char *id) +static char* asgml3_curvepoly(const LWCURVEPOLY* poly, const char *srs, int precision, int opts, const char *prefix, const char *id) { - size_t size = asgml3_curvepoly_size(poly, srs, precision, opts, prefix, id); - lwvarlena_t *output = lwalloc(LWVARHDRSZ + size); - size = asgml3_curvepoly_buf(poly, srs, output->data, precision, opts, prefix, id); - LWSIZE_SET(output->size, size + LWVARHDRSZ); - return output; + char* gml; + size_t size; + + size = asgml3_curvepoly_size( poly, srs, precision, opts, prefix, id ); + gml = lwalloc( size ); + asgml3_curvepoly_buf( poly, srs, gml, precision, opts, prefix, id ); + return gml; } @@ -1384,18 +1368,15 @@ asgml3_triangle_buf(const LWTRIANGLE *triangle, const char *srs, char *output, i return (ptr-output); } -static lwvarlena_t * -asgml3_triangle(const LWTRIANGLE *triangle, - const char *srs, - int precision, - int opts, - const char *prefix, - const char *id) +static char * +asgml3_triangle(const LWTRIANGLE *triangle, const char *srs, int precision, int opts, const char *prefix, const char *id) { - size_t size = asgml3_triangle_size(triangle, srs, precision, opts, prefix, id); - lwvarlena_t *output = lwalloc(LWVARHDRSZ + size); - size = asgml3_triangle_buf(triangle, srs, output->data, precision, opts, prefix, id); - LWSIZE_SET(output->size, size + LWVARHDRSZ); + char *output; + int size; + + size = asgml3_triangle_size(triangle, srs, precision, opts, prefix, id); + output = lwalloc(size); + asgml3_triangle_buf(triangle, srs, output, precision, opts, prefix, id); return output; } @@ -1504,14 +1485,16 @@ asgml3_multi_buf(const LWCOLLECTION *col, const char *srs, char *output, int pre /* * Don't call this with single-geoms inspected! */ -static lwvarlena_t * +static char * asgml3_multi(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id) { - size_t size = asgml3_multi_size(col, srs, precision, opts, prefix, id); - lwvarlena_t *output = lwalloc(LWVARHDRSZ + size); - size = asgml3_multi_buf(col, srs, output->data, precision, opts, prefix, id); - LWSIZE_SET(output->size, size + LWVARHDRSZ); - return output; + char *gml; + size_t size; + + size = asgml3_multi_size(col, srs, precision, opts, prefix, id); + gml = lwalloc(size); + asgml3_multi_buf(col, srs, gml, precision, opts, prefix, id); + return gml; } @@ -1567,14 +1550,16 @@ asgml3_psurface_buf(const LWPSURFACE *psur, const char *srs, char *output, int p /* * Don't call this with single-geoms inspected! */ -static lwvarlena_t * +static char * asgml3_psurface(const LWPSURFACE *psur, const char *srs, int precision, int opts, const char *prefix, const char *id) { - size_t size = asgml3_psurface_size(psur, srs, precision, opts, prefix, id); - lwvarlena_t *output = lwalloc(LWVARHDRSZ + size); - size = asgml3_psurface_buf(psur, srs, output->data, precision, opts, prefix, id); - LWSIZE_SET(output->size, size + LWVARHDRSZ); - return output; + char *gml; + size_t size; + + size = asgml3_psurface_size(psur, srs, precision, opts, prefix, id); + gml = lwalloc(size); + asgml3_psurface_buf(psur, srs, gml, precision, opts, prefix, id); + return gml; } @@ -1630,14 +1615,16 @@ asgml3_tin_buf(const LWTIN *tin, const char *srs, char *output, int precision, i /* * Don't call this with single-geoms inspected! */ -static lwvarlena_t * +static char * asgml3_tin(const LWTIN *tin, const char *srs, int precision, int opts, const char *prefix, const char *id) { - size_t size = asgml3_tin_size(tin, srs, precision, opts, prefix, id); - lwvarlena_t *output = lwalloc(LWVARHDRSZ + size); - size = asgml3_tin_buf(tin, srs, output->data, precision, opts, prefix, id); - LWSIZE_SET(output->size, size + LWVARHDRSZ); - return output; + char *gml; + size_t size; + + size = asgml3_tin_size(tin, srs, precision, opts, prefix, id); + gml = lwalloc(size); + asgml3_tin_buf(tin, srs, gml, precision, opts, prefix, id); + return gml; } static size_t @@ -1739,14 +1726,16 @@ asgml3_collection_buf(const LWCOLLECTION *col, const char *srs, char *output, in /* * Don't call this with single-geoms inspected! */ -static lwvarlena_t * +static char * asgml3_collection(const LWCOLLECTION *col, const char *srs, int precision, int opts, const char *prefix, const char *id) { - size_t size = asgml3_collection_size(col, srs, precision, opts, prefix, id); - lwvarlena_t *output = lwalloc(LWVARHDRSZ + size); - size = asgml3_collection_buf(col, srs, output->data, precision, opts, prefix, id); - LWSIZE_SET(output->size, size + LWVARHDRSZ); - return output; + char *gml; + size_t size; + + size = asgml3_collection_size(col, srs, precision, opts, prefix, id); + gml = lwalloc(size); + asgml3_collection_buf(col, srs, gml, precision, opts, prefix, id); + return gml; } static size_t asgml3_multicurve_size( const LWMCURVE* cur, const char *srs, int precision, int opts, const char *prefix, const char *id ) @@ -1817,14 +1806,13 @@ static size_t asgml3_multicurve_buf( const LWMCURVE* cur, const char *srs, char return (ptr - output); } -static lwvarlena_t * -asgml3_multicurve(const LWMCURVE *cur, const char *srs, int precision, int opts, const char *prefix, const char *id) +static char *asgml3_multicurve( const LWMCURVE* cur, const char *srs, int precision, int opts, const char *prefix, const char *id ) { - size_t size = asgml3_multicurve_size(cur, srs, precision, opts, prefix, id); - lwvarlena_t *output = lwalloc(LWVARHDRSZ + size); - size = asgml3_multicurve_buf(cur, srs, output->data, precision, opts, prefix, id); - LWSIZE_SET(output->size, size + LWVARHDRSZ); - return output; + char* gml; + size_t size =asgml3_multicurve_size( cur, srs, precision, opts, prefix, id ); + gml = lwalloc( size ); + asgml3_multicurve_buf( cur, srs, gml, precision, opts, prefix, id ); + return gml; } static size_t asgml3_multisurface_size(const LWMSURFACE *sur, const char *srs, int precision, int opts, const char *prefix, const char *id) @@ -1884,14 +1872,13 @@ static size_t asgml3_multisurface_buf(const LWMSURFACE *sur, const char *srs, ch return ptr - output; } -static lwvarlena_t * -asgml3_multisurface(const LWMSURFACE *sur, const char *srs, int precision, int opts, const char *prefix, const char *id) +static char *asgml3_multisurface(const LWMSURFACE *sur, const char *srs, int precision, int opts, const char *prefix, const char *id) { - size_t size = asgml3_multisurface_size(sur, srs, precision, opts, prefix, id); - lwvarlena_t *output = lwalloc(LWVARHDRSZ + size); - size = asgml3_multisurface_buf(sur, srs, output->data, precision, opts, prefix, id); - LWSIZE_SET(output->size, size + LWVARHDRSZ); - return output; + char* gml; + size_t size = asgml3_multisurface_size( sur, srs, precision, opts, prefix, id ); + gml = lwalloc( size ); + asgml3_multisurface_buf( sur, srs, gml, precision, opts, prefix, id ); + return gml; } diff --git a/liblwgeom/lwout_kml.c b/liblwgeom/lwout_kml.c index 886f15796..eb3ebe35f 100644 --- a/liblwgeom/lwout_kml.c +++ b/liblwgeom/lwout_kml.c @@ -40,11 +40,12 @@ static int ptarray_to_kml2_sb(const POINTARRAY *pa, int precision, stringbuffer_ */ /* takes a GEOMETRY and returns a KML representation */ -lwvarlena_t * +char* lwgeom_to_kml2(const LWGEOM *geom, int precision, const char *prefix) { stringbuffer_t *sb; int rv; + char *kml; /* Can't do anything with empty */ if( lwgeom_is_empty(geom) ) @@ -59,10 +60,10 @@ lwgeom_to_kml2(const LWGEOM *geom, int precision, const char *prefix) return NULL; } - lwvarlena_t *v = stringbuffer_getvarlenacopy(sb); + kml = stringbuffer_getstringcopy(sb); stringbuffer_destroy(sb); - return v; + return kml; } static int diff --git a/liblwgeom/lwout_svg.c b/liblwgeom/lwout_svg.c index 0afb066ac..ca1645cdd 100644 --- a/liblwgeom/lwout_svg.c +++ b/liblwgeom/lwout_svg.c @@ -34,13 +34,13 @@ #include "liblwgeom_internal.h" -static lwvarlena_t *assvg_point(const LWPOINT *point, int relative, int precision); -static lwvarlena_t *assvg_line(const LWLINE *line, int relative, int precision); -static lwvarlena_t *assvg_polygon(const LWPOLY *poly, int relative, int precision); -static lwvarlena_t *assvg_multipoint(const LWMPOINT *mpoint, int relative, int precision); -static lwvarlena_t *assvg_multiline(const LWMLINE *mline, int relative, int precision); -static lwvarlena_t *assvg_multipolygon(const LWMPOLY *mpoly, int relative, int precision); -static lwvarlena_t *assvg_collection(const LWCOLLECTION *col, int relative, int precision); +static char * assvg_point(const LWPOINT *point, int relative, int precision); +static char * assvg_line(const LWLINE *line, int relative, int precision); +static char * assvg_polygon(const LWPOLY *poly, int relative, int precision); +static char * assvg_multipoint(const LWMPOINT *mpoint, int relative, int precision); +static char * assvg_multiline(const LWMLINE *mline, int relative, int precision); +static char * assvg_multipolygon(const LWMPOLY *mpoly, int relative, int precision); +static char * assvg_collection(const LWCOLLECTION *col, int relative, int precision); static size_t assvg_geom_size(const LWGEOM *geom, int relative, int precision); static size_t assvg_geom_buf(const LWGEOM *geom, char *output, int relative, int precision); @@ -52,18 +52,18 @@ static size_t pointArray_svg_abs(POINTARRAY *pa, char * output, int close_ring, /** * Takes a GEOMETRY and returns a SVG representation */ -lwvarlena_t * +char * lwgeom_to_svg(const LWGEOM *geom, int precision, int relative) { - lwvarlena_t *ret = NULL; + char *ret = NULL; int type = geom->type; - /* Empty varlena for empties */ + /* Empty string for empties */ if( lwgeom_is_empty(geom) ) { - lwvarlena_t *v = lwalloc(LWVARHDRSZ); - LWSIZE_SET(v->size, LWVARHDRSZ); - return v; + ret = lwalloc(1); + ret[0] = '\0'; + return ret; } switch (type) @@ -134,14 +134,17 @@ assvg_point_buf(const LWPOINT *point, char * output, int circle, int precision) return (ptr-output); } -static lwvarlena_t * +static char * assvg_point(const LWPOINT *point, int circle, int precision) { - size_t size = assvg_point_size(point, circle, precision); - lwvarlena_t *v = lwalloc(LWVARHDRSZ + size); - size = assvg_point_buf(point, v->data, circle, precision); - LWSIZE_SET(v->size, LWVARHDRSZ + size); - return v; + char *output; + int size; + + size = assvg_point_size(point, circle, precision); + output = lwalloc(size); + assvg_point_buf(point, output, circle, precision); + + return output; } @@ -175,14 +178,17 @@ assvg_line_buf(const LWLINE *line, char * output, int relative, int precision) return (ptr-output); } -static lwvarlena_t * +static char * assvg_line(const LWLINE *line, int relative, int precision) { - size_t size = assvg_line_size(line, relative, precision); - lwvarlena_t *v = lwalloc(LWVARHDRSZ + size); - size = assvg_line_buf(line, v->data, relative, precision); - LWSIZE_SET(v->size, LWVARHDRSZ + size); - return v; + char *output; + int size; + + size = assvg_line_size(line, relative, precision); + output = lwalloc(size); + assvg_line_buf(line, output, relative, precision); + + return output; } @@ -229,14 +235,17 @@ assvg_polygon_buf(const LWPOLY *poly, char * output, int relative, int precision return (ptr-output); } -static lwvarlena_t * +static char * assvg_polygon(const LWPOLY *poly, int relative, int precision) { - size_t size = assvg_polygon_size(poly, relative, precision); - lwvarlena_t *v = lwalloc(LWVARHDRSZ + size); - size = assvg_polygon_buf(poly, v->data, relative, precision); - LWSIZE_SET(v->size, LWVARHDRSZ + size); - return v; + char *output; + int size; + + size = assvg_polygon_size(poly, relative, precision); + output = lwalloc(size); + assvg_polygon_buf(poly, output, relative, precision); + + return output; } @@ -278,14 +287,17 @@ assvg_multipoint_buf(const LWMPOINT *mpoint, char *output, int relative, int pre return (ptr-output); } -static lwvarlena_t * +static char * assvg_multipoint(const LWMPOINT *mpoint, int relative, int precision) { - size_t size = assvg_multipoint_size(mpoint, relative, precision); - lwvarlena_t *v = lwalloc(LWVARHDRSZ + size); - size = assvg_multipoint_buf(mpoint, v->data, relative, precision); - LWSIZE_SET(v->size, LWVARHDRSZ + size); - return v; + char *output; + int size; + + size = assvg_multipoint_size(mpoint, relative, precision); + output = lwalloc(size); + assvg_multipoint_buf(mpoint, output, relative, precision); + + return output; } @@ -327,14 +339,17 @@ assvg_multiline_buf(const LWMLINE *mline, char *output, int relative, int precis return (ptr-output); } -static lwvarlena_t * +static char * assvg_multiline(const LWMLINE *mline, int relative, int precision) { - size_t size = assvg_multiline_size(mline, relative, precision); - lwvarlena_t *v = lwalloc(LWVARHDRSZ + size); - size = assvg_multiline_buf(mline, v->data, relative, precision); - LWSIZE_SET(v->size, LWVARHDRSZ + size); - return v; + char *output; + int size; + + size = assvg_multiline_size(mline, relative, precision); + output = lwalloc(size); + assvg_multiline_buf(mline, output, relative, precision); + + return output; } @@ -376,14 +391,17 @@ assvg_multipolygon_buf(const LWMPOLY *mpoly, char *output, int relative, int pre return (ptr-output); } -static lwvarlena_t * +static char * assvg_multipolygon(const LWMPOLY *mpoly, int relative, int precision) { - size_t size = assvg_multipolygon_size(mpoly, relative, precision); - lwvarlena_t *v = lwalloc(LWVARHDRSZ + size); - size = assvg_multipolygon_buf(mpoly, v->data, relative, precision); - LWSIZE_SET(v->size, LWVARHDRSZ + size); - return v; + char *output; + int size; + + size = assvg_multipolygon_size(mpoly, relative, precision); + output = lwalloc(size); + assvg_multipolygon_buf(mpoly, output, relative, precision); + + return output; } @@ -432,14 +450,17 @@ assvg_collection_buf(const LWCOLLECTION *col, char *output, int relative, int pr return (ptr - output); } -static lwvarlena_t * +static char * assvg_collection(const LWCOLLECTION *col, int relative, int precision) { - size_t size = assvg_collection_size(col, relative, precision); - lwvarlena_t *v = lwalloc(LWVARHDRSZ + size); - size = assvg_collection_buf(col, v->data, relative, precision); - LWSIZE_SET(v->size, LWVARHDRSZ + size); - return v; + char *output; + int size; + + size = assvg_collection_size(col, relative, precision); + output = lwalloc(size); + assvg_collection_buf(col, output, relative, precision); + + return output; } diff --git a/liblwgeom/lwout_twkb.c b/liblwgeom/lwout_twkb.c index 6d099f6a6..e87a72c8e 100644 --- a/liblwgeom/lwout_twkb.c +++ b/liblwgeom/lwout_twkb.c @@ -585,13 +585,10 @@ static int lwgeom_write_to_buffer(const LWGEOM *geom, TWKB_GLOBALS *globals, TWK * Convert LWGEOM to a char* in TWKB format. Caller is responsible for freeing * the returned array. */ -lwvarlena_t * -lwgeom_to_twkb_with_idlist(const LWGEOM *geom, - int64_t *idlist, - uint8_t variant, - int8_t precision_xy, - int8_t precision_z, - int8_t precision_m) +uint8_t* +lwgeom_to_twkb_with_idlist(const LWGEOM *geom, int64_t *idlist, uint8_t variant, + int8_t precision_xy, int8_t precision_z, int8_t precision_m, + size_t *twkb_size) { LWDEBUGF(2, "Entered %s", __func__); LWDEBUGF(2, "variant value %x", variant); @@ -600,6 +597,8 @@ lwgeom_to_twkb_with_idlist(const LWGEOM *geom, TWKB_STATE ts; bytebuffer_t geom_bytebuffer; + uint8_t *twkb; + memset(&ts, 0, sizeof(TWKB_STATE)); memset(&tg, 0, sizeof(TWKB_GLOBALS)); @@ -627,15 +626,18 @@ lwgeom_to_twkb_with_idlist(const LWGEOM *geom, bytebuffer_init_with_size(ts.geom_buf, 512); lwgeom_write_to_buffer(geom, &tg, &ts); - lwvarlena_t *v = bytebuffer_get_buffer_varlena(ts.geom_buf); + twkb = bytebuffer_get_buffer_copy(ts.geom_buf, twkb_size); bytebuffer_destroy_buffer(ts.geom_buf); - return v; + return twkb; } -lwvarlena_t * -lwgeom_to_twkb(const LWGEOM *geom, uint8_t variant, int8_t precision_xy, int8_t precision_z, int8_t precision_m) + +uint8_t* +lwgeom_to_twkb(const LWGEOM *geom, uint8_t variant, + int8_t precision_xy, int8_t precision_z, int8_t precision_m, + size_t *twkb_size) { - return lwgeom_to_twkb_with_idlist(geom, NULL, variant, precision_xy, precision_z, precision_m); + return lwgeom_to_twkb_with_idlist(geom, NULL, variant, precision_xy, precision_z, precision_m, twkb_size); } diff --git a/liblwgeom/lwout_wkb.c b/liblwgeom/lwout_wkb.c index 3de8b5b5e..0ba78d6aa 100644 --- a/liblwgeom/lwout_wkb.c +++ b/liblwgeom/lwout_wkb.c @@ -24,7 +24,6 @@ #include -#include // for ptrdiff_t #include "liblwgeom_internal.h" #include "lwgeom_log.h" @@ -672,17 +671,12 @@ static uint8_t* lwcollection_to_wkb_buf(const LWCOLLECTION *col, uint8_t *buf, u /* * GEOMETRY */ -static size_t -lwgeom_to_wkb_size(const LWGEOM *geom, uint8_t variant) +static size_t lwgeom_to_wkb_size(const LWGEOM *geom, uint8_t variant) { size_t size = 0; - if (geom == NULL) - { - LWDEBUG(4, "Cannot convert NULL into WKB."); - lwerror("Cannot convert NULL into WKB."); + if ( geom == NULL ) return 0; - } /* Short circuit out empty geometries */ if ( (!(variant & WKB_EXTENDED)) && lwgeom_is_empty(geom) ) @@ -793,11 +787,43 @@ static uint8_t* lwgeom_to_wkb_buf(const LWGEOM *geom, uint8_t *buf, uint8_t vari * @param size_out If supplied, will return the size of the returned memory segment, * including the null terminator in the case of ASCII. */ -static ptrdiff_t -lwgeom_to_wkb_write_buf(const LWGEOM *geom, uint8_t variant, uint8_t *buffer) +uint8_t* lwgeom_to_wkb(const LWGEOM *geom, uint8_t variant, size_t *size_out) { + size_t buf_size; + uint8_t *buf = NULL; + uint8_t *wkb_out = NULL; + + /* Initialize output size */ + if ( size_out ) *size_out = 0; + + if ( geom == NULL ) + { + LWDEBUG(4,"Cannot convert NULL into WKB."); + lwerror("Cannot convert NULL into WKB."); + return NULL; + } + + /* Calculate the required size of the output buffer */ + buf_size = lwgeom_to_wkb_size(geom, variant); + LWDEBUGF(4, "WKB output size: %d", buf_size); + + if ( buf_size == 0 ) + { + LWDEBUG(4,"Error calculating output WKB buffer size."); + lwerror("Error calculating output WKB buffer size."); + return NULL; + } + + /* Hex string takes twice as much space as binary + a null character */ + if ( variant & WKB_HEX ) + { + buf_size = 2 * buf_size + 1; + LWDEBUGF(4, "Hex WKB output size: %d", buf_size); + } + /* If neither or both variants are specified, choose the native order */ - if (!(variant & WKB_NDR || variant & WKB_XDR) || (variant & WKB_NDR && variant & WKB_XDR)) + if ( ! (variant & WKB_NDR || variant & WKB_XDR) || + (variant & WKB_NDR && variant & WKB_XDR) ) { if (IS_BIG_ENDIAN) variant = variant | WKB_XDR; @@ -805,74 +831,48 @@ lwgeom_to_wkb_write_buf(const LWGEOM *geom, uint8_t variant, uint8_t *buffer) variant = variant | WKB_NDR; } + /* Allocate the buffer */ + buf = lwalloc(buf_size); + + if ( buf == NULL ) + { + LWDEBUGF(4,"Unable to allocate %d bytes for WKB output buffer.", buf_size); + lwerror("Unable to allocate %d bytes for WKB output buffer.", buf_size); + return NULL; + } + + /* Retain a pointer to the front of the buffer for later */ + wkb_out = buf; + /* Write the WKB into the output buffer */ - int written_bytes = (lwgeom_to_wkb_buf(geom, buffer, variant) - buffer); + buf = lwgeom_to_wkb_buf(geom, buf, variant); - return written_bytes; -} - -uint8_t * -lwgeom_to_wkb_buffer(const LWGEOM *geom, uint8_t variant) -{ - size_t b_size = lwgeom_to_wkb_size(geom, variant); - /* Hex string takes twice as much space as binary + a null character */ - if (variant & WKB_HEX) + /* Null the last byte if this is a hex output */ + if ( variant & WKB_HEX ) { - b_size = 2 * b_size + 1; + *buf = '\0'; + buf++; } - uint8_t *buffer = (uint8_t *)lwalloc(b_size); - ptrdiff_t written_size = lwgeom_to_wkb_write_buf(geom, variant, buffer); - if (variant & WKB_HEX) - { - buffer[written_size] = '\0'; - written_size++; - } + LWDEBUGF(4,"buf (%p) - wkb_out (%p) = %d", buf, wkb_out, buf - wkb_out); - if (written_size != (ptrdiff_t)b_size) + /* The buffer pointer should now land at the end of the allocated buffer space. Let's check. */ + if ( buf_size != (size_t) (buf - wkb_out) ) { - char *wkt = lwgeom_to_wkt(geom, WKT_EXTENDED, 15, NULL); - lwerror("Output WKB is not the same size as the allocated buffer. Variant: %u, Geom: %s", variant, wkt); - lwfree(wkt); - lwfree(buffer); + LWDEBUG(4,"Output WKB is not the same size as the allocated buffer."); + lwerror("Output WKB is not the same size as the allocated buffer."); + lwfree(wkb_out); return NULL; } - return buffer; + /* Report output size */ + if ( size_out ) *size_out = buf_size; + + return wkb_out; } -char * -lwgeom_to_hexwkb_buffer(const LWGEOM *geom, uint8_t variant) +char* lwgeom_to_hexwkb(const LWGEOM *geom, uint8_t variant, size_t *size_out) { - return (char *)lwgeom_to_wkb_buffer(geom, variant | WKB_HEX); + return (char*)lwgeom_to_wkb(geom, variant | WKB_HEX, size_out); } -lwvarlena_t * -lwgeom_to_wkb_varlena(const LWGEOM *geom, uint8_t variant) -{ - size_t b_size = lwgeom_to_wkb_size(geom, variant); - /* Hex string takes twice as much space as binary, but No NULL ending in varlena */ - if (variant & WKB_HEX) - { - b_size = 2 * b_size; - } - - lwvarlena_t *buffer = (lwvarlena_t *)lwalloc(b_size + LWVARHDRSZ); - int written_size = lwgeom_to_wkb_write_buf(geom, variant, (uint8_t *)buffer->data); - if (written_size != (ptrdiff_t)b_size) - { - char *wkt = lwgeom_to_wkt(geom, WKT_EXTENDED, 15, NULL); - lwerror("Output WKB is not the same size as the allocated buffer. Variant: %u, Geom: %s", variant, wkt); - lwfree(wkt); - lwfree(buffer); - return NULL; - } - LWSIZE_SET(buffer->size, written_size + LWVARHDRSZ); - return buffer; -} - -lwvarlena_t * -lwgeom_to_hexwkb_varlena(const LWGEOM *geom, uint8_t variant) -{ - return lwgeom_to_wkb_varlena(geom, variant | WKB_HEX); -} diff --git a/liblwgeom/lwout_wkt.c b/liblwgeom/lwout_wkt.c index f23b6b494..7f38d0f10 100644 --- a/liblwgeom/lwout_wkt.c +++ b/liblwgeom/lwout_wkt.c @@ -659,10 +659,21 @@ static void lwgeom_to_wkt_sb(const LWGEOM *geom, stringbuffer_t *sb, int precisi } } -static stringbuffer_t * -lwgeom_to_wkt_internal(const LWGEOM *geom, uint8_t variant, int precision) +/** + * WKT emitter function. Allocates a new *char and fills it with the WKT + * representation. If size_out is not NULL, it will be set to the size of the + * allocated *char. + * + * @param variant Bitmasked value, accepts one of WKT_ISO, WKT_SFSQL, + * WKT_EXTENDED. + * @param precision Maximal number of digits after comma in the output doubles. + * @param size_out If supplied, will return the size of the returned string, + * including the null terminator. + */ +char* lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out) { stringbuffer_t *sb; + char *str = NULL; if ( geom == NULL ) return NULL; sb = stringbuffer_create(); @@ -677,40 +688,10 @@ lwgeom_to_wkt_internal(const LWGEOM *geom, uint8_t variant, int precision) lwerror("Uh oh"); return NULL; } - return sb; -} - -/** - * WKT emitter function. Allocates a new *char and fills it with the WKT - * representation. If size_out is not NULL, it will be set to the size of the - * allocated *char. - * - * @param variant Bitmasked value, accepts one of WKT_ISO, WKT_SFSQL, - * WKT_EXTENDED. - * @param precision Maximal number of digits after comma in the output doubles. - * @param size_out If supplied, will return the size of the returned string, - * including the null terminator. - */ -char * -lwgeom_to_wkt(const LWGEOM *geom, uint8_t variant, int precision, size_t *size_out) -{ - stringbuffer_t *sb = lwgeom_to_wkt_internal(geom, variant, precision); - if (!sb) - return NULL; - char *str = stringbuffer_getstringcopy(sb); + str = stringbuffer_getstringcopy(sb); if ( size_out ) *size_out = stringbuffer_getlength(sb) + 1; stringbuffer_destroy(sb); return str; } -lwvarlena_t * -lwgeom_to_wkt_varlena(const LWGEOM *geom, uint8_t variant, int precision) -{ - stringbuffer_t *sb = lwgeom_to_wkt_internal(geom, variant, precision); - if (!sb) - return NULL; - lwvarlena_t *output = stringbuffer_getvarlenacopy(sb); - stringbuffer_destroy(sb); - return output; -} diff --git a/liblwgeom/lwout_x3d.c b/liblwgeom/lwout_x3d.c index 05644062a..f1265610b 100644 --- a/liblwgeom/lwout_x3d.c +++ b/liblwgeom/lwout_x3d.c @@ -26,25 +26,26 @@ * @file X3D output routines. * **********************************************************************/ - #include "lwout_x3d.h" /* * VERSION X3D 3.0.2 http://www.web3d.org/specifications/x3d-3.0.dtd */ /* takes a GEOMETRY and returns a X3D representation */ -lwvarlena_t * +char* lwgeom_to_x3d3(const LWGEOM *geom, char *srs, int precision, int opts, const char *defid) { stringbuffer_t *sb; int rv; + char *result; - /* Empty varlena for empties */ + /* Empty string for empties */ if( lwgeom_is_empty(geom) ) { - lwvarlena_t *v = lwalloc(LWVARHDRSZ); - LWSIZE_SET(v->size, LWVARHDRSZ); - return v; + char *ret = NULL; + ret = lwalloc(1); + ret[0] = '\0'; + return ret; } sb = stringbuffer_create(); @@ -56,10 +57,10 @@ lwgeom_to_x3d3(const LWGEOM *geom, char *srs, int precision, int opts, const cha return NULL; } - lwvarlena_t *v = stringbuffer_getvarlenacopy(sb); + result = stringbuffer_getstringcopy(sb); stringbuffer_destroy(sb); - return v; + return result; } /* takes a GEOMETRY and appends to string buffer the x3d output */ static int diff --git a/liblwgeom/stringbuffer.c b/liblwgeom/stringbuffer.c index 9babf0a91..30a46f345 100644 --- a/liblwgeom/stringbuffer.c +++ b/liblwgeom/stringbuffer.c @@ -130,17 +130,6 @@ stringbuffer_getstringcopy(stringbuffer_t *s) return str; } -lwvarlena_t * -stringbuffer_getvarlenacopy(stringbuffer_t *s) -{ - size_t size = (s->str_end - s->str_start); - lwvarlena_t *output = (lwvarlena_t *)lwalloc(size + LWVARHDRSZ); - LWSIZE_SET(output->size, size + LWVARHDRSZ); - - memcpy(output->data, s->str_start, size); - return output; -} - /** * Returns the length of the current string, not including the * null terminator (same behavior as strlen()). diff --git a/liblwgeom/stringbuffer.h b/liblwgeom/stringbuffer.h index eac9ceb49..1a2d5197a 100644 --- a/liblwgeom/stringbuffer.h +++ b/liblwgeom/stringbuffer.h @@ -55,7 +55,6 @@ void stringbuffer_copy(stringbuffer_t *sb, stringbuffer_t *src); extern int stringbuffer_aprintf(stringbuffer_t *sb, const char *fmt, ...); extern const char *stringbuffer_getstring(stringbuffer_t *sb); extern char *stringbuffer_getstringcopy(stringbuffer_t *sb); -extern lwvarlena_t *stringbuffer_getvarlenacopy(stringbuffer_t *s); extern int stringbuffer_getlength(stringbuffer_t *sb); extern char stringbuffer_lastchar(stringbuffer_t *s); extern int stringbuffer_trim_trailing_white(stringbuffer_t *s); diff --git a/loader/shp2pgsql-core.c b/loader/shp2pgsql-core.c index b6963cdb1..5480ebc1c 100644 --- a/loader/shp2pgsql-core.c +++ b/loader/shp2pgsql-core.c @@ -292,7 +292,7 @@ GeneratePointGeometry(SHPLOADERSTATE *state, SHPObject *obj, char **geometry, in } else { - mem = lwgeom_to_hexwkb_buffer(lwgeom, WKB_EXTENDED); + mem = lwgeom_to_hexwkb(lwgeom, WKB_EXTENDED, &mem_length); } if ( !mem ) @@ -385,7 +385,7 @@ GenerateLineStringGeometry(SHPLOADERSTATE *state, SHPObject *obj, char **geometr } if (!state->config->use_wkt) - mem = lwgeom_to_hexwkb_buffer(lwgeom, WKB_EXTENDED); + mem = lwgeom_to_hexwkb(lwgeom, WKB_EXTENDED, &mem_length); else mem = lwgeom_to_wkt(lwgeom, WKT_EXTENDED, WKT_PRECISION, &mem_length); @@ -706,7 +706,7 @@ GeneratePolygonGeometry(SHPLOADERSTATE *state, SHPObject *obj, char **geometry) } if (!state->config->use_wkt) - mem = lwgeom_to_hexwkb_buffer(lwgeom, WKB_EXTENDED); + mem = lwgeom_to_hexwkb(lwgeom, WKB_EXTENDED, &mem_length); else mem = lwgeom_to_wkt(lwgeom, WKT_EXTENDED, WKT_PRECISION, &mem_length); @@ -1831,7 +1831,7 @@ done_cell: } } - // free(geometry); + free(geometry); } /* Tidy up everything */ diff --git a/postgis/geography_inout.c b/postgis/geography_inout.c index 8db14c878..55cb1527a 100644 --- a/postgis/geography_inout.c +++ b/postgis/geography_inout.c @@ -189,10 +189,16 @@ Datum geography_in(PG_FUNCTION_ARGS) PG_FUNCTION_INFO_V1(geography_out); Datum geography_out(PG_FUNCTION_ARGS) { + LWGEOM *lwgeom = NULL; + GSERIALIZED *g = NULL; + char *hexwkb; - GSERIALIZED *g = PG_GETARG_GSERIALIZED_P(0); - LWGEOM *lwgeom = lwgeom_from_gserialized(g); - PG_RETURN_CSTRING(lwgeom_to_hexwkb_buffer(lwgeom, WKB_EXTENDED)); + g = PG_GETARG_GSERIALIZED_P(0); + lwgeom = lwgeom_from_gserialized(g); + hexwkb = lwgeom_to_hexwkb(lwgeom, WKB_EXTENDED, 0); + lwgeom_free(lwgeom); + + PG_RETURN_CSTRING(hexwkb); } @@ -204,7 +210,8 @@ Datum geography_as_gml(PG_FUNCTION_ARGS) { LWGEOM *lwgeom = NULL; GSERIALIZED *g = NULL; - lwvarlena_t *v; + char *gml; + text *result; int version; char *srs; int32_t srid = SRID_DEFAULT; @@ -226,6 +233,7 @@ Datum geography_as_gml(PG_FUNCTION_ARGS) */ Oid first_type = get_fn_expr_argtype(fcinfo->flinfo, 0); int argnum = 0; + int argeom = 0; if (first_type != INT4OID) { version = 2; @@ -234,6 +242,7 @@ Datum geography_as_gml(PG_FUNCTION_ARGS) { /* Get the version */ version = PG_GETARG_INT32(argnum++); + argeom = 1; if (version != 2 && version != 3) { elog(ERROR, "Only GML 2 and GML 3 are supported"); @@ -313,14 +322,22 @@ Datum geography_as_gml(PG_FUNCTION_ARGS) } if (version == 2) - v = lwgeom_to_gml2(lwgeom, srs, precision, prefix); + gml = lwgeom_to_gml2(lwgeom, srs, precision, prefix); else - v = lwgeom_to_gml3(lwgeom, srs, precision, lwopts, prefix, id); + gml = lwgeom_to_gml3(lwgeom, srs, precision, lwopts, prefix, id); - if (!v) + lwgeom_free(lwgeom); + PG_FREE_IF_COPY(g, argeom); + + /* Return null on null */ + if (!gml) PG_RETURN_NULL(); - else - PG_RETURN_TEXT_P(v); + + /* Turn string result into text for return */ + result = cstring_to_text(gml); + lwfree(gml); + + PG_RETURN_TEXT_P(result); } @@ -331,7 +348,8 @@ PG_FUNCTION_INFO_V1(geography_as_kml); Datum geography_as_kml(PG_FUNCTION_ARGS) { - lwvarlena_t *kml; + char *kml; + text *result; static const char *default_prefix = ""; char *prefixbuf; const char *prefix = default_prefix; @@ -363,9 +381,17 @@ Datum geography_as_kml(PG_FUNCTION_ARGS) } kml = lwgeom_to_kml2(lwgeom, precision, prefix); - if (kml) - PG_RETURN_TEXT_P(kml); - PG_RETURN_NULL(); + + lwgeom_free(lwgeom); + PG_FREE_IF_COPY(g, 0); + + if (!kml) + PG_RETURN_NULL(); + + result = cstring_to_text(kml); + lwfree(kml); + + PG_RETURN_TEXT_P(result); } @@ -375,6 +401,8 @@ Datum geography_as_kml(PG_FUNCTION_ARGS) PG_FUNCTION_INFO_V1(geography_as_svg); Datum geography_as_svg(PG_FUNCTION_ARGS) { + char *svg; + text *result; GSERIALIZED *g = PG_GETARG_GSERIALIZED_P(0); int relative = PG_GETARG_INT32(1) ? 1 : 0; int precision = PG_GETARG_INT32(2); @@ -385,7 +413,15 @@ Datum geography_as_svg(PG_FUNCTION_ARGS) else if (precision < 0) precision = 0; - PG_RETURN_TEXT_P(lwgeom_to_svg(lwgeom, precision, relative)); + svg = lwgeom_to_svg(lwgeom, precision, relative); + + lwgeom_free(lwgeom); + PG_FREE_IF_COPY(g, 0); + + result = cstring_to_text(svg); + lwfree(svg); + + PG_RETURN_TEXT_P(result); } @@ -395,7 +431,8 @@ Datum geography_as_svg(PG_FUNCTION_ARGS) PG_FUNCTION_INFO_V1(geography_as_geojson); Datum geography_as_geojson(PG_FUNCTION_ARGS) { - lwvarlena_t *geojson; + char *geojson; + text *result; int has_bbox = 0; char * srs = NULL; GSERIALIZED *g = PG_GETARG_GSERIALIZED_P(0); @@ -433,11 +470,14 @@ Datum geography_as_geojson(PG_FUNCTION_ARGS) if (option & 1) has_bbox = 1; geojson = lwgeom_to_geojson(lwgeom, srs, precision, has_bbox); - lwgeom_free(lwgeom); + lwgeom_free(lwgeom); PG_FREE_IF_COPY(g, 0); if (srs) pfree(srs); - PG_RETURN_TEXT_P(geojson); + result = cstring_to_text(geojson); + lwfree(geojson); + + PG_RETURN_TEXT_P(result); } @@ -594,7 +634,21 @@ Datum geography_recv(PG_FUNCTION_ARGS) PG_FUNCTION_INFO_V1(geography_send); Datum geography_send(PG_FUNCTION_ARGS) { - GSERIALIZED *g = PG_GETARG_GSERIALIZED_P(0); - LWGEOM *lwgeom = lwgeom_from_gserialized(g); - PG_RETURN_POINTER(lwgeom_to_wkb_varlena(lwgeom, WKB_EXTENDED)); + LWGEOM *lwgeom = NULL; + GSERIALIZED *g = NULL; + size_t size_result; + uint8_t *wkb; + bytea *result; + + g = PG_GETARG_GSERIALIZED_P(0); + lwgeom = lwgeom_from_gserialized(g); + wkb = lwgeom_to_wkb(lwgeom, WKB_EXTENDED, &size_result); + lwgeom_free(lwgeom); + + result = palloc(size_result + VARHDRSZ); + SET_VARSIZE(result, size_result + VARHDRSZ); + memcpy(VARDATA(result), wkb, size_result); + lwfree(wkb); + + PG_RETURN_POINTER(result); } diff --git a/postgis/lwgeom_dump.c b/postgis/lwgeom_dump.c index 7d6ae6423..ae511459c 100644 --- a/postgis/lwgeom_dump.c +++ b/postgis/lwgeom_dump.c @@ -144,7 +144,7 @@ Datum LWGEOM_dump(PG_FUNCTION_ARGS) if ( ! lwgeom_is_collection(state->root) ) { values[0] = "{}"; - values[1] = lwgeom_to_hexwkb_buffer(state->root, WKB_EXTENDED); + values[1] = lwgeom_to_hexwkb(state->root, WKB_EXTENDED, 0); tuple = BuildTupleFromCStrings(funcctx->attinmeta, values); result = HeapTupleGetDatum(tuple); @@ -201,7 +201,7 @@ Datum LWGEOM_dump(PG_FUNCTION_ARGS) lwgeom->srid = state->root->srid; values[0] = address; - values[1] = lwgeom_to_hexwkb_buffer(lwgeom, WKB_EXTENDED); + values[1] = lwgeom_to_hexwkb(lwgeom, WKB_EXTENDED, 0); tuple = BuildTupleFromCStrings(funcctx->attinmeta, values); result = TupleGetDatum(funcctx->slot, tuple); node->idx++; @@ -301,7 +301,7 @@ Datum LWGEOM_dump_rings(PG_FUNCTION_ARGS) sprintf(address, "{%d}", state->ringnum); values[0] = address; - values[1] = lwgeom_to_hexwkb_buffer(ringgeom, WKB_EXTENDED); + values[1] = lwgeom_to_hexwkb(ringgeom, WKB_EXTENDED, 0); MemoryContextSwitchTo(oldcontext); diff --git a/postgis/lwgeom_export.c b/postgis/lwgeom_export.c index 585dcce73..074c213a2 100644 --- a/postgis/lwgeom_export.c +++ b/postgis/lwgeom_export.c @@ -205,7 +205,8 @@ Datum LWGEOM_asGML(PG_FUNCTION_ARGS) { GSERIALIZED *geom; LWGEOM *lwgeom; - lwvarlena_t *v = NULL; + char *gml = NULL; + text *result; int version; char *srs; int32_t srid; @@ -308,21 +309,31 @@ Datum LWGEOM_asGML(PG_FUNCTION_ARGS) if (version == 2) { if (lwopts & LW_GML_EXTENT) - v = lwgeom_extent_to_gml2(lwgeom, srs, precision, prefix); + gml = lwgeom_extent_to_gml2( + lwgeom, srs, precision, prefix); else - v = lwgeom_to_gml2(lwgeom, srs, precision, prefix); + gml = lwgeom_to_gml2(lwgeom, srs, precision, prefix); } if (version == 3) { if (lwopts & LW_GML_EXTENT) - v = lwgeom_extent_to_gml3(lwgeom, srs, precision, lwopts, prefix); + gml = lwgeom_extent_to_gml3( + lwgeom, srs, precision, lwopts, prefix); else - v = lwgeom_to_gml3(lwgeom, srs, precision, lwopts, prefix, gml_id); + gml = lwgeom_to_gml3( + lwgeom, srs, precision, lwopts, prefix, gml_id); } - if (!v) + lwgeom_free(lwgeom); + PG_FREE_IF_COPY(geom, 1); + + /* Return null on null */ + if ( ! gml ) PG_RETURN_NULL(); - PG_RETURN_TEXT_P(v); + + result = cstring_to_text(gml); + lwfree(gml); + PG_RETURN_TEXT_P(result); } @@ -334,7 +345,8 @@ Datum LWGEOM_asGeoJson(PG_FUNCTION_ARGS) { GSERIALIZED *geom; LWGEOM *lwgeom; - lwvarlena_t *geojson; + char *geojson; + text *result; int precision = DBL_DIG; int output_bbox = LW_FALSE; int output_long_crs = LW_FALSE; @@ -398,8 +410,11 @@ Datum LWGEOM_asGeoJson(PG_FUNCTION_ARGS) if (srs) pfree(srs); + result = cstring_to_text(geojson); + lwfree(geojson); + PG_FREE_IF_COPY(geom, 0); - PG_RETURN_TEXT_P(geojson); + PG_RETURN_TEXT_P(result); } @@ -411,10 +426,12 @@ Datum geometry_to_json(PG_FUNCTION_ARGS) { GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0); LWGEOM *lwgeom = lwgeom_from_gserialized(geom); - lwvarlena_t *geojson = lwgeom_to_geojson(lwgeom, NULL, 15, 0); + char *geojson = lwgeom_to_geojson(lwgeom, NULL, 15, 0); + text *result = cstring_to_text(geojson); lwgeom_free(lwgeom); + pfree(geojson); PG_FREE_IF_COPY(geom, 0); - PG_RETURN_TEXT_P(geojson); + PG_RETURN_TEXT_P(result); } PG_FUNCTION_INFO_V1(geometry_to_jsonb); @@ -422,9 +439,9 @@ Datum geometry_to_jsonb(PG_FUNCTION_ARGS) { GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0); LWGEOM *lwgeom = lwgeom_from_gserialized(geom); - lwvarlena_t *geojson = lwgeom_to_geojson(lwgeom, NULL, 15, 0); + char *geojson = lwgeom_to_geojson(lwgeom, NULL, 15, 0); lwgeom_free(lwgeom); - PG_RETURN_DATUM(DirectFunctionCall1(jsonb_in, PointerGetDatum(pstrdup(geojson->data)))); + PG_RETURN_DATUM(DirectFunctionCall1(jsonb_in, PointerGetDatum(geojson))); } @@ -436,6 +453,8 @@ Datum LWGEOM_asSVG(PG_FUNCTION_ARGS) { GSERIALIZED *geom; LWGEOM *lwgeom; + char *svg; + text *result; int relative = 0; int precision=DBL_DIG; @@ -457,7 +476,13 @@ Datum LWGEOM_asSVG(PG_FUNCTION_ARGS) } lwgeom = lwgeom_from_gserialized(geom); - PG_RETURN_TEXT_P(lwgeom_to_svg(lwgeom, precision, relative)); + svg = lwgeom_to_svg(lwgeom, precision, relative); + result = cstring_to_text(svg); + lwgeom_free(lwgeom); + pfree(svg); + PG_FREE_IF_COPY(geom, 0); + + PG_RETURN_TEXT_P(result); } /** @@ -468,6 +493,8 @@ Datum LWGEOM_asX3D(PG_FUNCTION_ARGS) { GSERIALIZED *geom; LWGEOM *lwgeom; + char *x3d; + text *result; int version; char *srs; int32_t srid; @@ -545,7 +572,16 @@ Datum LWGEOM_asX3D(PG_FUNCTION_ARGS) } } - PG_RETURN_TEXT_P(lwgeom_to_x3d3(lwgeom, srs, precision, option, defid)); + + x3d = lwgeom_to_x3d3(lwgeom, srs, precision,option, defid); + + lwgeom_free(lwgeom); + PG_FREE_IF_COPY(geom, 1); + + result = cstring_to_text(x3d); + lwfree(x3d); + + PG_RETURN_TEXT_P(result); } /** @@ -556,7 +592,9 @@ Datum LWGEOM_asEncodedPolyline(PG_FUNCTION_ARGS) { GSERIALIZED *geom; LWGEOM *lwgeom; + char *encodedpolyline; int precision = 5; + text *result; if ( PG_ARGISNULL(0) ) PG_RETURN_NULL(); @@ -574,5 +612,12 @@ Datum LWGEOM_asEncodedPolyline(PG_FUNCTION_ARGS) if ( precision < 0 ) precision = 5; } - PG_RETURN_TEXT_P(lwgeom_to_encoded_polyline(lwgeom, precision)); + encodedpolyline = lwgeom_to_encoded_polyline(lwgeom, precision); + lwgeom_free(lwgeom); + PG_FREE_IF_COPY(geom, 0); + + result = cstring_to_text(encodedpolyline); + lwfree(encodedpolyline); + + PG_RETURN_TEXT_P(result); } diff --git a/postgis/lwgeom_functions_basic.c b/postgis/lwgeom_functions_basic.c index e955d0ca2..6fc280377 100644 --- a/postgis/lwgeom_functions_basic.c +++ b/postgis/lwgeom_functions_basic.c @@ -2389,12 +2389,28 @@ Datum LWGEOM_setpoint_linestring(PG_FUNCTION_ARGS) PG_FUNCTION_INFO_V1(LWGEOM_asEWKT); Datum LWGEOM_asEWKT(PG_FUNCTION_ARGS) { - GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0); - LWGEOM *lwgeom = lwgeom_from_gserialized(geom); + GSERIALIZED *geom; + LWGEOM *lwgeom; + char *wkt; + size_t wkt_size; + text *result; POSTGIS_DEBUG(2, "LWGEOM_asEWKT called."); - PG_RETURN_TEXT_P(lwgeom_to_wkt_varlena(lwgeom, WKT_EXTENDED, DBL_DIG)); + geom = PG_GETARG_GSERIALIZED_P(0); + lwgeom = lwgeom_from_gserialized(geom); + + /* Write to WKT and free the geometry */ + wkt = lwgeom_to_wkt(lwgeom, WKT_EXTENDED, DBL_DIG, &wkt_size); + lwgeom_free(lwgeom); + + /* Write to text and free the WKT */ + result = cstring_to_text(wkt); + lwfree(wkt); + + /* Return the text */ + PG_FREE_IF_COPY(geom, 0); + PG_RETURN_TEXT_P(result); } /** @@ -2698,7 +2714,8 @@ Datum ST_GeoHash(PG_FUNCTION_ARGS) GSERIALIZED *geom = NULL; int precision = 0; - lwvarlena_t *geohash = NULL; + char *geohash = NULL; + text *result = NULL; if (PG_ARGISNULL(0)) { @@ -2713,9 +2730,14 @@ Datum ST_GeoHash(PG_FUNCTION_ARGS) } geohash = lwgeom_geohash((LWGEOM *)(lwgeom_from_gserialized(geom)), precision); - if (geohash) - PG_RETURN_TEXT_P(geohash); - PG_RETURN_NULL(); + + if (!geohash) + PG_RETURN_NULL(); + + result = cstring_to_text(geohash); + pfree(geohash); + + PG_RETURN_TEXT_P(result); } PG_FUNCTION_INFO_V1(ST_CollectionExtract); diff --git a/postgis/lwgeom_geos.c b/postgis/lwgeom_geos.c index de47de562..8030ece98 100644 --- a/postgis/lwgeom_geos.c +++ b/postgis/lwgeom_geos.c @@ -1581,7 +1581,7 @@ Datum isvaliddetail(PG_FUNCTION_ARGS) values[1] = reason; /* the location */ - values[2] = location ? lwgeom_to_hexwkb_buffer(location, WKB_EXTENDED) : 0; + values[2] = location ? lwgeom_to_hexwkb(location, WKB_EXTENDED, 0) : 0; tuple = BuildTupleFromCStrings(attinmeta, values); result = (HeapTupleHeader) palloc(tuple->t_len); diff --git a/postgis/lwgeom_inout.c b/postgis/lwgeom_inout.c index 5a1ae1562..3573d2858 100644 --- a/postgis/lwgeom_inout.c +++ b/postgis/lwgeom_inout.c @@ -282,8 +282,15 @@ PG_FUNCTION_INFO_V1(LWGEOM_out); Datum LWGEOM_out(PG_FUNCTION_ARGS) { GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0); - LWGEOM *lwgeom = lwgeom_from_gserialized(geom); - PG_RETURN_CSTRING(lwgeom_to_hexwkb_buffer(lwgeom, WKB_EXTENDED)); + LWGEOM *lwgeom; + char *hexwkb; + size_t hexwkb_size; + + lwgeom = lwgeom_from_gserialized(geom); + hexwkb = lwgeom_to_hexwkb(lwgeom, WKB_EXTENDED, &hexwkb_size); + lwgeom_free(lwgeom); + + PG_RETURN_CSTRING(hexwkb); } /* @@ -294,12 +301,17 @@ Datum LWGEOM_asHEXEWKB(PG_FUNCTION_ARGS) { GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0); LWGEOM *lwgeom; + char *hexwkb; + size_t hexwkb_size; uint8_t variant = 0; + text *result; + text *type; + size_t text_size; /* If user specified endianness, respect it */ if ( (PG_NARGS()>1) && (!PG_ARGISNULL(1)) ) { - text *type = PG_GETARG_TEXT_P(1); + type = PG_GETARG_TEXT_P(1); if ( ! strncmp(VARDATA(type), "xdr", 3) || ! strncmp(VARDATA(type), "XDR", 3) ) @@ -314,7 +326,19 @@ Datum LWGEOM_asHEXEWKB(PG_FUNCTION_ARGS) /* Create WKB hex string */ lwgeom = lwgeom_from_gserialized(geom); - PG_RETURN_TEXT_P(lwgeom_to_hexwkb_varlena(lwgeom, variant | WKB_EXTENDED)); + hexwkb = lwgeom_to_hexwkb(lwgeom, variant | WKB_EXTENDED, &hexwkb_size); + lwgeom_free(lwgeom); + + /* Prepare the PgSQL text return type */ + text_size = hexwkb_size - 1 + VARHDRSZ; + result = palloc(text_size); + memcpy(VARDATA(result), hexwkb, hexwkb_size - 1); + SET_VARSIZE(result, text_size); + + /* Clean up and return */ + lwfree(hexwkb); + PG_FREE_IF_COPY(geom, 0); + PG_RETURN_TEXT_P(result); } @@ -329,8 +353,23 @@ PG_FUNCTION_INFO_V1(LWGEOM_to_text); Datum LWGEOM_to_text(PG_FUNCTION_ARGS) { GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0); - LWGEOM *lwgeom = lwgeom_from_gserialized(geom); - PG_RETURN_TEXT_P(lwgeom_to_hexwkb_varlena(lwgeom, WKB_EXTENDED)); + LWGEOM *lwgeom; + char *hexwkb; + size_t hexwkb_size; + text *result; + + /* Generate WKB hex text */ + lwgeom = lwgeom_from_gserialized(geom); + hexwkb = lwgeom_to_hexwkb(lwgeom, WKB_EXTENDED, &hexwkb_size); + lwgeom_free(lwgeom); + + /* Copy into text obect */ + result = cstring_to_text(hexwkb); + lwfree(hexwkb); + + /* Clean up and return */ + PG_FREE_IF_COPY(geom, 0); + PG_RETURN_TEXT_P(result); } /* @@ -397,12 +436,15 @@ Datum WKBFromLWGEOM(PG_FUNCTION_ARGS) { GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0); LWGEOM *lwgeom; + uint8_t *wkb; + size_t wkb_size; uint8_t variant = 0; - + bytea *result; + text *type; /* If user specified endianness, respect it */ if ( (PG_NARGS()>1) && (!PG_ARGISNULL(1)) ) { - text *type = PG_GETARG_TEXT_P(1); + type = PG_GETARG_TEXT_P(1); if ( ! strncmp(VARDATA(type), "xdr", 3) || ! strncmp(VARDATA(type), "XDR", 3) ) @@ -414,10 +456,22 @@ Datum WKBFromLWGEOM(PG_FUNCTION_ARGS) variant = variant | WKB_NDR; } } - + wkb_size= VARSIZE_ANY_EXHDR(geom); /* Create WKB hex string */ lwgeom = lwgeom_from_gserialized(geom); - PG_RETURN_BYTEA_P(lwgeom_to_wkb_varlena(lwgeom, variant | WKB_EXTENDED)); + + wkb = lwgeom_to_wkb(lwgeom, variant | WKB_EXTENDED , &wkb_size); + lwgeom_free(lwgeom); + + /* Prepare the PgSQL text return type */ + result = palloc(wkb_size + VARHDRSZ); + memcpy(VARDATA(result), wkb, wkb_size); + SET_VARSIZE(result, wkb_size+VARHDRSZ); + + /* Clean up and return */ + lwfree(wkb); + PG_FREE_IF_COPY(geom, 0); + PG_RETURN_BYTEA_P(result); } PG_FUNCTION_INFO_V1(TWKBFromLWGEOM); @@ -425,7 +479,10 @@ Datum TWKBFromLWGEOM(PG_FUNCTION_ARGS) { GSERIALIZED *geom; LWGEOM *lwgeom; + uint8_t *twkb; + size_t twkb_size; uint8_t variant = 0; + bytea *result; srs_precision sp; /*check for null input since we cannot have the sql-function as strict. @@ -462,7 +519,14 @@ Datum TWKBFromLWGEOM(PG_FUNCTION_ARGS) /* Create TWKB binary string */ lwgeom = lwgeom_from_gserialized(geom); - PG_RETURN_BYTEA_P(lwgeom_to_twkb(lwgeom, variant, sp.precision_xy, sp.precision_z, sp.precision_m)); + twkb = lwgeom_to_twkb(lwgeom, variant, sp.precision_xy, sp.precision_z, sp.precision_m, &twkb_size); + + /* Prepare the PgSQL text return type */ + result = palloc(twkb_size + VARHDRSZ); + memcpy(VARDATA(result), twkb, twkb_size); + SET_VARSIZE(result, twkb_size + VARHDRSZ); + + PG_RETURN_BYTEA_P(result); } @@ -486,6 +550,9 @@ Datum TWKBFromLWGEOMArray(PG_FUNCTION_ARGS) uint8_t variant = 0; srs_precision sp; + uint8_t *twkb; + size_t twkb_size; + bytea *result; /* The first two arguments are required */ if ( PG_NARGS() < 2 || PG_ARGISNULL(0) || PG_ARGISNULL(1) ) @@ -601,8 +668,24 @@ Datum TWKBFromLWGEOMArray(PG_FUNCTION_ARGS) variant |= TWKB_BBOX; /* Write out the TWKB */ - PG_RETURN_BYTEA_P(lwgeom_to_twkb_with_idlist( - lwcollection_as_lwgeom(col), idlist, variant, sp.precision_xy, sp.precision_z, sp.precision_m)); + twkb = lwgeom_to_twkb_with_idlist(lwcollection_as_lwgeom(col), + idlist, variant, + sp.precision_xy, sp.precision_z, sp.precision_m, + &twkb_size); + + /* Convert to a bytea return type */ + result = palloc(twkb_size + VARHDRSZ); + memcpy(VARDATA(result), twkb, twkb_size); + SET_VARSIZE(result, twkb_size + VARHDRSZ); + + /* Clean up */ + pfree(twkb); + pfree(idlist); + lwcollection_free(col); + PG_FREE_IF_COPY(arr_geoms, 0); + PG_FREE_IF_COPY(arr_ids, 1); + + PG_RETURN_BYTEA_P(result); } diff --git a/postgis/lwgeom_ogc.c b/postgis/lwgeom_ogc.c index 38984324e..08ab516e8 100644 --- a/postgis/lwgeom_ogc.c +++ b/postgis/lwgeom_ogc.c @@ -821,13 +821,32 @@ Datum LWGEOM_from_WKB(PG_FUNCTION_ARGS) PG_FUNCTION_INFO_V1(LWGEOM_asText); Datum LWGEOM_asText(PG_FUNCTION_ARGS) { - GSERIALIZED *geom = PG_GETARG_GSERIALIZED_P(0); - LWGEOM *lwgeom = lwgeom_from_gserialized(geom); - + GSERIALIZED *geom; + LWGEOM *lwgeom; + char *wkt; + size_t wkt_size; + text *result; int dbl_dig_for_wkt = DBL_DIG; + + POSTGIS_DEBUG(2, "Called."); + + geom = PG_GETARG_GSERIALIZED_P(0); + lwgeom = lwgeom_from_gserialized(geom); + if (PG_NARGS() > 1) dbl_dig_for_wkt = PG_GETARG_INT32(1); - PG_RETURN_TEXT_P(lwgeom_to_wkt_varlena(lwgeom, WKT_ISO, dbl_dig_for_wkt)); + /* Write to WKT and free the geometry */ + wkt = lwgeom_to_wkt(lwgeom, WKT_ISO, dbl_dig_for_wkt, &wkt_size); + lwgeom_free(lwgeom); + POSTGIS_DEBUGF(3, "WKT size = %u, WKT length = %u", (unsigned int)wkt_size, (unsigned int)strlen(wkt)); + + /* Write to text and free the WKT */ + result = cstring_to_text(wkt); + lwfree(wkt); + + /* Return the text */ + PG_FREE_IF_COPY(geom, 0); + PG_RETURN_TEXT_P(result); } @@ -837,6 +856,9 @@ Datum LWGEOM_asBinary(PG_FUNCTION_ARGS) { GSERIALIZED *geom; LWGEOM *lwgeom; + uint8_t *wkb; + size_t wkb_size; + bytea *result; uint8_t variant = WKB_ISO; if (PG_ARGISNULL(0)) @@ -864,7 +886,18 @@ Datum LWGEOM_asBinary(PG_FUNCTION_ARGS) } /* Write to WKB and free the geometry */ - PG_RETURN_BYTEA_P(lwgeom_to_wkb_varlena(lwgeom, variant)); + wkb = lwgeom_to_wkb(lwgeom, variant, &wkb_size); + lwgeom_free(lwgeom); + + /* Write to text and free the WKT */ + result = palloc(wkb_size + VARHDRSZ); + memcpy(VARDATA(result), wkb, wkb_size); + SET_VARSIZE(result, wkb_size + VARHDRSZ); + lwfree(wkb); + + /* Return the text */ + PG_FREE_IF_COPY(geom, 0); + PG_RETURN_BYTEA_P(result); } diff --git a/postgis/lwgeom_transform.c b/postgis/lwgeom_transform.c index 0d47fefd7..71ed6c27c 100644 --- a/postgis/lwgeom_transform.c +++ b/postgis/lwgeom_transform.c @@ -170,7 +170,8 @@ PG_FUNCTION_INFO_V1(LWGEOM_asKML); Datum LWGEOM_asKML(PG_FUNCTION_ARGS) { LWGEOM *lwgeom; - lwvarlena_t *kml; + char *kml; + text *result; const char *default_prefix = ""; /* default prefix */ char *prefixbuf; const char *prefix = default_prefix; @@ -223,7 +224,14 @@ Datum LWGEOM_asKML(PG_FUNCTION_ARGS) } kml = lwgeom_to_kml2(lwgeom, precision, prefix); - if (kml) - PG_RETURN_TEXT_P(kml); - PG_RETURN_NULL(); + lwgeom_free(lwgeom); + PG_FREE_IF_COPY(geom, 0); + + if (!kml) + PG_RETURN_NULL(); + + result = cstring_to_text(kml); + lwfree(kml); + + PG_RETURN_POINTER(result); } diff --git a/raster/rt_core/rt_geometry.c b/raster/rt_core/rt_geometry.c index d8e0e31f4..745f55b4f 100644 --- a/raster/rt_core/rt_geometry.c +++ b/raster/rt_core/rt_geometry.c @@ -1266,10 +1266,10 @@ rt_raster_gdal_polygonize( RASTER_DEBUGF(4, "LWGEOM wkt = %s", wkt); rtdealloc(wkt); - lwvarlena_t *lwwkb = lwgeom_to_wkb_varlena(lwgeom, WKB_ISO | WKB_NDR); - size_t lwwkbsize = LWSIZE_GET(lwwkb->size) - LWVARHDRSZ; + size_t lwwkbsize = 0; + uint8_t *lwwkb = lwgeom_to_wkb(lwgeom, WKB_ISO | WKB_NDR, &lwwkbsize); if (lwwkbsize) { - d_print_binary_hex("LWGEOM wkb", (const uint8_t *)lwwkb->data, lwwkbsize); + d_print_binary_hex("LWGEOM wkb", lwwkb, lwwkbsize); rtdealloc(lwwkb); } } diff --git a/raster/rt_pg/rtpg_geometry.c b/raster/rt_pg/rtpg_geometry.c index 29eaa17db..68ee1302b 100644 --- a/raster/rt_pg/rtpg_geometry.c +++ b/raster/rt_pg/rtpg_geometry.c @@ -728,7 +728,8 @@ Datum RASTER_asRaster(PG_FUNCTION_ARGS) rt_raster rast = NULL; rt_pgraster *pgrast = NULL; - lwvarlena_t *wkb; + unsigned char *wkb; + size_t wkb_len = 0; unsigned char variant = WKB_SFSQL; double scale[2] = {0}; @@ -1275,33 +1276,25 @@ Datum RASTER_asRaster(PG_FUNCTION_ARGS) /* get wkb of geometry */ POSTGIS_RT_DEBUG(3, "RASTER_asRaster: getting wkb of geometry"); - wkb = lwgeom_to_wkb_varlena(geom, variant); + wkb = lwgeom_to_wkb(geom, variant, &wkb_len); lwgeom_free(geom); PG_FREE_IF_COPY(gser, 0); /* rasterize geometry */ POSTGIS_RT_DEBUG(3, "RASTER_asRaster: rasterizing geometry"); /* use nodatavals for the init parameter */ - rast = rt_raster_gdal_rasterize((unsigned char *)wkb->data, - LWSIZE_GET(wkb->size) - LWVARHDRSZ, - srs, - num_bands, - pixtypes, - nodatavals, - values, - nodatavals, - hasnodatas, - dim_x, - dim_y, - scale_x, - scale_y, - ul_xw, - ul_yw, - grid_xw, - grid_yw, - skew_x, - skew_y, - options); + rast = rt_raster_gdal_rasterize(wkb, + (uint32_t) wkb_len, srs, + num_bands, pixtypes, + nodatavals, values, + nodatavals, hasnodatas, + dim_x, dim_y, + scale_x, scale_y, + ul_xw, ul_yw, + grid_xw, grid_yw, + skew_x, skew_y, + options + ); if (pixtypes_len) pfree(pixtypes); if (values_len) pfree(values); diff --git a/raster/rt_pg/rtpg_mapalgebra.c b/raster/rt_pg/rtpg_mapalgebra.c index d771a484e..5993473ce 100644 --- a/raster/rt_pg/rtpg_mapalgebra.c +++ b/raster/rt_pg/rtpg_mapalgebra.c @@ -3027,7 +3027,8 @@ Datum RASTER_clip(PG_FUNCTION_ARGS) GSERIALIZED *gser = NULL; LWGEOM *geom = NULL; - lwvarlena_t *wkb = NULL; + unsigned char *wkb = NULL; + size_t wkb_len; ArrayType *array; Oid etype; @@ -3319,30 +3320,23 @@ Datum RASTER_clip(PG_FUNCTION_ARGS) /* get wkb of geometry */ POSTGIS_RT_DEBUG(3, "getting wkb of geometry"); - wkb = lwgeom_to_wkb_varlena(geom, WKB_SFSQL); + wkb = lwgeom_to_wkb(geom, WKB_SFSQL, &wkb_len); lwgeom_free(geom); /* rasterize geometry */ - arg->mask = rt_raster_gdal_rasterize((unsigned char *)wkb->data, - LWSIZE_GET(wkb->size) - LWVARHDRSZ, - NULL, - 0, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - &(gt[1]), - &(gt[5]), - NULL, - NULL, - &(gt[0]), - &(gt[3]), - &(gt[2]), - &(gt[4]), - NULL); + arg->mask = rt_raster_gdal_rasterize( + wkb, wkb_len, + NULL, + 0, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + &(gt[1]), &(gt[5]), + NULL, NULL, + &(gt[0]), &(gt[3]), + &(gt[2]), &(gt[4]), + NULL + ); pfree(wkb); if (arg->mask == NULL) { diff --git a/raster/rt_pg/rtpg_pixel.c b/raster/rt_pg/rtpg_pixel.c index 6fdae0785..06c952b2e 100644 --- a/raster/rt_pg/rtpg_pixel.c +++ b/raster/rt_pg/rtpg_pixel.c @@ -1213,7 +1213,8 @@ Datum RASTER_setPixelValuesGeomval(PG_FUNCTION_ARGS) GSERIALIZED *gser = NULL; uint8_t gtype; - lwvarlena_t *wkb = NULL; + unsigned char *wkb = NULL; + size_t wkb_len; int i = 0; uint32_t j = 0; @@ -1371,29 +1372,22 @@ Datum RASTER_setPixelValuesGeomval(PG_FUNCTION_ARGS) /* get wkb of geometry */ POSTGIS_RT_DEBUG(3, "getting wkb of geometry"); - wkb = lwgeom_to_wkb_varlena(arg->gv[arg->ngv].geom, WKB_SFSQL); + wkb = lwgeom_to_wkb(arg->gv[arg->ngv].geom, WKB_SFSQL, &wkb_len); /* rasterize geometry */ - arg->gv[arg->ngv].mask = rt_raster_gdal_rasterize((unsigned char *)wkb->data, - LWSIZE_GET(wkb->size) - LWVARHDRSZ, - NULL, - 0, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - &(gt[1]), - &(gt[5]), - NULL, - NULL, - &(gt[0]), - &(gt[3]), - &(gt[2]), - &(gt[4]), - NULL); + arg->gv[arg->ngv].mask = rt_raster_gdal_rasterize( + wkb, wkb_len, + NULL, + 0, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, + &(gt[1]), &(gt[5]), + NULL, NULL, + &(gt[0]), &(gt[3]), + &(gt[2]), &(gt[4]), + NULL + ); pfree(wkb); if (gtype != POINTTYPE && gtype != MULTIPOINTTYPE) { diff --git a/topology/postgis_topology.c b/topology/postgis_topology.c index 46c245d70..a5d3b0cb5 100644 --- a/topology/postgis_topology.c +++ b/topology/postgis_topology.c @@ -144,11 +144,13 @@ _box2d_to_lwgeom(const GBOX *bbox, int32_t srid) static char * _box2d_to_hexwkb(const GBOX *bbox, int32_t srid) { - char *hex; - LWGEOM *geom = _box2d_to_lwgeom(bbox, srid); - hex = lwgeom_to_hexwkb_buffer(geom, WKT_EXTENDED); - lwgeom_free(geom); - return hex; + char *hex; + size_t sz; + LWGEOM *geom = _box2d_to_lwgeom(bbox, srid); + hex = lwgeom_to_hexwkb(geom, WKT_EXTENDED, &sz); + lwgeom_free(geom); + assert(hex[sz-1] == '\0'); + return hex; } /* Backend callbacks */ @@ -346,6 +348,7 @@ addEdgeFields(StringInfo str, int fields, int fullEdgeData) static void addEdgeValues(StringInfo str, const LWT_ISO_EDGE *edge, int fields, int fullEdgeData) { + size_t hexewkb_size; char *hexewkb; const char *sep = ""; @@ -396,9 +399,10 @@ addEdgeValues(StringInfo str, const LWT_ISO_EDGE *edge, int fields, int fullEdge { if ( edge->geom ) { - hexewkb = lwgeom_to_hexwkb_buffer(lwline_as_lwgeom(edge->geom), WKB_EXTENDED); - appendStringInfo(str, "%s'%s'::geometry", sep, hexewkb); - lwfree(hexewkb); + hexewkb = lwgeom_to_hexwkb(lwline_as_lwgeom(edge->geom), + WKB_EXTENDED, &hexewkb_size); + appendStringInfo(str, "%s'%s'::geometry", sep, hexewkb); + lwfree(hexewkb); } else { @@ -422,6 +426,7 @@ addEdgeUpdate(StringInfo str, const LWT_ISO_EDGE* edge, int fields, const char *sep = ""; const char *sep1; const char *op; + size_t hexewkb_size; char *hexewkb; switch (updType) @@ -496,7 +501,8 @@ addEdgeUpdate(StringInfo str, const LWT_ISO_EDGE* edge, int fields, if ( fields & LWT_COL_EDGE_GEOM ) { appendStringInfo(str, "%sgeom", sep); - hexewkb = lwgeom_to_hexwkb_buffer(lwline_as_lwgeom(edge->geom), WKB_EXTENDED); + hexewkb = lwgeom_to_hexwkb(lwline_as_lwgeom(edge->geom), + WKB_EXTENDED, &hexewkb_size); appendStringInfo(str, "%s'%s'::geometry", op, hexewkb); lwfree(hexewkb); } @@ -509,6 +515,7 @@ addNodeUpdate(StringInfo str, const LWT_ISO_NODE* node, int fields, const char *sep = ""; const char *sep1; const char *op; + size_t hexewkb_size; char *hexewkb; switch (updType) @@ -550,7 +557,8 @@ addNodeUpdate(StringInfo str, const LWT_ISO_NODE* node, int fields, if ( fields & LWT_COL_NODE_GEOM ) { appendStringInfo(str, "%sgeom", sep); - hexewkb = lwgeom_to_hexwkb_buffer(lwpoint_as_lwgeom(node->geom), WKB_EXTENDED); + hexewkb = lwgeom_to_hexwkb(lwpoint_as_lwgeom(node->geom), + WKB_EXTENDED, &hexewkb_size); appendStringInfo(str, "%s'%s'::geometry", op, hexewkb); lwfree(hexewkb); } @@ -598,6 +606,7 @@ addFaceFields(StringInfo str, int fields) static void addNodeValues(StringInfo str, const LWT_ISO_NODE *node, int fields) { + size_t hexewkb_size; char *hexewkb; const char *sep = ""; @@ -623,9 +632,10 @@ addNodeValues(StringInfo str, const LWT_ISO_NODE *node, int fields) { if ( node->geom ) { - hexewkb = lwgeom_to_hexwkb_buffer(lwpoint_as_lwgeom(node->geom), WKB_EXTENDED); - appendStringInfo(str, "%s'%s'::geometry", sep, hexewkb); - lwfree(hexewkb); + hexewkb = lwgeom_to_hexwkb(lwpoint_as_lwgeom(node->geom), + WKB_EXTENDED, &hexewkb_size); + appendStringInfo(str, "%s'%s'::geometry", sep, hexewkb); + lwfree(hexewkb); } else { @@ -1362,6 +1372,7 @@ cb_getEdgeWithinDistance2D(const LWT_BE_TOPOLOGY *topo, LWT_ISO_EDGE *edges; int spi_result; int64_t elems_requested = limit; + size_t hexewkb_size; char *hexewkb; MemoryContext oldcontext = CurrentMemoryContext; StringInfoData sqldata; @@ -1380,7 +1391,7 @@ cb_getEdgeWithinDistance2D(const LWT_BE_TOPOLOGY *topo, } appendStringInfo(sql, " FROM \"%s\".edge_data", topo->name); // TODO: use binary cursor here ? - hexewkb = lwgeom_to_hexwkb_buffer(lwpoint_as_lwgeom(pt), WKB_EXTENDED); + hexewkb = lwgeom_to_hexwkb(lwpoint_as_lwgeom(pt), WKB_EXTENDED, &hexewkb_size); if ( dist ) { appendStringInfo(sql, " WHERE ST_DWithin('%s'::geometry, geom, %g)", hexewkb, dist); @@ -1461,6 +1472,7 @@ cb_getNodeWithinDistance2D(const LWT_BE_TOPOLOGY *topo, MemoryContext oldcontext = CurrentMemoryContext; LWT_ISO_NODE *nodes; int spi_result; + size_t hexewkb_size; char *hexewkb; StringInfoData sqldata; StringInfo sql = &sqldata; @@ -1486,7 +1498,7 @@ cb_getNodeWithinDistance2D(const LWT_BE_TOPOLOGY *topo, } appendStringInfo(sql, " FROM \"%s\".node", topo->name); // TODO: use binary cursor here ? - hexewkb = lwgeom_to_hexwkb_buffer(lwpoint_as_lwgeom(pt), WKB_EXTENDED); + hexewkb = lwgeom_to_hexwkb(lwpoint_as_lwgeom(pt), WKB_EXTENDED, &hexewkb_size); if ( dist ) { appendStringInfo(sql, " WHERE ST_DWithin(geom, '%s'::geometry, %g)",