/* See LICENSE file for copyright and license details. */
#include "libradharc.h"
#include <stdarg.h>
int
libradharc_parse_response(const void *msg, size_t msglen, struct libradharc_response *response_out)
{
const unsigned char *m = msg;
int enum_value;
int64_t i64;
int32_t i32;
if (!msg || !msglen || !response_out) {
errno = EINVAL;
return -1;
}
response_out->type = (enum libradharc_response_type)*m++;
msglen--;
switch (response_out->type) {
case LIBRADHARC_RESPONSE_UNSUPPORTED:
case LIBRADHARC_RESPONSE_INVALID_REQUEST:
case LIBRADHARC_RESPONSE_ACK:
case LIBRADHARC_RESPONSE_ACK_NOOP:
case LIBRADHARC_RESPONSE_UNSET:
case LIBRADHARC_RESPONSE_YES:
case LIBRADHARC_RESPONSE_NO:
if (msglen)
goto ebadmsg;
break;
case LIBRADHARC_RESPONSE_ERROR_STRING:
case LIBRADHARC_RESPONSE_SET_STRING:
if (!msglen || m[--msglen] || memchr(m, 0, msglen))
goto ebadmsg;
response_out->value.string = (const char *)m;
break;
case LIBRADHARC_RESPONSE_SET_TIME:
if (msglen != sizeof(i64) + sizeof(i32))
goto ebadmsg;
memcpy(&i64, &m[0], sizeof(i64));
memcpy(&i32, &m[sizeof(i64)], sizeof(i32));
response_out->value.time.tv_sec = (time_t)i64;
response_out->value.time.tv_nsec = i32;
if (response_out->value.time.tv_sec < 0 ||
response_out->value.time.tv_nsec < 0 ||
response_out->value.time.tv_nsec >= 1000000000L)
goto ebadmsg;
break;
case LIBRADHARC_RESPONSE_SET_REAL:
if (msglen != sizeof(response_out->value.real))
goto ebadmsg;
goto raw;
case LIBRADHARC_RESPONSE_SET_REAL_PAIR:
if (msglen != sizeof(response_out->value.real_pair))
goto ebadmsg;
goto raw;
case LIBRADHARC_RESPONSE_SET_SIGNED64:
if (msglen != sizeof(response_out->value.signed64))
goto ebadmsg;
raw:
memcpy(&response_out->value, m, msglen);
break;
case LIBRADHARC_RESPONSE_SET_ENUM:
if (msglen != sizeof(enum_value))
goto ebadmsg;
memcpy(&enum_value, m, sizeof(enum_value));
response_out->value.operation_mode = (enum libradharc_operation_mode)enum_value; /* any enum */
break;
default:
ebadmsg:
errno = EBADMSG;
return -1;
}
return 0;
}
size_t
libradharc_format_request__n__(void *buffer, enum libradharc_request_type type, int what, size_t n, ...)
{
char *buf = buffer;;
size_t off = 0;
const char *value;
size_t size;
va_list args;
va_start(args, n);
if (buf)
buf[off] = (char)((n << 4) | type);
off++;
if (buf)
buf[off] = (char)what;
off++;
while (n--) {
value = va_arg(args, const char *);
size = va_arg(args, size_t);
if (buf)
memcpy(&buf[off], value, size);
off += size;
}
va_end(args);
return off;
}
extern inline size_t libradharc_format_request__0__(void *, enum libradharc_request_type, int);
extern inline size_t libradharc_format_request__1__(void *, enum libradharc_request_type, int, const void *, size_t);
extern inline size_t libradharc_format_request__2__(void *, enum libradharc_request_type, int, const void *, size_t,
const void *, size_t);
extern inline size_t libradharc_format_request__3__(void *, enum libradharc_request_type, int, const void *, size_t,
const void *, size_t, const void *, size_t);
extern inline size_t libradharc_format_get_request__0__(void *, enum libradharc_property );
extern inline size_t libradharc_format_get_request__s__(void *, enum libradharc_property , const char *);
extern inline size_t libradharc_format_set_request__64i__(void *, enum libradharc_property, int64_t);
extern inline size_t libradharc_format_set_request__i__(void *, enum libradharc_property, int);
extern inline size_t libradharc_format_set_request__r__(void *, enum libradharc_property, double);
extern inline size_t libradharc_format_set_request__rt__(void *, enum libradharc_property, double, const struct timespec *);
extern inline size_t libradharc_format_set_request__rr__(void *, enum libradharc_property, double, double);
extern inline size_t libradharc_format_set_request__s__(void *, enum libradharc_property, const char *);
extern inline size_t libradharc_format_set_request__ss__(void *, enum libradharc_property, const char *, const char *);
extern inline size_t libradharc_format_set_request__t__(void *, enum libradharc_property, const struct timespec *);
extern inline size_t libradharc_format_unset_request__0__(void *, enum libradharc_property);
extern inline size_t libradharc_format_signal_request__0__(void *, int);
extern inline size_t libradharc_format_signal_request__t__(void *, int, const struct timespec *);
extern inline size_t libradharc_format_set_request__rnt__(void *, enum libradharc_property, double, const struct timespec *);
extern inline size_t libradharc_format_set_request__sns__(void *, enum libradharc_property, const char *, const char *);
extern inline size_t libradharc_format_signal_request__nt__(void *, int, const struct timespec *);
extern inline size_t libradharc_format_set_fade_in(void *, const struct timespec *);
extern inline size_t libradharc_format_get_fade_in(void *);
extern inline size_t libradharc_format_set_fade_out(void *, const struct timespec *);
extern inline size_t libradharc_format_get_fade_out(void *);
extern inline size_t libradharc_format_set_high_temperature(void *, double);
extern inline size_t libradharc_format_get_high_temperature(void *);
extern inline size_t libradharc_format_set_low_temperature(void *, double);
extern inline size_t libradharc_format_get_low_temperature(void *);
extern inline size_t libradharc_format_set_high_elevation(void *, double);
extern inline size_t libradharc_format_get_high_elevation(void *);
extern inline size_t libradharc_format_set_low_elevation(void *, double);
extern inline size_t libradharc_format_get_low_elevation(void *);
extern inline size_t libradharc_format_set_location(void *, double, double);
extern inline size_t libradharc_format_get_location(void *);
extern inline size_t libradharc_format_unset_location(void *);
extern inline size_t libradharc_format_set_operation_mode(void *, enum libradharc_operation_mode);
extern inline size_t libradharc_format_get_operation_mode(void *);
extern inline size_t libradharc_format_set_temperature(void *, double, const struct timespec *);
extern inline size_t libradharc_format_get_temperature(void *);
extern inline size_t libradharc_format_set_priority(void *, int64_t);
extern inline size_t libradharc_format_get_priority(void *);
extern inline size_t libradharc_format_set_vendor_option(void *, const char *, const char *);
extern inline size_t libradharc_format_get_vendor_option(void *, const char *);
extern inline size_t libradharc_format_get_status(void *);
extern inline size_t libradharc_format_smooth_terminate(void *, const struct timespec *);
extern inline size_t libradharc_format_freeze_terminate(void *);
extern inline size_t libradharc_format_disable(void *, const struct timespec *);
extern inline size_t libradharc_format_enable(void *, const struct timespec *);