]> granicus.if.org Git - postgis/commitdiff
Added support to make WKB a full type.
authorDavid Blasby <dblasby@gmail.com>
Tue, 4 Sep 2001 19:30:12 +0000 (19:30 +0000)
committerDavid Blasby <dblasby@gmail.com>
Tue, 4 Sep 2001 19:30:12 +0000 (19:30 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@60 b70326c6-7e19-0410-871a-916f4a2858ee

postgis.h
postgis.sql.in
postgis_fn.c
postgis_inout.c

index ca4f1347c4138315d7c25711c7683c4a212884d6..c65f5b4707a20963542b608a13d5540f4768a151 100644 (file)
--- a/postgis.h
+++ b/postgis.h
@@ -205,6 +205,13 @@ typedef struct geomkey {
 } GEOMETRYKEY; 
 
 
+// WKB structure  -- exactly the same as TEXT
+typedef struct Well_known_bin {
+       int32 size;    // total size of this structure
+       unsigned char  data[1]; //THIS HOLD VARIABLE LENGTH DATA
+} WellKnownBinary;
+
+
 //prototypes 
 
      int isspace(int c);
@@ -312,6 +319,8 @@ double distance_seg_seg(POINT3D *A, POINT3D *B, POINT3D *C, POINT3D *D);
 bool point_in_poly(POINT3D *p, POLYGON3D *poly);
 
 void print_point_debug(POINT3D *p);
+unsigned char  parse_hex(char *str);
+void deparse_hex(unsigned char str, unsigned char *result);
 
 
 char *geometry_to_text(GEOMETRY  *geometry);
@@ -412,6 +421,9 @@ Datum centroid(PG_FUNCTION_ARGS);
 
 Datum postgis_gist_sel(PG_FUNCTION_ARGS);
 
+Datum WKB_in(PG_FUNCTION_ARGS);
+Datum WKB_out(PG_FUNCTION_ARGS);
+
 
 //for GIST index
 typedef char* (*BINARY_UNION)(char*, char*, int*);
index b7a1c9ef6f13a1028e8aed991214ac8830141503..803a529507c0e01254afcc71e515261aac5c2dda 100644 (file)
@@ -241,11 +241,22 @@ CREATE TYPE BOX3D (
        output = BOX3D_out
 );
 
+create function WKB_in(opaque)
+       RETURNS WKB
+   AS '@MODULE_FILENAME@','WKB_in'
+   LANGUAGE 'c' with (isstrict);
+
+create function WKB_out(opaque)
+       RETURNS opaque
+   AS '@MODULE_FILENAME@','WKB_out'
+   LANGUAGE 'c' with (isstrict);
+
+
 CREATE TYPE WKB (
-       alignment = double,
        internallength = VARIABLE,
-       input =  textin,
-       output =  textout
+       input =  WKB_in,
+       output =  WKB_out,
+       storage= extended
 );
 
 
index fd4e1fa238f3ca053c2017c385ba310c04444967..c0d226a1097a91a53f1e613e01c7933944b50143 100644 (file)
@@ -2192,4 +2192,7 @@ Datum centroid(PG_FUNCTION_ARGS)
        pfree(cent);
        PG_RETURN_POINTER(result);
 
-}
\ No newline at end of file
+}
+
+
+
index 3ca4440786e6ff9c0e3800b45268cc8d537c4104..2a27e931428c3df14ddcbc7bee90574e9978a620 100644 (file)
@@ -2764,7 +2764,7 @@ Datum asbinary_specify(PG_FUNCTION_ARGS)
 
        if  ( ( strcmp(VARDATA(type) ,"xdr") == 0 ) || (strcmp(VARDATA(type) ,"XDR") == 0) )
        {
-printf("requested XDR\n");
+//printf("requested XDR\n");
                if (BYTE_ORDER == BIG_ENDIAN)
                        PG_RETURN_POINTER(to_wkb(geom, FALSE));
                else
@@ -2772,7 +2772,7 @@ printf("requested XDR\n");
        }
        else
        {
-printf("requested NDR\n");
+//printf("requested NDR\n");
                if (BYTE_ORDER == LITTLE_ENDIAN)
                        PG_RETURN_POINTER(to_wkb(geom, FALSE));
                else
@@ -3060,3 +3060,297 @@ LINE3D  *make_line(int  npoints, POINT3D        *pts, int       *size)
        return result;
 }
 
