diff options
Diffstat (limited to '')
-rw-r--r-- | src/libmdsclient/proto-util.c | 713 |
1 files changed, 357 insertions, 356 deletions
diff --git a/src/libmdsclient/proto-util.c b/src/libmdsclient/proto-util.c index 49ed887..8fd43bc 100644 --- a/src/libmdsclient/proto-util.c +++ b/src/libmdsclient/proto-util.c @@ -32,7 +32,7 @@ * it is beneficial to sort them. */ #ifndef LIBMDS_HEADERS_SORT_THRESHOLD -# define LIBMDS_HEADERS_SORT_THRESHOLD 100 /* XXX: Value is chosen at random */ +# define LIBMDS_HEADERS_SORT_THRESHOLD 100 /* XXX: Value is chosen at random */ #endif /** @@ -44,7 +44,7 @@ * a header array. */ #ifndef LIBMDS_HEADERS_COPY_THRESHOLD -# define LIBMDS_HEADERS_COPY_THRESHOLD 10 /* XXX: Value is chosen at random */ +# define LIBMDS_HEADERS_COPY_THRESHOLD 10 /* XXX: Value is chosen at random */ #endif /** @@ -56,7 +56,7 @@ * is is either full binary or full linear. */ #ifndef LIBMDS_HEADERS_BINSEARCH_THRESHOLD -# define LIBMDS_HEADERS_BINSEARCH_THRESHOLD 1000 /* XXX: Value is chosen at semirandom */ +# define LIBMDS_HEADERS_BINSEARCH_THRESHOLD 1000 /* XXX: Value is chosen at semirandom */ #endif @@ -69,21 +69,21 @@ * @param header_b The header that may not include a value * @return Same syntax as strcmp(3) */ -static int headercmp(const char* header_a, const char* header_b) +static int +headercmp(const char *header_a, const char *header_b) { - int a, b; - for (;;) - { - a = (int)*header_a++; - b = (int)*header_b++; - - if ((a == ':') && (*header_a == ' ')) - return 0 - b; - if ((a == 0) || (b == 0)) - return a - b; - if (a - b) - return a - b; - } + int a, b; + for (;;) { + a = (int)*header_a++; + b = (int)*header_b++; + + if (a == ':' && *header_a == ' ') + return 0 - b; + if (!a || !b) + return a - b; + if (a - b) + return a - b; + } } @@ -96,28 +96,28 @@ static int headercmp(const char* header_a, const char* header_b) * @param strp_b Pointer to the second string * @return Will return `strcmp(*strp_a, *strp_b)`, see strcmp(3) */ -static int headerpcmp(const void* headerp_a, const void* headerp_b) +static int +headerpcmp(const void *headerp_a, const void *headerp_b) { - const char* header_a = *(char* const*)headerp_a; - const char* header_b = *(char* const*)headerp_b; - int a, b, az, bz; - - for (;;) - { - a = (int)*header_a++; - b = (int)*header_b++; - az = (a == ':') && (*header_a == ' '); - bz = (b == ':') && (*header_b == ' '); - - if (az) - return 0 - !(bz || (b == 0)); - if (bz) - return a - 0; - if ((a == 0) || (b == 0)) - return a - b; - if (a - b) - return a - b; - } + const char *header_a = *(char *const *)headerp_a; + const char *header_b = *(char *const *)headerp_b; + int a, b, az, bz; + + for (;;) { + a = (int)*header_a++; + b = (int)*header_b++; + az = a == ':' && *header_a == ' '; + bz = b == ':' && *header_b == ' '; + + if (az) + return 0 - !(bz || !b); + if (bz) + return a - 0; + if (!a || !b) + return a - b; + if (a - b) + return a - b; + } } @@ -145,17 +145,18 @@ static int headerpcmp(const void* headerp_a, const void* headerp_b) * @throws ENOMEM Out of memory, Possibly, the process hit the RLIMIT_AS or * RLIMIT_DATA limit described in getrlimit(2). */ -int libmds_headers_cherrypick(char** restrict headers, size_t header_count, size_t* restrict found, - libmds_cherrypick_optimisation_t optimisation, ...) +int +libmds_headers_cherrypick(char **restrict headers, size_t header_count, size_t *restrict found, + libmds_cherrypick_optimisation_t optimisation, ...) { - va_list args; - int r, saved_errno; - va_start(args, optimisation); - r = libmds_headers_cherrypick_v(headers, header_count, found, optimisation, args); - saved_errno = errno; - va_end(args); - errno = saved_errno; - return r; + va_list args; + int r, saved_errno; + va_start(args, optimisation); + r = libmds_headers_cherrypick_v(headers, header_count, found, optimisation, args); + saved_errno = errno; + va_end(args); + errno = saved_errno; + return r; } @@ -177,17 +178,18 @@ int libmds_headers_cherrypick(char** restrict headers, size_t header_count, size * more headers in the list, it should be terminated with a `NULL`. * @return The number of found headers of those that were requested */ -size_t libmds_headers_cherrypick_linear_unsorted(char** restrict headers, size_t header_count, ...) +size_t +libmds_headers_cherrypick_linear_unsorted(char **restrict headers, size_t header_count, ...) { - va_list args; - size_t r; - int saved_errno; - va_start(args, header_count); - r = libmds_headers_cherrypick_linear_unsorted_v(headers, header_count, args); - saved_errno = errno; - va_end(args); - errno = saved_errno; - return r; + va_list args; + size_t r; + int saved_errno; + va_start(args, header_count); + r = libmds_headers_cherrypick_linear_unsorted_v(headers, header_count, args); + saved_errno = errno; + va_end(args); + errno = saved_errno; + return r; } @@ -209,17 +211,17 @@ size_t libmds_headers_cherrypick_linear_unsorted(char** restrict headers, size_t * more headers in the list, it should be terminated with a `NULL`. * @return The number of found headers of those that were requested */ -size_t libmds_headers_cherrypick_linear_sorted(char** restrict headers, size_t header_count, ...) +size_t libmds_headers_cherrypick_linear_sorted(char **restrict headers, size_t header_count, ...) { - va_list args; - size_t r; - int saved_errno; - va_start(args, header_count); - r = libmds_headers_cherrypick_linear_sorted_v(headers, header_count, args); - saved_errno = errno; - va_end(args); - errno = saved_errno; - return r; + va_list args; + size_t r; + int saved_errno; + va_start(args, header_count); + r = libmds_headers_cherrypick_linear_sorted_v(headers, header_count, args); + saved_errno = errno; + va_end(args); + errno = saved_errno; + return r; } @@ -241,17 +243,18 @@ size_t libmds_headers_cherrypick_linear_sorted(char** restrict headers, size_t h * more headers in the list, it should be terminated with a `NULL`. * @return The number of found headers of those that were requested */ -size_t libmds_headers_cherrypick_binary_unsorted(char** restrict headers, size_t header_count, ...) +size_t +libmds_headers_cherrypick_binary_unsorted(char **restrict headers, size_t header_count, ...) { - va_list args; - size_t r; - int saved_errno; - va_start(args, header_count); - r = libmds_headers_cherrypick_binary_unsorted_v(headers, header_count, args); - saved_errno = errno; - va_end(args); - errno = saved_errno; - return r; + va_list args; + size_t r; + int saved_errno; + va_start(args, header_count); + r = libmds_headers_cherrypick_binary_unsorted_v(headers, header_count, args); + saved_errno = errno; + va_end(args); + errno = saved_errno; + return r; } @@ -274,17 +277,18 @@ size_t libmds_headers_cherrypick_binary_unsorted(char** restrict headers, size_t * more headers in the list, it should be terminated with a `NULL`. * @return The number of found headers of those that were requested */ -size_t libmds_headers_cherrypick_binary_sorted(char** restrict headers, size_t header_count, ...) +size_t +libmds_headers_cherrypick_binary_sorted(char **restrict headers, size_t header_count, ...) { - va_list args; - size_t r; - int saved_errno; - va_start(args, header_count); - r = libmds_headers_cherrypick_binary_sorted_v(headers, header_count, args); - saved_errno = errno; - va_end(args); - errno = saved_errno; - return r; + va_list args; + size_t r; + int saved_errno; + va_start(args, header_count); + r = libmds_headers_cherrypick_binary_sorted_v(headers, header_count, args); + saved_errno = errno; + va_end(args); + errno = saved_errno; + return r; } @@ -312,58 +316,55 @@ size_t libmds_headers_cherrypick_binary_sorted(char** restrict headers, size_t h * @throws ENOMEM Out of memory, Possibly, the process hit the RLIMIT_AS or * RLIMIT_DATA limit described in getrlimit(2). */ -int libmds_headers_cherrypick_v(char** restrict headers, size_t header_count, size_t* restrict found, - libmds_cherrypick_optimisation_t optimisation, va_list args) +int +libmds_headers_cherrypick_v(char **restrict headers, size_t header_count, size_t *restrict found, + libmds_cherrypick_optimisation_t optimisation, va_list args) { - char** headers_ = headers; - size_t found_; - libmds_cherrypick_optimisation_t sorted; - - if (found != NULL) - *found = 0; - - optimisation ^= sorted = optimisation & ARGS_SORTED; - - if (optimisation == DO_NOT_SORT) - { - if (header_count >= LIBMDS_HEADERS_SORT_THRESHOLD + LIBMDS_HEADERS_COPY_THRESHOLD) - { - headers_ = malloc(header_count * sizeof(char*)); - if (headers_ == NULL) - return -1; - memcpy(headers_, headers, header_count * sizeof(char*)); - libmds_headers_sort(headers_, header_count); - optimisation = SORTED; + char **headers_ = headers; + size_t found_; + libmds_cherrypick_optimisation_t sorted; + + if (found) + *found = 0; + + optimisation ^= sorted = optimisation & ARGS_SORTED; + + if (optimisation == DO_NOT_SORT) { + if (header_count >= LIBMDS_HEADERS_SORT_THRESHOLD + LIBMDS_HEADERS_COPY_THRESHOLD) { + headers_ = malloc(header_count * sizeof(char*)); + if (!headers_) + return -1; + memcpy(headers_, headers, header_count * sizeof(char*)); + libmds_headers_sort(headers_, header_count); + optimisation = SORTED; + } + } else if (optimisation == SORT) { + if (header_count >= LIBMDS_HEADERS_SORT_THRESHOLD) { + libmds_headers_sort(headers_, header_count); + optimisation = SORTED; + } + } + + if (optimisation != SORTED) { + found_ = libmds_headers_cherrypick_linear_unsorted_v(headers_, header_count, args); + } else if (header_count < LIBMDS_HEADERS_BINSEARCH_THRESHOLD) { + if (sorted) + found_ = libmds_headers_cherrypick_linear_sorted_v(headers_, header_count, args); + else + found_ = libmds_headers_cherrypick_linear_unsorted_v(headers_, header_count, args); + } else if (sorted) { + found_ = libmds_headers_cherrypick_binary_sorted_v(headers_, header_count, args); + } else { + found_ = libmds_headers_cherrypick_binary_unsorted_v(headers_, header_count, args); } - } - else if (optimisation == SORT) - if (header_count >= LIBMDS_HEADERS_SORT_THRESHOLD) - { - libmds_headers_sort(headers_, header_count); - optimisation = SORTED; - } - - if (optimisation != SORTED) - found_ = libmds_headers_cherrypick_linear_unsorted_v(headers_, header_count, args); - else if (header_count < LIBMDS_HEADERS_BINSEARCH_THRESHOLD) - { - if (sorted) - found_ = libmds_headers_cherrypick_linear_sorted_v(headers_, header_count, args); - else - found_ = libmds_headers_cherrypick_linear_unsorted_v(headers_, header_count, args); - } - else if (sorted) - found_ = libmds_headers_cherrypick_binary_sorted_v(headers_, header_count, args); - else - found_ = libmds_headers_cherrypick_binary_unsorted_v(headers_, header_count, args); - - if (found != NULL) - *found = found_; - - if (headers_ != headers) - free(headers_); - - return 0; + + if (found) + *found = found_; + + if (headers_ != headers) + free(headers_); + + return 0; } @@ -385,29 +386,29 @@ int libmds_headers_cherrypick_v(char** restrict headers, size_t header_count, si * more headers in the list, it should be terminated with a `NULL`. * @return The number of found headers of those that were requested */ -size_t libmds_headers_cherrypick_linear_unsorted_v(char** restrict headers, size_t header_count, va_list args) +size_t +libmds_headers_cherrypick_linear_unsorted_v(char **restrict headers, size_t header_count, va_list args) { - const char* header; - char** value_out; - size_t found = 0, i; - - for (;;) - { - header = va_arg(args, const char*); - if (header == NULL) - return found; - - value_out = va_arg(args, char**); - *value_out = NULL; - - for (i = 0; i < header_count; i++) - if (!headercmp(headers[i], header)) - { - *value_out = strstr(headers[i], ": ") + 2; - found++; - break; - } - } + const char *header; + char **value_out; + size_t found = 0, i; + + for (;;) { + header = va_arg(args, const char*); + if (!header) + return found; + + value_out = va_arg(args, char**); + *value_out = NULL; + + for (i = 0; i < header_count; i++) { + if (!headercmp(headers[i], header)) { + *value_out = strstr(headers[i], ": ") + 2; + found++; + break; + } + } + } } @@ -431,35 +432,33 @@ size_t libmds_headers_cherrypick_linear_unsorted_v(char** restrict headers, size * more headers in the list, it should be terminated with a `NULL`. * @return The number of found headers of those that were requested */ -size_t libmds_headers_cherrypick_linear_sorted_v(char** restrict headers, size_t header_count, va_list args) +size_t +libmds_headers_cherrypick_linear_sorted_v(char **restrict headers, size_t header_count, va_list args) { - const char* header; - char** value_out; - size_t found = 0, i = 0; - int r; - - for (;;) - { - header = va_arg(args, const char*); - if (header == NULL) - return found; - - value_out = va_arg(args, char**); - *value_out = NULL; - - for (; i < header_count; i++) - { - r = headercmp(headers[i], header); - if (r == 0) - { - *value_out = strstr(headers[i], ": ") + 2; - found++, i++; - break; - } - if (r > 0) - break; + const char *header; + char **value_out; + size_t found = 0, i = 0; + int r; + + for (;;) { + header = va_arg(args, const char*); + if (!header) + return found; + + value_out = va_arg(args, char**); + *value_out = NULL; + + for (; i < header_count; i++) { + r = headercmp(headers[i], header); + if (!r) { + *value_out = strstr(headers[i], ": ") + 2; + found++, i++; + break; + } + if (r > 0) + break; + } } - } } @@ -481,26 +480,26 @@ size_t libmds_headers_cherrypick_linear_sorted_v(char** restrict headers, size_t * more headers in the list, it should be terminated with a `NULL`. * @return The number of found headers of those that were requested */ -size_t libmds_headers_cherrypick_binary_unsorted_v(char** restrict headers, size_t header_count, va_list args) +size_t +libmds_headers_cherrypick_binary_unsorted_v(char **restrict headers, size_t header_count, va_list args) { - const char* header; - char** value_out; - void* found_element; - size_t found = 0; - - for (;;) - { - header = va_arg(args, const char*); - if (header == NULL) - return found; - - value_out = va_arg(args, char**); - *value_out = NULL; - - found_element = bsearch(&header, headers, header_count, sizeof(char*), headerpcmp); - if (found_element != NULL) - *value_out = strstr(*(char**)found_element, ": ") + 2, found++; - } + const char *header; + char **value_out; + void *found_element; + size_t found = 0; + + for (;;) { + header = va_arg(args, const char*); + if (!header) + return found; + + value_out = va_arg(args, char**); + *value_out = NULL; + + found_element = bsearch(&header, headers, header_count, sizeof(char*), headerpcmp); + if (found_element) + *value_out = strstr(*(char**)found_element, ": ") + 2, found++; + } } @@ -523,35 +522,34 @@ size_t libmds_headers_cherrypick_binary_unsorted_v(char** restrict headers, size * more headers in the list, it should be terminated with a `NULL`. * @return The number of found headers of those that were requested */ -size_t libmds_headers_cherrypick_binary_sorted_v(char** restrict headers, size_t header_count, va_list args) +size_t +libmds_headers_cherrypick_binary_sorted_v(char **restrict headers, size_t header_count, va_list args) { - const char* header; - char** value_out; - void* found_element; - size_t found = 0; - size_t offset = 0; - - /* I sincerely doubt even this amount of optimisation is needed, - * so there is no need for even faster algorithms, keep in mind - * that the overhead increases with faster algorithms. */ - - for (;;) - { - header = va_arg(args, const char*); - if (header == NULL) - return found; - - value_out = va_arg(args, char**); - *value_out = NULL; - - found_element = bsearch(&header, headers + offset, header_count - offset, sizeof(char*), headerpcmp); - if (found_element != NULL) - { - offset = (size_t)((char**)found_element - headers); - *value_out = strstr(*(char**)found_element, ": ") + 2; - found++; + const char *header; + char **value_out; + void *found_element; + size_t found = 0; + size_t offset = 0; + + /* I sincerely doubt even this amount of optimisation is needed, + * so there is no need for even faster algorithms, keep in mind + * that the overhead increases with faster algorithms. */ + + for (;;) { + header = va_arg(args, const char*); + if (!header) + return found; + + value_out = va_arg(args, char**); + *value_out = NULL; + + found_element = bsearch(&header, headers + offset, header_count - offset, sizeof(char *), headerpcmp); + if (found_element) { + offset = (size_t)((char **)found_element - headers); + *value_out = strstr(*(char **)found_element, ": ") + 2; + found++; + } } - } } @@ -562,9 +560,10 @@ size_t libmds_headers_cherrypick_binary_sorted_v(char** restrict headers, size_t * @param headers The array of headers * @param headr_count The number of elements in `headers` */ -void libmds_headers_sort(char** restrict headers, size_t header_count) +void +libmds_headers_sort(char **restrict headers, size_t header_count) { - qsort(headers, header_count, sizeof(char*), headerpcmp); + qsort(headers, header_count, sizeof(char *), headerpcmp); } @@ -610,17 +609,18 @@ void libmds_headers_sort(char** restrict headers, size_t header_count) * @throws ENOMEM Out of memory, Possibly, the process hit the RLIMIT_AS or * RLIMIT_DATA limit described in getrlimit(2). */ -int libmds_compose(char** restrict buffer, size_t* restrict buffer_size, size_t* restrict length, - const char* restrict payload, const size_t* restrict payload_length, ...) +int +libmds_compose(char **restrict buffer, size_t *restrict buffer_size, size_t *restrict length, + const char *restrict payload, const size_t *restrict payload_length, ...) { - va_list args; - int r, saved_errno; - va_start(args, payload_length); - r = libmds_compose_v(buffer, buffer_size, length, payload, payload_length, args); - saved_errno = errno; - va_end(args); - errno = saved_errno; - return r; + va_list args; + int r, saved_errno; + va_start(args, payload_length); + r = libmds_compose_v(buffer, buffer_size, length, payload, payload_length, args); + saved_errno = errno; + va_end(args); + errno = saved_errno; + return r; } @@ -666,105 +666,106 @@ int libmds_compose(char** restrict buffer, size_t* restrict buffer_size, size_t* * @throws ENOMEM Out of memory, Possibly, the process hit the RLIMIT_AS or * RLIMIT_DATA limit described in getrlimit(2). */ -int libmds_compose_v(char** restrict buffer, size_t* restrict buffer_size, size_t* restrict length, - const char* restrict payload, const size_t* restrict payload_length, va_list args) +int +libmds_compose_v(char **restrict buffer, size_t *restrict buffer_size, size_t *restrict length, + const char *restrict payload, const size_t *restrict payload_length, va_list args) { - char* buf = *buffer; - size_t bufsize = *buffer_size; - size_t len = 0; - int part_len; - char* part_msg; - size_t payload_len = 0; - const char* format; - int include; - int saved_errno; - - *length = 0; - - if (payload != NULL) - payload_len = payload_length == NULL ? strlen(payload) : *payload_length; - - if (bufsize == 0) - { - bufsize = 128; - buf = realloc(buf, bufsize * sizeof(char)); - if (buf == NULL) - return -1; - } - - for (;;) - { - format = va_arg(args, const char*); - if (format == NULL) - break; - - include = 1; - if (*format == '?') - { - include = va_arg(args, int); - format++; + char *buf = *buffer; + size_t bufsize = *buffer_size; + size_t len = 0; + int part_len; + char *part_msg; + size_t payload_len = 0; + const char* format; + int include; + int saved_errno; + + *length = 0; + + if (payload) + payload_len = payload_length == NULL ? strlen(payload) : *payload_length; + + if (!bufsize) { + bufsize = 128; + buf = realloc(buf, bufsize * sizeof(char)); + if (!buf) + return -1; } - + + for (;;) { + format = va_arg(args, const char*); + if (!format) + break; + + include = 1; + if (*format == '?') { + include = va_arg(args, int); + format++; + } + +#if defined(__GNUC__) # pragma GCC diagnostic push # pragma GCC diagnostic ignored "-Wformat-nonliteral" # pragma GCC diagnostic ignored "-Wsuggest-attribute=format" - part_len = vasprintf(&part_msg, format, args); - /* XXX vbprintf in slibc will be a nice replacement for this horror. */ +#endif + part_len = vasprintf(&part_msg, format, args); + /* XXX vbprintf in slibc will be a nice replacement for this horror. */ +#if defined(__GNUC__) # pragma GCC diagnostic pop +#endif + + if (!include) { + if (part_len >= 0) + free(part_msg); + continue; + } + + if (part_len < 0) + return -1; - if (include == 0) - { - if (part_len >= 0) - free(part_msg); - continue; + if (len + (size_t)part_len >= bufsize) { + *buffer_size = bufsize; + *buffer = buf; + do + bufsize <<= 1; + while (len + (size_t)part_len >= bufsize); + buf = realloc(buf, bufsize * sizeof(char)); + if (!buf) + return saved_errno = errno, free(part_msg), errno = saved_errno, -1; + } + + memcpy(buf + len, part_msg, ((size_t)part_len) * sizeof(char)); + len += (size_t)part_len; + buf[len++] = '\n'; + free(part_msg); } - - if (part_len < 0) - return -1; - - if (len + (size_t)part_len >= bufsize) - { - *buffer_size = bufsize; - *buffer = buf; - do - bufsize <<= 1; - while (len + (size_t)part_len >= bufsize); - buf = realloc(buf, bufsize * sizeof(char)); - if (buf == NULL) - return saved_errno = errno, free(part_msg), errno = saved_errno, -1; + +#define LENGTH_LEN \ + (payload_len > 0 ? ((sizeof("Length: \n") / sizeof(char) - 1) + 3 * sizeof(size_t)) : 0) + + if (len + LENGTH_LEN + 1 + payload_len + 1 > bufsize) { + *buffer_size = bufsize; + *buffer = buf; + bufsize = len + LENGTH_LEN + 1 + payload_len + 1; + buf = realloc(buf, bufsize * sizeof(char)); + if (!buf) + return -1; } - - memcpy(buf + len, part_msg, ((size_t)part_len) * sizeof(char)); - len += (size_t)part_len; - buf[len++] = '\n'; - free(part_msg); - } - -#define LENGTH_LEN \ - (payload_len > 0 ? ((sizeof("Length: \n") / sizeof(char) - 1) + 3 * sizeof(size_t)) : 0) - if (len + LENGTH_LEN + 1 + payload_len + 1 > bufsize) - { - *buffer_size = bufsize; - *buffer = buf; - bufsize = len + LENGTH_LEN + 1 + payload_len + 1; - buf = realloc(buf, bufsize * sizeof(char)); - if (buf == NULL) - return -1; - } + #undef LENGTH_LEN - - if (payload_len > 0) - sprintf(buf + len, "Length: %zu\n%n", payload_len, &part_len), - len += (size_t)part_len; - buf[len++] = '\n'; - if (payload_len > 0) - memcpy(buf + len, payload, payload_len * sizeof(char)), - len += payload_len; - - *buffer_size = bufsize; - *buffer = buf; - *length = len; - return 0; + + if (payload_len > 0) + sprintf(buf + len, "Length: %zu\n%n", payload_len, &part_len), + len += (size_t)part_len; + buf[len++] = '\n'; + if (payload_len > 0) + memcpy(buf + len, payload, payload_len * sizeof(char)), + len += payload_len; + + *buffer_size = bufsize; + *buffer = buf; + *length = len; + return 0; } @@ -789,28 +790,28 @@ int libmds_compose_v(char** restrict buffer, size_t* restrict buffer_size, size_ * there are no free message ID:s. * @throws Any error that `test` may throw. */ -int libmds_next_message_id(uint32_t* restrict message_id, - int (*test)(uint32_t message_id, void* data), void* data) +int +libmds_next_message_id(uint32_t *restrict message_id, + int (*test)(uint32_t message_id, void *data), void *data) { - uint32_t id = *message_id; - uint32_t first_test; - int r; - - id = id == UINT32_MAX ? 0 : (id + 1); - if (test != NULL) - for (first_test = id;;) - { - r = test(id, data); - if (r < 0) - return -1; - if (r) - break; + uint32_t id = *message_id; + uint32_t first_test; + int r; + id = id == UINT32_MAX ? 0 : (id + 1); - if (id == first_test) - return errno = EAGAIN, -1; - } - - *message_id = id; - return 0; -} + if (test) { + for (first_test = id;;) { + r = test(id, data); + if (r < 0) + return -1; + if (r) + break; + id = id == UINT32_MAX ? 0 : (id + 1); + if (id == first_test) + return errno = EAGAIN, -1; + } + } + *message_id = id; + return 0; +} |