Implement skipstone_message_unpack()
This commit is contained in:
parent
ae3c45fe02
commit
448937b6fb
2 changed files with 78 additions and 0 deletions
|
@ -14,4 +14,8 @@ ssize_t skipstone_message_pack(void *message,
|
||||||
size_t len,
|
size_t len,
|
||||||
const char *template, ...);
|
const char *template, ...);
|
||||||
|
|
||||||
|
ssize_t skipstone_message_unpack(void *message,
|
||||||
|
size_t len,
|
||||||
|
const char *template, ...);
|
||||||
|
|
||||||
#endif /* _SKIPSTONE_MESSAGE_H */
|
#endif /* _SKIPSTONE_MESSAGE_H */
|
||||||
|
|
|
@ -95,3 +95,77 @@ error_invalid_template:
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define case_unpack(t, bytes) \
|
||||||
|
case t: \
|
||||||
|
if (len < offset + bytes) { \
|
||||||
|
goto done; \
|
||||||
|
} \
|
||||||
|
memcpy(va_arg(args, void *), (uint8_t *)message + offset, bytes); \
|
||||||
|
offset += bytes; \
|
||||||
|
break;
|
||||||
|
|
||||||
|
ssize_t skipstone_message_unpack(void *message,
|
||||||
|
size_t len,
|
||||||
|
const char *template, ...) {
|
||||||
|
va_list args;
|
||||||
|
size_t offset = 0,
|
||||||
|
i;
|
||||||
|
|
||||||
|
va_start(args, template);
|
||||||
|
|
||||||
|
for (i=0; template[i]; i++) {
|
||||||
|
char c = template[i];
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case_unpack('c', sizeof(int8_t));
|
||||||
|
case_unpack('C', sizeof(uint8_t));
|
||||||
|
case_unpack('s', sizeof(int16_t));
|
||||||
|
case_unpack('S', sizeof(uint16_t));
|
||||||
|
case_unpack('l', sizeof(int32_t));
|
||||||
|
case_unpack('L', sizeof(uint32_t));
|
||||||
|
case_unpack('q', sizeof(int64_t));
|
||||||
|
case_unpack('Q', sizeof(uint64_t));
|
||||||
|
|
||||||
|
case 'z': {
|
||||||
|
uint8_t sz;
|
||||||
|
void *dest;
|
||||||
|
|
||||||
|
if (len < offset + 1) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
sz = ((uint8_t *)message)[offset++];
|
||||||
|
|
||||||
|
if (len < offset + sz + 1) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
dest = va_arg(args, void *);
|
||||||
|
|
||||||
|
memcpy(dest, (uint8_t *)message + offset, sz);
|
||||||
|
|
||||||
|
offset += sz;
|
||||||
|
|
||||||
|
((uint8_t *)message)[offset++] = '\0';
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
errno = EINVAL;
|
||||||
|
|
||||||
|
goto error_invalid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
done:
|
||||||
|
return offset;
|
||||||
|
|
||||||
|
error_invalid:
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue