// ---------------------------------------------------------------------------- // endianness API int is_big(); API int is_little(); API uint16_t swap16( uint16_t x ); API uint32_t swap32( uint32_t x ); API uint64_t swap64( uint64_t x ); API float swap32f(float n); API double swap64f(double n); API uint16_t lil16(uint16_t n); API uint32_t lil32(uint32_t n); API uint64_t lil64(uint64_t n); API uint16_t big16(uint16_t n); API uint32_t big32(uint32_t n); API uint64_t big64(uint64_t n); API float lil32f(float n); API double lil64f(double n); API float big32f(float n); API double big64f(double n); API uint16_t* lil16p(void *p, int sz); API uint16_t* big16p(void *p, int sz); API uint32_t* lil32p(void *p, int sz); API uint32_t* big32p(void *p, int sz); API uint64_t* lil64p(void *p, int sz); API uint64_t* big64p(void *p, int sz); API float * lil32pf(void *p, int sz); API float * big32pf(void *p, int sz); API double * lil64pf(void *p, int sz); API double * big64pf(void *p, int sz); #if is(cl) #define swap16 _byteswap_ushort #define swap32 _byteswap_ulong #define swap64 _byteswap_uint64 #elif is(gcc) #define swap16 __builtin_bswap16 #define swap32 __builtin_bswap32 #define swap64 __builtin_bswap64 #endif #define hton16 big16 #define ntoh16 big16 #define hton32 big32 #define ntoh32 big32 #define hton64 big64 #define ntoh64 big64 #define IS_BIG ((*(uint16_t *)"\0\1") == 1) #define IS_LITTLE ((*(uint16_t *)"\0\1") != 1) // ---------------------------------------------------------------------------- // half packing typedef uint16_t half; API float half_to_float(half value); API half float_to_half(float value); // ---------------------------------------------------------------------------- // int packing // pack16i() -- store a 16-bit int into a char buffer (like htons()) // pack32i() -- store a 32-bit int into a char buffer (like htonl()) // pack64i() -- store a 64-bit int into a char buffer (like htonl()) API void pack16i(uint8_t *buf, uint16_t i, int swap); API void pack32i(uint8_t *buf, uint32_t i, int swap); API void pack64i(uint8_t *buf, uint64_t i, int swap); // unpack16i() -- unpack a 16-bit int from a char buffer (like ntohs()) // unpack32i() -- unpack a 32-bit int from a char buffer (like ntohl()) // unpack64i() -- unpack a 64-bit int from a char buffer (like ntohl()) // changes unsigned numbers to signed if needed. API int16_t unpack16i(const uint8_t *buf, int swap); API int32_t unpack32i(const uint8_t *buf, int swap); API int64_t unpack64i(const uint8_t *buf, int swap); // ---------------------------------------------------------------------------- // float un/packing: 8 (micro), 16 (half), 32 (float), 64 (double) types #define pack754_8(f) ( pack754((f), 8, 4)) #define pack754_16(f) ( pack754((f), 16, 5)) #define pack754_32(f) ( pack754((f), 32, 8)) #define pack754_64(f) ( pack754((f), 64, 11)) #define unpack754_8(u) (unpack754((u), 8, 4)) #define unpack754_16(u) (unpack754((u), 16, 5)) #define unpack754_32(u) (unpack754((u), 32, 8)) #define unpack754_64(u) (unpack754((u), 64, 11)) API uint64_t pack754(long double f, unsigned bits, unsigned expbits); API long double unpack754(uint64_t i, unsigned bits, unsigned expbits); // ---------------------------------------------------------------------------- // variable-length integer packing API uint64_t pack64uv( uint8_t *buffer, uint64_t value ); API uint64_t unpack64uv( const uint8_t *buffer, uint64_t *value ); API uint64_t pack64iv( uint8_t *buffer, int64_t value_ ); API uint64_t unpack64iv( const uint8_t *buffer, int64_t *value ); // ---------------------------------------------------------------------------- // msgpack v5, schema based struct/buffer bitpacking // api v2 API int msgpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{" API bool msgunpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{" // api v1 API int msgpack_new(uint8_t *w, size_t l); API int msgpack_nil(); // write null API int msgpack_chr(bool n); // write boolean API int msgpack_uns(uint64_t n); // write unsigned integer API int msgpack_int(int64_t n); // write integer API int msgpack_str(const char *s); // write string API int msgpack_bin(const char *s, size_t n); // write binary pointer API int msgpack_flt(double g); // write real API int msgpack_ext(uint8_t key, void *val, size_t n); // write extension type API int msgpack_arr(uint32_t n); // write array mark for next N items API int msgpack_map(uint32_t n); // write map mark for next N pairs (N keys + N values) API int msgpack_eof(); // write full? API int msgpack_err(); // write error? API bool msgunpack_new( const void *opaque_or_FILE, size_t bytes ); API bool msgunpack_nil(); API bool msgunpack_chr(bool *chr); API bool msgunpack_uns(uint64_t *uns); API bool msgunpack_int(int64_t *sig); API bool msgunpack_str(char **str); API bool msgunpack_bin(void **bin, uint64_t *len); API bool msgunpack_flt(float *flt); API bool msgunpack_dbl(double *dbl); API bool msgunpack_ext(uint8_t *key, void **val, uint64_t *len); API bool msgunpack_arr(uint64_t *len); API bool msgunpack_map(uint64_t *len); API bool msgunpack_eof(); API bool msgunpack_err(); // ---------------------------------------------------------------------------- // Based on code by Brian "Beej Jorgensen" Hall (public domain) [1]. // Based on code by Ginger Bill's half<->float (public domain) [2]. // - rlyeh, public domain. // // pack.c -- perl/python-ish pack/unpack functions // like printf and scanf, but for binary data. // // format flags: // (<) little endian (>) big endian (! also) (=) native endian // (c) 8-bit char (b) 8-bit byte // (h) 16-bit half (w) 16-bit word // (i) 32-bit integer (u) 32-bit unsigned (f) 32-bit float // (l) 64-bit long (q) 64-bit quad (d) 64-bit double // (v) varint // (s) string (64-bit varint length prepended) // (S) string (32-bit fixed length prepended) // (m) memblock (64-bit varint length prepended) // (M) memblock (32-bit fixed length prepended) // (z) memblock (zeroed) // (#) number of arguments processed (only when unpacking) // // @todo: // - (x) document & test flag // @totest: // - (s) string (64-bit variable length automatically prepended) // - (S) string (32-bit fixed length automatically prepended) // - (m) memblock (64-bit variable length automatically prepended) // - (M) memblock (32-bit fixed length automatically prepended) // - (z) memblock (zeroed) // - (#) number of arguments processed (only when unpacking) // - save data dictated by the format string from the buffer. return: number of bytes written, or 0 if error. // if first argument is zero, returns number of bytes required for packing. API int savef(FILE *file, const char *format, ...); API int saveb(unsigned char *buf, const char *format, ...); // - load data dictated by the format string into the buffer. return: number of bytes read, or 0 if error. // if first argument is zero, returns number of bytes required for unpacking. API int loadf(FILE *file, const char *format, ...); API int loadb(const unsigned char *buf, const char *format, ...);