26 #include "../postgis_config.h"
34 #define LW_PARSER_MAX_DEPTH 200
68 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
69 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
70 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
72 0,1,2,3,4,5,6,7,8,9,20,20,20,20,20,20,
74 20,10,11,12,13,14,15,20,20,20,20,20,20,20,20,20,
76 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
78 20,10,11,12,13,14,15,20,20,20,20,20,20,20,20,20,
79 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
81 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
82 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
83 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
84 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
85 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
86 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
87 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
88 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20
95 register uint8_t h1, h2;
99 lwerror(
"Invalid hex string, length (%d) has to be a multiple of two!", hexsize);
104 lwerror(
"Unable to allocate memory buffer.");
106 for( i = 0; i < hexsize/2; i++ )
111 lwerror(
"Invalid hex character (%c) encountered", hexbuf[2*i]);
113 lwerror(
"Invalid hex character (%c) encountered", hexbuf[2*i+1]);
115 buf[i] = ((h1 & 0x0F) << 4) | (h2 & 0x0F);
133 if( (
s->pos + next) > (
s->wkb +
s->wkb_size) )
135 lwerror(
"WKB structure does not match expected size!");
147 uint32_t wkb_simple_type;
149 LWDEBUG(4,
"Entered function");
156 if( wkb_type & 0xF0000000 )
161 LWDEBUGF(4,
"Extended type: has_z=%d has_m=%d has_srid=%d",
s->has_z,
s->has_m,
s->has_srid);
165 wkb_type = wkb_type & 0x0FFFFFFF;
168 if ( wkb_type >= 4000 ) {
169 lwerror(
"Unknown WKB type (%d)!", wkb_type);
174 wkb_simple_type = wkb_type % 1000;
177 if( wkb_type >= 3000 && wkb_type < 4000 )
182 else if ( wkb_type >= 2000 && wkb_type < 3000 )
186 else if ( wkb_type >= 1000 && wkb_type < 2000 )
191 switch (wkb_simple_type)
251 lwerror(
"Unknown WKB type (%d)! Full WKB type number was (%d).", wkb_simple_type, wkb_type);
267 LWDEBUG(4,
"Entered function");
272 LWDEBUG(4,
"Passed state check");
274 char_value =
s->pos[0];
275 LWDEBUGF(4,
"Read byte value: %x", char_value);
303 tmp = ((uint8_t*)(&i))[j];
304 ((uint8_t*)(&i))[j] = ((uint8_t*)(&i))[
WKB_INT_SIZE - j - 1];
331 tmp = ((uint8_t*)(&d))[i];
352 uint32_t npoints = 0;
360 if (npoints > maxpoints)
363 lwerror(
"Pointarray length (%d) is too large", npoints);
367 LWDEBUGF(4,
"Pointarray has %d points", npoints);
369 if(
s->has_z ) ndims++;
370 if(
s->has_m ) ndims++;
383 if( !
s->swap_bytes )
395 for( i = 0; i < npoints * ndims; i++ )
415 static uint32_t npoints = 1;
422 if(
s->has_z ) ndims++;
423 if(
s->has_m ) ndims++;
432 if( !
s->swap_bytes )
444 for( i = 0; i < ndims; i++ )
452 if ( isnan(pt->
x) && isnan(pt->
y) )
477 if( pa == NULL || pa->
npoints == 0 )
508 if( pa == NULL || pa->
npoints == 0 )
546 LWDEBUGF(4,
"Polygon has %d rings", nrings);
552 for( i = 0; i < nrings; i++ )
586 LWDEBUG(2,
"Unable to add ring to polygon");
587 lwerror(
"Unable to add ring to polygon");
616 lwerror(
"Triangle has wrong number of rings: %d", nrings);
661 for ( i = 0; i < ngeoms; i++ )
668 lwerror(
"Unable to add geometry (%p) to curvepoly (%p)", geom, cp);
694 LWDEBUGF(4,
"Collection has %d components", ngeoms);
708 lwerror(
"Geometry has too many chained collections");
711 for ( i = 0; i < ngeoms; i++ )
718 lwerror(
"Unable to add geometry (%p) to collection (%p)", geom, col);
737 char wkb_little_endian;
746 if( wkb_little_endian != 1 && wkb_little_endian != 0 )
748 LWDEBUG(4,
"Leaving due to bad first byte!");
749 lwerror(
"Invalid endian flag value encountered.");
767 LWDEBUGF(4,
"Got WKB type number: 0x%X", wkb_type);
840 s.wkb_size = wkb_size;
852 if (!wkb || !wkb_size)
866 lwerror(
"lwgeom_from_hexwkb: null input");
870 hexwkb_len = strlen(hexwkb);
LWPOINT * lwpoint_construct_empty(int32_t srid, char hasz, char hasm)
#define LW_PARSER_CHECK_ODD
POINTARRAY * ptarray_construct_copy_data(char hasz, char hasm, uint32_t npoints, const uint8_t *ptlist)
Construct a new POINTARRAY, copying in the data from ptlist.
#define LW_PARSER_CHECK_CLOSURE
void lwgeom_free(LWGEOM *geom)
#define LW_PARSER_CHECK_ZCLOSURE
int lwpoly_add_ring(LWPOLY *poly, POINTARRAY *pa)
Add a ring, allocating extra space if necessary.
POINTARRAY * ptarray_construct(char hasz, char hasm, uint32_t npoints)
Construct an empty pointarray, allocating storage and setting the npoints, but not filling in any inf...
#define POINTTYPE
LWTYPE numbers, used internally by PostGIS.
LWLINE * lwline_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
LWTRIANGLE * lwtriangle_construct_empty(int32_t srid, char hasz, char hasm)
LWPOINT * lwpoint_construct(int32_t srid, GBOX *bbox, POINTARRAY *point)
#define POLYHEDRALSURFACETYPE
int lwcurvepoly_add_ring(LWCURVEPOLY *poly, LWGEOM *ring)
Add a ring, allocating extra space if necessary.
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int32_t srid, char hasz, char hasm)
int ptarray_is_closed_z(const POINTARRAY *pa)
const char * lwtype_name(uint8_t type)
Return the type name string associated with a type number (e.g.
void lwcollection_free(LWCOLLECTION *col)
#define LW_PARSER_CHECK_MINPOINTS
Parser check flags.
void ptarray_free(POINTARRAY *pa)
LWCOLLECTION * lwcollection_add_lwgeom(LWCOLLECTION *col, const LWGEOM *geom)
Appends geom to the collection managed by col.
void * lwalloc(size_t size)
int ptarray_is_closed_2d(const POINTARRAY *pa)
void lwpoly_free(LWPOLY *poly)
#define LW_TRUE
Return types for functions with status returns.
LWCURVEPOLY * lwcurvepoly_construct_empty(int32_t srid, char hasz, char hasm)
#define SRID_UNKNOWN
Unknown SRID value.
#define WKBZOFFSET
Flags applied in EWKB to indicate Z/M dimensions and presence/absence of SRID and bounding boxes.
LWPOLY * lwpoly_construct_empty(int32_t srid, char hasz, char hasm)
LWCIRCSTRING * lwcircstring_construct_empty(int32_t srid, char hasz, char hasm)
LWCIRCSTRING * lwcircstring_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
LWLINE * lwline_construct_empty(int32_t srid, char hasz, char hasm)
LWTRIANGLE * lwtriangle_construct(int32_t srid, GBOX *bbox, POINTARRAY *points)
int32_t clamp_srid(int32_t srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
#define WKB_COMPOUNDCURVE_TYPE
#define WKB_POLYHEDRALSURFACE_TYPE
#define WKB_GEOMETRYCOLLECTION_TYPE
#define WKB_TRIANGLE_TYPE
#define WKB_MULTIPOLYGON_TYPE
#define WKB_MULTIPOINT_TYPE
#define WKB_MULTISURFACE_TYPE
#define WKB_CURVEPOLYGON_TYPE
#define WKB_POINT_TYPE
Well-Known Binary (WKB) Geometry Types.
#define WKB_MULTICURVE_TYPE
#define WKB_MULTILINESTRING_TYPE
#define WKB_LINESTRING_TYPE
#define WKB_CIRCULARSTRING_TYPE
#define WKB_DOUBLE_SIZE
Well-Known Binary (WKB) Output Variant Types.
#define LWDEBUG(level, msg)
#define LWDEBUGF(level, msg,...)
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
static uint32_t integer_from_wkb_state(wkb_parse_state *s)
Int32 Read 4-byte integer and advance the parse state forward.
static LWCURVEPOLY * lwcurvepoly_from_wkb_state(wkb_parse_state *s)
CURVEPOLYTYPE.
LWGEOM * lwgeom_from_hexwkb(const char *hexwkb, const char check)
static POINTARRAY * ptarray_from_wkb_state(wkb_parse_state *s)
POINTARRAY Read a dynamically sized point array and advance the parse state forward.
static void wkb_parse_state_check(wkb_parse_state *s, size_t next)
Check that we are not about to read off the end of the WKB array.
static LWPOLY * lwpoly_from_wkb_state(wkb_parse_state *s)
POLYGON Read a WKB polygon, starting just after the endian byte, type number and optional srid number...
uint8_t * bytes_from_hexbytes(const char *hexbuf, size_t hexsize)
static double double_from_wkb_state(wkb_parse_state *s)
Double Read an 8-byte double and advance the parse state forward.
static LWPOINT * lwpoint_from_wkb_state(wkb_parse_state *s)
POINT Read a WKB point, starting just after the endian byte, type number and optional srid number.
static LWLINE * lwline_from_wkb_state(wkb_parse_state *s)
LINESTRING Read a WKB linestring, starting just after the endian byte, type number and optional srid ...
static LWCOLLECTION * lwcollection_from_wkb_state(wkb_parse_state *s)
POLYHEDRALSURFACETYPE.
static char byte_from_wkb_state(wkb_parse_state *s)
Byte Read a byte and advance the parse state forward.
static LWCIRCSTRING * lwcircstring_from_wkb_state(wkb_parse_state *s)
CIRCULARSTRING Read a WKB circularstring, starting just after the endian byte, type number and option...
static void lwtype_from_wkb_state(wkb_parse_state *s, uint32_t wkb_type)
Take in an unknown kind of wkb type number and ensure it comes out as an extended WKB type number (wi...
#define LW_PARSER_MAX_DEPTH
Max depth in a geometry.
LWGEOM * lwgeom_from_wkb_state(wkb_parse_state *s)
Internal function declarations.
static uint8_t hex2char[256]
LWGEOM * lwgeom_from_wkb(const uint8_t *wkb, const size_t wkb_size, const char check)
WKB inputs must have a declared size, to prevent malformed WKB from reading off the end of the memory...
static LWTRIANGLE * lwtriangle_from_wkb_state(wkb_parse_state *s)
TRIANGLE Read a WKB triangle, starting just after the endian byte, type number and optional srid numb...
static const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
uint8_t * serialized_pointlist
Used for passing the parse state between the parsing functions.