I'm in the middle of writing an Objective-C wrapper around the base c-ares
library. There's a small tweak to the API that I'd like to request that
would make things a (tiny) bit better for my needs.
Since I'm providing high-level 'object' based 'parsed' results, I have a
need to call both ares_expand_string() and ares_expand_name() to extract the
various fields from the raw buffer.
The current API returns a malloc()'d buffer containing the expanded result.
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. If
this change is made, I'd assume that the current ares_expand_string() and
ares_expand_name() would simply be modified to be a wrapper around the
length / user supplied buffer routines.
I'm thinking the API would look something like:
int ares_expand_string_length(const unsigned char *encoded, const unsigned
char *abuf, int alen, size_t *enclen);
int ares_expand_string_to_buffer(const unsigned char *encoded, const
unsigned char *abuf, int alen, unsigned char *encbuf, size_t enclen, size_t
I'm using the size_t type since it's the preferred, standards-based way of
specifying 'length' like arguments (ie, automatically adjusts between 32/64
bit sizes depending on the architecture, or whatever the appropriate size is
for the given architecture).
ares_expand_string_length() returns an ARES_XXX result and returns the
length via the size_t *enclen argument.
ares_expand_string_to_buffer() also returns an ARES_XXX result and expands
the result in to encbuf.
The enclen argument specifies how big encbuf is and is used to ensure that
buffer overruns don't take place. An additional error, say ARES_ETOOSMALL,
should be created to indicate that the size of encbuf is not large enough to
hold the expanded result.
*enc_used is used to return how many bytes of encbuf was used to hold the
result and (IMHO) can optionally be NULL if that information isn't needed by
IMHO, these should be geared towards "zero terminated C strings". With that
in mind, the _length() API doesn't return the strlen() length of the result,
but the strlen() + 1 length, enough to hold the trailing 0. The
_to_buffer() function would also require that the buffer be big enough to
hold the string plus one extra for the 0 terminator.
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. 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- depending on the details, there's sometimes a
chance that "something" could go wrong between the time that ares_expand_()
is called, the various instantiations that use that buffer, and the free().
Leaks are pretty much impossible with a stack allocated temporary buffer,
so it simplifies the code and reduces the dreaded "corner cases".
Received on 2009-11-02