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
This commit is contained in:
Sandro Santilli 2005-01-18 09:32:03 +00:00
parent 71c40da56f
commit f6329625dc
4 changed files with 143 additions and 41 deletions

View file

@ -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;
}

View file

@ -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,';');
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);
}

View file

@ -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);

View file

@ -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,34 +370,76 @@ 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--)
{
for(bc=size; bc; bc--)
{
*out_pos++ = outchr[ptr[bc-1]>>4];
*out_pos++ = outchr[ptr[bc-1]&0x0F];
}
*out_pos++ = outchr[ptr[bc-1]>>4];
*out_pos++ = outchr[ptr[bc-1]&0x0F];
}
else
ptr+=size;
}
}
/* 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++)
{
for(bc=0; bc<size; bc++)
{
*out_pos++ = outchr[ptr[bc]>>4];
*out_pos++ = outchr[ptr[bc]&0x0F];
}
*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;
}
}
byte *
output_wkb_point(byte* geom)
{
@ -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);
ensure(1);
*out_pos=0;
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.
*