On Thu, Aug 23, 2012 at 3:27 PM, Darryl L. Pierce <[email protected]>wrote:
> In working on the stable Ruby APIs on top of Swig I've hit an
> interesting problem with this API.
>
> The stable API for this is Qpid::Proton::get_message_data(msg, size)
> and returns an array that is the size of the string and the string
> itself, respectively. The swig wrapper currently is:
>
> %rename (pn_message_save) wrap_pn_message_save;
> %inline %{
> int wrap_pn_message_save(pn_message_t *msg, char *OUTPUT, size_t
> *OUTPUT_SIZE) {
> ssize_t sz = pn_message_save(msg, OUTPUT, OUTPUT_SIZE);
>
> if (sz < 0) *OUTPUT_SIZE = 0;
> return *OUTPUT_SIZE;
> }
> %}
> %ignore pn_message_save;
>
> One test I've written is to generate random strings of various lengths,
> throwing them at the message and then getting them back to verify they
> were saved properly. And what I'm seeing happening is that, at certain
> lengths (2 specifically), the APIs fail.
>
> Initially, when the length hits either 129 or 257 bytes, the string
> returned does not match the string submitted. If it gets past 129 then
> it ALWAYS fails at 257 bytes. And if I tell it to ignore anything before
> 257 then it always fails at 513.
>
> Not sure on first glance what's causing the problem.
>
I'm a little confused by what you're trying to do with the wrapper. This is
what I have for the wrapper in my ruby.i:
int pn_message_save(pn_message_t *msg, char *OUTPUT, size_t *OUTPUT_SIZE);
%ignore pn_message_save;
I believe this is all that is necessary since the standard typemaps should
pick up on OUTPUT and OUTPUT_SIZE and just do the right thing.
Regardless, I think the cause for the issue is that your wrapper function
is assuming pn_message_save returns a signed size, but actually it returns
an int that is 0 on success or an error code on failure:
int pn_message_save(pn_message_t *message, char *data, size_t *size);
On success the size of the output data is stored into *size. (I'll add some
API-doc for this.)
As an aside in looking at this I noticed that there is some duplication
between the php, ruby, and python files that could be consolidated into the
cproton.i. I think this particular declaration is part of that duplication
unless there is some reason I'm missing that it has to be different for
ruby.
--Rafael