On Tue, 2015-04-07 at 17:57 -0400, Rafael Schloming wrote: > Maybe I'm not following something, but I don't see how passing around > allocation functions actually solves any ownership problems. I would think > the ownership problems come from pn_data_t holding onto a pointer > regardless of whether that pointer was gotten from malloc or from a > callback. I'm assuming you want to be able to do something like use a > pn_data_t that is owned by one thread to encode into a buffer and pass that > buffer over to another thread. How does passing in a bunch of allocators > help with this? If the pn_data_t holds a pointer to whatever those > allocators return, then aren't you going to have ownership issues no matter > what? > > To answer Bozzo's original question, I think that it's good to keep the > encoder/decoder decoupled from the buffer for a number of reasons. In > addition to the ownership issues that Alan points out, the encoded data may > have a different lifecycle from the pn_data_t that created it for non > thread related reasons, or you may simply want to encode directly into a > frame buffer and avoid an extra copy. > > If the goal here is simply to provide a convenient way to avoid having to > repeat the resizing loop then I would suggest simply providing a > convenience API that accepts a growable buffer of some sort. This provides > both convenience and avoids ownership issues with holding pointers. I'm > thinking something along the lines of: > > pn_data_t data = ...; > pn_string/buffer_t buf = ...; > pn_data_encode_conveniently(data, buf); // obviously needs a better name > > It is perhaps not *quite* as convenient in the minimal case as pn_data_t > holding the buffer internally, but it is an improvement in general and > probably simpler than having to mess with function pointers in the case > where the buffer's lifecycle is independent from the pn_data_t. (Not that I > really understand how that would work anyways.)
The issue is that we need buffer growth AND control over allocation. pn_buffer_t forces use of malloc/free/realloc. That won't help if you're trying to get the data into a buffer allocated by Go for example. I agree a growable buffer type is a nicer API than raw function pointers, but the buffer type itself would need to use function pointers so we can replace the functions used for alloc/free/realloc.
