Commit f6329625 authored by Sandro Santilli's avatar Sandro Santilli
Browse files

Changed unparse_WKB interface to take an output size pointer and an HEXFORM

specifier. Reworked code in wktunparse to use function pointers.


git-svn-id: http://svn.osgeo.org/postgis/trunk@1311 b70326c6-7e19-0410-871a-916f4a2858ee
parent 71c40da5
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -379,7 +379,7 @@ char *
lwgeom_to_hexwkb(LWGEOM *lwgeom, unsigned int byteorder)
{
	char *serialized = lwgeom_serialize(lwgeom);
	char *hexwkb = unparse_WKB(serialized, lwalloc, lwfree, byteorder);
	char *hexwkb = unparse_WKB(serialized, lwalloc, lwfree, byteorder,NULL,1);
	lwfree(serialized);
	return hexwkb;
}
+48 −14
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@

#include "lwgeom_pg.h"
#include "wktparse.h"
#include "profile.h"

void elog_ERROR(const char* string);

@@ -106,7 +107,7 @@ Datum LWGEOM_out(PG_FUNCTION_ARGS)
	init_pg_func();

	lwgeom = (PG_LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	result = unparse_WKB(SERIALIZED_FORM(lwgeom),lwalloc,lwfree,-1);
	result = unparse_WKB(SERIALIZED_FORM(lwgeom),lwalloc,lwfree,-1,NULL,1);

	PG_RETURN_CSTRING(result);
}
@@ -122,15 +123,16 @@ Datum LWGEOM_to_text(PG_FUNCTION_ARGS)
	PG_LWGEOM *lwgeom;
	char *result;
	text *text_result;
	size_t size;

	init_pg_func();

	lwgeom = (PG_LWGEOM *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
	result = unparse_WKB(SERIALIZED_FORM(lwgeom),lwalloc,lwfree,-1);
	result = unparse_WKB(SERIALIZED_FORM(lwgeom),lwalloc,lwfree,-1,&size,1);

	text_result = palloc(strlen(result)+VARHDRSZ);
	memcpy(VARDATA(text_result),result,strlen(result));
	VARATT_SIZEP(text_result) = strlen(result)+VARHDRSZ;
	text_result = palloc(size+VARHDRSZ);
	memcpy(VARDATA(text_result),result,size);
	VARATT_SIZEP(text_result) = size+VARHDRSZ;
	pfree(result);

	PG_RETURN_POINTER(text_result);
@@ -200,7 +202,7 @@ Datum LWGEOMFromWKB(PG_FUNCTION_ARGS)
	}

#ifdef DEBUG
	elog(NOTICE, "LWGEOMFromWKB returning %s", unparse_WKB(SERIALIZED_FORM(lwgeom), pg_alloc, pg_free, -1));
	elog(NOTICE, "LWGEOMFromWKB returning %s", unparse_WKB(SERIALIZED_FORM(lwgeom), pg_alloc, pg_free, -1, NULL, 1));
#endif

	PG_RETURN_POINTER(lwgeom);
@@ -211,16 +213,24 @@ Datum LWGEOMFromWKB(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(WKBFromLWGEOM);
Datum WKBFromLWGEOM(PG_FUNCTION_ARGS)
{
//#define BINARY_FROM_HEX 1

	PG_LWGEOM *lwgeom_input; // SRID=#;<hexized wkb>
	char *hexized_wkb_srid;
	char *hexized_wkb; // hexized_wkb_srid w/o srid
	char *result; //wkb
	int len_hexized_wkb;
	int size_result;
#ifdef BINARY_FROM_HEX
	char *hexized_wkb_srid;
	char *semicolonLoc;
	int t;
#endif // BINARY_FROM_HEX
	text *type;
	unsigned int byteorder=-1;
	size_t size;

#ifdef PROFILE
	profstart(PROF_QRUN);
#endif

	init_pg_func();

@@ -245,15 +255,16 @@ 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);
		lwalloc, lwfree, byteorder, &size, 1);

