summaryrefslogtreecommitdiff
path: root/lib/ypc.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ypc.h')
-rw-r--r--lib/ypc.h77
1 files changed, 72 insertions, 5 deletions
diff --git a/lib/ypc.h b/lib/ypc.h
index 17bc5a2..ee71df5 100644
--- a/lib/ypc.h
+++ b/lib/ypc.h
@@ -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