2024-08-12 15:11:25 +00:00
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// compression api
|
|
|
|
|
|
|
|
enum COMPRESS_FLAGS {
|
|
|
|
COMPRESS_RAW = 0,
|
|
|
|
COMPRESS_PPP = (1<<4),
|
|
|
|
COMPRESS_ULZ = (2<<4),
|
|
|
|
COMPRESS_LZ4 = (3<<4),
|
|
|
|
COMPRESS_CRUSH = (4<<4),
|
|
|
|
COMPRESS_DEFLATE = (5<<4),
|
|
|
|
COMPRESS_LZP1 = (6<<4),
|
|
|
|
COMPRESS_LZMA = (7<<4),
|
|
|
|
COMPRESS_BALZ = (8<<4),
|
|
|
|
COMPRESS_LZW3 = (9<<4),
|
|
|
|
COMPRESS_LZSS = (10<<4),
|
|
|
|
COMPRESS_BCM = (11<<4),
|
|
|
|
COMPRESS_ZLIB = (12<<4), // same as deflate with header
|
|
|
|
};
|
|
|
|
|
|
|
|
API unsigned zbounds(unsigned inlen, unsigned flags);
|
|
|
|
API unsigned zencode(void *out, unsigned outlen, const void *in, unsigned inlen, unsigned flags);
|
|
|
|
API unsigned zexcess(unsigned flags);
|
|
|
|
API unsigned zdecode(void *out, unsigned outlen, const void *in, unsigned inlen, unsigned flags);
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// array de/interleaving
|
|
|
|
//
|
|
|
|
// results:
|
|
|
|
// R0G0B0 R1G1B1 R2G2B2... -> R0R1R2... B0B1B2... G0G1G2...
|
|
|
|
// R0G0B0A0 R1G1B1A1 R2G2B2A2... -> R0R1R2... A0A1A2... B0B1B2... G0G1G2...
|
|
|
|
|
|
|
|
API void *interleave( void *out, const void *list, int list_count, int sizeof_item, unsigned columns );
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// cobs en/decoder
|
|
|
|
|
|
|
|
API unsigned cobs_bounds(unsigned len);
|
|
|
|
API unsigned cobs_encode(const void *in, unsigned inlen, void *out, unsigned outlen);
|
|
|
|
API unsigned cobs_decode(const void *in, unsigned inlen, void *out, unsigned outlen);
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// base92 en/decoder
|
|
|
|
|
|
|
|
API unsigned base92_encode(const void *in, unsigned inlen, void* out, unsigned outlen);
|
|
|
|
API unsigned base92_decode(const void *in, unsigned inlen, void* out, unsigned outlen);
|
|
|
|
API unsigned base92_bounds(unsigned inlen);
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// netstring en/decoder
|
|
|
|
|
|
|
|
API unsigned netstring_bounds(unsigned inlen);
|
|
|
|
API unsigned netstring_encode(const char *in, unsigned inlen, char *out, unsigned outlen);
|
|
|
|
API unsigned netstring_decode(const char *in, unsigned inlen, char *out, unsigned outlen);
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// delta en/decoder
|
|
|
|
|
|
|
|
API void delta8_encode(void *buffer, unsigned count);
|
|
|
|
API void delta8_decode(void *buffer, unsigned count);
|
|
|
|
|
|
|
|
API void delta16_encode(void *buffer, unsigned count);
|
|
|
|
API void delta16_decode(void *buffer, unsigned count);
|
|
|
|
|
|
|
|
API void delta32_encode(void *buffer, unsigned count);
|
|
|
|
API void delta32_decode(void *buffer, unsigned count);
|
|
|
|
|
|
|
|
API void delta64_encode(void *buffer, unsigned count);
|
|
|
|
API void delta64_decode(void *buffer, unsigned count);
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// zigzag en/decoder
|
|
|
|
|
|
|
|
API uint64_t zig64( int64_t value ); // convert sign|magnitude to magnitude|sign
|
|
|
|
API int64_t zag64( uint64_t value ); // convert magnitude|sign to sign|magnitude
|
|
|
|
|
|
|
|
API uint32_t enczig32u( int32_t n);
|
|
|
|
API uint64_t enczig64u( int64_t n);
|
|
|
|
API int32_t deczig32i(uint32_t n);
|
|
|
|
API int64_t deczig64i(uint64_t n);
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// arc4 en/decryptor
|
|
|
|
|
|
|
|
API void *arc4( void *buffer, unsigned buflen, const void *pass, unsigned passlen );
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// crc64
|
|
|
|
|
|
|
|
API uint64_t crc64(uint64_t h, const void *ptr, uint64_t len);
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// entropy encoder
|
|
|
|
|
|
|
|
API void entropy( void *buf, unsigned n );
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
// semantic versioning in a single byte (octal)
|
|
|
|
|
|
|
|
API int semver( int major, int minor, int patch );
|
|
|
|
API int semvercmp( int v1, int v2 );
|
|
|
|
|
|
|
|
#define SEMVER(major,minor,patch) (0100 * (major) + 010 * (minor) + (patch))
|
|
|
|
#define SEMVERCMP(v1,v2) (((v1) & 0110) - ((v2) & 0110))
|
|
|
|
#define SEMVERFMT "%03o"
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
// storage types. refer to vec2i/3i, vec2/3/4 if you plan to do math operations
|
|
|
|
|
|
|
|
typedef struct byte2 { uint8_t x,y; } byte2;
|
|
|
|
typedef struct byte3 { uint8_t x,y,z; } byte3;
|
|
|
|
typedef struct byte4 { uint8_t x,y,z,w; } byte4;
|
|
|
|
|
|
|
|
typedef struct int2 { int x,y; } int2;
|
|
|
|
typedef struct int3 { int x,y,z; } int3;
|
|
|
|
typedef struct int4 { int x,y,z,w; } int4;
|
|
|
|
|
|
|
|
typedef struct uint2 { unsigned int x,y; } uint2;
|
|
|
|
typedef struct uint3 { unsigned int x,y,z; } uint3;
|
|
|
|
typedef struct uint4 { unsigned int x,y,z,w; } uint4;
|
|
|
|
|
|
|
|
typedef struct float2 { float x,y; } float2;
|
|
|
|
typedef struct float3 { float x,y,z; } float3;
|
|
|
|
typedef struct float4 { float x,y,z,w; } float4;
|
|
|
|
|
|
|
|
typedef struct double2 { double x,y; } double2;
|
|
|
|
typedef struct double3 { double x,y,z; } double3;
|
|
|
|
typedef struct double4 { double x,y,z,w; } double4;
|
|
|
|
|
|
|
|
#define byte2(x,y) C_CAST(byte2, (uint8_t)(x), (uint8_t)(y) )
|
|
|
|
#define byte3(x,y,z) C_CAST(byte3, (uint8_t)(x), (uint8_t)(y), (uint8_t)(z) )
|
|
|
|
#define byte4(x,y,z,w) C_CAST(byte4, (uint8_t)(x), (uint8_t)(y), (uint8_t)(z), (uint8_t)(w) )
|
|
|
|
|
|
|
|
#define int2(x,y) C_CAST(int2, (int)(x), (int)(y) )
|
|
|
|
#define int3(x,y,z) C_CAST(int3, (int)(x), (int)(y), (int)(z) )
|
|
|
|
#define int4(x,y,z,w) C_CAST(int4, (int)(x), (int)(y), (int)(z), (int)(w) )
|
|
|
|
|
|
|
|
#define uint2(x,y) C_CAST(uint2, (unsigned)(x), (unsigned)(y) )
|
|
|
|
#define uint3(x,y,z) C_CAST(uint3, (unsigned)(x), (unsigned)(y), (unsigned)(z) )
|
|
|
|
#define uint4(x,y,z,w) C_CAST(uint4, (unsigned)(x), (unsigned)(y), (unsigned)(z), (unsigned)(w) )
|
|
|
|
|
|
|
|
#define float2(x,y) C_CAST(float2, (float)(x), (float)(y) )
|
|
|
|
#define float3(x,y,z) C_CAST(float3, (float)(x), (float)(y), (float)(z) )
|
|
|
|
#define float4(x,y,z,w) C_CAST(float4, (float)(x), (float)(y), (float)(z), (float)(w) )
|
|
|
|
|
|
|
|
#define double2(x,y) C_CAST(double2, (double)(x), (double)(y) )
|
|
|
|
#define double3(x,y,z) C_CAST(double3, (double)(x), (double)(y), (double)(z) )
|
|
|
|
#define double4(x,y,z,w) C_CAST(double4, (double)(x), (double)(y), (double)(z), (double)(w) )
|
|
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
|
|
// compile-time fourcc, eightcc
|
|
|
|
|
|
|
|
API char *cc4str(unsigned cc);
|
|
|
|
API char *cc8str(uint64_t cc);
|
|
|
|
|
|
|
|
enum {
|
|
|
|
# define _(a,b,c,d,e) cc__##a, cc__##b, cc__##c, cc__##d, cc__##e
|
|
|
|
cc__1 = '1', _(2,3,4,5,6),_(7,8,9,0,_), cc__ = ' ',
|
|
|
|
cc__A = 'A', _(B,C,D,E,F),_(G,H,I,J,K),_(L,M,N,O,P),_(Q,R,S,T,U),_(V,W,X,Y,Z),
|
|
|
|
cc__a = 'a', _(b,c,d,e,f),_(g,h,i,j,k),_(l,m,n,o,p),_(q,r,s,t,u),_(v,w,x,y,z),
|
|
|
|
# undef _
|
|
|
|
};
|
|
|
|
|
|
|
|
#ifdef BIG
|
|
|
|
#define cc4(a,b,c,d) ((uint32_t)(cc__##a<<24) | (cc__##b<<16) | (cc__##c<<8) | (cc__##d<<0))
|
|
|
|
#define cc8(a,b,c,d,e,f,g,h) (((uint64_t)cc4(a,b,c,d) << 32ULL) | cc4(e,f,g,h))
|
|
|
|
#else
|
|
|
|
#define cc4(a,b,c,d) ((uint32_t)(cc__##d<<24) | (cc__##c<<16) | (cc__##b<<8) | (cc__##a<<0))
|
|
|
|
#define cc8(a,b,c,d,e,f,g,h) (((uint64_t)cc4(e,f,g,h) << 32ULL) | cc4(a,b,c,d))
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define cc3(a,b,c) cc4(,a,b,c)
|
|
|
|
#define cc5(a,b,c,d,e) cc6(,a,b,c,d,e)
|
|
|
|
#define cc6(a,b,c,d,e,f) cc7(,a,b,c,d,e,f)
|
|
|
|
#define cc7(a,b,c,d,e,f,g) cc8(,a,b,c,d,e,f,g)
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// text conversions
|
|
|
|
|
|
|
|
API char* ftoa1(float v);
|
|
|
|
API char* ftoa2(vec2 v);
|
|
|
|
API char* ftoa3(vec3 v);
|
|
|
|
API char* ftoa4(vec4 v);
|
|
|
|
|
|
|
|
API float atof1(const char *s);
|
|
|
|
API vec2 atof2(const char *s);
|
|
|
|
API vec3 atof3(const char *s);
|
|
|
|
API vec4 atof4(const char *s);
|
|
|
|
|
|
|
|
API char* itoa1(int v);
|
|
|
|
API char* itoa2(vec2i v);
|
|
|
|
API char* itoa3(vec3i v);
|
|
|
|
|
|
|
|
API int atoi1(const char *s);
|
|
|
|
API vec2i atoi2(const char *s);
|
|
|
|
API vec3i atoi3(const char *s);
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// 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 void swapf(float *a, float *b);
|
|
|
|
API void swapf2(vec2 *a, vec2 *b);
|
|
|
|
API void swapf3(vec3 *a, vec3 *b);
|
|
|
|
API void swapf4(vec4 *a, vec4 *b);
|
|
|
|
|
|
|
|
API uint16_t lil16(uint16_t n); // swap16 as lil
|
|
|
|
API uint32_t lil32(uint32_t n); // swap32 as lil
|
|
|
|
API uint64_t lil64(uint64_t n); // swap64 as lil
|
|
|
|
API float lil32f(float n); // swap32 as lil
|
|
|
|
API double lil64f(double n); // swap64 as lil
|
|
|
|
|
|
|
|
API uint16_t big16(uint16_t n); // swap16 as big
|
|
|
|
API uint32_t big32(uint32_t n); // swap32 as big
|
|
|
|
API uint64_t big64(uint64_t n); // swap64 as big
|
|
|
|
API float big32f(float n); // swap32 as big
|
|
|
|
API double big64f(double n); // swap64 as big
|
|
|
|
|
|
|
|
API uint16_t* lil16p(void *p, int sz);
|
|
|
|
API uint32_t* lil32p(void *p, int sz);
|
|
|
|
API uint64_t* lil64p(void *p, int sz);
|
|
|
|
API float * lil32pf(void *p, int sz);
|
|
|
|
API double * lil64pf(void *p, int sz);
|
|
|
|
|
|
|
|
API uint16_t* big16p(void *p, int sz);
|
|
|
|
API uint32_t* big32p(void *p, int sz);
|
|
|
|
API uint64_t* big64p(void *p, int sz);
|
|
|
|
API float * big32pf(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,[,{". returns number of written bytes
|
|
|
|
API int msgunpack(const char *fmt, ... ); // va arg pack "n,b,u,d/i,s,p,f/g,e,[,{". returns number of parsed args
|
|
|
|
|
|
|
|
// 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, ...);
|
|
|
|
|