]> granicus.if.org Git - postgis/commitdiff
Added endiannes specification to unparse_WKB, AsBinary, lwgeom_to_wkb.
authorSandro Santilli <strk@keybit.net>
Mon, 11 Oct 2004 14:03:33 +0000 (14:03 +0000)
committerSandro Santilli <strk@keybit.net>
Mon, 11 Oct 2004 14:03:33 +0000 (14:03 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@984 b70326c6-7e19-0410-871a-916f4a2858ee

lwgeom/liblwgeom.h
lwgeom/lwgeom.c
lwgeom/lwgeom.h
lwgeom/lwgeom_inout.c
lwgeom/lwgeom_ogc.c
lwgeom/lwgeom_pg.h
lwgeom/lwpostgis.sql.in
lwgeom/test.c
lwgeom/wktparse.h
lwgeom/wktunparse.c

index 17b6a99fdcfcf295582da6b9cf471acfa345af5c..0a33ee1062cfc8887b999d5d9ecbd2c5b11e0870 100644 (file)
@@ -1007,7 +1007,8 @@ extern LWCOLLECTION *lwcollection_segmentize2d(LWCOLLECTION *coll, double dist);
 extern unsigned char   parse_hex(char *str);
 extern void deparse_hex(unsigned char str, unsigned char *result);
 extern char *parse_lwgeom_wkt(char *wkt_input);
-extern char * lwgeom_to_wkt(LWGEOM *lwgeom);
+extern char *lwgeom_to_wkt(LWGEOM *lwgeom);
+extern char *lwgeom_to_hexwkb(LWGEOM *lwgeom, unsigned int byteorder);
 
 extern void *lwalloc(size_t size);
 extern void *lwrealloc(void *mem, size_t size);
index 408262d6fca17fed8a8dfe5f8c5a89e795a18533..ad2b4c9942edb01b58823ce8d0b29db7081b9e38 100644 (file)
@@ -371,6 +371,18 @@ lwgeom_to_wkt(LWGEOM *lwgeom)
        return ret;
 }
 
+/*
+ * Return an alloced string
+ */
+char *
+lwgeom_to_hexwkb(LWGEOM *lwgeom, unsigned int byteorder)
+{
+       char *serialized = lwgeom_serialize(lwgeom);
+       char *hexwkb = unparse_WKB(serialized, lwalloc, lwfree, byteorder);
+       lwfree(serialized);
+       return hexwkb;
+}
+
 // geom1 same as geom2
 //  iff
 //      + have same type                                                        //      + have same # objects
index cc2b62b034f5ace0cfec0591348220198127c189..9c475a54798983e3c00c7f78893a26c038b00b67 100644 (file)
@@ -31,6 +31,7 @@ typedef struct LWGEOM_T *LWGEOM;
 
 // Conversions
 extern char *lwgeom_to_wkt(LWGEOM lwgeom);
+extern char *lwgeom_to_hexwkb(LWGEOM lwgeom, unsigned int byteorder);
 
 // Construction
 extern LWGEOM lwpoint_construct(int SRID, char wantbbox, POINTARRAY pa);
index 05ab4c441ebba687169df9820ea1910b78475c95..653bb6977ddb4b8a003be4fcb5e07a598ed040e2 100644 (file)
@@ -117,7 +117,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);
+       result = unparse_WKB(SERIALIZED_FORM(lwgeom),lwalloc,lwfree,-1);
 
        PG_RETURN_CSTRING(result);
 }
@@ -201,11 +201,34 @@ Datum WKBFromLWGEOM(PG_FUNCTION_ARGS)
        int size_result;
        char *semicolonLoc;
        int t;
+       text *type;
+       unsigned int byteorder=-1;
 
        init_pg_func();
 
