Re: [Vala] Problems retrieving binary data from a sqlite3 database BLOB column



Btw, C-code shows that preallocating array is pointless here (and, I
think, it is OK and obvious from the side of how pointers and
assigning work): assigning one array to another lead to first array is
freed (data = (g_free (data), NULL);) and pointer to new array
assigned to old variable. In this situation array returned from the
column_blob need to be copied to 'data' (not assigned to), or 'data'
array should be initialized with existing array and size, but, AFAIK,
there is no way how express both in terms of current Vala syntax.

I think that something like Cocoa's (just for example) [[NSData alloc]
initWithBytes: length:] initialization will be great for situations
like this.

Also, sqlite documentation says that sqlite3_column_blob() should be
followed by sqlite3_column_bytes(), not vice versa— you first get
pointer to sqlite-managed data and *then* getting its size and copy it
to your array or do whatever you want.

-- Alexey

On Mon, Jun 27, 2011 at 12:17 AM, Iñigo Serna <inigoserna gmail com> wrote:
Hi Alexandre,

thanks for your comments, I'm closer to the solution.

On 26 June 2011 21:18, Alexandre Rosenfeld
<alexandre rosenfeld gmail com> wrote:
On Sun, Jun 26, 2011 at 13:18, Iñigo Serna <inigoserna gmail com> wrote:

if I include a line like:

uint8[]? data = (uint8[]) stmt.column_blob(3);

it's translated as next C code:

_tmp11_ = (_tmp10_ = (guint8*) _tmp9_, (_tmp10_ == NULL) ? ((gpointer)
_tmp10_) : _vala_array_dup3 (_tmp10_, -1));

I had this problem a lot of times before I realized that Vala arrays must
have a length, but this length is not always retrieved by the API, so Vala
has no idea of the size of the array returned from Sqlite. The -1 ilustrated
at the C code shows this, because Vala thinks this array has -1 items.
You can use stmt.column_bytes to retrieve the number of items in the array
(at this case, the number of bytes) and assign it to the array length such
as:

data.length = stmt.column_bytes(3);

So now Vala knows the size of the array and you can use it anyway you want
to.

Alexandre Rosenfeld

VALA code:
var data = new uint8[stmt.column_bytes(4)];
data = (uint8[]) stmt.column_blob(4);
FileUtils.set_data("image2.png", data);


Generated C code:
gint _tmp8_;
guint8* _tmp9_ = NULL;
guint8* data;
gint data_length1;
gint _data_size_;
void* _tmp10_ = NULL;
guint8* _tmp11_;
guint8* _tmp12_;
_tmp8_ = sqlite3_column_bytes (stmt, 4);
_tmp9_ = g_new0 (guint8, _tmp8_);
data = _tmp9_;
data_length1 = _tmp8_;
data_size_ = data_length1;
_tmp10_ = sqlite3_column_blob (stmt, 4);
_tmp12_ = (_tmp11_ = (guint8*) _tmp10_, (_tmp11_ == NULL) ?
((gpointer) _tmp11_) : _vala_array_dup3 (_tmp11_, -1));
data = (g_free (data), NULL);
data = _tmp12_;
data_length1 = -1;
_data_size_ = data_length1;
g_file_set_contents ("image2.png", (const char*) data, (size_t)
data_length1, &_inner_error_);

And it crash with the same error.


But if I edit C code and change to:
_tmp12_ = (_tmp11_ = (guint8*) _tmp10_, (_tmp11_ == NULL) ?
((gpointer) _tmp11_) : _vala_array_dup3 (_tmp11_, _tmp8_));
...
data_length1 = _tmp8_;

it works correctly.
Am I missing something more? is this a bug in the code generated by vala?


Regards,
Iñigo Serna
_______________________________________________
vala-list mailing list
vala-list gnome org
http://mail.gnome.org/mailman/listinfo/vala-list




-- 
С уважением, Алексей Саварцов



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]