msgpuck.h(3)

πŸ“¦
version 2.0 Β· 3 versions
, in ubuntu resolute, ubuntu stonking

🌸 NAME 🌸

okay bestie, welcome to msgpuck.h(3) β€” that's section 3, the Library Functions Manual, and it's giving iconic ✨

msgpuck.h β€” MsgPuck is a simple and efficient MsgPack encoder/decoder library in a single self-contained file. that's it. that's the whole vibe. one file, no drama, no build system trauma πŸ’…


✨ SYNOPSIS ✨

first things first, you gotta pull in the whole friend group of headers 🫢

#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <assert.h>
#include <stdarg.h>
#include <stdio.h>

πŸŽ€ Enumerations πŸŽ€

enum mp_type { MP_NIL = 0, MP_UINT, MP_INT, MP_STR, MP_BIN, MP_ARRAY,
    MP_MAP, MP_BOOL, MP_FLOAT, MP_DOUBLE, MP_EXT }

these are your MsgPack data types, no cap 🌈 that's the whole list, MP_NIL through MP_EXT, and yes MP_NIL is literally 0 because of course it is.

πŸ”₯ Functions πŸ”₯

okay here comes the main event, the whole cast of characters πŸ‘‘

  • MP_PROTO enum mp_type mp_typeof (const char c) β€” figure out the MsgPack type by peeking at the first byte c of your encoded data. little sniff test, very main character πŸ‘ƒβœ¨
  • MP_PROTO uint32_t mp_sizeof_array (uint32_t size) β€” calculate the exact buffer size you need to store an array header of size elements. the biggest it can return is 5. and because performance is a love language, you're allowed to just preallocate the max size without even calling this function πŸ’…
  • MP_PROTO char * mp_encode_array (char *data, uint32_t size) β€” encode an array header of size elements.
  • MP_PROTO ptrdiff_t mp_check_array (const char *cur, const char *end) β€” check that the cur buffer actually has enough bytes to decode an array header.
  • MP_PROTO uint32_t mp_decode_array (const char **data) β€” decode an array header from MsgPack data.
  • MP_PROTO uint32_t mp_sizeof_map (uint32_t size) β€” same energy as mp_sizeof_array, but for a map header of size elements. max return value is 5, and again, for performance reasons you can preallocate the max size without calling the function πŸŽ€
  • MP_PROTO char * mp_encode_map (char *data, uint32_t size) β€” encode a map header of size elements.
  • MP_PROTO ptrdiff_t mp_check_map (const char *cur, const char *end) β€” check that cur has enough bytes to decode a map header.
  • MP_PROTO uint32_t mp_decode_map (const char **data) β€” decode a map header from MsgPack data.
  • MP_PROTO uint32_t mp_sizeof_uint (uint64_t num) β€” calculate the exact buffer size needed to store an integer num. max return value is 9. for performance reasons you can preallocate the max size without calling the function. Example usage:
  • MP_PROTO uint32_t mp_sizeof_int (int64_t num) β€” calculate the exact buffer size needed to store an integer num. max return value is 9. for performance reasons you can preallocate the max size without calling the function.
  • MP_PROTO char * mp_encode_uint (char *data, uint64_t num) β€” encode an unsigned integer num. bestie, it is your responsibility to make sure data has enough space 😭
  • MP_PROTO char * mp_encode_int (char *data, int64_t num) β€” encode a signed integer num. again, your responsibility to make sure data has enough space.
  • MP_PROTO ptrdiff_t mp_check_uint (const char *cur, const char *end) β€” check that cur has enough bytes to decode an uint.
  • MP_PROTO ptrdiff_t mp_check_int (const char *cur, const char *end) β€” check that cur has enough bytes to decode an int.
  • MP_PROTO uint64_t mp_decode_uint (const char **data) β€” decode an unsigned integer from MsgPack data.
  • MP_PROTO int64_t mp_decode_int (const char **data) β€” decode a signed integer from MsgPack data.
  • MP_PROTO int mp_compare_uint (const char *data_a, const char *data_b) β€” compare two packed unsigned integers. who's winning, data_a or data_b πŸ’€
  • MP_PROTO uint32_t mp_sizeof_float (float num) β€” calculate the exact buffer size needed to store a float num. the return value is always 5. this function was added to provide integrity of the library, periodt.
  • MP_PROTO uint32_t mp_sizeof_double (double num) β€” calculate the exact buffer size needed to store a double num. the return value is either 5 or 9. added to provide integrity of the library, and for performance reasons you can preallocate the max size without calling the function.
  • MP_PROTO char * mp_encode_float (char *data, float num) β€” encode a float num. your responsibility that data has enough space, bestie πŸ™ˆ
  • MP_PROTO char * mp_encode_double (char *data, double num) β€” encode a double num. same deal, your responsibility.
  • MP_PROTO ptrdiff_t mp_check_float (const char *cur, const char *end) β€” check that cur has enough bytes to decode a float.
  • MP_PROTO ptrdiff_t mp_check_double (const char *cur, const char *end) β€” check that cur has enough bytes to decode a double.
  • MP_PROTO float mp_decode_float (const char **data) β€” decode a float from MsgPack data.
  • MP_PROTO double mp_decode_double (const char **data) β€” decode a double from MsgPack data.
  • MP_PROTO uint32_t mp_sizeof_strl (uint32_t len) β€” calculate the exact buffer size needed to store a string header of length num. max return value is 5, and for performance reasons you can preallocate the max size without calling the function.
  • MP_PROTO uint32_t mp_sizeof_str (uint32_t len) β€” equivalent to mp_sizeof_strl(len) + len. math girlies rise 🧚
  • MP_PROTO uint32_t mp_sizeof_binl (uint32_t len) β€” calculate the exact buffer size needed to store a binstring header of length num. max return value is 5, same preallocate-max-perf situation.
  • MP_PROTO uint32_t mp_sizeof_bin (uint32_t len) β€” equivalent to mp_sizeof_binl(len) + len.
  • MP_PROTO char * mp_encode_strl (char *data, uint32_t len) β€” encode a string header of length len.
  • MP_PROTO char * mp_encode_str (char *data, const char *str, uint32_t len) β€” encode a string of length len. this one is literally equivalent to mp_encode_strl() + memcpy πŸ’«
  • MP_PROTO char * mp_encode_binl (char *data, uint32_t len) β€” encode a binstring header of length len. see mp_encode_strl() for more details, iykyk.
  • MP_PROTO char * mp_encode_bin (char *data, const char *str, uint32_t len) β€” encode a binstring of length len. equivalent to mp_encode_binl() + memcpy.
  • size_t mp_format (char *data, size_t data_size, const char *format,...) β€” encode a sequence of values according to the format string. example time β€” and ngl the source text here arrives fully garbled, so here it is exactly as it shows up in the page, character for character 😭
