postgis/liblwgeom/cunit/cu_out_twkb.c
Raúl Marín 591d0c69ba Revert incorrect "Optimize varlena returning functions"
This reverts commit 0696fa4669.

I'm not sure what I did there, it seems like I pushed smaller commits
instead of a squashed one, and then did a revert that undid everything.

References #4623
2020-04-28 19:13:38 +02:00

289 lines
8.3 KiB
C

/**********************************************************************
*
* PostGIS - Spatial Types for PostgreSQL
* http://postgis.net
* Copyright 2014 Nicklas Avén
*
* This is free software; you can redistribute and/or modify it under
* the terms of the GNU General Public Licence. See the COPYING file.
*
**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "CUnit/Basic.h"
#include "liblwgeom_internal.h"
#include "cu_tester.h"
/*
** Global variable to hold hex TWKB strings
*/
static char *s;
static char *w;
/*
** The suite initialization function.
** Create any re-used objects.
*/
static int init_twkb_out_suite(void)
{
s = NULL;
w = NULL;
return 0;
}
/*
** The suite cleanup function.
** Frees any global objects.
*/
static int clean_twkb_out_suite(void)
{
if (s) free(s);
if (w) free(w);
s = NULL;
w = NULL;
return 0;
}
/*
** Creating an input TWKB from a wkt string
*/
static void cu_twkb(char *wkt, int8_t prec_xy, int8_t prec_z, int8_t prec_m, uint8_t variant)
{
LWGEOM *g = lwgeom_from_wkt(wkt, LW_PARSER_CHECK_NONE);
if ( ! g ) lwnotice("input wkt is invalid: %s", wkt);
lwvarlena_t *twkb = lwgeom_to_twkb(g, variant, prec_xy, prec_z, prec_m);
lwgeom_free(g);
if ( s ) free(s);
s = hexbytes_from_bytes((uint8_t *)twkb->data, LWSIZE_GET(twkb->size) - LWVARHDRSZ);
free(twkb);
}
/*
** Creating an input TWKB from a wkt string
*/
static void cu_twkb_idlist(char *wkt, int64_t *idlist, int8_t prec_xy, int8_t prec_z, int8_t prec_m, uint8_t variant)
{
LWGEOM *g = lwgeom_from_wkt(wkt, LW_PARSER_CHECK_NONE);
LWGEOM *g_b;
if ( ! g ) lwnotice("input wkt is invalid: %s", wkt);
lwvarlena_t *twkb = lwgeom_to_twkb_with_idlist(g, idlist, variant, prec_xy, prec_z, prec_m);
lwgeom_free(g);
if ( s ) free(s);
if ( w ) free(w);
s = hexbytes_from_bytes((uint8_t *)twkb->data, LWSIZE_GET(twkb->size) - LWVARHDRSZ);
g_b = lwgeom_from_twkb((uint8_t *)twkb->data, LWSIZE_GET(twkb->size) - LWVARHDRSZ, LW_PARSER_CHECK_NONE);
w = lwgeom_to_ewkt(g_b);
lwgeom_free(g_b);
free(twkb);
}
static void test_twkb_out_point(void)
{
cu_twkb("POINT EMPTY", 0, 0, 0, 0);
CU_ASSERT_STRING_EQUAL(s,"0110");
cu_twkb("POINT(0 0)", 0, 0, 0, 0);
CU_ASSERT_STRING_EQUAL(s,"01000000");
cu_twkb("POINT(0 0 0 0)", 0, 0, 0, 0);
CU_ASSERT_STRING_EQUAL(s,"01080300000000");
/* Point with bounding box */
cu_twkb("POINT(0 0)", 0, 0, 0, TWKB_BBOX);
CU_ASSERT_STRING_EQUAL(s,"0101000000000000");
// printf("TWKB: %s\n",s);
/* Adding a size paramters to X/Y */
cu_twkb("POINT(0 0)", 0, 0, 0, TWKB_SIZE);
CU_ASSERT_STRING_EQUAL(s,"0102020000");
/* Adding a size paramters to X/Y/M */
cu_twkb("POINTM(0 0 0)", 0, 0, 0, TWKB_SIZE);
CU_ASSERT_STRING_EQUAL(s,"010A0203000000");
/* Adding a size paramters to X/Y/Z/M */
cu_twkb("POINT(0 0 0 0)", 0, 0, 0, TWKB_SIZE);
CU_ASSERT_STRING_EQUAL(s,"010A030400000000");
/* Since the third dimension is Z it shall get a precision of 1 decimal (third argument) */
cu_twkb("POINTZ(1 1 1)", 0,1,2, 0);
CU_ASSERT_STRING_EQUAL(s,"010845020214");
/* Since the third dimension is M it shall get a precision of 2 decimals (fourth argument) */
cu_twkb("POINTM(1 1 1)", 0,1,2, 0);
// printf("\n%s\n", s);
CU_ASSERT_STRING_EQUAL(s,"0108460202C801");
}
static void test_twkb_out_linestring(void)
{
cu_twkb("LINESTRING(0 0,1 1)", 0, 0, 0, 0);
CU_ASSERT_STRING_EQUAL(s,"02000200000202");
// printf("TWKB: %s\n",s);
cu_twkb("LINESTRING(0 0 1,1 1 2,2 2 3)", 0, 0, 0, 0);
CU_ASSERT_STRING_EQUAL(s,"02080103000002020202020202");
// printf("TWKB: %s\n",s);
/* Line with bounding box */
cu_twkb("LINESTRING(0 0,1 1,2 2)", 0, 0, 0, TWKB_BBOX);
CU_ASSERT_STRING_EQUAL(s,"02010004000403000002020202");
// printf("TWKB: %s\n",s);
cu_twkb("LINESTRING EMPTY", 0, 0, 0, 0);
CU_ASSERT_STRING_EQUAL(s,"0210");
// printf("TWKB: %s\n",s);
}
static void test_twkb_out_polygon(void)
{
cu_twkb("SRID=4;POLYGON((0 0 0, 0 1 0,1 1 0,1 0 0, 0 0 0))", 0, 0, 0, 0);
CU_ASSERT_STRING_EQUAL(s,"0308010105000000000200020000000100010000");
// printf("TWKB: %s\n",s);
cu_twkb("SRID=14;POLYGON((0 0 0 1, 0 1 0 2,1 1 0 3,1 0 0 4, 0 0 0 5))", 0, 0, 0, 0);
CU_ASSERT_STRING_EQUAL(s,"03080301050000000200020002020000020001000201000002");
// printf("TWKB: %s\n",s);
cu_twkb("POLYGON EMPTY", 0, 0, 0, 0);
CU_ASSERT_STRING_EQUAL(s,"0310");
// printf("TWKB: %s\n",s);
}
static void test_twkb_out_multipoint(void)
{
cu_twkb("MULTIPOINT(0 0 0, 0 1 0,1 1 0,1 0 0, 0 0 0)", 0, 0, 0, 0);
CU_ASSERT_STRING_EQUAL(s,"04080105000000000200020000000100010000");
cu_twkb("MULTIPOINT(0 0 0, 0.26794919243112270647255365849413 1 3)",7 ,7 , 0, 0);
//printf("WKB: %s",s);
CU_ASSERT_STRING_EQUAL(s,"E4081D02000000888BC70280DAC409808ECE1C");
// printf("TWKB: %s\n",s);
}
static void test_twkb_out_multilinestring(void) {}
static void test_twkb_out_multipolygon(void)
{
cu_twkb("MULTIPOLYGON(((0 0 0, 0 1 0,1 1 0,1 0 0, 0 0 0)),((-1 -1 0,-1 2 0,2 2 0,2 -1 0,-1 -1 0),(0 0 0, 0 1 0,1 1 0,1 0 0, 0 0 0)))", 0, 0, 0, 0);
CU_ASSERT_STRING_EQUAL(s,"060801020105000000000200020000000100010000020501010000060006000000050005000005020200000200020000000100010000");
}
static void test_twkb_out_collection(void)
{
cu_twkb("GEOMETRYCOLLECTION(LINESTRING(1 1, 2 2), LINESTRING(3 3, 4 4), LINESTRING(5 5, 6 6))", 0, 0, 0, 0);
// printf("TWKB: %s\n",s);
CU_ASSERT_STRING_EQUAL(s,"07000302000202020202020002060602020200020A0A0202");
cu_twkb("GEOMETRYCOLLECTION(POLYGON((0 0 0, 0 1 0,1 1 0,1 0 0, 0 0 0)),POINT(1 1 1))", 0, 0, 0, 0);
// printf("TWKB: %s\n",s);
CU_ASSERT_STRING_EQUAL(s,"070801020308010105000000000200020000000100010000010801020202");
cu_twkb("GEOMETRYCOLLECTION EMPTY", 0, 0, 0, 0);
CU_ASSERT_STRING_EQUAL(s,"0710");
}
static void test_twkb_out_idlist(void)
{
int64_t idlist[2];
idlist[0] = 2;
idlist[1] = 4;
cu_twkb_idlist("MULTIPOINT(1 1, 0 0)",idlist, 0, 0, 0, 0);
// printf("TWKB: %s\n",s);
// printf("WKT: %s\n",w);
CU_ASSERT_STRING_EQUAL(s,"040402040802020101");
CU_ASSERT_STRING_EQUAL(w,"MULTIPOINT(1 1,0 0)");
/*
04 06 multipoint, size/idlist
07 size 7 bytes
02 two geometries
0408 idlist (2, 4)
0202 first point @ 1,1
0101 second point offset -1,-1
*/
idlist[0] = 2;
idlist[1] = 4;
cu_twkb_idlist("MULTIPOINT(1 1, 0 0)",idlist, 0, 0, 0, TWKB_SIZE);
// printf("TWKB: %s\n",s);
// printf("WKT: %s\n",w);
CU_ASSERT_STRING_EQUAL(s,"04060702040802020101");
CU_ASSERT_STRING_EQUAL(w,"MULTIPOINT(1 1,0 0)");
/*
04 07 multipoint, bbox/size/idlist
0B size 11 bytes
00020002 bbox x(0,1), y(0,1)
02 two geometries
0408 idlist (2,4)
0202 first point @ 1,1
0101 seconds point offset -1,-1
*/
idlist[0] = 2;
idlist[1] = 4;
cu_twkb_idlist("MULTIPOINT(1 1, 0 0)",idlist, 0, 0, 0, TWKB_SIZE | TWKB_BBOX);
// printf("TWKB: %s\n",s);
// printf("WKT: %s\n",w);
CU_ASSERT_STRING_EQUAL(s,"04070B0002000202040802020101");
CU_ASSERT_STRING_EQUAL(w,"MULTIPOINT(1 1,0 0)");
/*
0704 geometrycollection, idlist
02 two geometries
0408 idlist (2,4)
01000202 first point (type, meta, x, y)
01000000 second point (type, meta, x, y)
*/
idlist[0] = 2;
idlist[1] = 4;
cu_twkb_idlist("GEOMETRYCOLLECTION(POINT(1 1),POINT(0 0))",idlist, 0, 0, 0, 0);
// printf("TWKB: %s\n",s);
CU_ASSERT_STRING_EQUAL(s,"07040204080100020201000000");
CU_ASSERT_STRING_EQUAL(w,"GEOMETRYCOLLECTION(POINT(1 1),POINT(0 0))");
/*
0706 geometrycollection, size/idlist
0D size, 13 bytes
02 two geometries
0408 idlist (2,4)
0102020202 first point (type, meta, size, x, y)
0102020000 second point (type, meta, size, x, y)
*/
idlist[0] = 2;
idlist[1] = 4;
cu_twkb_idlist("GEOMETRYCOLLECTION(POINT(1 1),POINT(0 0))",idlist, 0, 0, 0, TWKB_SIZE);
// printf("TWKB: %s\n",s);
CU_ASSERT_STRING_EQUAL(s,"07060D02040801020202020102020000");
CU_ASSERT_STRING_EQUAL(w,"GEOMETRYCOLLECTION(POINT(1 1),POINT(0 0))");
}
/*
** Used by test harness to register the tests in this file.
*/
void twkb_out_suite_setup(void);
void twkb_out_suite_setup(void)
{
CU_pSuite suite = CU_add_suite("twkb_output", init_twkb_out_suite, clean_twkb_out_suite);
PG_ADD_TEST(suite, test_twkb_out_point);
PG_ADD_TEST(suite, test_twkb_out_linestring);
PG_ADD_TEST(suite, test_twkb_out_polygon);
PG_ADD_TEST(suite, test_twkb_out_multipoint);
PG_ADD_TEST(suite, test_twkb_out_multilinestring);
PG_ADD_TEST(suite, test_twkb_out_multipolygon);
PG_ADD_TEST(suite, test_twkb_out_collection);
PG_ADD_TEST(suite, test_twkb_out_idlist);
}