diff options
Diffstat (limited to 'lib/ypc.h')
-rw-r--r-- | lib/ypc.h | 77 |
1 files changed, 72 insertions, 5 deletions
@@ -24,6 +24,26 @@ typedef struct { uint32_t size, len; } ypc_val; +typedef struct { + const uint8_t *buf; +} ypc_get; + +typedef struct { + const uint8_t *buf; +} ypc_iter; + +typedef enum { + YPC_NULL, + YPC_BOOL, + YPC_INT, + YPC_FLOAT, + YPC_BIN, + YPC_TEXT, + YPC_ARRAY, + YPC_MAP, + YPC_CLOSE +} ypc_type; + #define YPC_NONBLOCK 0x01 #define YPC_RECV 0x02 @@ -72,6 +92,9 @@ YPC_IMPORT int ypc_add_int(ypc_val *, int64_t); YPC_IMPORT int ypc_add_float(ypc_val *, double); YPC_IMPORT int ypc_add_bin(ypc_val *, const uint8_t *, size_t); YPC_IMPORT int ypc_add_textn(ypc_val *, const char *, size_t); +YPC_IMPORT int64_t ypc_get_int(ypc_get); +YPC_IMPORT double ypc_get_float(ypc_get); +YPC_IMPORT size_t ypc_get_size(ypc_get); YPC_IMPORT ypc_msg *ypc_msg_new(const char *, size_t); YPC_IMPORT void ypc_msg_free(ypc_msg *); @@ -99,11 +122,55 @@ YPC_IMPORT void ypc_serv_free(ypc_serv *); /* Smallish stuff that is better suited for inlining */ static inline int ypc_val_init(ypc_val *v, size_t size) { v->buf = NULL; v->len = 0; return ypc_val_resize(v, size ? size : 512); } -static inline int ypc_add_null(ypc_val *v) { return ypc_add_raw(v, (uint8_t *)"\0", 1); } -static inline int ypc_add_bool(ypc_val *v, bool b) { return ypc_add_raw(v, (uint8_t *)(b ? "\2" : "\1"), 1); } +static inline void ypc_val_free(ypc_val *v) { free(v->buf); } +static inline int ypc_add_null(ypc_val *v) { return ypc_add_raw(v, (const uint8_t *)"\0", 1); } +static inline int ypc_add_bool(ypc_val *v, bool b) { return ypc_add_raw(v, (const uint8_t *)(b ? "\2" : "\1"), 1); } static inline int ypc_add_text(ypc_val *v, const char *t) { return ypc_add_textn(v, t, strlen(t)); } -static inline int ypc_add_array(ypc_val *v) { return ypc_add_raw(v, (uint8_t *)"\12", 1); } -static inline int ypc_add_map(ypc_val *v) { return ypc_add_raw(v, (uint8_t *)"\13", 1); } -static inline int ypc_add_close(ypc_val *v) { return ypc_add_raw(v, (uint8_t *)"\14", 1); } +static inline int ypc_add_array(ypc_val *v) { return ypc_add_raw(v, (const uint8_t *)"\12", 1); } +static inline int ypc_add_map(ypc_val *v) { return ypc_add_raw(v, (const uint8_t *)"\13", 1); } +static inline int ypc_add_close(ypc_val *v) { return ypc_add_raw(v, (const uint8_t *)"\14", 1); } +static inline int ypc_add_val(ypc_val *v, ypc_get g) { return ypc_add_raw(v, g.buf, ypc_get_size(g)); } + +static inline ypc_get ypc_val_get(ypc_val *v) { ypc_get g = {v->buf}; return g; } +static inline bool ypc_get_bool(ypc_get g) { return *g.buf == 2; } +static inline const char * ypc_get_text(ypc_get g) { return (const char *)g.buf+1; } +static inline const uint8_t *ypc_get_bin(ypc_get g) { return g.buf+4; } +static inline size_t ypc_get_bin_len(ypc_get g) { return (g.buf[1] << 16) | (g.buf[2] << 8) | g.buf[3]; } +static inline ypc_iter ypc_get_iter(ypc_get g) { ypc_iter i = {g.buf+1}; return i; } +static inline bool ypc_iter_end(ypc_iter i) { return *i.buf == 12; } +static inline ypc_get ypc_iter_next(ypc_iter *i) { ypc_get g = {i->buf}; i->buf += ypc_get_size(g); return g; } + +/* While not very small, this is still a static inline to enable a bunch of + * optimizations. E.g. ypc_get_type(v) == YPC_TEXT should compile down to + * *v->buf == 9, which is much cheaper than a function call. A similar + * optimization is possible when using ypc_get_type() in a switch statement. + */ +static inline ypc_type ypc_get_type(ypc_get *v) { + switch(*v->buf) { + case 0: + return YPC_NULL; + case 1: + case 2: + return YPC_BOOL; + case 3: + case 4: + case 5: + case 6: + return YPC_INT; + case 7: + return YPC_FLOAT; + case 8: + return YPC_BIN; + case 9: + return YPC_TEXT; + case 10: + return YPC_ARRAY; + case 11: + return YPC_MAP; + case 12: + return YPC_CLOSE; + } + return 0; /* Should not happen... */ +} #endif |