mp_format(buf, sz, [%d{%d%s%d%s}]",42,0,false,1,true);togetamsgpackarrayoftwoitems:number42andmap(0->"false,2->"true")Doesnotwriteitemsthatdon'tfittodata_sizeargument.

decoded from the chaos: you call mp_format to get a msgpack array of two items β€” number 42, and a map (0 -> "false", 2 -> "true"). and the last bit is important: it does not write items that don't fit into the data_size argument 🫢

  • size_t mp_vformat (char *data, size_t data_size, const char *format, va_list args) β€” the mp_format variation that takes a variable argument list. example:
va_list args;
va_start(args, fmt);
mp_vformat(data, data_size, fmt, args);
va_end(args);
  • int mp_fprint (FILE *file, const char *data) β€” print MsgPack data to file using a JSON-like format. MP_EXT is printed as undefined" (yes, that stray quote is really in there πŸ’€).
  • int mp_snprint (char *buf, int size, const char *data) β€” format MsgPack data into buf using a JSON-like format.
  • MP_PROTO ptrdiff_t mp_check_strl (const char *cur, const char *end) β€” check that cur has enough bytes to decode a string header.
  • MP_PROTO ptrdiff_t mp_check_binl (const char *cur, const char *end) β€” check that cur has enough bytes to decode a binstring header.
  • MP_PROTO uint32_t mp_decode_strl (const char **data) β€” decode a length of a string from MsgPack data.
  • MP_PROTO const char * mp_decode_str (const char **data, uint32_t *len) β€” decode a string from MsgPack data.
  • MP_PROTO uint32_t mp_decode_binl (const char **data) β€” decode a length of a binstring from MsgPack data.
  • MP_PROTO const char * mp_decode_bin (const char **data, uint32_t *len) β€” decode a binstring from MsgPack data.
  • MP_PROTO uint32_t mp_decode_strbinl (const char **data) β€” decode a length of a string or binstring from MsgPack data. flexible queen ✨
  • MP_PROTO const char * mp_decode_strbin (const char **data, uint32_t *len) β€” decode a string or binstring from MsgPack data.
  • MP_PROTO uint32_t mp_sizeof_nil (void) β€” calculate the exact buffer size needed to store the nil value. return value is always 1. added to provide integrity of the library πŸŽ€
  • MP_PROTO char * mp_encode_nil (char *data) β€” encode the nil value. and yep, your responsibility that data has enough space.
  • MP_PROTO ptrdiff_t mp_check_nil (const char *cur, const char *end) β€” check that cur has enough bytes to decode nil.
  • MP_PROTO void mp_decode_nil (const char **data) β€” decode the nil value from MsgPack data.
  • MP_PROTO uint32_t mp_sizeof_bool (bool val) β€” calculate the exact buffer size needed to store a boolean value. return value is always 1. added to provide integrity of the library.
  • MP_PROTO char * mp_encode_bool (char *data, bool val) β€” encode a bool value val. your responsibility that data has enough space, bestie 😭
  • MP_PROTO ptrdiff_t mp_check_bool (const char *cur, const char *end) β€” check that cur has enough bytes to decode a bool value.
  • MP_PROTO bool mp_decode_bool (const char **data) β€” decode a bool value from MsgPack data.
  • MP_PROTO int mp_read_int32 (const char **data, int32_t *ret) β€” decode an integer value as int32_t from MsgPack data.
  • MP_PROTO int mp_read_int64 (const char **data, int64_t *ret) β€” decode an integer value as int64_t from MsgPack data.
  • MP_PROTO int mp_read_double (const char **data, double *ret) β€” decode a floating point value as double from MsgPack data.
  • MP_PROTO void mp_next (const char **data) β€” skip one element in a packed data. ghosting, but make it structural πŸ‘»
  • MP_PROTO int mp_check (const char **data, const char *end) β€” equivalent to mp_next() but it also validates MsgPack in data. the responsible bestie of the group 🫢