+       if ( (PG_NARGS()>1) && (!PG_ARGISNULL(1)) )
+       {
+               type = PG_GETARG_TEXT_P(1);
+               if (VARSIZE(type) < 7)  
+               {
+                       elog(ERROR,"asbinary(geometry, <type>) - type should be 'XDR' or 'NDR'.  type length is %i",VARSIZE(type) -4);
+                       PG_RETURN_NULL();
+               }
+
+               if  ( ! strncmp(VARDATA(type), "xdr", 3) ||
+                       ! strncmp(VARDATA(type), "XDR", 3) )
+               {
+                       byteorder = BIG_ENDIAN;
+               }
+               else
+               {
+                       byteorder = LITTLE_ENDIAN;
+               }
+       }
+
        lwgeom_input = (PG_LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
-       hexized_wkb_srid = unparse_WKB(SERIALIZED_FORM(lwgeom_input), lwalloc, lwfree);
+       hexized_wkb_srid = unparse_WKB(SERIALIZED_FORM(lwgeom_input),
+               lwalloc, lwfree, byteorder);
 
 //elog(NOTICE, "in WKBFromLWGEOM with WKB = '%s'", hexized_wkb_srid);
 
index 5c186f638cfc423973ba7d00cbaba8ef2a8e3b1a..984badb0095c9d1403177e9a6dfef6a75b324950 100644 (file)
@@ -709,11 +709,7 @@ Datum LWGEOM_from_text(PG_FUNCTION_ARGS)
        PG_LWGEOM *result = NULL;
 
        // read user-requested SRID if any
-#if USE_VERSION < 73
-       if ( fcinfo->nargs > 1 )
-#else
        if ( PG_NARGS() > 1 )
-#endif
        {
                SRID = PG_GETARG_INT32(1);
                if ( SRID != lwgeom_getSRID(geom) )
index f09a24382d5efd1c9626158b0d68c6e8c67c59e8..35f6d2ff934e76ff033099cb5d32e9c6666b9720 100644 (file)
@@ -6,6 +6,10 @@
 #include "fmgr.h"
 #include "liblwgeom.h"
 
+#ifndef PG_NARGS
+#define PG_NARGS() (fcinfo->nargs)
+#endif
+
 void *pg_alloc(size_t size);
 void *pg_realloc(void *ptr, size_t size);
 void pg_free(void *ptr);
index 981d6491650abd09aa5694995e20f13d922c6119..75eb6bc0b8be6b82e9d8c7a5cb851e1ced3457f5 100644 (file)
@@ -1077,6 +1077,11 @@ CREATEFUNCTION AsBinary(geometry)
        AS '@MODULE_FILENAME@','WKBFromLWGEOM'
        LANGUAGE 'C' WITH (isstrict,iscachable);
 
+CREATEFUNCTION AsBinary(geometry,text)
+       RETURNS bytea
+       AS '@MODULE_FILENAME@','WKBFromLWGEOM'
+       LANGUAGE 'C' WITH (isstrict,iscachable);
+
 CREATEFUNCTION AsText(geometry)
        RETURNS TEXT
        AS '@MODULE_FILENAME@','LWGEOM_asText'
index ddb951b0a9bb22e7a5e2781ad26fdf93c3c67f83..78cfc7e1846508a3ec7cc8291c4ab5fc5af1ad0e 100644 (file)
@@ -26,8 +26,9 @@ int main()
        // Construct a point LWGEOM
        point = lwpoint_construct(-1, 0, pa);
 
-       // Print WKT
+       // Print WKT end HEXWKB
        printf("WKT: %s\n", lwgeom_to_wkt(point));
+       printf("HEXWKB: %s\n", lwgeom_to_hexwkb(point,-1));
 
        // Construct a 5-points pointarray2d
        pa = ptarray_construct2d(5, pts2d);
@@ -35,8 +36,9 @@ int main()
        // Construct a line LWGEOM
        line = lwline_construct(-1, 0, pa);
 
-       // Print WKT
+       // Print WKT and HEXWKB
        printf("WKT: %s\n", lwgeom_to_wkt(line));
+       printf("HEXWKB: %s\n", lwgeom_to_hexwkb(point,-1));
 
        return 1;
 }
index a0fb5136f4cd0886e8913595825966e145666b20..f975845d84574d34e227985063132edc442bd969 100644 (file)
@@ -68,6 +68,6 @@ 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* unparse_WKB(byte* serialized, allocator alloc,freeor free, unsigned int endian);
 
 
index 92bc6acbebc25c871a78336f1e49f844b937ab87..d4cc1634d3a0ce33519e190b1c50fdfd16ba6d06 100644 (file)
@@ -4,8 +4,10 @@
  * Copyright Telogis 2004
  * www.telogis.com
  *
+ * $Id$
  */
 
+
 #include "wktparse.h"
 #include <string.h>
 #include <math.h>
 static int endian_check_int = 1; // dont modify this!!!
 
 #define LITTLE_ENDIAN_CHECK 1
-static char getMachineEndian()
+static unsigned int getMachineEndian()
 {
-       return *((char *) &endian_check_int); // 0 = big endian, 1 = little endian
+       // 0 = big endian, 1 = little endian
+       if ( *((char *) &endian_check_int) )
+       {
+               return LITTLE_ENDIAN;
+       }
+       else
+       {
+               return BIG_ENDIAN;
+       }
 }
 
 //-- Typedefs ----------------------------------------------
@@ -46,7 +56,7 @@ 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,int cnt);
+void write_wkb_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);
@@ -62,6 +72,7 @@ static char*  out_start;
 static char*  out_pos;
 static int len;
 static int lwgi;