//elog(NOTICE, "in WKBFromLWGEOM with WKB = '%s'", hexized_wkb_srid);

	hexized_wkb = hexized_wkb_srid;
	semicolonLoc = strchr(hexized_wkb_srid,';');


	semicolonLoc = strchr(hexized_wkb_srid,';');
	if (semicolonLoc != NULL)
	{
		hexized_wkb = (semicolonLoc+1);
@@ -261,20 +272,43 @@ Datum WKBFromLWGEOM(PG_FUNCTION_ARGS)

//elog(NOTICE, "in WKBFromLWGEOM with WKB (with no 'SRID=#;' = '%s'", hexized_wkb);

	len_hexized_wkb = strlen(hexized_wkb);
	size_result = len_hexized_wkb/2 + VARHDRSZ;
	size_result = size/2 + VARHDRSZ;
	result = palloc(size_result);

	memcpy(result, &size_result,VARHDRSZ); // size header

	// have a hexized string, want to make it binary
	for (t=0; t< (len_hexized_wkb/2); t++)
	for (t=0; t< (size/2); t++)
	{
		((unsigned char *) result +VARHDRSZ)[t] = parse_hex(  hexized_wkb + (t*2) );
	}

	pfree(hexized_wkb_srid);

#else // ndef BINARY_FROM_HEX

	hexized_wkb = unparse_WKB(SERIALIZED_FORM(lwgeom_input),
		lwalloc, lwfree, byteorder, &size, 0);

	size_result = size+VARHDRSZ;
	result = palloc(size_result);
	memcpy(result, &size_result, VARHDRSZ);
	memcpy(VARDATA(result), hexized_wkb, size);
	pfree(hexized_wkb);

#endif

#ifdef PROFILE
	profstop(PROF_QRUN);
	lwnotice("unparse_WKB: prof: %lu", proftime[PROF_QRUN]);
#endif

#ifdef DEBUG
	lwnotice("Output size is %lu (comp: %lu)",
		VARSIZE(result), (unsigned long)size);
#endif // def DEBUG


	PG_RETURN_POINTER(result);
}

+1 −1
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ void alloc_wkb(const char* parser);
byte* parse_lwg(const char* wkt,allocator allocfunc,report_error errfunc);
byte* parse_lwgi(const char* wkt,allocator allocfunc,report_error errfunc);
char* unparse_WKT(byte* serialized, allocator alloc,freeor free);
char* unparse_WKB(byte* serialized, allocator alloc,freeor free, char endian);
char* unparse_WKB(byte* serialized, allocator alloc,freeor free, char endian, size_t *outsize, byte hexform);
int lwg_parse_yyparse(void);
int lwg_parse_yyerror(char* s);

+93 −25
Original line number Diff line number Diff line
@@ -41,7 +41,12 @@ byte* output_single(byte* geom,int supress);
byte* output_collection(byte* geom,outfunc func,int supress);
byte* output_collection_2(byte* geom,int suppress);
byte* output_multipoint(byte* geom,int suppress);
void write_wkb_bytes(byte* ptr,unsigned int cnt,size_t size);

void write_wkb_hex_bytes(byte* ptr, unsigned int cnt, size_t size);
void write_wkb_bin_bytes(byte* ptr, unsigned int cnt, size_t size);
void write_wkb_bin_flip_bytes(byte* ptr, unsigned int cnt, size_t size);
void write_wkb_hex_flip_bytes(byte* ptr, unsigned int cnt, size_t size);

void write_wkb_int(int i);
byte* output_wkb_collection(byte* geom,outwkbfunc func);
byte* output_wkb_collection_2(byte* geom);
@@ -57,8 +62,9 @@ static char* out_start;
static char*  out_pos;
static int len;
static int lwgi;
static int flipbytes;
byte endianbyte;
//static int flipbytes;
static byte endianbyte;
void (*write_wkb_bytes)(byte* ptr,unsigned int cnt,size_t size);

//----------------------------------------------------------

@@ -364,30 +370,72 @@ unparse_WKT(byte* serialized, allocator alloc, freeor free)