πŸ’– Detailed Description πŸ’–

MsgPuck is a simple and efficient MsgPack encoder/decoder library in a single self-contained file.

MsgPuck.

okay so here's the usage example, and it's honestly the whole story in one go 🌟

// Encode
char buf[1024];
char *w = buf;
w = mp_encode_array(w, 4)
w = mp_encode_uint(w, 10);
w = mp_encode_str(w, "hello world", strlen("hello world"));
w = mp_encode_bool(w, true);
w = mp_encode_double(w, 3.1415);

// Validate
const char *b = buf;
int r = mp_check(&b, w);
assert(!r)
assert(b == w);

// Decode
uint32_t size;
uint64_t ival;
const char *sval;
uint32_t sval_len;
bool bval;
double dval;

const char *r = buf;

size = mp_decode_array(&r);
// size is 4

ival = mp_decode_uint(&r);
// ival is 10;

sval = mp_decode_str(&r, &sval_len);
// sval is "hello world", sval_len is strlen("hello world")

bval = mp_decode_bool(&r);
// bval is true

dval = mp_decode_double(&r);
// dval is 3.1415

assert(r == w);

like. encode it, validate it, decode it, assert you landed back where you started. chef's kiss πŸ‘‘

πŸ¦‹ Note πŸ¦‹

  • Supported compilers. the implementation requires a C99+ or C++03+ compatible compiler. so dust off that old toolchain, she's fine ✨
  • Inline functions. the implementation is compatible with both C99 and GNU inline functions. please link libmsgpuck.a static library for the non-inlined versions of functions and global tables πŸ’…

✨ Function Documentation ✨

okay bestie, buckle up, this is the part where we meet the actual functions πŸ’… we got checkers, we got decoders, we got encoders, and every single one of them is here, no skips, no cap 🫢


πŸŽ€ MP_PROTO int mp_check (const char ** data, const char * end)

It's giving "same energy as mp_next()" but with a lil ✨bonus✨ β€” this one also validates the MsgPack sitting in data. Like, it doesn't just walk past it, it inspects it. 🌸

Parameters

  • data β€” the pointer to a buffer
  • end β€” the end of a buffer

Return values

  • 0 when MsgPack in data is valid πŸ’–
  • != 0 when MsgPack in data is not valid πŸ’€

Postcondition

  • *data = *data + mp_sizeof_TYPE() where TYPE is mp_typeof(**data)
  • *data is not defined if MsgPack is not valid 🚨

See also

  • mp_next()

πŸŽ€ MP_PROTO ptrdiff_t mp_check_array (const char * cur, const char * end)

Vibe check: does the cur buffer have enough bytes to decode an array header? πŸ‘‘

Parameters

  • cur buffer
  • end end of the buffer

Return values

  • 0 β€” buffer has enough bytes βœ…
  • > 0 β€” the number of remaining bytes to read 😬

Precondition

  • cur < end
  • mp_typeof(*cur) == MP_ARRAY

πŸŽ€ MP_PROTO ptrdiff_t mp_check_binl (const char * cur, const char * end)

Same vibe check but for a binstring header πŸ“

Parameters

  • cur buffer
  • end end of the buffer

Return values

  • 0 β€” buffer has enough bytes βœ…
  • > 0 β€” the number of remaining bytes to read 😬

Precondition

  • cur < end
  • mp_typeof(*cur) == MP_BIN

πŸŽ€ MP_PROTO ptrdiff_t mp_check_bool (const char * cur, const char * end)

Checking there's enough bytes to decode a bool value πŸŽ€

Parameters

  • cur buffer
  • end end of the buffer

Return values

  • 0 β€” buffer has enough bytes βœ…
  • > 0 β€” the number of remaining bytes to read 😬

Precondition

  • cur < end
  • mp_typeof(*cur) == MP_BOOL

πŸŽ€ MP_PROTO ptrdiff_t mp_check_double (const char * cur, const char * end)

Enough bytes for a double? let's find out πŸ¦‹

Parameters

  • cur buffer
  • end end of the buffer

Return values

  • 0 β€” buffer has enough bytes βœ…
  • > 0 β€” the number of remaining bytes to read 😬

Precondition

  • cur < end
  • mp_typeof(*cur) == MP_DOUBLE

πŸŽ€ MP_PROTO ptrdiff_t mp_check_float (const char * cur, const char * end)

Enough bytes for a float? same deal bestie 🌸

Parameters

  • cur buffer
  • end end of the buffer

Return values

  • 0 β€” buffer has enough bytes βœ…
  • > 0 β€” the number of remaining bytes to read 😬

Precondition

  • cur < end
  • mp_typeof(*cur) == MP_FLOAT