+static int flipbytes;
 
 //----------------------------------------------------------
 
@@ -368,13 +379,30 @@ unparse_WKT(byte* serialized, allocator alloc, freeor free)
 static char outchr[]={"0123456789ABCDEF" };
 
 void
-write_wkb_bytes(byte* ptr,int cnt){
-       ensure(cnt*2);
+write_wkb_bytes(byte* ptr, unsigned int cnt, size_t size)
+{
+       unsigned int bc; // byte count
+
+       ensure(cnt*2*size);
 
        while(cnt--){
-               *out_pos++ = outchr[*ptr>>4];
-               *out_pos++ = outchr[*ptr&0x0F];
-               ptr ++;
+               if (flipbytes)
+               {
+                       for(bc=size; bc; bc--)
+                       {
+                               *out_pos++ = outchr[ptr[bc-1]>>4];
+                               *out_pos++ = outchr[ptr[bc-1]&0x0F];
+                       }
+               }
+               else
+               {
+                       for(bc=0; bc<size; bc++)
+                       {
+                               *out_pos++ = outchr[ptr[bc]>>4];
+                               *out_pos++ = outchr[ptr[bc]&0x0F];
+                       }
+               }
+               ptr+=size;
        }
 }
 
@@ -382,18 +410,18 @@ byte *
 output_wkb_point(byte* geom)
 {
        if ( lwgi ){
-               write_wkb_bytes(geom,dims*4);
+               write_wkb_bytes(geom,dims,4);
                return geom + (4*dims);
        }
        else{
-               write_wkb_bytes(geom,dims*8);
+               write_wkb_bytes(geom,dims,8);
                return geom + (8*dims);
        }
 }
 
 void
 write_wkb_int(int i){
-       write_wkb_bytes((byte*)&i,4);
+       write_wkb_bytes((byte*)&i,1,4);
 }
 
 byte *
@@ -419,7 +447,6 @@ output_wkb(byte* geom)
 {
        unsigned char type=*geom++;
        int4 wkbtype;
-       byte endian;
 
        dims = TYPE_NDIMS(type); 
 #ifdef DEBUG
@@ -445,15 +472,6 @@ output_wkb(byte* geom)
        if ( TYPE_HASM(type) )
                 wkbtype |= WKBMOFFSET;
 
-       if ( getMachineEndian() != LITTLE_ENDIAN_CHECK ){
-               endian=0;
-               write_wkb_bytes(&endian,1);
-       }
-       else{
-               endian=1;
-               write_wkb_bytes(&endian,1);
-       }
-
        write_wkb_int(wkbtype);
 
        switch(TYPE_GETTYPE(type)){
@@ -501,8 +519,9 @@ output_wkb(byte* geom)
 }
 
 char *
-unparse_WKB(byte* serialized, allocator alloc, freeor free)
+unparse_WKB(byte* serialized, allocator alloc, freeor free, unsigned int endian)
 {
+       byte endianbyte;
 
 #ifdef DEBUG
        lwnotice("unparse_WKB(%p,...) called", serialized);
@@ -517,6 +536,16 @@ unparse_WKB(byte* serialized, allocator alloc, freeor free)
        out_start = out_pos = alloc(len);
        lwgi=0;
 
+       if ( endian == -1 ) endian = getMachineEndian();
+
+       if ( endian == LITTLE_ENDIAN) endianbyte=1;
+       else endianbyte=0;
+
+       write_wkb_bytes(&endianbyte,1,1);
+
+       if ( endian != getMachineEndian() ) flipbytes = 1;
+       else flipbytes = 0;
+
        output_wkb(serialized);
        ensure(1);
        *out_pos=0;
@@ -525,3 +554,9 @@ unparse_WKB(byte* serialized, allocator alloc, freeor free)
 }
 
 
+/******************************************************************
+ * $Log$
+ * Revision 1.10  2004/10/11 14:03:33  strk
+ * Added endiannes specification to unparse_WKB, AsBinary, lwgeom_to_wkb.
+ *
+ ******************************************************************/