Subject: Re: API tweak request

Re: API tweak request

From: John Engelhart <john.engelhart_at_gmail.com>
Date: Mon, 2 Nov 2009 17:58:23 -0500

On Mon, Nov 2, 2009 at 4:18 PM, Daniel Stenberg <daniel_at_haxx.se> wrote:

> On Mon, 2 Nov 2009, John Engelhart wrote:
>
> I'm wondering if the API could be expanded such that there were two calls:
>> one that provided the length of the buffer needed to hold the expanded
>> result, and one that did the expansion in to a user supplied buffer.
>>
>
> I'm not particularly against the idea, I'm just not too thrilled about the
> idea of providing two new functions that don't offer a lot of news. Also,
> they are highly specific for the ares_expand_*() functionality while one
> could argue the way you do for all the functions c-ares provides that return
> allocated data. And I don't want two new functions for each and every one of
> them.
>
> So where do we draw the line?

Well, as I mentioned, it's a minor inconvenience for me. It's a 'different'
way of dealing with returning results, and it's one of those choices that
once you've made it, it's hard to undo it. The ICU Unicode library tends to
use the API style I outlined, for example.

>
> The reason why this would be useful to me is because the way things are
>> now, I get the result from ares_expand_() and use that malloc() buffer to
>> create an Objective-C object. Typically that object will allocate its own
>> buffer to store the string and make a copy. I then immediately free() the
>> ares_expand_() buffer.
>>
>
> But that's your choice, you can just as well keep the data c-ares allocated
> and then avoid the extra alloc+copy.

In this case, it's not really my choice. The way any given object manages
it's internals is beyond me. It's similar to not being able to 'force' any
given function in C to "keep" the passed in pointer to a buffer instead of
malloc()ing it's own private copy, such as when ares_search() does a
strdup() on the query name argument.

>
> I'd really like to just be able to allocate a buffer off the stack to hold
>> the temporary expanded results. This also reduces the chance of a memory
>> leak
>>
>
> It's not very hard to make sure that memory doesn't leak in such a design.
> I find that a rather weak argument.

I would generally agree with you if we were talking about C99. Even though
Objective-C is a strict superset of C, there are some differences, and one
of those is Objective-C has an exception handling infrastructure (which,
depending on the architecture and ABI, uses plain C and a combination of
setjmp/longjmp + runtime bits and pieces, or the C++ exception handling
machinery). An exception could be thrown which will cause the stack to
unwind until something catches the exception. A C equivalent might be
something like:

void *p = malloc(1024);
printf("Throws an exception for NULL string pointers. malloc pointer: %p,
string: %s", p, NULL);
free(p);

If printf() in the above "throws an exception" for a NULL %s pointer,
control would never reach the free(p); statement. There's obviously ways to
deal with this so that it's robust, but the easiest way is to not have to
deal with it at all. :) I happen to use '[NSString
stringWithCString:expandedStringCString encoding:NSUTF8StringEncoding]' to
create a NSString object from the ares_expand_() malloc buffer. Immediately
after I create the string, I call ares_free_string(). If the data in that
buffer isn't valid UTF8, then NSString might throw an exception. It's not
something I've dealt with yet because it works "well enough" to be useful at
this time.

Like I said, it's not a big deal or a show stopper. Hey, let's face it, I
want to be lazy and simplify things. :)

Which reminds me: Just what is the encoding for the strings that
ares_expand_name() and ares_expand_string() return? I haven't dug that deep
in to the DNS RFC's at this point to dig out the official answer. Anyone
know off the top of their head? Or any pointers for dealing with
"non-ASCIIish" stuff in DNS replies?
Received on 2009-11-02