πŸŽ€ MP_PROTO ptrdiff_t mp_check_int (const char * cur, const char * end)

Enough bytes for an int? say less πŸ’œ

Parameters

  • cur buffer
  • end end of the buffer

Return values

  • 0 β€” buffer has enough bytes βœ…
  • > 0 β€” the number of remaining bytes to read 😬

Precondition

  • cur < end
  • mp_typeof(*cur) == MP_INT

πŸŽ€ MP_PROTO ptrdiff_t mp_check_map (const char * cur, const char * end)

Enough bytes to decode a map header? iconic behavior 🌈

Parameters

  • cur buffer
  • end end of the buffer

Return values

  • 0 β€” buffer has enough bytes βœ…
  • > 0 β€” the number of remaining bytes to read 😬

Precondition

  • cur < end
  • mp_typeof(*cur) == MP_MAP

πŸŽ€ MP_PROTO ptrdiff_t mp_check_nil (const char * cur, const char * end)

Enough bytes to decode nil? the void, the emptiness, the MP_NIL πŸ’€βœ¨

Parameters

  • cur buffer
  • end end of the buffer

Return values

  • 0 β€” buffer has enough bytes βœ…
  • > 0 β€” the number of remaining bytes to read 😬

Precondition

  • cur < end
  • mp_typeof(*cur) == MP_NIL

πŸŽ€ MP_PROTO ptrdiff_t mp_check_strl (const char * cur, const char * end)

Enough bytes to decode a string header? slay πŸŽ€

Parameters

  • cur buffer
  • end end of the buffer

Return values

  • 0 β€” buffer has enough bytes βœ…
  • > 0 β€” the number of remaining bytes to read 😬

Precondition

  • cur < end
  • mp_typeof(*cur) == MP_STR

πŸŽ€ MP_PROTO ptrdiff_t mp_check_uint (const char * cur, const char * end)

Enough bytes to decode an uint? last one of the checker squad πŸ‘‘

Parameters

  • cur buffer
  • end end of the buffer

Return values

  • 0 β€” buffer has enough bytes βœ…
  • > 0 β€” the number of remaining bytes to read 😬

Precondition

  • cur < end
  • mp_typeof(*cur) == MP_UINT

πŸŽ€ MP_PROTO int mp_compare_uint (const char * data_a, const char * data_b)

Comparing two packed unsigned integers 🫢 and here's the tea: this is faster than making two mp_decode_uint() calls. Efficiency ate, no crumbs left πŸ”₯

Parameters

  • data_a unsigned int a
  • data_b unsigned int b

Return values

  • < 0 when a < b
  • 0 when a == b
  • > 0 when a > b

πŸŽ€ MP_PROTO uint32_t mp_decode_array (const char ** data)

Decode an array header out of MsgPack data πŸ’– heads up bestie: all array members have to be decoded after the header, the header is just the intro, the rest is the main character energy.

Parameters

  • data β€” the pointer to a buffer

Returns

  • the number of elements in an array

Postcondition

  • *data = *data + mp_sizeof_array(retval)

See also

  • An usage example

πŸŽ€ MP_PROTO const char * mp_decode_bin (const char ** data, uint32_t * len)

Decode a binstring out of MsgPack data πŸ“

Parameters

  • data β€” the pointer to a buffer
  • len β€” the pointer to save a binstring length

Returns

  • a pointer to a decoded binstring

Postcondition

  • *data = *data + mp_sizeof_str(*len)

See also

  • mp_encode_binl

πŸŽ€ MP_PROTO uint32_t mp_decode_binl (const char ** data)

Decode just the length of a binstring from MsgPack data πŸŽ€

Parameters

  • data β€” the pointer to a buffer

Returns

  • a length of a binstring

Postcondition

  • *data = *data + mp_sizeof_binl(retval)

See also

  • mp_encode_binl

πŸŽ€ MP_PROTO bool mp_decode_bool (const char ** data)

Decode a bool value from MsgPack data πŸ¦‹ true or false, no in between, periodt.

Parameters

  • data β€” the pointer to a buffer

Returns

  • a decoded bool value

Postcondition

  • *data = *data + mp_sizeof_bool(retval)

πŸŽ€ MP_PROTO double mp_decode_double (const char ** data)

Decode a double from MsgPack data ✨

Parameters

  • data β€” the pointer to a buffer

Returns

  • a double

Postcondition

  • *data = *data + mp_sizeof_double(retval)

πŸŽ€ MP_PROTO float mp_decode_float (const char ** data)

Decode a float from MsgPack data 🌸

Parameters

  • data β€” the pointer to a buffer

Returns

  • a float

Postcondition

  • *data = *data + mp_sizeof_float(retval)

πŸŽ€ MP_PROTO int64_t mp_decode_int (const char ** data)

Decode a signed integer from MsgPack data πŸ’œ

Parameters

  • data β€” the pointer to a buffer

Returns

  • an unsigned number

Postcondition

  • *data = *data + mp_sizeof_int(retval)

πŸŽ€ MP_PROTO uint32_t mp_decode_map (const char ** data)