static char outchr[]={"0123456789ABCDEF" };

/* Write HEX bytes flipping */
void
write_wkb_bytes(byte* ptr, unsigned int cnt, size_t size)
write_wkb_hex_flip_bytes(byte* ptr, unsigned int cnt, size_t size)
{
	unsigned int bc; // byte count

	ensure(cnt*2*size);

	while(cnt--){
		if (flipbytes)
		{
		for(bc=size; bc; bc--)
		{
			*out_pos++ = outchr[ptr[bc-1]>>4];
			*out_pos++ = outchr[ptr[bc-1]&0x0F];
		}
		ptr+=size;
	}
		else
}

/* Write HEX bytes w/out flipping */
void
write_wkb_hex_bytes(byte* ptr, unsigned int cnt, size_t size)
{
	unsigned int bc; // byte count

	ensure(cnt*2*size);

	while(cnt--){
		for(bc=0; bc<size; bc++)
		{
			*out_pos++ = outchr[ptr[bc]>>4];
			*out_pos++ = outchr[ptr[bc]&0x0F];
		}
		ptr+=size;
	}
}

/* Write BIN bytes flipping */
void
write_wkb_bin_flip_bytes(byte* ptr, unsigned int cnt, size_t size)
{
	unsigned int bc; // byte count

	ensure(cnt*size);

	while(cnt--)
	{
		for(bc=size; bc; bc--)
			*out_pos++ = ptr[bc-1];
		ptr+=size;
	}
}


/* Write BIN bytes w/out flipping */
void
write_wkb_bin_bytes(byte* ptr, unsigned int cnt, size_t size)
{
	unsigned int bc; // byte count

	ensure(cnt*size);

	/* Could just use a memcpy here ... */
	while(cnt--)
	{
		for(bc=0; bc<size; bc++)
			*out_pos++ = ptr[bc];
		ptr+=size;
	}
}
@@ -510,9 +558,8 @@ output_wkb(byte* geom)
}

char *
unparse_WKB(byte* serialized, allocator alloc, freeor free, char endian)
unparse_WKB(byte* serialized, allocator alloc, freeor free, char endian, size_t *outsize, byte hex)
{

#ifdef DEBUG
	lwnotice("unparse_WKB(%p,...) called", serialized);
#endif
@@ -526,18 +573,35 @@ unparse_WKB(byte* serialized, allocator alloc, freeor free, char endian)
	out_start = out_pos = alloc(len);
	lwgi=0;

	if ( endian == -1 ) {
	if ( endian == -1 )
	{
		endianbyte = getMachineEndian();
		flipbytes = 0;
	} else {
		if ( hex ) write_wkb_bytes = write_wkb_hex_bytes;
		else write_wkb_bytes = write_wkb_bin_bytes;
	}
	else
	{
		endianbyte = endian;
		if ( endianbyte != getMachineEndian() ) flipbytes = 1;
		else flipbytes = 0;
		if ( endianbyte != getMachineEndian() )
		{
			if ( hex ) write_wkb_bytes = write_wkb_hex_flip_bytes;
			else write_wkb_bytes = write_wkb_bin_flip_bytes;
		}
		else
		{
			if ( hex ) write_wkb_bytes = write_wkb_hex_bytes;
			else write_wkb_bytes = write_wkb_bin_bytes;
		}
	}

	output_wkb(serialized);

	if ( hex ) {
		ensure(1);
		*out_pos=0;
	}

	if ( outsize ) *outsize = (out_pos-out_start);

	return out_start;
}
@@ -545,6 +609,10 @@ unparse_WKB(byte* serialized, allocator alloc, freeor free, char endian)

/******************************************************************
 * $Log$
 * Revision 1.16  2005/01/18 09:32:03  strk
 * Changed unparse_WKB interface to take an output size pointer and an HEXFORM
 * specifier. Reworked code in wktunparse to use function pointers.
 *
 * Revision 1.15  2004/12/21 15:19:01  strk
 * Canonical binary reverted back to EWKB, now supporting SRID inclusion.
 *