]> granicus.if.org Git - postgis/commitdiff
Changed unparse_WKB interface to take an output size pointer and an HEXFORM
authorSandro Santilli <strk@keybit.net>
Tue, 18 Jan 2005 09:32:03 +0000 (09:32 +0000)
committerSandro Santilli <strk@keybit.net>
Tue, 18 Jan 2005 09:32:03 +0000 (09:32 +0000)
specifier. Reworked code in wktunparse to use function pointers.

git-svn-id: http://svn.osgeo.org/postgis/trunk@1311 b70326c6-7e19-0410-871a-916f4a2858ee

lwgeom/lwgeom.c
lwgeom/lwgeom_inout.c
lwgeom/wktparse.h
lwgeom/wktunparse.c

index ea9dbc27561774d271782d3f090f5d38d80c8976..7be070986cb8c498a049ecff6a7d2b26f9ed6b5e 100644 (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;
 }
index c60e03f05350ea21ff20ae0c979428d849e21353..9645da7bf0e9c72648e2a89582065f1180e3be57 100644 (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,';');
-
 
+       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);
 }
 
index 1e465c560e7f32ee50859e3bff150a6b54dc7817..d27a1aba9d3cf4c7fd813f02dbb763354d0849a5 100644 (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);
 
index a2ff9b431ad41886e71f3ea6a80ab76388dccd6f..850ca65fa02c0444b4b1a348581682c99238d7b2 100644 (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.
  *