Decode a map header from MsgPack data πŸ—ΊοΈ and yes, all map key-value pairs must be decoded after the header β€” the header is not the whole story, bestie.

Parameters

  • data β€” the pointer to a buffer

Returns

  • the number of key/value pairs in a map

Postcondition

  • *data = *data + mp_sizeof_array(retval)

See also

  • An usage example

πŸŽ€ MP_PROTO void mp_decode_nil (const char ** data)

Decode the nil value from MsgPack data πŸ•³οΈ nothing to return, it's literally nothing, that's the whole point πŸ’€

Parameters

  • data β€” the pointer to a buffer

Postcondition

  • *data = *data + mp_sizeof_nil()

πŸŽ€ MP_PROTO const char * mp_decode_str (const char ** data, uint32_t * len)

Decode a string from MsgPack data πŸ’–

Parameters

  • data β€” the pointer to a buffer
  • len β€” the pointer to save a string length

Returns

  • a pointer to a decoded string

Postcondition

  • *data = *data + mp_sizeof_str(*len)

See also

  • mp_encode_binl

πŸŽ€ MP_PROTO const char * mp_decode_strbin (const char ** data, uint32_t * len)

Decode a string or a binstring from MsgPack data 🌈 the flexible icon, truly undecided and thriving.

Parameters

  • data β€” the pointer to a buffer
  • len β€” the pointer to save a binstring length

Returns

  • a pointer to a decoded binstring

Postcondition

  • *data = *data + mp_sizeof_strbinl(*len)

See also

  • mp_encode_binl

πŸŽ€ MP_PROTO uint32_t mp_decode_strbinl (const char ** data)

Decode the length of a string or binstring from MsgPack data πŸŽ€

Parameters

  • data β€” the pointer to a buffer

Returns

  • a length of a string

Postcondition

  • *data = *data + mp_sizeof_strbinl(retval)

See also

  • mp_encode_binl

πŸŽ€ MP_PROTO uint32_t mp_decode_strl (const char ** data)

Decode the length of a string from MsgPack data 🌸

Parameters

  • data β€” the pointer to a buffer

Returns

  • a length of astring

Postcondition

  • *data = *data + mp_sizeof_strl(retval)

See also

  • mp_encode_strl

πŸŽ€ MP_PROTO uint64_t mp_decode_uint (const char ** data)

Decode an unsigned integer from MsgPack data πŸ‘‘

Parameters

  • data β€” the pointer to a buffer

Returns

  • an unsigned number

Postcondition

  • *data = *data + mp_sizeof_uint(retval)

πŸŽ€ MP_PROTO char * mp_encode_array (char * data, uint32_t size)

Encode an array header of size elements πŸ’… and reminder bestie: all array members must be encoded after the header. The header opens the door, you still gotta walk everybody through it.

Example usage, and yes we're keeping it exactly as written, semicolons and all 🫢:

// Encode
char buf[1024];
char *w = buf;
w = mp_encode_array(w, 2)
w = mp_encode_uint(w, 10);
w = mp_encode_uint(w, 15);

// Decode
const char *r = buf;
uint32_t size = mp_decode_array(&r);
for (uint32_t i = 0; i < size; i++) {
    uint64_t val = mp_decode_uint(&r);
}
assert (r == w);
⚠️ It is your responsibility to ensure that data has enough space. Nobody's gonna hold your hand on this one, the buffer is yours πŸ’€

Parameters

  • data β€” a buffer
  • size β€” a number of elements

Returns

  • data + mp_sizeof_array(size)

See also

  • mp_sizeof_array

πŸŽ€ MP_PROTO char * mp_encode_bin (char * data, const char * str, uint32_t len)

Encode a binstring of length len πŸ“ this one is literally mp_encode_binl() + memcpy, that's the whole recipe, no secret ingredients.

Parameters

  • data β€” a buffer
  • str β€” a pointer to binstring data
  • len β€” a binstring length

Returns

  • data + mp_sizeof_bin(len) == data + mp_sizeof_binl(len) + len

See also

  • mp_encode_strl

πŸŽ€ MP_PROTO char * mp_encode_binl (char * data, uint32_t len)

Encode a binstring header of length len πŸŽ€ and bestie, go peek at mp_encode_strl() for the deets.

Parameters

  • data β€” a bufer
  • len β€” a string length

Returns

  • data + mp_sizeof_binl(len)

See also

  • mp_encode_strl

πŸŽ€ MP_PROTO char * mp_encode_bool (char * data, bool val)

Encode a bool value val πŸ¦‹

⚠️ It is your responsibility to ensure that data has enough space. Yes, again. This is a recurring theme, bestie, it's giving "the library trusts you" 😭

Parameters

  • data β€” a buffer
  • val β€” a bool

Returns

  • data + mp_sizeof_bool(val)

See also

  • An usage example
  • mp_sizeof_bool()

πŸŽ€ MP_PROTO char * mp_encode_double (char * data, double num)

Encode a double num ✨

⚠️ It is your responsibility to ensure that data has enough space. Same warning, same energy, we stay consistent πŸ’œ

Parameters

  • data β€” a buffer
  • num β€” a float

Returns β€” data + mp_sizeof_double(num)

