// SPDX-License-Identifier: LGPL-3.0-or-later #pragma once #define HKVS_API extern __attribute__((__visibility__("protected"), __nothrow__)) #define HKVS_INTERNAL extern __attribute__((__visibility__("hidden"), __nothrow__)) #define HKVS_PURE __attribute__((__pure__)) #define HKVS_CONST __attribute__((__const__)) #define HKVS_NORETURN __attribute__((__noreturn__, __cold__)) #define HKVS_FALLTHROUGH __attribute__((__fallthrough__)) #include #include #include #include #include HKVS_INLINE void hkvs_assume(bool cond) { if(!cond) { #ifdef HKVS_FUZZING hkvs_die("assumption failed"); #else __builtin_unreachable(); #endif } } HKVS_INLINE uint8_t hkvs_read_u8(const char *pv) { const uint8_t *p = (const uint8_t*)pv; return *p; } HKVS_INLINE void hkvs_write_u8(char *pv, uint8_t v) { uint8_t *p = (uint8_t*)pv; p[0] = v; } HKVS_INLINE uint16_t hkvs_read_u16(const char *pv) { const uint8_t *p = (const uint8_t*)pv; return (uint16_t)( (uint16_t)p[0] | (uint16_t)p[1] << 8 ); } HKVS_INLINE void hkvs_write_u16(char *pv, uint16_t v) { uint8_t *p = (uint8_t*)pv; p[0] = (uint8_t)(v >> 0); p[1] = (uint8_t)(v >> 8); } HKVS_INLINE uint32_t hkvs_read_u32(const char *pv) { const uint8_t *p = (const uint8_t*)pv; return (uint32_t)( (uint32_t)p[0] | (uint32_t)p[1] << 8 | (uint32_t)p[2] << 16 | (uint32_t)p[3] << 24 ); } HKVS_INLINE void hkvs_write_u32(char *pv, uint32_t v) { uint8_t *p = (uint8_t*)pv; p[0] = (uint8_t)(v >> 0); p[1] = (uint8_t)(v >> 8); p[2] = (uint8_t)(v >> 16); p[3] = (uint8_t)(v >> 24); } HKVS_INLINE uint64_t hkvs_read_u64(const char *pv) { const uint8_t *p = (const uint8_t*)pv; return (uint64_t)( (uint64_t)p[0] | (uint64_t)p[1] << 8 | (uint64_t)p[2] << 16 | (uint64_t)p[3] << 24 | (uint64_t)p[4] << 32 | (uint64_t)p[5] << 40 | (uint64_t)p[6] << 48 | (uint64_t)p[7] << 56 ); } HKVS_INLINE void hkvs_write_u64(char *pv, uint64_t v) { uint8_t *p = (uint8_t*)pv; p[0] = (uint8_t)(v >> 0); p[1] = (uint8_t)(v >> 8); p[2] = (uint8_t)(v >> 16); p[3] = (uint8_t)(v >> 24); p[4] = (uint8_t)(v >> 32); p[5] = (uint8_t)(v >> 40); p[6] = (uint8_t)(v >> 48); p[7] = (uint8_t)(v >> 56); } HKVS_INTERNAL HKVS_NORETURN void hkvs_die(const char *msg); HKVS_INTERNAL HKVS_NORETURN void hkvs_die_ext(const char *func, const char *file, int line, const char *msg); #define hkvs_die(msg) hkvs_die_ext(__func__, __FILE__, __LINE__, msg) HKVS_INTERNAL HKVS_PURE uint64_t hkvs_hash(const char *hk, const char *data, size_t data_size);