Fr?d?ric Ledain wrote:
Hi.
I have to design new API, which some of them have to return a string.
I have mixed feelings about the various strategies I can choose :
1. API(char *s, long *size)
=> the client gives a string pointer and its size; If the server has
to return a longer string, it fails, and the client calls back with a
longer string.
Strengths: buffer protection.
Weaknesses: possibly refuses the server unnecessarily.
Observations: size_t would be an improvement over long int. Did you
really want a pointer? (But see below.)
2. API(char *s)
=> the client receives a statically allocated string pointer from the
server. It can be changed when the client calls other APIs.
Strengths: none that I can think of.
Weaknesses: no buffer protection. "static" and "multi-threaded"
don't mix well.
Observations: it sucks.
3. API(char *s)
=> the client receives a dynamically allocated copy of the string from
the server. The client has to call back the server to release this
pointer (APIRelease(s)) ;
Strengths: none that I can think of.
Weaknesses: no buffer protection.
Observations: it sucks.
Can you help me to choose the "best" one ?
My constraints : multi-thread, Windows / UNIX.
Consider this possibility:
int API(char **s, size_t *size, size_t max);
Caller passes a pointer to a char * that initially has the value NULL,
and a size_t with the initial value 0.
Function reallocates buffer size as necessary to accommodate
incoming data, but refuses to expand past the "max" safety limit
(to avoid hostile connections attempting to tie up all your RAM).
Buffer can be reused over and over, as long as you continue to
allow the size_t object (whose address is passed) to remain
uncorrupted.
Caller can simply free() when done.
Strengths: buffer protection, reusable buffer, protection against
RAM denial.
Weaknesses: several params. Struct is tempting.
HTH. HAND.