See also β€” An usage example, mp_sizeof_double()


MP_PROTO char * mp_encode_float (char * data, float num)</p>

Encodes a float num, bestie. And yes, it's on you to make sure data has enough room β€” the function is not gonna check for you. It is your responsibility to ensure that data has enough space.

Parameters

  • data β€” a buffer
  • num β€” a float

Returns

data + mp_sizeof_float(num)

See also

  • mp_sizeof_float()
  • An usage example

MP_PROTO char * mp_encode_int (char * data, int64_t num)</p>

Encodes a signed integer num πŸ’œ. Same deal as always: it is your responsibility to ensure that data has enough space.

Parameters

  • data β€” a buffer
  • num β€” a number

Returns

data + mp_sizeof_int(num)

See also

  • An usage example
  • mp_sizeof_int()

Precondition

num < 0


MP_PROTO char * mp_encode_map (char * data, uint32_t size)</p>

Encodes a map header of size elements ✨. Heads up though β€” the header is only the header. All the map's key-value pairs have to be encoded after it, one by one, in order. No skipping, no shortcuts.

Example usage:

char buf[1024];

// Encode
char *w = buf;
w = mp_encode_map(b, 2);
w = mp_encode_str(b, "key1", 4);
w = mp_encode_str(b, "value1", 6);
w = mp_encode_str(b, "key2", 4);
w = mp_encode_str(b, "value2", 6);

// Decode
const char *r = buf;
uint32_t size = mp_decode_map(&r);
for (uint32_t i = 0; i < size; i++) {
     // Use switch(mp_typeof(**r)) to support more types
    uint32_t key_len, val_len;
    const char *key = mp_decode_str(&r, key_len);
    const char *val = mp_decode_str(&r, val_len);
}
assert (r == w);

It is your responsibility to ensure that data has enough space. (say it with me now 🫢)

Parameters

  • data β€” a buffer
  • size β€” a number of key/value pairs

Returns

data + mp_sizeof_map(size)

See also

  • mp_sizeof_map

MP_PROTO char * mp_encode_nil (char * data)</p>

Encodes the nil value, the little nothingburger of MsgPack πŸ’€. And guess what: it is your responsibility to ensure that data has enough space.

Parameters

  • data β€” a buffer

Returns

data + mp_sizeof_nil()

See also

  • An usage example
  • mp_sizeof_nil()

MP_PROTO char * mp_encode_str (char * data, const char * str, uint32_t len)</p>

Encodes a string of length len 🌸. This one is literally just mp_encode_strl() + memcpy β€” header first, then the bytes. That's the whole vibe.

Parameters

  • data β€” a buffer
  • str β€” a pointer to string data
  • len β€” a string length

Returns

data + mp_sizeof_str(len) == data + mp_sizeof_strl(len) + len

See also

  • mp_encode_strl

MP_PROTO char * mp_encode_strl (char * data, uint32_t len)</p>

Encodes a string header of length len β€” and I mean only the header, bestie. It writes the MsgPack header for a string of length len, and then you have to append the actual string data to the buffer yourself, by hand: exactly len bytes, no trailing '\0' πŸ™ˆ.

This approach is super useful when you already know the total length of the string up front, but the string data isn't sitting in one continuous buffer (think network packets arriving one by one β€” classic).

It is your responsibility to ensure that data has enough space. Usage example:

char buffer[1024];
char *b = buffer;
b = mp_encode_strl(b, hdr.total_len);
char *s = b;
memcpy(b, pkt1.data, pkt1.len)
b += pkt1.len;
// get next packet
memcpy(b, pkt2.data, pkt2.len)
b += pkt2.len;
// get next packet
memcpy(b, pkt1.data, pkt3.len)
b += pkt3.len;

// Check that all data was received
assert(hdr.total_len == (uint32_t) (b - s))

Hint: you can dynamically reallocate the buffer during the process. πŸ‘‘

Parameters

  • data β€” a buffer
  • len β€” a string length

Returns

data + mp_sizeof_strl(len)

See also

  • mp_sizeof_strl()

MP_PROTO char * mp_encode_uint (char * data, uint64_t num)</p>

Encodes an unsigned integer num ⭐. And yep, the eternal rule: it is your responsibility to ensure that data has enough space.

Parameters

  • data β€” a buffer
  • num β€” a number

Returns

data + mp_sizeof_uint(num)

See also

  • An usage example
  • mp_sizeof_uint()

size_t mp_format (char * data, size_t data_size, const char * format, ...)</p>

Encodes a whole sequence of values according to a format string 🌈. Like, one call, many values, iconic behaviour.

Example: mp_format(buf, sz, "[%d {%d%s%d%s}]", 42, 0, "false", 1, "true"); gets you a msgpack array of two items β€” the number 42, and a map (0->"false", 2->"true"). Does not write items that don't fit to data_size argument.

