26 #include "../postgis_config.h"
34 #define LW_PARSER_MAX_DEPTH 200
67 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
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,
71 0,1,2,3,4,5,6,7,8,9,20,20,20,20,20,20,
73 20,10,11,12,13,14,15,20,20,20,20,20,20,20,20,20,
75 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
77 20,10,11,12,13,14,15,20,20,20,20,20,20,20,20,20,
78 20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,
80 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
98 lwerror(
"Invalid hex string, length (%d) has to be a multiple of two!", hexsize);
103 lwerror(
"Unable to allocate memory buffer.");
105 for( i = 0; i < hexsize/2; i++ )
110 lwerror(
"Invalid hex character (%c) encountered", hexbuf[2*i]);
112 lwerror(
"Invalid hex character (%c) encountered", hexbuf[2*i+1]);
114 buf[i] = ((h1 & 0x0F) << 4) | (h2 & 0x0F);
132 if( (
s->pos + next) > (
s->wkb +
s->wkb_size) )
134 lwerror(
"WKB structure does not match expected size!");
148 LWDEBUG(4,
"Entered function");
155 if( wkb_type & 0xF0000000 )
160 LWDEBUGF(4,
"Extended type: has_z=%d has_m=%d has_srid=%d",
s->has_z,
s->has_m,
s->has_srid);
164 wkb_type = wkb_type & 0x0FFFFFFF;
166 wkb_simple_type = wkb_type % 1000;
169 if( wkb_type >= 3000 && wkb_type < 4000 )
174 else if ( wkb_type >= 2000 && wkb_type < 3000 )
178 else if ( wkb_type >= 1000 && wkb_type < 2000 )
183 switch (wkb_simple_type)
243 lwerror(
"Unknown WKB type (%d)! Full WKB type number was (%d).", wkb_simple_type, wkb_type);
259 LWDEBUG(4,
"Entered function");
262 LWDEBUG(4,
"Passed state check");
264 char_value =
s->pos[0];
265 LWDEBUGF(4,
"Read byte value: %x", char_value);
347 if (npoints > maxpoints)
349 lwerror(
"Pointarray length (%d) is too large");
353 LWDEBUGF(4,
"Pointarray has %d points", npoints);
355 if(
s->has_z ) ndims++;
356 if(
s->has_m ) ndims++;
367 if( !
s->swap_bytes )
379 for( i = 0; i < npoints * ndims; i++ )
406 if(
s->has_z ) ndims++;
407 if(
s->has_m ) ndims++;
414 if( !
s->swap_bytes )
426 for( i = 0; i < ndims; i++ )
434 if ( isnan(pt->
x) && isnan(pt->
y) )
457 if( pa == NULL || pa->
npoints == 0 )
485 if( pa == NULL || pa->
npoints == 0 )
517 LWDEBUGF(4,
"Polygon has %d rings", nrings);
523 for( i = 0; i < nrings; i++ )
548 LWDEBUG(2,
"Unable to add ring to polygon");
549 lwerror(
"Unable to add ring to polygon");
576 lwerror(
"Triangle has wrong number of rings: %d", nrings);
621 for ( i = 0; i < ngeoms; i++ )
628 lwerror(
"Unable to add geometry (%p) to curvepoly (%p)", geom, cp);
652 LWDEBUGF(4,
"Collection has %d components", ngeoms);
666 lwerror(
"Geometry has too many chained collections");
669 for ( i = 0; i < ngeoms; i++ )
676 lwerror(
"Unable to add geometry (%p) to collection (%p)", geom, col);
695 char wkb_little_endian;
702 if( wkb_little_endian != 1 && wkb_little_endian != 0 )
704 LWDEBUG(4,
"Leaving due to bad first byte!");
705 lwerror(
"Invalid endian flag value encountered.");
713 if ( ! wkb_little_endian )
718 if ( wkb_little_endian )
724 LWDEBUGF(4,
"Got WKB type number: 0x%X", wkb_type);
795 s.wkb_size = wkb_size;
817 lwerror(
"lwgeom_from_hexwkb: null input");
821 hexwkb_len = strlen(hexwkb);
#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.
LWCIRCSTRING * lwcircstring_construct_empty(int srid, char hasz, char hasm)
#define LW_PARSER_CHECK_CLOSURE
LWCURVEPOLY * lwcurvepoly_construct_empty(int srid, char hasz, char hasm)
LWCOLLECTION * lwcollection_construct_empty(uint8_t type, int srid, char hasz, char hasm)
void lwgeom_free(LWGEOM *geom)
#define LW_PARSER_CHECK_ZCLOSURE
LWLINE * lwline_construct_empty(int srid, char hasz, char hasm)
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.
LWPOINT * lwpoint_construct(int srid, GBOX *bbox, POINTARRAY *point)
#define POLYHEDRALSURFACETYPE
int lwcurvepoly_add_ring(LWCURVEPOLY *poly, LWGEOM *ring)
Add a ring, allocating extra space if necessary.
LWCIRCSTRING * lwcircstring_construct(int srid, GBOX *bbox, POINTARRAY *points)
int ptarray_is_closed_z(const POINTARRAY *pa)
int clamp_srid(int srid)
Return a valid SRID from an arbitrary integer Raises a notice if what comes out is different from wha...
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)
#define LW_TRUE
Return types for functions with status returns.
#define SRID_UNKNOWN
Unknown SRID value.
LWPOINT * lwpoint_construct_empty(int srid, char hasz, char hasm)
LWLINE * lwline_construct(int srid, GBOX *bbox, POINTARRAY *points)
#define WKBZOFFSET
Flags applied in EWKB to indicate Z/M dimensions and presence/absence of SRID and bounding boxes.
LWPOLY * lwpoly_construct_empty(int srid, char hasz, char hasm)
LWTRIANGLE * lwtriangle_construct_empty(int srid, char hasz, char hasm)
const POINT2D * getPoint2d_cp(const POINTARRAY *pa, uint32_t n)
Returns a POINT2D pointer into the POINTARRAY serialized_ptlist, suitable for reading from.
#define WKB_COMPOUNDCURVE_TYPE
#define WKB_POLYHEDRALSURFACE_TYPE
#define WKB_GEOMETRYCOLLECTION_TYPE
#define WKB_TRIANGLE_TYPE
char getMachineEndian(void)
#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...
uint8_t * serialized_pointlist
Used for passing the parse state between the parsing functions.