+//given one byte, populate result with two byte representing 
+// the hex number
+// ie deparse_hex( 255, mystr)
+//             -> mystr[0] = 'F' and mystr[1] = 'F'
+// no error checking done
+void deparse_hex(unsigned char str, unsigned char *result)
+{
+       int     input_high;
+       int  input_low;
+       
+       input_high = (str>>4);
+       input_low = (str & 0x0F);
+
+       switch (input_high)
+       {
+               case 0:
+                       result[0] = '0';
+                       break;
+               case 1:
+                       result[0] = '1';
+                       break;
+               case 2:
+                       result[0] = '2';
+                       break;
+               case 3:
+                       result[0] = '3';
+                       break;
+               case 4:
+                       result[0] = '4';
+                       break;
+               case 5:
+                       result[0] = '5';
+                       break;
+               case 6:
+                       result[0] = '6';
+                       break;
+               case 7:
+                       result[0] = '7';
+                       break;
+               case 8:
+                       result[0] = '8';
+                       break;
+               case 9:
+                       result[0] = '9';
+                       break;
+               case 10:
+                       result[0] = 'A';
+                       break;
+               case 11:
+                       result[0] = 'B';
+                       break;
+               case 12:
+                       result[0] = 'C';
+                       break;
+               case 13:
+                       result[0] = 'D';
+                       break;
+               case 14:
+                       result[0] = 'E';
+                       break;
+               case 15:
+                       result[0] = 'F';
+                       break;
+       }
+
+       switch (input_low)
+       {
+               case 0:
+                       result[1] = '0';
+                       break;
+               case 1:
+                       result[1] = '1';
+                       break;
+               case 2:
+                       result[1] = '2';
+                       break;
+               case 3:
+                       result[1] = '3';
+                       break;
+               case 4:
+                       result[1] = '4';
+                       break;
+               case 5:
+                       result[1] = '5';
+                       break;
+               case 6:
+                       result[1] = '6';
+                       break;
+               case 7:
+                       result[1] = '7';
+                       break;
+               case 8:
+                       result[1] = '8';
+                       break;
+               case 9:
+                       result[1] = '9';
+                       break;
+               case 10:
+                       result[1] = 'A';
+                       break;
+               case 11:
+                       result[1] = 'B';
+                       break;
+               case 12:
+                       result[1] = 'C';
+                       break;
+               case 13:
+                       result[1] = 'D';
+                       break;
+               case 14:
+                       result[1] = 'E';
+                       break;
+               case 15:
+                       result[1] = 'F';
+                       break;
+       }
+}
+
+
+//given a string with at least 2 chars in it, convert them to
+// a byte value.  No error checking done!
+unsigned char  parse_hex(char *str)
+{
+       //do this a little brute force to make it faster
+
+       unsigned char           result_high;
+       unsigned char           result_low;
+
+       switch (str[0])
+       {
+               case '0' :
+                       result_high = 0;
+                       break;
+               case '1' :
+                       result_high = 1;
+                       break;
+               case '2' :
+                       result_high = 2;
+                       break;
+               case '3' :
+                       result_high = 3;
+                       break;
+               case '4' :
+                       result_high = 4;
+                       break;
+               case '5' :
+                       result_high = 5;
+                       break;
+               case '6' :
+                       result_high = 6;
+                       break;
+               case '7' :
+                       result_high = 7;
+                       break;
+               case '8' :
+                       result_high = 8;
+                       break;
+               case '9' :
+                       result_high = 9;
+                       break;
+               case 'A' :
+                       result_high = 10;
+                       break;
+               case 'B' :
+                       result_high = 11;
+                       break;
+               case 'C' :
+                       result_high = 12;
+                       break;
+               case 'D' :
+                       result_high = 13;
+                       break;
+               case 'E' :
+                       result_high = 14;
+                       break;
+               case 'F' :
+                       result_high = 15;
+                       break;
+       }
+       switch (str[1])
+       {
+               case '0' :
+                       result_low = 0;
+                       break;
+               case '1' :
+                       result_low = 1;
+                       break;
+               case '2' :
+                       result_low = 2;
+                       break;
+               case '3' :
+                       result_low = 3;
+                       break;
+               case '4' :
+                       result_low = 4;
+                       break;
+               case '5' :
+                       result_low = 5;
+                       break;
+               case '6' :
+                       result_low = 6;
+                       break;
+               case '7' :
+                       result_low = 7;
+                       break;
+               case '8' :
+                       result_low = 8;
+                       break;
+               case '9' :
+                       result_low = 9;
+                       break;
+               case 'A' :
+                       result_low = 10;
+                       break;
+               case 'B' :
+                       result_low = 11;
+                       break;
+               case 'C' :
+                       result_low = 12;
+                       break;
+               case 'D' :
+                       result_low = 13;
+                       break;
+               case 'E' :
+                       result_low = 14;
+                       break;
+               case 'F' :
+                       result_low = 15;
+                       break;
+       }
+       return (unsigned char) ((result_high<<4) + result_low);
+}
+
+
+// input is a string with hex chars in it.  Convert to binary and put in the result
+PG_FUNCTION_INFO_V1(WKB_in);
+Datum WKB_in(PG_FUNCTION_ARGS)
+{
+       char                    *str = PG_GETARG_CSTRING(0);
+       WellKnownBinary         *result;
+       int                     size;
+       int                     t;
+       int                     input_str_len;
+
+//printf("wkb_in called\n");
+
+       input_str_len = strlen(str);
+
+       if  ( ( ( (int)(input_str_len/2.0) ) *2.0) != input_str_len)
+       {
+               elog(ERROR,"WKB_in parser - should be even number of characters!");
+               PG_RETURN_NULL();
+       }
+
+       if (strspn(str,"0123456789ABCDEF") != strlen(str) )
+       {
+               elog(ERROR,"WKB_in parser - input contains bad characters.  Should only have '0123456789ABCDEF'!");
+               PG_RETURN_NULL();       
+       }
+       size = (input_str_len/2) + 4;
+       result = (WellKnownBinary *) palloc(size);
+       result->size = size;
+       
+       for (t=0;t<input_str_len/2;t++)
+       {
+               ((unsigned char *)result)[t+4] = parse_hex( &str[t*2]) ;
+       }
+       PG_RETURN_POINTER(result);
+}
+
+
+//given a WKB structure, convert it to Hex and put it in a string
+PG_FUNCTION_INFO_V1(WKB_out);
+Datum WKB_out(PG_FUNCTION_ARGS)
+{
+       WellKnownBinary               *WKB = (WellKnownBinary *)  PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
+       char                                    *result;
+       int                                     size_result;
+       int                                     t;
+
+//printf("wkb_out called\n");
+
+       size_result = (WKB->size - 4) *2 +1; //+1 for null char
+       result = palloc (size_result);
+       result[size_result-1] = 0; //null terminate
+
+       for (t=0; t< (WKB->size -4); t++)
+       {
+               deparse_hex( ((unsigned char *) WKB)[4 + t], &result[t*2]);                     
+       }
+       PG_RETURN_CSTRING(result);      
+}
+
+