Parameters

  • data β€” a buffer
  • data_size β€” a buffer size
  • format β€” zero-end string, containing structure of resulting msgpack and types of next arguments. Format can contain '[' and ']' pairs, defining arrays, '{' and '}' pairs, defining maps, and format specifiers, described below:
    • d, i β€” int
    • u β€” unsigned int
    • ld, li β€” long
    • lu β€” unsigned long
    • lld, lli β€” long long
    • llu β€” unsigned long long
    • hd, hi β€” short
    • hu β€” unsigned short
    • hhd, hhi β€” char (as number)
    • hhu β€” unsigned char (as number)
    • f β€” float
    • lf β€” double
    • b β€” bool
    • s β€” zero-end string
    • %.*s β€” string with specified length
    • p β€” MsgPack data
    • %.*p β€” MsgPack data with specified length
    • %% is ignored
    • smthelse assert and undefined behaviour ⚠️
    • NIL β€” a nil value
    • all other symbols are ignored.

Returns

the number of requred bytes.

Return values

> data_size means that is not enough space and whole msgpack was not encoded.


int mp_fprint (FILE * file, const char * data)</p>

Prints MsgPack data to a file using a JSON-like format πŸŽ€. Fun fact: MP_EXT gets printed as "undefined".

Parameters

  • file β€” pointer to file (or NULL for stdout)
  • data β€” pointer to buffer containing msgpack object

Return values

  • >=0 β€” the number of bytes printed
  • -1 β€” error

See also

  • fprintf()

MP_PROTO void mp_next (const char ** data)</p>

Skips exactly one element in a packed data blob πŸ¦‹. It's faster than the mp_typeof + mp_decode_XXX() combo β€” no cap. And it's thorough too: for arrays and maps it also skips all the members, and for strings and binstrings it also skips the string data. One call, whole object, gone. Periodt.

Usage example:

char buf[1024];

char *w = buf;
// First MsgPack object
w = mp_encode_uint(w, 10);

// Second MsgPack object
w = mp_encode_array(w, 4);
   w = mp_encode_array(w, 2);
        // Begin of an inner array
        w = mp_encode_str(w, "second inner 1", 14);
        w = mp_encode_str(w, "second inner 2", 14);
        // End of an inner array
   w = mp_encode_str(w, "second", 6);
   w = mp_encode_uint(w, 20);
   w = mp_encode_bool(w, true);

// Third MsgPack object
w = mp_encode_str(w, "third", 5);
// EOF

const char *r = buf;

// First MsgPack object
assert(mp_typeof(**r) == MP_UINT);
mp_next(&r); // skip the first object

// Second MsgPack object
assert(mp_typeof(**r) == MP_ARRAY);
mp_decode_array(&r);
    assert(mp_typeof(**r) == MP_ARRAY); // inner array
    mp_next(&r); // -->> skip the entire inner array (with all members)
    assert(mp_typeof(**r) == MP_STR); // second
    mp_next(&r);
    assert(mp_typeof(**r) == MP_UINT); // 20
    mp_next(&r);
    assert(mp_typeof(**r) == MP_BOOL); // true
    mp_next(&r);

// Third MsgPack object
assert(mp_typeof(**r) == MP_STR); // third
mp_next(&r);

assert(r == w); // EOF

Parameters

  • data β€” the pointer to a buffer

Postcondition

*data = *data + mp_sizeof_TYPE() where TYPE is mp_typeof(**data)


MP_PROTO int mp_read_double (const char ** data, double * ret)</p>

Decodes a floating point value as double from MsgPack data πŸ’œ.

Parameters

  • data β€” the pointer to a buffer
  • ret β€” the pointer to save a result

Return values

  • 0 on success
  • -1 if underlying mp type is not MP_INT, MP_UINT, MP_FLOAT, or MP_DOUBLE
  • -1 if the result can't be stored in double

MP_PROTO int mp_read_int32 (const char ** data, int32_t * ret)</p>

Decodes an integer value as int32_t from MsgPack data ✨.

Parameters

  • data β€” the pointer to a buffer
  • ret β€” the pointer to save a result

Return values

  • 0 on success
  • -1 if underlying mp type is not MP_INT or MP_UINT
  • -1 if the result can't be stored in int32_t

MP_PROTO int mp_read_int64 (const char ** data, int64_t * ret)</p>

Decodes an integer value as int64_t from MsgPack data 🌸.

Parameters

  • data β€” the pointer to a buffer
  • ret β€” the pointer to save a result

Return values

  • 0 on success
  • -1 if underlying mp type is not MP_INT or MP_UINT
  • -1 if the result can't be stored in int64_t

MP_PROTO uint32_t mp_sizeof_array (uint32_t size)</p>

Calculates the exact buffer size you need to store an array header of size elements πŸ“. Maximum return value is 5. And because performance girlies stay winning: for performance reasons you can preallocate a buffer for the maximum size without even calling the function. Slay.

Parameters

  • size β€” a number of elements

Returns

buffer size in bytes (max is 5)


MP_PROTO uint32_t mp_sizeof_bin (uint32_t len)</p>

Equivalent to mp_sizeof_binl(len) + len πŸŽ€.

Parameters

  • len β€” a string length

Returns

size in chars (max is 5 + len)


MP_PROTO uint32_t mp_sizeof_binl (uint32_t len)</p>

