From 4f8c4b5e8f3b76f28c6b74a62c31589026fb2902 Mon Sep 17 00:00:00 2001 From: Mark Cave-Ayland Date: Sun, 13 Jul 2008 10:50:56 +0000 Subject: [PATCH] More work on improving the EWKT/B parser; remove all references to allocator functions from outside of liblwgeom by generating wrapper functions with more meaningful names. As well as cleaning up the API, it also makes the code much more readable git-svn-id: http://svn.osgeo.org/postgis/trunk@2839 b70326c6-7e19-0410-871a-916f4a2858ee --- liblwgeom/liblwgeom.h | 10 +++--- liblwgeom/lwgeom.c | 58 ++++++++++++++++++++++++++++++++- liblwgeom/lwgeom_api.c | 18 ---------- lwgeom/lwgeom_functions_basic.c | 2 +- lwgeom/lwgeom_geos_c.c | 4 +-- lwgeom/lwgeom_gist.c | 2 +- lwgeom/lwgeom_inout.c | 21 +++++------- lwgeom/lwgeom_ogc.c | 4 +-- lwgeom/lwgeom_pg.c | 5 ++- 9 files changed, 80 insertions(+), 44 deletions(-) diff --git a/liblwgeom/liblwgeom.h b/liblwgeom/liblwgeom.h index 4067b871f..1be0a2b34 100644 --- a/liblwgeom/liblwgeom.h +++ b/liblwgeom/liblwgeom.h @@ -1115,15 +1115,17 @@ extern uchar parse_hex(char *str); extern void deparse_hex(uchar str, char *result); /* Parser access routines */ -extern char *unparse_WKT(uchar* serialized, lwallocator alloc, lwfreeor free); -extern char *unparse_WKB(uchar* serialized, lwallocator alloc, lwfreeor free, char endian, size_t *outsize, uchar hex); - -extern SERIALIZED_LWGEOM *parse_lwgeom_wkt(char *wkt_input); +extern SERIALIZED_LWGEOM *ewkt_to_lwgeom(char *wkt_input); extern char *lwgeom_to_ewkt(LWGEOM *lwgeom); extern char *lwgeom_to_hexwkb(LWGEOM *lwgeom, unsigned int byteorder); extern LWGEOM *lwgeom_from_ewkb(uchar *ewkb, size_t ewkblen); extern uchar *lwgeom_to_ewkb(LWGEOM *lwgeom, char byteorder, size_t *ewkblen); +extern char *serialized_lwgeom_to_ewkt(uchar *serialized); +extern char *serialized_lwgeom_to_hexwkb(uchar *serialized, unsigned int byteorder, size_t *size); +extern char *serialized_lwgeom_to_ewkb(uchar *serialized, unsigned int byteorder, size_t *size); + + extern void *lwalloc(size_t size); extern void *lwrealloc(void *mem, size_t size); extern void lwfree(void *mem); diff --git a/liblwgeom/lwgeom.c b/liblwgeom/lwgeom.c index a6972b581..61f7f838d 100644 --- a/liblwgeom/lwgeom.c +++ b/liblwgeom/lwgeom.c @@ -452,6 +452,28 @@ lwgeom_add(const LWGEOM *to, uint32 where, const LWGEOM *what) } } + +/* + * Make a LWGEOM object from a WKT input string + */ +SERIALIZED_LWGEOM * +ewkt_to_lwgeom(char *wkt_input) +{ + SERIALIZED_LWGEOM *serialized_form = parse_lwg(wkt_input, + lwalloc, lwerror); + + + LWDEBUGF(2, "ewkt_to_lwgeom with %s",wkt_input); + + if (serialized_form == NULL) + { + lwerror("ewkt_to_lwgeom:: couldnt parse!"); + return NULL; + } + + return serialized_form; +} + /* * Return an alloced string */ @@ -521,7 +543,7 @@ lwgeom_from_ewkb(uchar *ewkb, size_t size) hexewkb[hexewkblen] = '\0'; /* Rely on grammar parser to construct a LWGEOM */ - serialized_lwgeom = parse_lwgeom_wkt(hexewkb); + serialized_lwgeom = ewkt_to_lwgeom(hexewkb); /* Free intermediate HEXified representation */ lwfree(hexewkb); @@ -532,6 +554,40 @@ lwgeom_from_ewkb(uchar *ewkb, size_t size) return ret; } + +/* + * Parser functions for working with serialized LWGEOMs. Useful for cases where + * the function input is already serialized, e.g. some input and output functions + */ + +/* + * Return an alloced string + */ +char * +serialized_lwgeom_to_ewkt(uchar *serialized) +{ + return unparse_WKT(serialized, lwalloc, lwfree); +} + +/* + * Return an alloced string + */ +char * +serialized_lwgeom_to_hexwkb(uchar *serialized, unsigned int byteorder, size_t *size) +{ + return unparse_WKB(serialized, lwalloc, lwfree, byteorder, size, 1); +} + +/* + * Return an alloced string + */ +char * +serialized_lwgeom_to_ewkb(uchar *serialized, unsigned int byteorder, size_t *size) +{ + return unparse_WKB(serialized, lwalloc, lwfree, byteorder, size, 0); +} + + /* * geom1 same as geom2 * iff diff --git a/liblwgeom/lwgeom_api.c b/liblwgeom/lwgeom_api.c index 066ee9863..030b21302 100644 --- a/liblwgeom/lwgeom_api.c +++ b/liblwgeom/lwgeom_api.c @@ -2136,24 +2136,6 @@ deparse_hex(uchar str, char *result) } -SERIALIZED_LWGEOM * -parse_lwgeom_wkt(char *wkt_input) -{ - SERIALIZED_LWGEOM *serialized_form = parse_lwg(wkt_input, - lwalloc, lwerror); - - - LWDEBUGF(2, "parse_lwgeom_wkt with %s",wkt_input); - - if (serialized_form == NULL) - { - lwerror("parse_WKT:: couldnt parse!"); - return NULL; - } - - return serialized_form; - -} /* * Find interpolation point I diff --git a/lwgeom/lwgeom_functions_basic.c b/lwgeom/lwgeom_functions_basic.c index 474dc786b..b727d0cff 100644 --- a/lwgeom/lwgeom_functions_basic.c +++ b/lwgeom/lwgeom_functions_basic.c @@ -2910,7 +2910,7 @@ Datum LWGEOM_asEWKT(PG_FUNCTION_ARGS) /*char *semicolonLoc; */ lwgeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); - result_cstring = unparse_WKT(SERIALIZED_FORM(lwgeom),lwalloc,lwfree); + result_cstring = serialized_lwgeom_to_ewkt(SERIALIZED_FORM(lwgeom)); #if 0 semicolonLoc = strchr(result_cstring,';'); diff --git a/lwgeom/lwgeom_geos_c.c b/lwgeom/lwgeom_geos_c.c index 06f8d514a..79db62f55 100644 --- a/lwgeom/lwgeom_geos_c.c +++ b/lwgeom/lwgeom_geos_c.c @@ -3210,7 +3210,7 @@ Datum GEOSnoop(PG_FUNCTION_ARGS) geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); - POSTGIS_DEBUGF(2, "GEOSnoop: IN: %s", unparse_WKT(SERIALIZED_FORM(geom), malloc, free)); + POSTGIS_DEBUGF(2, "GEOSnoop: IN: %s", serialized_lwgeom_to_ewkt(SERIALIZED_FORM(geom))); geosgeom = POSTGIS2GEOS(geom); if ( ! geosgeom ) PG_RETURN_NULL(); @@ -3223,7 +3223,7 @@ Datum GEOSnoop(PG_FUNCTION_ARGS) result = GEOS2POSTGIS(geosgeom, TYPE_HASZ(geom->type)); GEOSGeom_destroy(geosgeom); - POSTGIS_DEBUGF(4, "GEOSnoop: OUT: %s", unparse_WKT(SERIALIZED_FORM(result), malloc, free)); + POSTGIS_DEBUGF(4, "GEOSnoop: OUT: %s", serialized_lwgeom_to_ewkt(SERIALIZED_FORM(result))); PG_FREE_IF_COPY(geom, 0); diff --git a/lwgeom/lwgeom_gist.c b/lwgeom/lwgeom_gist.c index c69666026..6879c6061 100644 --- a/lwgeom/lwgeom_gist.c +++ b/lwgeom/lwgeom_gist.c @@ -465,7 +465,7 @@ Datum LWGEOM_gist_compress(PG_FUNCTION_ARGS) /* lwgeom serialized form */ in = (PG_LWGEOM*)PG_DETOAST_DATUM(entry->key); - POSTGIS_DEBUGF(4, "GIST: LWGEOM_gist_compress detoasted entry->key: %s", unparse_WKT(in+VARHDRSZ, malloc, free)); + POSTGIS_DEBUGF(4, "GIST: LWGEOM_gist_compress detoasted entry->key: %s", serialized_lwgeom_to_ewkt(in+VARHDRSZ)); if (in == NULL) { diff --git a/lwgeom/lwgeom_inout.c b/lwgeom/lwgeom_inout.c index 8e75a7f63..19dc3bd58 100644 --- a/lwgeom/lwgeom_inout.c +++ b/lwgeom/lwgeom_inout.c @@ -68,7 +68,7 @@ Datum LWGEOM_in(PG_FUNCTION_ARGS) PG_LWGEOM *ret; /* will handle both HEXEWKB and EWKT */ - serialized_lwgeom = parse_lwgeom_wkt(str); + serialized_lwgeom = ewkt_to_lwgeom(str); lwgeom = lwgeom_deserialize(serialized_lwgeom->lwgeom); ret = pglwgeom_serialize(lwgeom); @@ -97,7 +97,7 @@ Datum LWGEOM_out(PG_FUNCTION_ARGS) char *result; lwgeom = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); - result = unparse_WKB(SERIALIZED_FORM(lwgeom),lwalloc,lwfree,-1,NULL,1); + result = serialized_lwgeom_to_hexwkb(SERIALIZED_FORM(lwgeom), -1, NULL); PG_RETURN_CSTRING(result); } @@ -137,8 +137,7 @@ Datum LWGEOM_asHEXEWKB(PG_FUNCTION_ARGS) } } - result = unparse_WKB(SERIALIZED_FORM(lwgeom),lwalloc,lwfree, - byteorder, &size, 1); + result = serialized_lwgeom_to_hexwkb(SERIALIZED_FORM(lwgeom), byteorder, &size); text_result = palloc(size+VARHDRSZ); memcpy(VARDATA(text_result),result,size); @@ -165,7 +164,7 @@ Datum LWGEOM_to_text(PG_FUNCTION_ARGS) size_t size; lwgeom = (PG_LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); - result = unparse_WKB(SERIALIZED_FORM(lwgeom),lwalloc,lwfree,-1,&size,1); + result = serialized_lwgeom_to_hexwkb(SERIALIZED_FORM(lwgeom), -1, &size); text_result = palloc(size+VARHDRSZ); memcpy(VARDATA(text_result),result,size); @@ -266,8 +265,7 @@ Datum WKBFromLWGEOM(PG_FUNCTION_ARGS) lwgeom_input = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); #ifdef BINARY_FROM_HEX - hexized_wkb_srid = unparse_WKB(SERIALIZED_FORM(lwgeom_input), - lwalloc, lwfree, byteorder, &size, 1); + hexized_wkb_srid = serialized_lwgeom_to_hexwkb(SERIALIZED_FORM(lwgeom_input), byteorder, &size); LWDEBUGF(3, "in WKBFromLWGEOM with WKB = '%s'", hexized_wkb_srid); @@ -296,8 +294,7 @@ Datum WKBFromLWGEOM(PG_FUNCTION_ARGS) #else /* ndef BINARY_FROM_HEX */ - hexized_wkb = unparse_WKB(SERIALIZED_FORM(lwgeom_input), - lwalloc, lwfree, byteorder, &size, 0); + hexized_wkb = serialized_lwgeom_to_ewkb(SERIALIZED_FORM(lwgeom_input), byteorder, &size); size_result = size+VARHDRSZ; result = palloc(size_result); @@ -309,7 +306,7 @@ Datum WKBFromLWGEOM(PG_FUNCTION_ARGS) #ifdef PROFILE profstop(PROF_QRUN); - lwnotice("unparse_WKB: prof: %lu", proftime[PROF_QRUN]); + lwnotice("serialized_lwgeom_to_ewkb: prof: %lu", proftime[PROF_QRUN]); #endif LWDEBUGF(3, "Output size is %lu (comp: %lu)", @@ -479,7 +476,7 @@ Datum parse_WKT_lwgeom(PG_FUNCTION_ARGS) POSTGIS_DEBUGF(3, "in parse_WKT_lwgeom with input: '%s'",wkt); - serialized_lwgeom = parse_lwgeom_wkt(wkt); + serialized_lwgeom = ewkt_to_lwgeom(wkt); lwgeom = lwgeom_deserialize(serialized_lwgeom->lwgeom); ret = pglwgeom_serialize(lwgeom); @@ -530,7 +527,7 @@ Datum LWGEOM_recv(PG_FUNCTION_ARGS) POSTGIS_DEBUG(3, "LWGEOM_recv advancing StringInfo buffer"); - POSTGIS_DEBUGF(3, "LWGEOM_from_bytea returned %s", unparse_WKB(SERIALIZED_FORM(result),pg_alloc,pg_free,-1,NULL,1)); + POSTGIS_DEBUGF(3, "LWGEOM_from_bytea returned %s", serialized_lwgeom_to_hexwkb(SERIALIZED_FORM(result), -1, NULL)); /* Set cursor to the end of buffer (so the backend is happy) */ buf->cursor = buf->len; diff --git a/lwgeom/lwgeom_ogc.c b/lwgeom/lwgeom_ogc.c index 51195282d..0c882b331 100644 --- a/lwgeom/lwgeom_ogc.c +++ b/lwgeom/lwgeom_ogc.c @@ -1002,7 +1002,7 @@ Datum LWGEOM_from_text(PG_FUNCTION_ARGS) POSTGIS_DEBUGF(3, "wkt: [%s]", wkt); - serialized_lwgeom = parse_lwgeom_wkt(wkt); + serialized_lwgeom = ewkt_to_lwgeom(wkt); lwgeom = lwgeom_deserialize(serialized_lwgeom->lwgeom); if ( lwgeom->SRID != -1 || TYPE_GETZM(lwgeom->type) != 0 ) @@ -1078,7 +1078,7 @@ Datum LWGEOM_asText(PG_FUNCTION_ARGS) ogclwgeom = (PG_LWGEOM *)DatumGetPointer(DirectFunctionCall1( LWGEOM_force_2d, PointerGetDatum(lwgeom))); - result_cstring = unparse_WKT(SERIALIZED_FORM(ogclwgeom),lwalloc,lwfree); + result_cstring = serialized_lwgeom_to_ewkt(SERIALIZED_FORM(ogclwgeom)); semicolonLoc = strchr(result_cstring,';'); diff --git a/lwgeom/lwgeom_pg.c b/lwgeom/lwgeom_pg.c index febf88fef..31c7f1397 100644 --- a/lwgeom/lwgeom_pg.c +++ b/lwgeom/lwgeom_pg.c @@ -264,7 +264,7 @@ pglwgeom_from_ewkb(uchar *ewkb, size_t ewkblen) } hexewkb[hexewkblen] = '\0'; - serialized_lwgeom = parse_lwgeom_wkt(hexewkb); + serialized_lwgeom = ewkt_to_lwgeom(hexewkb); ret = (PG_LWGEOM *)palloc(serialized_lwgeom->size + VARHDRSZ); SET_VARSIZE(ret, serialized_lwgeom->size + VARHDRSZ); @@ -282,8 +282,7 @@ char * pglwgeom_to_ewkb(PG_LWGEOM *geom, char byteorder, size_t *outsize) { uchar *srl = &(geom->type); - return unparse_WKB(srl, lwalloc, lwfree, - byteorder, outsize, 0); + return serialized_lwgeom_to_ewkb(srl, byteorder, outsize); } /* -- 2.50.1