From: Sandro Santilli Date: Wed, 29 Sep 2004 15:25:21 +0000 (+0000) Subject: Added serialize function for LWGEOM X-Git-Tag: pgis_1_0_0RC1~362 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=271ff4b2666d23a365bd9d4baad8c8343d61cb2f;p=postgis Added serialize function for LWGEOM git-svn-id: http://svn.osgeo.org/postgis/trunk@910 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/lwgeom/Makefile b/lwgeom/Makefile index 729ccefdd..3cbb66287 100644 --- a/lwgeom/Makefile +++ b/lwgeom/Makefile @@ -66,7 +66,7 @@ ifeq ($(USE_STATS),1) override CFLAGS += -DUSE_STATS endif -OBJS=lwgeom_pg.o lwgeom.o lwpoint.o lwline.o lwpoly.o lwmpoint.o lwmline.o lwmpoly.o lwcollection.o lwgeom_spheroid.o lwgeom_api.o lwgeom_ogc.o lwgeom_functions_analytic.o lwgeom_geos.o lwgeom_inout.o lwgeom_estimate.o lwgeom_functions_basic.o lwgeom_gist.o lwgeom_btree.o lwgeom_transform.o stringBuffer.o lwgeom_box.o lwgeom_box3d.o lwgeom_box2dfloat4.o lwgeom_chip.o lex.yy.o wktparse.tab.o lwgparse.o wktunparse.o lwgeom_svg.o lwgeom_gml.o $(GEOS_WRAPPER) +OBJS=lwgeom_pg.o liblwgeom.o lwgeom.o lwpoint.o lwline.o lwpoly.o lwmpoint.o lwmline.o lwmpoly.o lwcollection.o lwgeom_spheroid.o lwgeom_api.o lwgeom_ogc.o lwgeom_functions_analytic.o lwgeom_geos.o lwgeom_inout.o lwgeom_estimate.o lwgeom_functions_basic.o lwgeom_gist.o lwgeom_btree.o lwgeom_transform.o stringBuffer.o lwgeom_box.o lwgeom_box3d.o lwgeom_box2dfloat4.o lwgeom_chip.o lex.yy.o wktparse.tab.o lwgparse.o wktunparse.o lwgeom_svg.o lwgeom_gml.o $(GEOS_WRAPPER) OTHERS=y.output lex.yy.c wktparse.tab.c wktparse.tab.h lwpostgis.sql diff --git a/lwgeom/liblwgeom.h b/lwgeom/liblwgeom.h index fbe3aab1b..31a041c93 100644 --- a/lwgeom/liblwgeom.h +++ b/lwgeom/liblwgeom.h @@ -44,7 +44,6 @@ typedef struct double xmax, ymax, zmax; } BOX3D; - typedef struct chiptag { int size; //unused (for use by postgresql) @@ -292,6 +291,7 @@ extern uint32 lwgeom_size_poly(const char *serialized_line); typedef struct { + int type; char ndims; // 2=2d, 3=3d, 4=4d, 5=undef int SRID; // spatial ref sys POINTARRAY *point; // hide 2d/3d (this will be an array of 1 point) @@ -309,7 +309,7 @@ extern LWPOINT *lwpoint_construct(int ndims, int SRID, POINTARRAY *point); extern LWPOINT *lwpoint_deserialize(char *serialized_form); // Find size this point would get when serialized (no BBOX) -extern uint32 lwpoint_size(LWPOINT *point); +extern size_t lwpoint_serialize_size(LWPOINT *point); // convert this point into its serialize form // result's first char will be the 8bit type. See serialized form doc @@ -329,7 +329,8 @@ extern POINT3D lwpoint_getPoint3d(const LWPOINT *point); typedef struct { - char ndims; // 2=2d, 3=3d, 4=4d, 5=undef + int type; + char ndims; // 2=2d, 3=3d, 4=4d, 5=undef int SRID; // spatial ref sys -1=none POINTARRAY *points; // array of POINT3D } LWLINE; //"light-weight line" @@ -345,7 +346,7 @@ extern LWLINE *lwline_construct(int ndims, int SRID, POINTARRAY *points); extern LWLINE *lwline_deserialize(char *serialized_form); // find the size this line would get when serialized (no BBOX) -extern uint32 lwline_size(LWLINE *line); +extern size_t lwline_serialize_size(LWLINE *line); // convert this line into its serialize form // result's first char will be the 8bit type. See serialized form doc @@ -362,6 +363,7 @@ extern BOX3D *lwline_findbbox(LWLINE *line); typedef struct { + char type; int32 SRID; char ndims; int nrings; @@ -379,7 +381,7 @@ extern LWPOLY *lwpoly_construct(int ndims, int SRID, int nrings,POINTARRAY **poi extern LWPOLY *lwpoly_deserialize(char *serialized_form); // find the size this polygon would get when serialized (no bbox!) -extern uint32 lwpoly_size(LWPOLY *poly); +extern size_t lwpoly_serialize_size(LWPOLY *poly); // create the serialized form of the polygon // result's first char will be the 8bit type. See serialized form doc @@ -397,59 +399,73 @@ extern BOX3D *lwpoly_findbbox(LWPOLY *poly); // MULTIPOINTTYPE typedef struct { + int type; int32 SRID; char ndims; int npoints; LWPOINT **points; } LWMPOINT; +extern size_t lwmpoint_serialize_size(LWMPOINT *mpoint); +extern void lwmpoint_serialize_buf(LWMPOINT *mpoint, char *buf, int *size); + // MULTILINETYPE typedef struct -{ +{ + int type; int32 SRID; char ndims; int nlines; LWLINE **lines; } LWMLINE; +extern size_t lwmline_serialize_size(LWMLINE *mline); +extern void lwmline_serialize_buf(LWMLINE *mline, char *buf, int *size); + // MULTIPOLYGONTYPE typedef struct -{ +{ + int type; int32 SRID; char ndims; int npolys; LWPOLY **polys; } LWMPOLY; -// COLLECTIONTYPE +extern size_t lwmpoly_serialize_size(LWMPOLY *mpoly); +extern void lwmpoly_serialize_buf(LWMPOLY *mpoly, char *buf, int *size); + +// LWGEOM (any type) typedef struct { + int type; + void *data; +} LWGEOM; + +extern size_t lwgeom_serialize_size(LWGEOM *geom); +extern void lwgeom_serialize_buf(LWGEOM *geom, char *buf, int *size); +extern char *lwgeom_serialize(LWGEOM *geom, char wantbbox); + +// COLLECTIONTYPE +typedef struct +{ + int type; int32 SRID; char ndims; int ngeoms; - struct LWGEOM **geoms; + LWGEOM **geoms; } LWCOLLECTION; -// LWGEOM (any type) -typedef struct -{ - char type; - union { - LWPOINT *point; - LWMPOINT *mpoint; - LWLINE *line; - LWMLINE *mline; - LWPOLY *poly; - LWMPOLY *mpoly; - LWCOLLECTION *collection; - }; -} LWGEOM; +extern size_t lwcollection_serialize_size(LWCOLLECTION *coll); +extern void lwcollection_serialize_buf(LWCOLLECTION *mcoll, char *buf, int *size); LWGEOM *lwgeom_deserialize(char *serializedform); LWMPOINT *lwmpoint_deserialize(char *serializedform); LWMLINE *lwmline_deserialize(char *serializedform); LWMPOLY *lwmpoly_deserialize(char *serializedform); LWCOLLECTION *lwcollection_deserialize(char *serializedform); +LWGEOM *lwcollection_getsubgeom(LWCOLLECTION *, int); + //------------------------------------------------------ diff --git a/lwgeom/lwcollection.c b/lwgeom/lwcollection.c index dfdc618fd..875327e02 100644 --- a/lwgeom/lwcollection.c +++ b/lwgeom/lwcollection.c @@ -1,5 +1,6 @@ #include #include +#include #include "liblwgeom.h" LWCOLLECTION * @@ -20,6 +21,7 @@ lwcollection_deserialize(char *srl) insp = lwgeom_inspect(srl); result = lwalloc(sizeof(LWCOLLECTION)); + result->type = COLLECTIONTYPE; result->SRID = insp->SRID; result->ndims = lwgeom_ndims(insp->type); result->ngeoms = insp->ngeometries; @@ -27,9 +29,70 @@ lwcollection_deserialize(char *srl) for (i=0; ingeometries; i++) { - result->geoms[i] = (struct LWGEOM *)lwgeom_deserialize(insp->sub_geoms[i]); + result->geoms[i] = lwgeom_deserialize(insp->sub_geoms[i]); } return result; } +LWGEOM * +lwcollection_getsubgeom(LWCOLLECTION *col, int gnum) +{ + return (LWGEOM *)col->geoms[gnum]; +} + +// find serialized size of this collection +size_t +lwcollection_serialize_size(LWCOLLECTION *col) +{ + size_t size = 5; // type + nsubgeoms + int i; + + if ( col->SRID != -1 ) size += 4; // SRID + + for (i=0; ingeoms; i++) + size += lwgeom_serialize_size(lwcollection_getsubgeom(col, i)); + + return size; +} + +// convert this collectoin into its serialize form writing it into +// the given buffer, and returning number of bytes written into +// the given int pointer. +void +lwcollection_serialize_buf(LWCOLLECTION *coll, char *buf, int *retsize) +{ + int size=1; // type + int subsize=0; + char hasSRID; + char *loc; + int i; + + hasSRID = (coll->SRID != -1); + + buf[0] = (unsigned char) lwgeom_makeType(coll->ndims, + hasSRID, COLLECTIONTYPE); + loc = buf+1; + + // Add SRID if requested + if (hasSRID) + { + memcpy(loc, &coll->SRID, 4); + size += 4; + loc += 4; + } + + // Write number of subgeoms + memcpy(loc, &coll->ngeoms, 4); + size += 4; + loc += 4; + + // Serialize subgeoms + for (i=0; ingeoms; i++) + { + lwgeom_serialize_buf(coll->geoms[i], loc, &subsize); + size += subsize; + } + + if (retsize) *retsize = size; +} diff --git a/lwgeom/lwgeom.c b/lwgeom/lwgeom.c index c7b96334f..2f163b8fc 100644 --- a/lwgeom/lwgeom.c +++ b/lwgeom/lwgeom.c @@ -5,130 +5,126 @@ #include "lwgeom_pg.h" #include "liblwgeom.h" -#define CONTEXT_PG 0 -#define CONTEXT_STANDALONE 1 - -/* Define this to the default context liblwgeom runs with */ -#define DEFAULT_CONTEXT CONTEXT_PG - - -/* globals */ -#if DEFAULT_CONTEXT == CONTEXT_PG -lwallocator lwalloc = pg_alloc; -lwreallocator lwrealloc = pg_realloc; -lwfreeor lwfree = pg_free; -lwreporter lwerror = pg_error; -lwreporter lwnotice = pg_notice; -#else -lwallocator lwalloc = default_allocator; -lwreallocator lwrealloc = default_reallocator; -lwfreeor lwfree = default_freeor; -lwreporter lwerror = default_errorreporter; -lwreporter lwnotice = default_noticereporter; -#endif - LWGEOM * lwgeom_deserialize(char *srl) { - LWGEOM *result; int type = lwgeom_getType(srl[0]); - result = lwalloc(sizeof(LWGEOM)); - result->type = type; switch (type) { case POINTTYPE: - result->point = lwpoint_deserialize(srl); - break; + return (LWGEOM *)lwpoint_deserialize(srl); case LINETYPE: - result->line = lwline_deserialize(srl); - break; + return (LWGEOM *)lwline_deserialize(srl); case POLYGONTYPE: - result->poly = lwpoly_deserialize(srl); - break; + return (LWGEOM *)lwpoly_deserialize(srl); case MULTIPOINTTYPE: - result->mpoint = lwmpoint_deserialize(srl); - break; + return (LWGEOM *)lwmpoint_deserialize(srl); case MULTILINETYPE: - result->mline = lwmline_deserialize(srl); - break; + return (LWGEOM *)lwmline_deserialize(srl); case MULTIPOLYGONTYPE: - result->mpoly = lwmpoly_deserialize(srl); - break; + return (LWGEOM *)lwmpoly_deserialize(srl); case COLLECTIONTYPE: - result->collection = lwcollection_deserialize(srl); - break; + return (LWGEOM *)lwcollection_deserialize(srl); default: lwerror("Unknown geometry type: %d", type); return NULL; } - return result; } -void * -default_allocator(size_t size) +size_t +lwgeom_serialize_size(LWGEOM *lwgeom) { - void * result; - result = malloc(size); - return result; -} + int type = lwgeom->type; + size_t size; -void * -default_reallocator(void *mem, size_t size) -{ - void * result; - result = realloc(mem, size); - return result; + switch (type) + { + case POINTTYPE: + size = lwpoint_serialize_size((LWPOINT *)lwgeom); + case LINETYPE: + size = lwline_serialize_size((LWLINE *)lwgeom); + case POLYGONTYPE: + size = lwpoly_serialize_size((LWPOLY *)lwgeom); + case MULTIPOINTTYPE: + size = lwmpoint_serialize_size((LWMPOINT *)lwgeom); + case MULTILINETYPE: + size = lwmline_serialize_size((LWMLINE *)lwgeom); + case MULTIPOLYGONTYPE: + size = lwmpoly_serialize_size((LWMPOLY *)lwgeom); + case COLLECTIONTYPE: + size = lwcollection_serialize_size((LWCOLLECTION *)lwgeom); + default: + lwerror("Unknown geometry type: %d", type); + return 0; + } + + return size; } void -default_errorreporter(const char *fmt, ...) +lwgeom_serialize_buf(LWGEOM *lwgeom, char *buf, int *retsize) { - char *msg; - va_list ap; - - va_start (ap, fmt); + int type = lwgeom->type; + int size; - /* - * This is a GNU extension. - * Dunno how to handle errors here. - */ - if (!vasprintf (&msg, fmt, ap)) + switch (type) { - va_end (ap); - return; + case POINTTYPE: + lwpoint_serialize_buf((LWPOINT *)lwgeom, buf, &size); + break; + case LINETYPE: + lwline_serialize_buf((LWLINE *)lwgeom, buf, &size); + break; + case POLYGONTYPE: + lwpoly_serialize_buf((LWPOLY *)lwgeom, buf, &size); + break; + case MULTIPOINTTYPE: + lwmpoint_serialize_buf((LWMPOINT *)lwgeom, buf, &size); + break; + case MULTILINETYPE: + lwmline_serialize_buf((LWMLINE *)lwgeom, buf, &size); + break; + case MULTIPOLYGONTYPE: + lwmpoly_serialize_buf((LWMPOLY *)lwgeom, buf, &size); + break; + case COLLECTIONTYPE: + lwcollection_serialize_buf((LWCOLLECTION *)lwgeom, buf, &size); + break; + default: + lwerror("Unknown geometry type: %d", type); + return; } - va_end(ap); - fprintf(stderr, "%s", msg); - free(msg); + *retsize = size; + return; } -void -default_noticereporter(const char *fmt, ...) +char * +lwgeom_serialize(LWGEOM *lwgeom, char wantbbox) { - char *msg; - va_list ap; + size_t size = lwgeom_serialize_size(lwgeom); + size_t retsize; + char *loc; + + if ( wantbbox ) size += sizeof(BOX2DFLOAT4); - va_start (ap, fmt); + char *serialized = lwalloc(size); - /* - * This is a GNU extension. - * Dunno how to handle errors here. - */ - if (!vasprintf (&msg, fmt, ap)) + if ( wantbbox ) loc = serialized + sizeof(BOX2DFLOAT4); + else loc = serialized; + + lwgeom_serialize_buf(lwgeom, loc, &retsize); + +#ifdef DEBUG + if ( wantbbox ) retsize += 4; + if ( retsize != size ) { - va_end (ap); - return; + lwerror("lwgeom_serialize: computed size %d, returned size %d", + size, retsize); } - va_end(ap); - fprintf(stderr, "%s", msg); - free(msg); -} +#endif -void -default_freeor(void *ptr) -{ - free(ptr); + return serialized; } diff --git a/lwgeom/lwgeom_functions_basic.c b/lwgeom/lwgeom_functions_basic.c index fb993fb30..6de34d956 100644 --- a/lwgeom/lwgeom_functions_basic.c +++ b/lwgeom/lwgeom_functions_basic.c @@ -50,6 +50,7 @@ Datum LWGEOM_forceRHR_poly(PG_FUNCTION_ARGS); // internal char * lwgeom_summary_recursive(char *serialized, int offset); +char * lwgeom_summary(LWGEOM *serialized, int offset); int32 lwgeom_nrings_recursive(char *serialized); void dump_lwexploded(LWGEOM_EXPLODED *exploded); POINTARRAY *ptarray_reverse(const POINTARRAY *pa); @@ -765,11 +766,11 @@ ptarray_reverse(const POINTARRAY *ipa) uint32 i, j; int ptsize; - opa = (POINTARRAY *)palloc(sizeof(POINTARRAY)); + opa = (POINTARRAY *)lwalloc(sizeof(POINTARRAY)); opa->ndims = ipa->ndims; opa->npoints = ipa->npoints; ptsize = pointArray_ptsize(ipa); - opa->serialized_pointlist = palloc(ipa->npoints*ptsize); + opa->serialized_pointlist = lwalloc(ipa->npoints*ptsize); for (i=0, j=ipa->npoints-1; inpoints; i++, j--) { @@ -796,7 +797,7 @@ lwpoly_reverse(const LWPOLY *ipoly) POINTARRAY **rpa; int i; - rpa = palloc(sizeof(POINTARRAY *)*ipoly->nrings); + rpa = lwalloc(sizeof(POINTARRAY *)*ipoly->nrings); for (i=0; inrings; i++) { @@ -817,7 +818,7 @@ lwpoly_forceRHR(const LWPOLY *ipoly) int i; POINTARRAY *opa; - rpa = palloc(sizeof(POINTARRAY *)*ipoly->nrings); + rpa = lwalloc(sizeof(POINTARRAY *)*ipoly->nrings); if ( ptarray_isccw(ipoly->rings[0]) ) { @@ -862,8 +863,156 @@ Datum LWGEOM_mem_size(PG_FUNCTION_ARGS) PG_RETURN_INT32(size); } +char *lwcollection_summary(LWCOLLECTION *collection, int offset); +char *lwmpoly_summary(LWMPOLY *mpoly, int offset); +char *lwmline_summary(LWMLINE *mline, int offset); +char *lwmpoint_summary(LWMPOINT *mpoint, int offset); +char *lwpoly_summary(LWPOLY *poly, int offset); +char *lwline_summary(LWLINE *line, int offset); +char *lwpoint_summary(LWPOINT *point, int offset); + /* - * Returns a palloced string containing summary for the serialized + * Returns an alloced string containing summary for the LWGEOM object + */ +char * +lwpoint_summary(LWPOINT *point, int offset) +{ + char *result; + result = lwalloc(256); + sprintf(result, "Object %d is a POINT()\n", offset); + return result; +} + +char * +lwline_summary(LWLINE *line, int offset) +{ + char *result; + result = lwalloc(32); + sprintf(result, "Object %d is a LINE()\n", offset); + return result; +} + +char * +lwpoly_summary(LWPOLY *poly, int offset) +{ + char tmp[256]; + char *result = lwalloc(64*(poly->nrings+1)); + int i; + + result[0] = '\0'; + sprintf(tmp, "Object %d is a POLYGON() with %i rings\n", + offset, poly->nrings); + strcat(result, tmp); + for (i=0; inrings;i++) + { + sprintf(tmp," + ring %i has %i points\n", + i, poly->rings[i]->npoints); + strcat(result,tmp); + } + return result; +} + +char * +lwmpoint_summary(LWMPOINT *mpoint, int offset) +{ + char *result = lwalloc(60); + sprintf(result, "Object %d is a MULTIPOINT() with %d points\n", + offset, mpoint->npoints); + return result; +} + +char * +lwmline_summary(LWMLINE *mline, int offset) +{ + char *result = lwalloc(60*(mline->nlines+1)); + sprintf(result, "Object %d is a MULTILINE() with %d lines\n", + offset, mline->nlines); + return result; +} + +char * +lwmpoly_summary(LWMPOLY *mpoly, int offset) +{ + size_t size = 128; + char *result = lwalloc(size); + char *tmp; + int i; + + sprintf(result, "Object %d is a MULTIPOLYGON() with %d polys\n", + offset, mpoly->npolys); + + for (i=0; inpolys; i++) + { + tmp = lwpoly_summary(mpoly->polys[i], i); + size += strlen(tmp)+1; + result = lwrealloc(result, size); + strcat(result, tmp); + //lwfree(tmp); + } + + return result; +} + + +char * +lwcollection_summary(LWCOLLECTION *collection, int offset) +{ + char *result = lwalloc(60*(collection->ngeoms+1)); + char *tmp; + int i; + + sprintf(result, "Object %d is a COLLECTION() with %d subgeoms\n", + offset, collection->ngeoms); + + for (i=0; ingeoms; i++) + { + tmp = lwgeom_summary(lwcollection_getsubgeom(collection, i), i); + strcat(result, tmp); + lwfree(tmp); + } + + return result; +} + +char * +lwgeom_summary(LWGEOM *lwgeom, int offset) +{ + char *result; + + switch (lwgeom->type) + { + case POINTTYPE: + return lwpoint_summary((LWPOINT *)lwgeom, offset); + + case LINETYPE: + return lwline_summary((LWLINE *)lwgeom, offset); + + case POLYGONTYPE: + return lwpoly_summary((LWPOLY *)lwgeom, offset); + + case MULTIPOINTTYPE: + return lwmpoint_summary((LWMPOINT *)lwgeom, offset); + + case MULTILINETYPE: + return lwmline_summary((LWMLINE *)lwgeom, offset); + + case MULTIPOLYGONTYPE: + return lwmpoly_summary((LWMPOLY *)lwgeom, offset); + + case COLLECTIONTYPE: + return lwcollection_summary((LWCOLLECTION *)lwgeom, offset); + default: + result = palloc(256); + sprintf(result, "Object is of unknown type: %d", + lwgeom->type); + return result; + } + + return NULL; +} + +/* + * Returns a lwalloced string containing summary for the serialized * LWGEOM object */ char * @@ -878,7 +1027,7 @@ lwgeom_summary_recursive(char *serialized, int offset) int32 j,i; size = 1; - result = palloc(1); + result = lwalloc(1); result[0] = '\0'; if ( offset == 0 ) idx = 0; @@ -896,7 +1045,7 @@ lwgeom_summary_recursive(char *serialized, int offset) if ( lwgeom_getType(subgeom[0]) == 0 ) { size += 32; - result = repalloc(result,size); + result = lwrealloc(result,size); sprintf(tmp,"Object %i is EMPTY()\n", idx++); strcat(result,tmp); continue; @@ -907,7 +1056,7 @@ lwgeom_summary_recursive(char *serialized, int offset) if (point !=NULL) { size += 32; - result = repalloc(result,size); + result = lwrealloc(result,size); sprintf(tmp,"Object %i is a POINT()\n", idx++); strcat(result,tmp); continue; @@ -917,7 +1066,7 @@ lwgeom_summary_recursive(char *serialized, int offset) if (poly !=NULL) { size += 60*(poly->nrings+1); - result = repalloc(result,size); + result = lwrealloc(result,size); sprintf(tmp,"Object %i is a POLYGON() with %i rings\n", idx++, poly->nrings); strcat(result,tmp); @@ -934,7 +1083,7 @@ lwgeom_summary_recursive(char *serialized, int offset) if (line != NULL) { size += 57; - result = repalloc(result,size); + result = lwrealloc(result,size); sprintf(tmp, "Object %i is a LINESTRING() with %i points\n", idx++, line->points->npoints); strcat(result,tmp); continue; @@ -942,9 +1091,9 @@ lwgeom_summary_recursive(char *serialized, int offset) ptr = lwgeom_summary_recursive(subgeom, j); size += strlen(ptr); - result = repalloc(result,size); + result = lwrealloc(result,size); strcat(result, ptr); - pfree(ptr); + lwfree(ptr); } pfree_inspected(inspected); @@ -1037,14 +1186,20 @@ Datum LWGEOM_summary(PG_FUNCTION_ARGS) PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); char *result; text *mytext; + LWGEOM *lwgeom; + + init_pg_func(); + + lwgeom = lwgeom_deserialize(SERIALIZED_FORM(geom)); - result = lwgeom_summary_recursive(SERIALIZED_FORM(geom), 0); + //result = lwgeom_summary_recursive(SERIALIZED_FORM(geom), 0); + result = lwgeom_summary(lwgeom, 0); // create a text obj to return - mytext = (text *) palloc(VARHDRSZ + strlen(result) ); + mytext = (text *) lwalloc(VARHDRSZ + strlen(result) ); VARATT_SIZEP(mytext) = VARHDRSZ + strlen(result) ; memcpy(VARDATA(mytext) , result, strlen(result) ); - pfree(result); + lwfree(result); PG_RETURN_POINTER(mytext); } @@ -1053,7 +1208,7 @@ Datum postgis_lib_version(PG_FUNCTION_ARGS) { char *ver = POSTGIS_LIB_VERSION; text *result; - result = (text *) palloc(VARHDRSZ + strlen(ver)); + result = (text *) lwalloc(VARHDRSZ + strlen(ver)); VARATT_SIZEP(result) = VARHDRSZ + strlen(ver) ; memcpy(VARDATA(result), ver, strlen(ver)); PG_RETURN_POINTER(result); @@ -1064,7 +1219,7 @@ Datum postgis_scripts_released(PG_FUNCTION_ARGS) { char *ver = POSTGIS_SCRIPTS_VERSION; text *result; - result = (text *) palloc(VARHDRSZ + strlen(ver)); + result = (text *) lwalloc(VARHDRSZ + strlen(ver)); VARATT_SIZEP(result) = VARHDRSZ + strlen(ver) ; memcpy(VARDATA(result), ver, strlen(ver)); PG_RETURN_POINTER(result); @@ -1487,7 +1642,7 @@ lwgeom_force3d_recursive(char *serialized, char *optr, int *retsize) { newpts.ndims = 3; newpts.npoints = 1; - newpts.serialized_pointlist = palloc(sizeof(POINT3D)); + newpts.serialized_pointlist = lwalloc(sizeof(POINT3D)); loc = newpts.serialized_pointlist; getPoint3d_p(point->point, 0, loc); point->point = &newpts; @@ -1510,7 +1665,7 @@ elog(NOTICE, "lwgeom_force3d_recursive: it's a line"); { newpts.ndims = 3; newpts.npoints = line->points->npoints; - newpts.serialized_pointlist = palloc(24*line->points->npoints); + newpts.serialized_pointlist = lwalloc(24*line->points->npoints); loc = newpts.serialized_pointlist; for (j=0; jpoints->npoints; j++) { @@ -1535,17 +1690,17 @@ elog(NOTICE, "lwgeom_force3d_recursive: it's a line, size:%d", *retsize); { newpts.ndims = 3; newpts.npoints = 0; - newpts.serialized_pointlist = palloc(1); - nrings = palloc(sizeof(POINTARRAY *)*poly->nrings); + newpts.serialized_pointlist = lwalloc(1); + nrings = lwalloc(sizeof(POINTARRAY *)*poly->nrings); loc = newpts.serialized_pointlist; for (j=0; jnrings; j++) { POINTARRAY *ring = poly->rings[j]; - POINTARRAY *nring = palloc(sizeof(POINTARRAY)); + POINTARRAY *nring = lwalloc(sizeof(POINTARRAY)); nring->ndims = 3; nring->npoints = ring->npoints; nring->serialized_pointlist = - palloc(ring->npoints*24); + lwalloc(ring->npoints*24); loc = nring->serialized_pointlist; for (k=0; knpoints; k++) { @@ -1657,7 +1812,7 @@ lwgeom_force4d_recursive(char *serialized, char *optr, int *retsize) { newpts.ndims = 4; newpts.npoints = 1; - newpts.serialized_pointlist = palloc(sizeof(POINT4D)); + newpts.serialized_pointlist = lwalloc(sizeof(POINT4D)); loc = newpts.serialized_pointlist; getPoint4d_p(point->point, 0, loc); point->point = &newpts; @@ -1680,7 +1835,7 @@ elog(NOTICE, "lwgeom_force4d_recursive: it's a line"); { newpts.ndims = 4; newpts.npoints = line->points->npoints; - newpts.serialized_pointlist = palloc(sizeof(POINT4D)*line->points->npoints); + newpts.serialized_pointlist = lwalloc(sizeof(POINT4D)*line->points->npoints); loc = newpts.serialized_pointlist; for (j=0; jpoints->npoints; j++) { @@ -1705,17 +1860,17 @@ elog(NOTICE, "lwgeom_force4d_recursive: it's a line, size:%d", *retsize); { newpts.ndims = 4; newpts.npoints = 0; - newpts.serialized_pointlist = palloc(1); - nrings = palloc(sizeof(POINTARRAY *)*poly->nrings); + newpts.serialized_pointlist = lwalloc(1); + nrings = lwalloc(sizeof(POINTARRAY *)*poly->nrings); loc = newpts.serialized_pointlist; for (j=0; jnrings; j++) { POINTARRAY *ring = poly->rings[j]; - POINTARRAY *nring = palloc(sizeof(POINTARRAY)); + POINTARRAY *nring = lwalloc(sizeof(POINTARRAY)); nring->ndims = 4; nring->npoints = ring->npoints; nring->serialized_pointlist = - palloc(ring->npoints*sizeof(POINT4D)); + lwalloc(ring->npoints*sizeof(POINT4D)); loc = nring->serialized_pointlist; for (k=0; knpoints; k++) { @@ -1804,14 +1959,14 @@ Datum LWGEOM_force_2d(PG_FUNCTION_ARGS) if ( lwgeom_ndims(geom->type) == 2 ) PG_RETURN_POINTER(geom); // allocate a larger for safety and simplicity - result = (PG_LWGEOM *) palloc(geom->size); + result = (PG_LWGEOM *) lwalloc(geom->size); lwgeom_force2d_recursive(SERIALIZED_FORM(geom), SERIALIZED_FORM(result), &size); // we can safely avoid this... memory will be freed at // end of query processing anyway. - //result = repalloc(result, size+4); + //result = lwrealloc(result, size+4); result->size = size+4; @@ -1833,10 +1988,10 @@ Datum LWGEOM_force_3d(PG_FUNCTION_ARGS) if ( olddims == 3 ) PG_RETURN_POINTER(geom); if ( olddims > 3 ) { - result = (PG_LWGEOM *) palloc(geom->size); + result = (PG_LWGEOM *) lwalloc(geom->size); } else { // allocate double as memory a larger for safety - result = (PG_LWGEOM *) palloc(geom->size*1.5); + result = (PG_LWGEOM *) lwalloc(geom->size*1.5); } lwgeom_force3d_recursive(SERIALIZED_FORM(geom), @@ -1844,7 +1999,7 @@ Datum LWGEOM_force_3d(PG_FUNCTION_ARGS) // we can safely avoid this... memory will be freed at // end of query processing anyway. - //result = repalloc(result, size+4); + //result = lwrealloc(result, size+4); result->size = size+4; @@ -1866,14 +2021,14 @@ Datum LWGEOM_force_4d(PG_FUNCTION_ARGS) if ( olddims == 4 ) PG_RETURN_POINTER(geom); // allocate double as memory a larger for safety - result = (PG_LWGEOM *) palloc(geom->size*2); + result = (PG_LWGEOM *) lwalloc(geom->size*2); lwgeom_force4d_recursive(SERIALIZED_FORM(geom), SERIALIZED_FORM(result), &size); // we can safely avoid this... memory will be freed at // end of query processing anyway. - //result = repalloc(result, size+4); + //result = lwrealloc(result, size+4); result->size = size+4; @@ -1899,7 +2054,7 @@ Datum LWGEOM_force_collection(PG_FUNCTION_ARGS) // alread a multi*, just make it a collection if ( oldtype > 3 ) { - result = (PG_LWGEOM *)palloc(geom->size); + result = (PG_LWGEOM *)lwalloc(geom->size); result->size = geom->size; result->type = TYPE_SETTYPE(geom->type, COLLECTIONTYPE); memcpy(result->data, geom->data, geom->size-5); @@ -1911,7 +2066,7 @@ Datum LWGEOM_force_collection(PG_FUNCTION_ARGS) size = geom->size+5; // 4 for numgeoms, 1 for type - result = (PG_LWGEOM *)palloc(size); // 4 for numgeoms, 1 for type + result = (PG_LWGEOM *)lwalloc(size); // 4 for numgeoms, 1 for type result->size = size; result->type = TYPE_SETTYPE(geom->type, COLLECTIONTYPE); @@ -1977,7 +2132,7 @@ Datum LWGEOM_force_multi(PG_FUNCTION_ARGS) size = geom->size+5; // 4 for numgeoms, 1 for type - result = (PG_LWGEOM *)palloc(size); // 4 for numgeoms, 1 for type + result = (PG_LWGEOM *)lwalloc(size); // 4 for numgeoms, 1 for type result->size = size; result->type = TYPE_SETTYPE(geom->type, newtype); @@ -2330,19 +2485,19 @@ Datum LWGEOM_accum(PG_FUNCTION_ARGS) //elog(NOTICE, "geom_accum: adding %p (nelems=%d)", geom, nelems); /* - * Might use a more optimized version instead of repalloc'ing + * Might use a more optimized version instead of lwrealloc'ing * at every iteration. This is not the bottleneck anyway. * --strk(TODO); */ ++nelems; nbytes = ARR_OVERHEAD(1) + sizeof(Pointer *) * nelems; if ( ! array ) { - result = (ArrayType *) palloc(nbytes); + result = (ArrayType *) lwalloc(nbytes); result->size = nbytes; result->ndim = 1; *((int *) ARR_DIMS(result)) = nelems; } else { - result = (ArrayType *) repalloc(array, nbytes); + result = (ArrayType *) lwrealloc(array, nbytes); result->size = nbytes; result->ndim = 1; *((int *) ARR_DIMS(result)) = nelems; @@ -2514,7 +2669,7 @@ Datum LWGEOM_expand(PG_FUNCTION_ARGS) PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); double d = PG_GETARG_FLOAT8(1); BOX2DFLOAT4 box; - POINT2D *pts = palloc(sizeof(POINT2D)*5); + POINT2D *pts = lwalloc(sizeof(POINT2D)*5); POINTARRAY *pa[1]; LWPOLY *poly; int SRID; @@ -2542,7 +2697,7 @@ Datum LWGEOM_expand(PG_FUNCTION_ARGS) pts[4].x = box.xmin; pts[4].y = box.ymin; // Construct point array - pa[0] = palloc(sizeof(POINTARRAY)); + pa[0] = lwalloc(sizeof(POINTARRAY)); pa[0]->serialized_pointlist = (char *)pts; pa[0]->ndims = 2; pa[0]->npoints = 5; @@ -2565,7 +2720,7 @@ Datum LWGEOM_to_BOX(PG_FUNCTION_ARGS) { PG_LWGEOM *lwgeom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); BOX2DFLOAT4 box2d; - BOX *result = (BOX *)palloc(sizeof(BOX)); + BOX *result = (BOX *)lwalloc(sizeof(BOX)); if ( ! getbox2d_p(SERIALIZED_FORM(lwgeom), &box2d) ) { @@ -2584,7 +2739,7 @@ Datum LWGEOM_envelope(PG_FUNCTION_ARGS) { PG_LWGEOM *geom = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); BOX2DFLOAT4 box; - POINT2D *pts = palloc(sizeof(POINT2D)*5); + POINT2D *pts = lwalloc(sizeof(POINT2D)*5); POINTARRAY *pa[1]; LWPOLY *poly; int SRID; @@ -2609,7 +2764,7 @@ Datum LWGEOM_envelope(PG_FUNCTION_ARGS) pts[4].x = box.xmin; pts[4].y = box.ymin; // Construct point array - pa[0] = palloc(sizeof(POINTARRAY)); + pa[0] = lwalloc(sizeof(POINTARRAY)); pa[0]->serialized_pointlist = (char *)pts; pa[0]->ndims = 2; pa[0]->npoints = 5; @@ -2723,10 +2878,10 @@ segmentize2d_ptarray(POINTARRAY *ipa, double dist) pbuf.x = pbuf.y = pbuf.z = pbuf.m = 0; // Initial storage - opa = (POINTARRAY *)palloc(ptsize * maxpoints); + opa = (POINTARRAY *)lwalloc(ptsize * maxpoints); opa->ndims = ipa->ndims; opa->npoints = 0; - opa->serialized_pointlist = (char *)palloc(maxpoints*ptsize); + opa->serialized_pointlist = (char *)lwalloc(maxpoints*ptsize); // Add first point opa->npoints++; @@ -2759,7 +2914,7 @@ segmentize2d_ptarray(POINTARRAY *ipa, double dist) // Add point if ( ++(opa->npoints) > maxpoints ) { maxpoints *= 1.5; - opa->serialized_pointlist = (char *)repalloc( + opa->serialized_pointlist = (char *)lwrealloc( opa->serialized_pointlist, maxpoints*ptsize ); @@ -2856,7 +3011,7 @@ Datum LWGEOM_reverse(PG_FUNCTION_ARGS) } size = lwexploded_findlength(exp, wantbbox); - result = palloc(size+4); + result = lwalloc(size+4); result->size = (size+4); lwexploded_serialize_buf(exp, wantbbox, SERIALIZED_FORM(result), &size); @@ -2900,7 +3055,7 @@ Datum LWGEOM_forceRHR_poly(PG_FUNCTION_ARGS) } size = lwexploded_findlength(exp, wantbbox); - result = palloc(size+4); + result = lwalloc(size+4); result->size = (size+4); lwexploded_serialize_buf(exp, wantbbox, SERIALIZED_FORM(result), &size); diff --git a/lwgeom/lwline.c b/lwgeom/lwline.c index d5dd49c05..c68766382 100644 --- a/lwgeom/lwline.c +++ b/lwgeom/lwline.c @@ -12,6 +12,7 @@ LWLINE *lwline_construct(int ndims, int SRID, POINTARRAY *points) LWLINE *result; result = (LWLINE*) lwalloc( sizeof(LWLINE)); + result->type = LINETYPE; result->ndims =ndims; result->SRID = SRID; result->points = points; @@ -34,6 +35,8 @@ LWLINE *lwline_deserialize(char *serialized_form) result = (LWLINE*) lwalloc(sizeof(LWLINE)) ; type = (unsigned char) serialized_form[0]; + result->type = LINETYPE; + if ( lwgeom_getType(type) != LINETYPE) { lwerror("lwline_deserialize: attempt to deserialize a line when its not really a line"); @@ -247,10 +250,10 @@ BOX3D *lwline_findbbox(LWLINE *line) } // find length of this deserialized line -uint32 -lwline_size(LWLINE *line) +size_t +lwline_serialize_size(LWLINE *line) { - uint32 size = 1; //type + size_t size = 1; //type if ( line->SRID != -1 ) size += 4; // SRID size += sizeof(double)*line->ndims*line->points->npoints; // points diff --git a/lwgeom/lwmline.c b/lwgeom/lwmline.c index c4cfd85e9..45641efbd 100644 --- a/lwgeom/lwmline.c +++ b/lwgeom/lwmline.c @@ -1,5 +1,6 @@ #include #include +#include #include "liblwgeom.h" LWMLINE * @@ -20,6 +21,7 @@ lwmline_deserialize(char *srl) insp = lwgeom_inspect(srl); result = lwalloc(sizeof(LWMLINE)); + result->type = MULTILINETYPE; result->SRID = insp->SRID; result->ndims = lwgeom_ndims(insp->type); result->nlines = insp->ngeometries; @@ -39,3 +41,58 @@ lwmline_deserialize(char *srl) return result; } +// find serialized size of this mline +size_t +lwmline_serialize_size(LWMLINE *mline) +{ + size_t size = 5; // type + nsubgeoms + int i; + + if ( mline->SRID != -1 ) size += 4; // SRID + + for (i=0; inlines; i++) + size += lwline_serialize_size(mline->lines[i]); + + return size; +} + +// convert this multiline into its serialize form writing it into +// the given buffer, and returning number of bytes written into +// the given int pointer. +void +lwmline_serialize_buf(LWMLINE *mline, char *buf, int *retsize) +{ + int size=1; // type + int subsize=0; + char hasSRID; + char *loc; + int i; + + hasSRID = (mline->SRID != -1); + + buf[0] = (unsigned char) lwgeom_makeType(mline->ndims, + hasSRID, MULTILINETYPE); + loc = buf+1; + + // Add SRID if requested + if (hasSRID) + { + memcpy(loc, &mline->SRID, 4); + size += 4; + loc += 4; + } + + // Write number of subgeoms + memcpy(loc, &mline->nlines, 4); + size += 4; + loc += 4; + + // Serialize subgeoms + for (i=0; inlines; i++) + { + lwline_serialize_buf(mline->lines[i], loc, &subsize); + size += subsize; + } + + if (retsize) *retsize = size; +} diff --git a/lwgeom/lwmpoint.c b/lwgeom/lwmpoint.c index 945d4dd01..e02edd947 100644 --- a/lwgeom/lwmpoint.c +++ b/lwgeom/lwmpoint.c @@ -1,5 +1,6 @@ #include #include +#include #include "liblwgeom.h" LWMPOINT * @@ -20,6 +21,7 @@ lwmpoint_deserialize(char *srl) insp = lwgeom_inspect(srl); result = lwalloc(sizeof(LWMPOINT)); + result->type = MULTIPOINTTYPE; result->SRID = insp->SRID; result->ndims = lwgeom_ndims(insp->type); result->npoints = insp->ngeometries; @@ -39,3 +41,58 @@ lwmpoint_deserialize(char *srl) return result; } +// find serialized size of this mpoint +size_t +lwmpoint_serialize_size(LWMPOINT *mpoint) +{ + size_t size = 5; // type + nsubgeoms + int i; + + if ( mpoint->SRID != -1 ) size += 4; // SRID + + for (i=0; inpoints; i++) + size += lwpoint_serialize_size(mpoint->points[i]); + + return size; +} + +// convert this multipoint into its serialize form writing it into +// the given buffer, and returning number of bytes written into +// the given int pointer. +void +lwmpoint_serialize_buf(LWMPOINT *mpoint, char *buf, int *retsize) +{ + int size=1; // type + int subsize=0; + char hasSRID; + char *loc; + int i; + + hasSRID = (mpoint->SRID != -1); + + buf[0] = (unsigned char) lwgeom_makeType(mpoint->ndims, + hasSRID, MULTIPOINTTYPE); + loc = buf+1; + + // Add SRID if requested + if (hasSRID) + { + memcpy(loc, &mpoint->SRID, 4); + size += 4; + loc += 4; + } + + // Write number of subgeoms + memcpy(loc, &mpoint->npoints, 4); + size += 4; + loc += 4; + + // Serialize subgeoms + for (i=0; inpoints; i++) + { + lwpoint_serialize_buf(mpoint->points[i], loc, &subsize); + size += subsize; + } + + if (retsize) *retsize = size; +} diff --git a/lwgeom/lwmpoly.c b/lwgeom/lwmpoly.c index 97e01c297..92b9fc46e 100644 --- a/lwgeom/lwmpoly.c +++ b/lwgeom/lwmpoly.c @@ -1,5 +1,6 @@ #include #include +#include #include "liblwgeom.h" LWMPOLY * @@ -20,6 +21,8 @@ lwmpoly_deserialize(char *srl) insp = lwgeom_inspect(srl); result = lwalloc(sizeof(LWMPOLY)); + result->type = srl[0]; + result->type = MULTIPOLYGONTYPE; result->SRID = insp->SRID; result->ndims = lwgeom_ndims(insp->type); result->npolys = insp->ngeometries; @@ -39,3 +42,58 @@ lwmpoly_deserialize(char *srl) return result; } +// find serialized size of this mpoly +size_t +lwmpoly_serialize_size(LWMPOLY *mpoly) +{ + size_t size = 5; // type + nsubgeoms + int i; + + if ( mpoly->SRID != -1 ) size += 4; // SRID + + for (i=0; inpolys; i++) + size += lwpoly_serialize_size(mpoly->polys[i]); + + return size; +} + +// convert this multipolygon into its serialize form writing it into +// the given buffer, and returning number of bytes written into +// the given int pointer. +void +lwmpoly_serialize_buf(LWMPOLY *mpoly, char *buf, int *retsize) +{ + int size=1; // type + int subsize=0; + char hasSRID; + char *loc; + int i; + + hasSRID = (mpoly->SRID != -1); + + buf[0] = (unsigned char) lwgeom_makeType(mpoly->ndims, + hasSRID, MULTIPOLYGONTYPE); + loc = buf+1; + + // Add SRID if requested + if (hasSRID) + { + memcpy(loc, &mpoly->SRID, 4); + size += 4; + loc += 4; + } + + // Write number of subgeoms + memcpy(loc, &mpoly->npolys, 4); + size += 4; + loc += 4; + + // Serialize subgeoms + for (i=0; inpolys; i++) + { + lwpoly_serialize_buf(mpoly->polys[i], loc, &subsize); + size += subsize; + } + + if (retsize) *retsize = size; +} diff --git a/lwgeom/lwpoint.c b/lwgeom/lwpoint.c index 3f6ca9cec..e2eaa3ff6 100644 --- a/lwgeom/lwpoint.c +++ b/lwgeom/lwpoint.c @@ -127,10 +127,10 @@ lwpoint_getPoint3d(const LWPOINT *point) } // find length of this deserialized point -uint32 -lwpoint_size(LWPOINT *point) +size_t +lwpoint_serialize_size(LWPOINT *point) { - uint32 size = 1; // type + size_t size = 1; // type if ( point->SRID != -1 ) size += 4; // SRID size += point->ndims * sizeof(double); // point @@ -149,6 +149,7 @@ lwpoint_construct(int ndims, int SRID, POINTARRAY *point) return NULL; // error result = lwalloc(sizeof(LWPOINT)); + result->type = POINTTYPE; result->ndims = ndims; result->SRID = SRID; @@ -178,6 +179,7 @@ lwpoint_deserialize(char *serialized_form) type = (unsigned char) serialized_form[0]; if ( lwgeom_getType(type) != POINTTYPE) return NULL; + result->type = POINTTYPE; loc = serialized_form+1; diff --git a/lwgeom/lwpoly.c b/lwgeom/lwpoly.c index e34549074..98cb11c35 100644 --- a/lwgeom/lwpoly.c +++ b/lwgeom/lwpoly.c @@ -13,6 +13,7 @@ lwpoly_construct(int ndims, int SRID, int nrings,POINTARRAY **points) LWPOLY *result; result = (LWPOLY*) lwalloc(sizeof(LWPOLY)); + result->type = POLYGONTYPE; result->ndims = ndims; result->SRID = SRID; result->nrings = nrings; @@ -46,8 +47,9 @@ lwpoly_deserialize(char *serialized_form) result = (LWPOLY*) lwalloc(sizeof(LWPOLY)); - type = (unsigned char) serialized_form[0]; + result->type = POLYGONTYPE; + ndims = lwgeom_ndims(type); loc = serialized_form; @@ -366,10 +368,10 @@ lwgeom_size_poly(const char *serialized_poly) } // find length of this deserialized polygon -uint32 -lwpoly_size(LWPOLY *poly) +size_t +lwpoly_serialize_size(LWPOLY *poly) { - uint32 size = 1; // type + size_t size = 1; // type uint32 i; if ( poly->SRID != -1 ) size += 4; // SRID