1 /* 2 * Copyright (C) 2007 Armin Burgmeier <armin@openismus.com> 3 * Copyright (C) 2007 Murray Cumming <murrayc@murryac.com> 4 * Copyright (C) 2007 - 2011 Vivien Malerba <malerba@gnome-db.org> 5 * Copyright (C) 2010 David King <davidk@openismus.com> 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the 19 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 20 * Boston, MA 02110-1301, USA. 21 */ 22 23 /* 24 * BLOB (Binary Large OBject) handling functions specific to each provider. 25 */ 26 27 #include "gda-blob-op.h" 28 #include "gda-value.h" 29 30 #define PARENT_TYPE G_TYPE_OBJECT 31 #define CLASS(blob) (GDA_BLOB_OP_CLASS (G_OBJECT_GET_CLASS (blob))) 32 static void gda_blob_op_class_init (GdaBlobOpClass *klass); 33 static void gda_blob_op_init (GdaBlobOp *provider, GdaBlobOpClass *klass); 34 static void gda_blob_op_finalize (GObject *object); 35 36 static GObjectClass *parent_class = NULL; 37 38 GType 39 gda_blob_op_get_type (void) 40 { 41 static GType type = 0; 42 43 if (G_UNLIKELY (type == 0)) { 44 static GMutex registering; 45 static const GTypeInfo info = { 46 sizeof (GdaBlobOpClass), 47 (GBaseInitFunc) NULL, 48 (GBaseFinalizeFunc) NULL, 49 (GClassInitFunc) gda_blob_op_class_init, 50 NULL, 51 NULL, 52 sizeof (GdaBlobOp), 53 0, 54 (GInstanceInitFunc) gda_blob_op_init, 55 0 56 }; 57 58 g_mutex_lock (®istering); 59 if (type == 0) 60 type = g_type_register_static (PARENT_TYPE, "GdaBlobOp", &info, G_TYPE_FLAG_ABSTRACT); 61 g_mutex_unlock (®istering); 62 } 63 return type; 64 } 65 66 static void 67 gda_blob_op_class_init (GdaBlobOpClass *klass) 68 { 69 GObjectClass *object_class = G_OBJECT_CLASS (klass); 70 71 parent_class = g_type_class_peek_parent (klass); 72 73 object_class->finalize = gda_blob_op_finalize; 74 klass->get_length = NULL; 75 klass->read = NULL; 76 klass->write = NULL; 77 } 78 79 static void 80 gda_blob_op_init (G_GNUC_UNUSED GdaBlobOp *provider, G_GNUC_UNUSED GdaBlobOpClass *klass) 81 { 82 83 } 84 85 static void 86 gda_blob_op_finalize (GObject *object) 87 { 88 /* chain to parent class */ 89 parent_class->finalize (object); 90 } 91 92 93 /** 94 * gda_blob_op_get_length: 95 * @op: an existing #GdaBlobOp 96 * 97 * Returns: the length of the blob in bytes. In case of error, -1 is returned and the 98 * provider should have added an error (a #GdaConnectionEvent) to the connection. 99 */ 100 glong 101 gda_blob_op_get_length (GdaBlobOp *op) 102 { 103 g_return_val_if_fail (GDA_IS_BLOB_OP (op), -1); 104 105 if (CLASS (op)->get_length != NULL) 106 return CLASS (op)->get_length (op); 107 else 108 return -1; 109 } 110 111 /** 112 * gda_blob_op_read: 113 * @op: a #GdaBlobOp 114 * @blob: a #GdaBlob to read data to 115 * @offset: offset to read from the start of the blob (starts at 0) 116 * @size: maximum number of bytes to read. 117 * 118 * Reads a chunk of bytes from the BLOB accessible through @op into @blob. 119 * 120 * Returns: the number of bytes actually read. In case of error, -1 is returned and the 121 * provider should have added an error to the connection. 122 */ 123 glong 124 gda_blob_op_read (GdaBlobOp *op, GdaBlob *blob, glong offset, glong size) 125 { 126 g_return_val_if_fail (GDA_IS_BLOB_OP (op), -1); 127 128 if (CLASS (op)->read != NULL) 129 return CLASS (op)->read (op, blob, offset, size); 130 else 131 return -1; 132 } 133 134 /** 135 * gda_blob_op_read_all: 136 * @op: a #GdaBlobOp 137 * @blob: a #GdaBlob to read data to 138 * 139 * Reads the whole contents of the blob manipulated by @op into @blob 140 * 141 * Returns: TRUE if @blob->data contains the whole BLOB manipulated by @op 142 */ 143 gboolean 144 gda_blob_op_read_all (GdaBlobOp *op, GdaBlob *blob) 145 { 146 glong len; 147 g_return_val_if_fail (GDA_IS_BLOB_OP (op), FALSE); 148 g_return_val_if_fail (blob, FALSE); 149 150 len = gda_blob_op_get_length (blob->op); 151 if (len >= 0) 152 return (gda_blob_op_read (blob->op, blob, 0, len) < 0) ? FALSE : TRUE; 153 else 154 return FALSE; 155 } 156 157 /** 158 * gda_blob_op_write: 159 * @op: a #GdaBlobOp 160 * @blob: a #GdaBlob which contains the data to write 161 * @offset: offset to write from the start of the blob (starts at 0) 162 * 163 * Writes a chunk of bytes from a @blob to the BLOB accessible through @op, @blob is unchanged after 164 * this call. 165 * 166 * If @blob has an associated #GdaBlobOp (ie. if @blob->op is not %NULL) then the data to be written 167 * using @op is the data fetched using @blob->op. 168 * 169 * Returns: the number of bytes written. In case of error, -1 is returned and the 170 * provider should have added an error to the connection. 171 */ 172 glong 173 gda_blob_op_write (GdaBlobOp *op, GdaBlob *blob, glong offset) 174 { 175 g_return_val_if_fail (GDA_IS_BLOB_OP (op), -1); 176 177 if (CLASS (op)->write != NULL) 178 return CLASS (op)->write (op, blob, offset); 179 else 180 return -1; 181 } 182 183 /** 184 * gda_blob_op_write_all: 185 * @op: a #GdaBlobOp 186 * @blob: a #GdaBlob which contains the data to write 187 * 188 * Writes the whole contents of @blob into the blob manipulated by @op. If necessary the resulting 189 * blob is truncated from its previous length. 190 * 191 * Returns: TRUE on success 192 */ 193 gboolean 194 gda_blob_op_write_all (GdaBlobOp *op, GdaBlob *blob) 195 { 196 g_return_val_if_fail (GDA_IS_BLOB_OP (op), FALSE); 197 198 if (CLASS (op)->write_all != NULL) 199 return CLASS (op)->write_all (op, blob); 200 else { 201 glong res; 202 res = gda_blob_op_write (op, blob, 0); 203 return res >= 0 ? TRUE : FALSE; 204 } 205 } 206