#ifndef CUTILS_H
#define CUTILS_H
#include <stdlib.h>
#include <inttypes.h>
#undef WORDS_BIGENDIAN
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define force_inline inline __attribute__((always_inline))
#define no_inline __attribute__((noinline))
#define __maybe_unused __attribute__((unused))
#define xglue(x, y) x ## y
#define glue(x, y) xglue(x, y)
#define stringify(s) tostring(s)
#define tostring(s) #s
#ifndef offsetof
#define offsetof(type, field) ((size_t) &((type *)0)->field)
#endif
#ifndef countof
#define countof(x) (sizeof(x) / sizeof((x)[0]))
#endif
#define container_of(ptr, type, member) ((type *)((uint8_t *)(ptr) - offsetof(type, member)))
typedef
int
BOOL
;
#ifndef FALSE
enum
{
FALSE = 0,
TRUE = 1,
};
#endif
void
pstrcpy(
char
*buf,
int
buf_size,
const
char
*str);
char
*pstrcat(
char
*buf,
int
buf_size,
const
char
*s);
int
strstart(
const
char
*str,
const
char
*val,
const
char
**ptr);
int
has_suffix(
const
char
*str,
const
char
*suffix);
static
inline
int
max_int(
int
a,
int
b)
{
if
(a > b)
return
a;
else
return
b;
}
static
inline
int
min_int(
int
a,
int
b)
{
if
(a < b)
return
a;
else
return
b;
}
static
inline
uint32_t max_uint32(uint32_t a, uint32_t b)
{
if
(a > b)
return
a;
else
return
b;
}
static
inline
uint32_t min_uint32(uint32_t a, uint32_t b)
{
if
(a < b)
return
a;
else
return
b;
}
static
inline
int64_t max_int64(int64_t a, int64_t b)
{
if
(a > b)
return
a;
else
return
b;
}
static
inline
int64_t min_int64(int64_t a, int64_t b)
{
if
(a < b)
return
a;
else
return
b;
}
static
inline
int
clz32(unsigned
int
a)
{
return
__builtin_clz(a);
}
static
inline
int
clz64(uint64_t a)
{
return
__builtin_clzll(a);
}
static
inline
int
ctz32(unsigned
int
a)
{
return
__builtin_ctz(a);
}
static
inline
int
ctz64(uint64_t a)
{
return
__builtin_ctzll(a);
}
struct
__attribute__((packed)) packed_u64 {
uint64_t v;
};
struct
__attribute__((packed)) packed_u32 {
uint32_t v;
};
struct
__attribute__((packed)) packed_u16 {
uint16_t v;
};
static
inline
uint64_t get_u64(
const
uint8_t *tab)
{
return
((
const
struct
packed_u64 *)tab)->v;
}
static
inline
int64_t get_i64(
const
uint8_t *tab)
{
return
(int64_t)((
const
struct
packed_u64 *)tab)->v;
}
static
inline
void
put_u64(uint8_t *tab, uint64_t val)
{
((
struct
packed_u64 *)tab)->v = val;
}
static
inline
uint32_t get_u32(
const
uint8_t *tab)
{
return
((
const
struct
packed_u32 *)tab)->v;
}
static
inline
int32_t get_i32(
const
uint8_t *tab)
{
return
(int32_t)((
const
struct
packed_u32 *)tab)->v;
}
static
inline
void
put_u32(uint8_t *tab, uint32_t val)
{
((
struct
packed_u32 *)tab)->v = val;
}
static
inline
uint32_t get_u16(
const
uint8_t *tab)
{
return
((
const
struct
packed_u16 *)tab)->v;
}
static
inline
int32_t get_i16(
const
uint8_t *tab)
{
return
(int16_t)((
const
struct
packed_u16 *)tab)->v;
}
static
inline
void
put_u16(uint8_t *tab, uint16_t val)
{
((
struct
packed_u16 *)tab)->v = val;
}
static
inline
uint32_t get_u8(
const
uint8_t *tab)
{
return
*tab;
}
static
inline
int32_t get_i8(
const
uint8_t *tab)
{
return
(int8_t)*tab;
}
static
inline
void
put_u8(uint8_t *tab, uint8_t val)
{
*tab = val;
}
static
inline
uint16_t bswap16(uint16_t x)
{
return
(x >> 8) | (x << 8);
}
static
inline
uint32_t bswap32(uint32_t v)
{
return
((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >> 8) |
((v & 0x0000ff00) << 8) | ((v & 0x000000ff) << 24);
}
static
inline
uint64_t bswap64(uint64_t v)
{
return
((v & ((uint64_t)0xff << (7 * 8))) >> (7 * 8)) |
((v & ((uint64_t)0xff << (6 * 8))) >> (5 * 8)) |
((v & ((uint64_t)0xff << (5 * 8))) >> (3 * 8)) |
((v & ((uint64_t)0xff << (4 * 8))) >> (1 * 8)) |
((v & ((uint64_t)0xff << (3 * 8))) << (1 * 8)) |
((v & ((uint64_t)0xff << (2 * 8))) << (3 * 8)) |
((v & ((uint64_t)0xff << (1 * 8))) << (5 * 8)) |
((v & ((uint64_t)0xff << (0 * 8))) << (7 * 8));
}
typedef
void
*DynBufReallocFunc(
void
*opaque,
void
*ptr,
size_t
size);
typedef
struct
DynBuf {
uint8_t *buf;
size_t
size;
size_t
allocated_size;
BOOL
error;
DynBufReallocFunc *realloc_func;
void
*opaque;
} DynBuf;
void
dbuf_init(DynBuf *s);
void
dbuf_init2(DynBuf *s,
void
*opaque, DynBufReallocFunc *realloc_func);
int
dbuf_realloc(DynBuf *s,
size_t
new_size);
int
dbuf_write(DynBuf *s,
size_t
offset,
const
uint8_t *data,
size_t
len);
int
dbuf_put(DynBuf *s,
const
uint8_t *data,
size_t
len);
int
dbuf_put_self(DynBuf *s,
size_t
offset,
size_t
len);
int
dbuf_putc(DynBuf *s, uint8_t c);
int
dbuf_putstr(DynBuf *s,
const
char
*str);
static
inline
int
dbuf_put_u16(DynBuf *s, uint16_t val)
{
return
dbuf_put(s, (uint8_t *)&val, 2);
}
static
inline
int
dbuf_put_u32(DynBuf *s, uint32_t val)
{
return
dbuf_put(s, (uint8_t *)&val, 4);
}
static
inline
int
dbuf_put_u64(DynBuf *s, uint64_t val)
{
return
dbuf_put(s, (uint8_t *)&val, 8);
}
int
__attribute__((format(
printf
, 2, 3))) dbuf_printf(DynBuf *s,
const
char
*fmt, ...);
void
dbuf_free(DynBuf *s);
static
inline
BOOL
dbuf_error(DynBuf *s) {
return
s->error;
}
static
inline
void
dbuf_set_error(DynBuf *s)
{
s->error = TRUE;
}
#define UTF8_CHAR_LEN_MAX 6
int
unicode_to_utf8(uint8_t *buf, unsigned
int
c);
int
unicode_from_utf8(
const
uint8_t *p,
int
max_len,
const
uint8_t **pp);
static
inline
int
from_hex(
int
c)
{
if
(c >=
'0'
&& c <=
'9'
)
return
c -
'0'
;
else
if
(c >=
'A'
&& c <=
'F'
)
return
c -
'A'
+ 10;
else
if
(c >=
'a'
&& c <=
'f'
)
return
c -
'a'
+ 10;
else
return
-1;
}
void
rqsort(
void
*base,
size_t
nmemb,
size_t
size,
int
(*cmp)(
const
void
*,
const
void
*,
void
*),
void
*arg);
#endif /* CUTILS_H */