extern uchar parse_hex(char *str);
extern void deparse_hex(uchar str, char *result);
+/* Parser check flags */
+#define PARSER_CHECK_MINPOINTS 1
+#define PARSER_CHECK_ODD 2
+#define PARSER_CHECK_CLOSURE 4
+
+#define PARSER_CHECK_ALL (PARSER_CHECK_MINPOINTS | PARSER_CHECK_ODD | PARSER_CHECK_CLOSURE)
+
+
/* Parser access routines */
extern char *lwgeom_to_ewkt(LWGEOM *lwgeom);
extern char *lwgeom_to_hexwkb(LWGEOM *lwgeom, unsigned int byteorder);
-extern LWGEOM *lwgeom_from_ewkb(uchar *ewkb, size_t ewkblen);
+extern LWGEOM *lwgeom_from_ewkb(uchar *ewkb, size_t ewkblen, int flags);
extern uchar *lwgeom_to_ewkb(LWGEOM *lwgeom, char byteorder, size_t *ewkblen);
extern char *serialized_lwgeom_to_ewkt(uchar *serialized);
-extern SERIALIZED_LWGEOM *serialized_lwgeom_from_ewkt(char *wkt_input);
+extern SERIALIZED_LWGEOM *serialized_lwgeom_from_ewkt(char *wkt_input, int flags);
extern char *serialized_lwgeom_to_hexwkb(uchar *serialized, unsigned int byteorder, size_t *size);
extern char *serialized_lwgeom_to_ewkb(uchar *serialized, unsigned int byteorder, size_t *size);
* - deserialize it
*/
LWGEOM *
-lwgeom_from_ewkb(uchar *ewkb, size_t size)
+lwgeom_from_ewkb(uchar *ewkb, size_t size, int flags)
{
size_t hexewkblen = size*2;
char *hexewkb;
hexewkb[hexewkblen] = '\0';
/* Rely on grammar parser to construct a LWGEOM */
- serialized_lwgeom = serialized_lwgeom_from_ewkt(hexewkb);
+ serialized_lwgeom = serialized_lwgeom_from_ewkt(hexewkb, flags);
/* Free intermediate HEXified representation */
lwfree(hexewkb);
* Make a serialzed LWGEOM object from a WKT input string
*/
SERIALIZED_LWGEOM *
-serialized_lwgeom_from_ewkt(char *wkt_input)
+serialized_lwgeom_from_ewkt(char *wkt_input, int flags)
{
- SERIALIZED_LWGEOM *serialized_form = parse_lwg(wkt_input,
+ SERIALIZED_LWGEOM *serialized_form = parse_lwg(wkt_input, flags,
lwalloc, lwerror);
} the_geom;
tuple* free_list=0;
+
+
+/*
+ * Parser global check flags - a bitmap of flags that determine which checks the parser will perform
+ * (see liblwgeom.h for the related PARSER_CHECK constants)
+ */
+int parser_check_flags;
+
+
+/* Parser state flags - these are set automatically by the parser */
int minpoints;
int checkclosed;
double *first_point=NULL;
double *last_point=NULL;
+
/* External functions */
extern void init_parser(const char *);
void read_collection(const char **b, read_col_func f);
void parse_wkb(const char **b);
void alloc_wkb(const char *parser);
-SERIALIZED_LWGEOM* parse_it(const char* geometry, allocator allocfunc, report_error errfunc);
-SERIALIZED_LWGEOM* parse_lwg(const char* geometry, allocator allocfunc, report_error errfunc);
-SERIALIZED_LWGEOM* parse_lwgi(const char* geometry, allocator allocfunc, report_error errfunc);
+SERIALIZED_LWGEOM* parse_it(const char* geometry, int flags, allocator allocfunc, report_error errfunc);
+SERIALIZED_LWGEOM* parse_lwg(const char* geometry, int flags, allocator allocfunc, report_error errfunc);
+SERIALIZED_LWGEOM* parse_lwgi(const char* geometry, int flags, allocator allocfunc, report_error errfunc);
void
set_srid(double d_srid)
void
popc(void)
{
+ /* If the minimum point check has been enabled, perform it */
+ if (parser_check_flags & PARSER_CHECK_MINPOINTS) {
+ if ( the_geom.stack->uu.nn.num < minpoints){
+ error("geometry requires more points");
+ }
+ }
- if ( the_geom.stack->uu.nn.num < minpoints){
- error("geometry requires more points");
+ /* If the odd number point check has been enabled, perform it */
+ if (parser_check_flags & PARSER_CHECK_CLOSURE) {
+ if(isodd != -1 && the_geom.stack->uu.nn.num % 2 != isodd) {
+ error("geometry must have an odd number of points");
+ }
+ }
+
+ /* If the polygon closure check has been enabled, perform it */
+ if (parser_check_flags & PARSER_CHECK_ODD) {
+ if ( checkclosed && first_point && last_point) {
+ if ( memcmp(first_point, last_point,
+ sizeof(double)*the_geom.ndims) )
+ {
+ error("geometry contains non-closed rings");
+ }
+ }
}
- if(isodd != -1 && the_geom.stack->uu.nn.num % 2 != isodd) {
- error("geometry must have an odd number of points");
- }
- if ( checkclosed && first_point && last_point) {
- if ( memcmp(first_point, last_point,
- sizeof(double)*the_geom.ndims) )
- {
- error("geometry contains non-closed rings");
- }
- }
the_geom.stack = the_geom.stack->uu.nn.stack_next;
}
Parse a string and return a LW_GEOM
*/
SERIALIZED_LWGEOM *
-parse_it(const char *geometry, allocator allocfunc, report_error errfunc)
+parse_it(const char *geometry, int flags, allocator allocfunc, report_error errfunc)
{
LWDEBUGF(2, "parse_it: %s", geometry);
ferror_occured = 0;
+ /* Setup the inital parser flags */
+ parser_check_flags = flags;
+
init_parser(geometry);
lwg_parse_yyparse();
}
SERIALIZED_LWGEOM *
-parse_lwg(const char* geometry,allocator allocfunc,report_error errfunc)
+parse_lwg(const char* geometry, int flags, allocator allocfunc, report_error errfunc)
{
the_geom.lwgi=0;
- return parse_it(geometry,allocfunc,errfunc);
+ return parse_it(geometry, flags, allocfunc, errfunc);
}
SERIALIZED_LWGEOM *
-parse_lwgi(const char* geometry,allocator allocfunc,report_error errfunc)
+parse_lwgi(const char* geometry, int flags, allocator allocfunc, report_error errfunc)
{
the_geom.lwgi=1;
- return parse_it(geometry,allocfunc,errfunc);
+ return parse_it(geometry, flags, allocfunc, errfunc);
}
void
You are responsible for freeing the returned memory.
*/
-SERIALIZED_LWGEOM* parse_lwg(const char* wkt,allocator allocfunc,report_error errfunc);
-SERIALIZED_LWGEOM* parse_lwgi(const char* wkt,allocator allocfunc,report_error errfunc);
+SERIALIZED_LWGEOM* parse_lwg(const char* wkt, int flags, allocator allocfunc,report_error errfunc);
+SERIALIZED_LWGEOM* parse_lwgi(const char* wkt, int flags, allocator allocfunc,report_error errfunc);
char* unparse_WKT(uchar* serialized, allocator alloc,freeor free);
char* unparse_WKB(uchar* serialized, allocator alloc,freeor free, char endian, size_t *outsize, uchar hexform);
int lwg_parse_yyparse(void);
PG_FUNCTION_INFO_V1(LWGEOM_gist_decompress);
Datum LWGEOM_gist_decompress(PG_FUNCTION_ARGS)
{
-#if POSTGIS_DEBUG_LEVEL >= 4
static unsigned int counter2 = 0;
+#if POSTGIS_DEBUG_LEVEL >= 4
counter2++;
#endif
POSTGIS_DEBUGF(2, "GIST: LWGEOM_gist_decompress called %i",counter2);
PG_LWGEOM *ret;
/* will handle both HEXEWKB and EWKT */
- serialized_lwgeom = serialized_lwgeom_from_ewkt(str);
+ serialized_lwgeom = serialized_lwgeom_from_ewkt(str, PARSER_CHECK_ALL);
lwgeom = lwgeom_deserialize(serialized_lwgeom->lwgeom);
ret = pglwgeom_serialize(lwgeom);
POSTGIS_DEBUGF(3, "in parse_WKT_lwgeom with input: '%s'",wkt);
- serialized_lwgeom = serialized_lwgeom_from_ewkt(wkt);
+ serialized_lwgeom = serialized_lwgeom_from_ewkt(wkt, PARSER_CHECK_ALL);
lwgeom = lwgeom_deserialize(serialized_lwgeom->lwgeom);
ret = pglwgeom_serialize(lwgeom);
POSTGIS_DEBUGF(3, "wkt: [%s]", wkt);
- serialized_lwgeom = serialized_lwgeom_from_ewkt(wkt);
+ serialized_lwgeom = serialized_lwgeom_from_ewkt(wkt, PARSER_CHECK_ALL);
lwgeom = lwgeom_deserialize(serialized_lwgeom->lwgeom);
if ( lwgeom->SRID != -1 || TYPE_GETZM(lwgeom->type) != 0 )
}
hexewkb[hexewkblen] = '\0';
- serialized_lwgeom = serialized_lwgeom_from_ewkt(hexewkb);
+ serialized_lwgeom = serialized_lwgeom_from_ewkt(hexewkb, PARSER_CHECK_ALL);
ret = (PG_LWGEOM *)palloc(serialized_lwgeom->size + VARHDRSZ);
SET_VARSIZE(ret, serialized_lwgeom->size + VARHDRSZ);