blob: 572ef247db48d4ff79d22cbf63713a4d4ef96957 [file] [log] [blame]
#include <stdlib.h>
#include <string.h>
static bool is_big_endian(void) {
union {
uint32_t i;
char c[4];
} bint = {0x01020304};
return bint.c[0] == 1;
}
/* Decode an unsigned int LEB128 at buf into r, returning the nr of bytes read.
*/
inline size_t decode_uint_leb(const uint8_t* buf, const uint8_t* buf_end, uint64_t* r) {
const uint8_t* p = buf;
uint8_t shift = 0;
uint64_t result = 0;
uint8_t byte;
do {
if (p >= buf_end) {
return 0;
}
byte = *p++;
result |= ((uint64_t)(byte & 0x7f)) << shift;
shift += 7;
} while ((byte & 0x80) != 0);
*r = result;
return p - buf;
}
/* Decodes a string
*/
inline size_t
decode_string(uint64_t str_len, const uint8_t* buf, const uint8_t* buf_end, char* char_buf) {
// Return zero bytes read on buffer overflow
if (buf_end - buf < str_len) {
return 0;
}
const uint8_t* p = buf;
for (int i = 0; i < str_len; i++) {
char_buf[i] = *p++;
}
// Add the null terminator
char_buf[str_len] = '\0';
return str_len;
}
/* Decodes a float (4 bytes)
*/
inline size_t decode_float(const uint8_t* buf, const uint8_t* buf_end, float* r) {
// Return zero bytes read on buffer overflow
if (buf_end - buf < (unsigned)sizeof(float)) {
return 0;
}
if (is_big_endian()) {
uint8_t inverted[4] = {buf[3], buf[2], buf[1], buf[0]};
memcpy(r, inverted, sizeof(float));
} else {
memcpy(r, buf, sizeof(float));
}
return sizeof(float);
}
/* Decodes a single byte
*/
inline size_t decode_uint_8(const uint8_t* buf, const uint8_t* buf_end, uint8_t* r) {
// Return zero bytes read on buffer overflow
if (buf_end - buf < (unsigned)sizeof(uint8_t)) {
return 0;
}
memcpy(r, buf, sizeof(uint8_t));
return sizeof(uint8_t);
}
/* Decodes a 32 bit unsigned integer.
*/
inline size_t decode_uint_32(const uint8_t* buf, const uint8_t* buf_end, uint32_t* r) {
// Return zero bytes read on buffer overflow
if (buf_end - buf < (unsigned)sizeof(uint32_t)) {
return 0;
}
if (is_big_endian()) {
uint8_t inverted[4] = {buf[3], buf[2], buf[1], buf[0]};
memcpy(r, inverted, sizeof(uint32_t));
} else {
memcpy(r, buf, sizeof(uint32_t));
}
return sizeof(uint32_t);
}