1 /* 2 * Copyright (C) 2006 - 2013 Vivien Malerba <malerba@gnome-db.org> 3 * Copyright (C) 2007 Armin Burgmeier <armin@openismus.com> 4 * Copyright (C) 2007 Murray Cumming <murrayc@murrayc.com> 5 * Copyright (C) 2009 Bas Driessen <bas.driessen@xobas.com> 6 * Copyright (C) 2010 David King <davidk@openismus.com> 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the 20 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 21 * Boston, MA 02110-1301, USA. 22 */ 23 24 #include "gda-sqlite-handler-bin.h" 25 #include <string.h> 26 #include <glib/gi18n-lib.h> 27 #include <libgda/gda-server-provider.h> 28 #include <libgda/gda-util.h> 29 30 static void gda_sqlite_handler_bin_class_init (GdaSqliteHandlerBinClass * class); 31 static void gda_sqlite_handler_bin_init (GdaSqliteHandlerBin * wid); 32 static void gda_sqlite_handler_bin_dispose (GObject * object); 33 34 35 /* GdaDataHandler interface */ 36 static void gda_sqlite_handler_bin_data_handler_init (GdaDataHandlerIface *iface); 37 static gchar *gda_sqlite_handler_bin_get_sql_from_value (GdaDataHandler *dh, const GValue *value); 38 static gchar *gda_sqlite_handler_bin_get_str_from_value (GdaDataHandler *dh, const GValue *value); 39 static GValue *gda_sqlite_handler_bin_get_value_from_sql (GdaDataHandler *dh, const gchar *sql, 40 GType type); 41 static GValue *gda_sqlite_handler_bin_get_value_from_str (GdaDataHandler *dh, const gchar *sql, 42 GType type); 43 static gboolean gda_sqlite_handler_bin_accepts_g_type (GdaDataHandler * dh, GType type); 44 45 static const gchar *gda_sqlite_handler_bin_get_descr (GdaDataHandler *dh); 46 47 struct _GdaSqliteHandlerBinPriv { 48 gchar dummy; 49 }; 50 51 /* get a pointer to the parents to be able to call their destructor */ 52 static GObjectClass *parent_class = NULL; 53 54 GType 55 _gda_sqlite_handler_bin_get_type (void) 56 { 57 static GType type = 0; 58 59 if (G_UNLIKELY (type == 0)) { 60 static GMutex registering; 61 static const GTypeInfo info = { 62 sizeof (GdaSqliteHandlerBinClass), 63 (GBaseInitFunc) NULL, 64 (GBaseFinalizeFunc) NULL, 65 (GClassInitFunc) gda_sqlite_handler_bin_class_init, 66 NULL, 67 NULL, 68 sizeof (GdaSqliteHandlerBin), 69 0, 70 (GInstanceInitFunc) gda_sqlite_handler_bin_init, 71 NULL 72 }; 73 74 static const GInterfaceInfo data_entry_info = { 75 (GInterfaceInitFunc) gda_sqlite_handler_bin_data_handler_init, 76 NULL, 77 NULL 78 }; 79 80 g_mutex_lock (®istering); 81 if (type == 0) { 82 type = g_type_register_static (G_TYPE_OBJECT, CLASS_PREFIX "HandlerBin", &info, 0); 83 g_type_add_interface_static (type, GDA_TYPE_DATA_HANDLER, &data_entry_info); 84 } 85 g_mutex_unlock (®istering); 86 } 87 return type; 88 } 89 90 static void 91 gda_sqlite_handler_bin_data_handler_init (GdaDataHandlerIface *iface) 92 { 93 iface->get_sql_from_value = gda_sqlite_handler_bin_get_sql_from_value; 94 iface->get_str_from_value = gda_sqlite_handler_bin_get_str_from_value; 95 iface->get_value_from_sql = gda_sqlite_handler_bin_get_value_from_sql; 96 iface->get_value_from_str = gda_sqlite_handler_bin_get_value_from_str; 97 iface->get_sane_init_value = NULL; 98 iface->accepts_g_type = gda_sqlite_handler_bin_accepts_g_type; 99 iface->get_descr = gda_sqlite_handler_bin_get_descr; 100 } 101 102 103 static void 104 gda_sqlite_handler_bin_class_init (GdaSqliteHandlerBinClass * class) 105 { 106 GObjectClass *object_class = G_OBJECT_CLASS (class); 107 108 parent_class = g_type_class_peek_parent (class); 109 110 object_class->dispose = gda_sqlite_handler_bin_dispose; 111 } 112 113 static void 114 gda_sqlite_handler_bin_init (GdaSqliteHandlerBin * hdl) 115 { 116 /* Private structure */ 117 hdl->priv = g_new0 (GdaSqliteHandlerBinPriv, 1); 118 g_object_set_data (G_OBJECT (hdl), "name", "SqliteBin"); 119 g_object_set_data (G_OBJECT (hdl), "descr", _("SQLite binary representation")); 120 } 121 122 static void 123 gda_sqlite_handler_bin_dispose (GObject * object) 124 { 125 GdaSqliteHandlerBin *hdl; 126 127 g_return_if_fail (object != NULL); 128 g_return_if_fail (GDA_IS_SQLITE_HANDLER_BIN (object)); 129 130 hdl = GDA_SQLITE_HANDLER_BIN (object); 131 132 if (hdl->priv) { 133 g_free (hdl->priv); 134 hdl->priv = NULL; 135 } 136 137 /* for the parent class */ 138 parent_class->dispose (object); 139 } 140 141 /** 142 * _gda_sqlite_handler_bin_new 143 * 144 * Creates a data handler for binary values 145 * 146 * Returns: the new object 147 */ 148 GdaDataHandler * 149 _gda_sqlite_handler_bin_new (void) 150 { 151 GObject *obj; 152 153 obj = g_object_new (GDA_TYPE_SQLITE_HANDLER_BIN, NULL); 154 155 return (GdaDataHandler *) obj; 156 } 157 158 static gchar * 159 gda_sqlite_handler_bin_get_sql_from_value (G_GNUC_UNUSED GdaDataHandler *iface, const GValue *value) 160 { 161 g_assert (value); 162 163 gchar *retval; 164 GdaBinary *bin; 165 gint i; 166 167 bin = (GdaBinary *) gda_value_get_binary ((GValue *) value); 168 retval = g_new0 (gchar, bin->binary_length * 2 + 4); 169 retval [0] = 'x'; 170 retval [1] = '\''; 171 for (i = 0; i < bin->binary_length; i++) { 172 guchar *ptr; 173 174 ptr = bin->data + i; 175 if ((*ptr >> 4) <= 9) 176 retval [2*i + 2] = (*ptr >> 4) + '0'; 177 else 178 retval [2*i + 2] = (*ptr >> 4) + 'A' - 10; 179 if ((*ptr & 0xF) <= 9) 180 retval [2*i + 3] = (*ptr & 0xF) + '0'; 181 else 182 retval [2*i + 3] = (*ptr & 0xF) + 'A' - 10; 183 } 184 retval [bin->binary_length * 2 + 2] = '\''; 185 186 return retval; 187 } 188 189 static gchar * 190 gda_sqlite_handler_bin_get_str_from_value (G_GNUC_UNUSED GdaDataHandler *iface, const GValue *value) 191 { 192 g_assert (value); 193 194 gchar *retval; 195 GdaBinary *bin; 196 gint i; 197 198 bin = (GdaBinary *) gda_value_get_binary ((GValue *) value); 199 retval = g_new0 (gchar, bin->binary_length * 2 + 1); 200 for (i = 0; i < bin->binary_length; i++) { 201 guchar *ptr; 202 203 ptr = bin->data + i; 204 if ((*ptr >> 4) <= 9) 205 retval [2*i] = (*ptr >> 4) + '0'; 206 else 207 retval [2*i] = (*ptr >> 4) + 'A' - 10; 208 if ((*ptr & 0xF) <= 9) 209 retval [2*i + 1] = (*ptr & 0xF) + '0'; 210 else 211 retval [2*i + 1] = (*ptr & 0xF) + 'A' - 10; 212 } 213 214 return retval; 215 } 216 217 static int hex_to_int (int h) { 218 if (h >= '0' && h <= '9') 219 return h - '0'; 220 else if (h >= 'a' && h <= 'f') 221 return h - 'a' + 10; 222 else { 223 if (h >= 'A' && h <= 'F') 224 return h - 'A' + 10; 225 else 226 return 0; 227 } 228 } 229 230 static GValue * 231 gda_sqlite_handler_bin_get_value_from_sql (G_GNUC_UNUSED GdaDataHandler *iface, const gchar *sql, GType type) 232 { 233 g_assert (sql); 234 GValue *value = NULL; 235 236 if (*sql) { 237 gint n = strlen (sql); 238 if ((n >= 3) && 239 ! ((n-3) % 2) && 240 ((sql[0] == 'x') || (sql[0] == 'X')) && 241 (sql[1] == '\'') && 242 (sql[n] == '\'')) { 243 GdaBinary *bin; 244 245 bin = g_new0 (GdaBinary, 1); 246 if (n > 3) { 247 gint i; 248 bin->data = g_new0 (guchar, (n-3)/2); 249 for (i = 2; i < n-1; i += 2) 250 bin->data [i/2 - 1] = (hex_to_int (sql[i]) << 4) | hex_to_int (sql [i+1]); 251 bin->binary_length = n-3; 252 } 253 254 value = gda_value_new (GDA_TYPE_BINARY); 255 gda_value_take_binary (value, bin); 256 } 257 } 258 259 return value; 260 } 261 262 static GValue * 263 gda_sqlite_handler_bin_get_value_from_str (G_GNUC_UNUSED GdaDataHandler *iface, const gchar *str, GType type) 264 { 265 g_assert (str); 266 267 GValue *value = NULL; 268 269 if (*str) { 270 gint n = strlen (str); 271 if (! (n % 2)) { 272 GdaBinary *bin; 273 274 bin = g_new0 (GdaBinary, 1); 275 if (n > 0) { 276 gint i; 277 bin->data = g_new0 (guchar, n/2); 278 for (i = 0; i < n; i += 2) 279 bin->data [i/2] = (hex_to_int (str[i]) << 4) | hex_to_int (str [i+1]); 280 bin->binary_length = n; 281 } 282 283 value = gda_value_new (GDA_TYPE_BINARY); 284 gda_value_take_binary (value, bin); 285 } 286 } 287 else { 288 GdaBinary *bin; 289 bin = gda_string_to_binary (str); 290 value = gda_value_new (GDA_TYPE_BINARY); 291 gda_value_take_binary (value, bin); 292 } 293 294 return value; 295 } 296 297 static gboolean 298 gda_sqlite_handler_bin_accepts_g_type (G_GNUC_UNUSED GdaDataHandler *iface, GType type) 299 { 300 g_assert (iface); 301 return type == GDA_TYPE_BINARY ? TRUE : FALSE; 302 } 303 304 static const gchar * 305 gda_sqlite_handler_bin_get_descr (GdaDataHandler *iface) 306 { 307 g_return_val_if_fail (GDA_IS_SQLITE_HANDLER_BIN (iface), NULL); 308 return g_object_get_data (G_OBJECT (iface), "descr"); 309 } 310