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;
}
#include "lwgeom_pg.h"
#include "wktparse.h"
+#include "profile.h"
void elog_ERROR(const char* string);
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);
}
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);
}
#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);
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();
}
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);
//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);
}
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);
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);
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);
//----------------------------------------------------------
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)
{
}
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
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;
}
/******************************************************************
* $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.
*