[libgda: 2/5] improve geometric point support
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libgda: 2/5] improve geometric point support
- Date: Mon, 4 Oct 2021 04:14:05 +0000 (UTC)
commit db6bae8a26a180978fed568e422e6df78b6302e7
Author: taozuhong <taozuhong gmail com>
Date: Thu Sep 30 17:02:25 2021 +0800
improve geometric point support
libgda/gda-value.c | 21 ++++++++++
providers/mysql/gda-mysql-recordset.c | 73 ++++++++++++++++++++++++++++++++++-
2 files changed, 93 insertions(+), 1 deletion(-)
---
diff --git a/libgda/gda-value.c b/libgda/gda-value.c
index a68f9f72c..e7b87d1ea 100644
--- a/libgda/gda-value.c
+++ b/libgda/gda-value.c
@@ -192,6 +192,18 @@ set_from_string (GValue *value, const gchar *as_string)
retval = TRUE;
}
}
+ else if (type == GDA_TYPE_GEOMETRIC_POINT) {
+ GdaGeometricPoint* point = gda_geometric_point_new ();
+ as_string++;
+ gda_geometric_point_set_x (point, g_ascii_strtod (as_string, NULL));
+ as_string = strchr (as_string, ',');
+ as_string++;
+ gda_geometric_point_set_y (point, g_ascii_strtod (as_string, NULL));
+
+ gda_value_set_geometric_point (value, point);
+ gda_geometric_point_free (point);
+ retval = TRUE;
+ }
else if (type == GDA_TYPE_NUMERIC) {
GdaNumeric *numeric = gda_numeric_new ();
gda_numeric_set_from_string (numeric, as_string);
@@ -2748,6 +2760,15 @@ gda_value_stringify (const GValue *value)
else
return g_strdup ("NULL");
}
+ else if (g_type_is_a (type, GDA_TYPE_GEOMETRIC_POINT)) {
+ GdaGeometricPoint* point;
+ point = (GdaGeometricPoint*) g_value_get_boxed (value);
+ if (point != NULL) {
+ return g_strdup_printf ("(%.*g,%.*g)", DBL_DIG, point->x, DBL_DIG, point->y);
+ } else {
+ return "NULL";
+ }
+ }
else if (g_type_is_a (type, GDA_TYPE_TIME)) {
GdaTime *gts;
gts = (GdaTime*) g_value_get_boxed (value);
diff --git a/providers/mysql/gda-mysql-recordset.c b/providers/mysql/gda-mysql-recordset.c
index 7aea2fd1e..41917a544 100644
--- a/providers/mysql/gda-mysql-recordset.c
+++ b/providers/mysql/gda-mysql-recordset.c
@@ -278,6 +278,60 @@ gda_mysql_recordset_dispose (GObject *object)
G_OBJECT_CLASS (gda_mysql_recordset_parent_class)->dispose (object);
}
+/**
+ * Read a long from a byte buffer in big endian format.
+ * @param buf must be 8 bytes
+ */
+static gint64 read_long_from_bytes_big_endian(const guchar* buf) {
+ return (gint64) (buf[0] & 0xff) << 56
+ | (gint64) (buf[1] & 0xff) << 48
+ | (gint64) (buf[2] & 0xff) << 40
+ | (gint64) (buf[3] & 0xff) << 32
+ | (gint64) (buf[4] & 0xff) << 24
+ | (gint64) (buf[5] & 0xff) << 16
+ | (gint64) (buf[6] & 0xff) << 8
+ | (gint64) (buf[7] & 0xff);
+}
+/**
+ * Read a long from a byte buffer in little endian format.
+ * @param buf must be 8 bytes
+ */
+static gint64 read_long_from_bytes_little_endian(const guchar* buf) {
+ return (gint64) (buf[7] & 0xff) << 56
+ | (gint64) (buf[6] & 0xff) << 48
+ | (gint64) (buf[5] & 0xff) << 40
+ | (gint64) (buf[4] & 0xff) << 32
+ | (gint64) (buf[3] & 0xff) << 24
+ | (gint64) (buf[2] & 0xff) << 16
+ | (gint64) (buf[1] & 0xff) << 8
+ | (gint64) (buf[0] & 0xff);
+}
+/**
+ * Read a long from a byte buffer in big or little endian format.
+ * @param bigEndian true for big endian, false for little endian
+ * @param buf must be 8 bytes
+ */
+static gdouble read_double_from_bytes(const guchar* buf, gboolean big_endian) {
+ gint64 long_val = big_endian ? read_long_from_bytes_big_endian (buf)
+ : read_long_from_bytes_little_endian (buf);
+ union {
+ gint64 val_long;
+ gdouble val_double;
+ } val_union;
+ val_union.val_long = long_val;
+
+ return (gdouble)val_union.val_double;
+}
+
+/**
+* Read a long from a byte buffer in big or little endian format.
+* @param bigEndian true for big endian, false for little endian
+* @param buf must be 8 bytes length after offset
+*/
+static double read_double_from_bytes_offset(const guchar* buf, gint offset, gboolean big_endian) {
+ return read_double_from_bytes(buf + offset, big_endian);
+}
+
/*
* Public functions
*/
@@ -305,6 +359,9 @@ _gda_mysql_type_to_gda (G_GNUC_UNUSED MysqlConnectionData *cdata,
case MYSQL_TYPE_NEWDECIMAL:
gtype = GDA_TYPE_NUMERIC;
break;
+ case MYSQL_TYPE_GEOMETRY:
+ gtype = GDA_TYPE_GEOMETRIC_POINT;
+ break;
case MYSQL_TYPE_DOUBLE:
gtype = G_TYPE_DOUBLE;
break;
@@ -325,7 +382,6 @@ _gda_mysql_type_to_gda (G_GNUC_UNUSED MysqlConnectionData *cdata,
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_SET:
case MYSQL_TYPE_ENUM:
- case MYSQL_TYPE_GEOMETRY:
case MYSQL_TYPE_BIT:
case MYSQL_TYPE_BLOB:
default:
@@ -949,6 +1005,21 @@ new_row_from_mysql_stmt (GdaMysqlRecordset *imodel, G_GNUC_UNUSED gint rownum, G
gda_numeric_free (numeric);
}
}
+ else if (type == GDA_TYPE_GEOMETRIC_POINT) {
+ if (length > 0) {
+ GdaGeometricPoint* point = gda_geometric_point_new ();
+
+ guchar bytes = (guchar)(*(bvalue + 4));
+ gboolean is_big_endian = (0 == bytes);
+ gdouble x = read_double_from_bytes_offset(bvalue, 9, is_big_endian);
+ gdouble y = read_double_from_bytes_offset(bvalue, 17, is_big_endian);
+ gda_geometric_point_set_x (point, x);
+ gda_geometric_point_set_y (point, y);
+ gda_value_set_geometric_point (value, point);
+ // g_warning("Point: %s", gda_value_stringify(value));
+ gda_geometric_point_free (point);
+ }
+ }
else if (type == G_TYPE_DOUBLE) {
if (length > 0)
g_value_set_double (value, g_ascii_strtod (bvalue, NULL));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]