Calculates the exact buffer size needed to store a binstring header of length num πŸ’…. Maximum return value is 5. For performance reasons you can preallocate a buffer for the maximum size without calling the function β€” go off.

Parameters

  • len β€” a string length

Returns

size in chars (max is 5)


MP_PROTO uint32_t mp_sizeof_bool (bool val)</p>

Calculates the exact buffer size needed to store a boolean value βœ…. The return value is always 1. The function was added to provide integrity of the library.

Returns

buffer size in bytes (always 1)


MP_PROTO uint32_t mp_sizeof_double (double num)</p>

Calculates the exact buffer size needed to store a double num πŸ’–. The return value is either 5 or 9. The function was added to provide integrity of the library. And for performance reasons you can preallocate a buffer for the maximum size without calling the function.

Parameters

  • num β€” a double

Returns

buffer size in bytes (5 or 9)


MP_PROTO uint32_t mp_sizeof_float (float num)</p>

Calculates the exact buffer size needed to store a float num πŸ¦‹. The return value is always 5. The function was added to provide integrity of the library.

Parameters

  • num β€” a float

Returns

buffer size in bytes (always 5)


MP_PROTO uint32_t mp_sizeof_int (int64_t num)</p>

Calculates the exact buffer size needed to store an integer num ⭐. Maximum return value is 9. For performance reasons you can preallocate a buffer for the maximum size without calling the function.

Parameters

  • num β€” a number

Returns

buffer size in bytes (max is 9)

Precondition

num < 0

πŸ’– MP_PROTO uint32_t mp_sizeof_map (uint32_t size)

okay so bestie, you wanna know exactly how many bytes it takes to hold a map header for size elements? this is the girl for the job. the biggest number she'll ever hand you back is 5. and because she's a performance queen, you're totally allowed to just preallocate for the max size and skip calling her altogether 🫢

Parameters

  • size β€” how many elements you're packing in

Returns

  • the buffer size in bytes (max is 5) ✨

πŸŽ€ MP_PROTO uint32_t mp_sizeof_nil (void )

how big is the nil value? literally always 1. that's it, that's the whole vibe. and bestie, the reason this function exists at all is to keep the library's integrity intact β€” she's here for the ~aesthetic~ of consistency πŸ’…

Returns

  • buffer size in bytes (always 1)

πŸ¦‹ MP_PROTO uint32_t mp_sizeof_str (uint32_t len)

this one's just mp_sizeof_strl(len) + len. simple math, no cap. πŸ“

Parameters

  • len β€” a string length

Returns

  • size in chars (max is 5 + len)

🌸 MP_PROTO uint32_t mp_sizeof_strl (uint32_t len)

calculate the exact buffer size needed to store a string header of length num. biggest return value she'll give you is 5. and for performance reasons (slay), you can preallocate a buffer for the maximum size without ever calling her. icon behaviour honestly πŸ‘‘

Parameters

  • len β€” a string length

Returns

  • size in chars (max is 5)

⭐ MP_PROTO uint32_t mp_sizeof_uint (uint64_t num)

how many bytes does it take to store the integer num? she'll tell you exactly. max return value is 9. and again, for performance reasons you can preallocate for the maximum size without calling her β€” do it like this:

char **data = ...;
char *end = *data;
my_buffer_ensure(mp_sizeof_uint(x), &end);
// my_buffer_ensure(9, &end);
mp_encode_uint(buffer, x);

Parameters

  • num β€” a number

Returns

  • buffer size in bytes (max is 9)

πŸ’œ int mp_snprint (char * buf, int size, const char * data)

formats MsgPack data into buf using a JSON-like format. it's giving "make it readable for the humans" 😌

See also

  • mp_fprint()

Parameters

  • buf β€” buffer to use
  • size β€” buffer size. This function writes at most size bytes (including the terminating null byte ('\0'))
  • data β€” pointer to buffer containing msgpack object

Return values

  • <size β€” the number of characters printed (excluding the null byte)
  • >=size β€” the number of characters (excluding the null byte), which would have been written to the final string if enough space had been available.
  • -1 β€” error 😭

See also

  • snprintf()

🌈 MP_PROTO enum mp_type mp_typeof (const char c)

figures out the MsgPack type from the first byte c of encoded data. like a little vibe check on your bytes πŸ”₯ example usage:

assert(MP_ARRAY == mp_typeof(0x90));

Parameters

  • c β€” a first byte of encoded data

Returns

  • MsgPack type

🧚 size_t mp_vformat (char * data, size_t data_size, const char * format, va_list args)

it's mp_format but the variation that takes a variable argument list. bestie, watch the glow-up:

va_list args;
va_start(args, fmt);
mp_vformat(data, data_size, fmt, args);
va_end(args);

See also

  • mp_format()

πŸ‘‘ Author

Generated automatically by Doxygen for MsgPuck from the source code. (yes, the robots did this, and honestly? they ate πŸ’…)


and that's a wrap on part 4, bestie!! πŸŽ‰ this page came from MsgPuck, dated Mon Dec 8 2025 16:16:59, and you're reading msgpuck.h(3). go forth and serialize responsibly, mwah πŸ’–πŸ¦‹βœ¨

πŸ“¦ where this page comes from