X-Git-Url: https://jfr.im/git/solanum.git/blobdiff_plain/b830b64106720904e9b2f0efd18a7a2bc471ad25..8b7503c89abf94300c96597bfb5718b4fd655e89:/include/msgbuf.h diff --git a/include/msgbuf.h b/include/msgbuf.h index a595794e..9bc34bf7 100644 --- a/include/msgbuf.h +++ b/include/msgbuf.h @@ -26,27 +26,63 @@ /* a key-value structure for each message tag. */ struct MsgTag { - const char *key; - const char *value; + const char *key; /* the key of the tag (must be set) */ + const char *value; /* the value of the tag or NULL */ + unsigned int capmask; /* the capability mask this tag belongs to (used only when sending) */ }; struct MsgBuf { - size_t n_tags; - struct MsgTag tags[MAXPARA]; + size_t n_tags; /* the number of tags in the MsgBuf */ + struct MsgTag tags[MAXPARA]; /* the tags themselves, upto MAXPARA tags available */ - const char *origin; - const char *cmd; + const char *origin; /* the origin of the message (or NULL) */ + const char *target; /* the target of the message (either NULL, or custom defined) */ + const char *cmd; /* the cmd/verb of the message (either NULL, or para[0]) */ - size_t parselen; - size_t n_para; - const char *para[MAXPARA]; + size_t n_para; /* the number of parameters (always at least 1 if a full message) */ + const char *para[MAXPARA]; /* parameters vector (starting with cmd as para[0]) */ +}; + +struct MsgBuf_str_data { + const struct MsgBuf *msgbuf; + unsigned int caps; +}; + +#define MSGBUF_CACHE_SIZE 32 + +struct MsgBuf_cache_entry { + unsigned int caps; + buf_head_t linebuf; + struct MsgBuf_cache_entry *next; +}; + +struct MsgBuf_cache { + const struct MsgBuf *msgbuf; + char message[DATALEN + 1]; + unsigned int overall_capmask; + + /* Fixed maximum size linked list, new entries are allocated at the end + * of the array but are accessed through the "next" pointers. + * + * This does not use rb dlink to avoid unnecessary individual allocations. + */ + struct MsgBuf_cache_entry entry[MSGBUF_CACHE_SIZE]; + struct MsgBuf_cache_entry *head; /* LRU cache head */ }; /* * parse a message into a MsgBuf. * returns 0 on success, 1 on error. */ -int msgbuf_parse(struct MsgBuf *msgbuf, const char *line); +int msgbuf_parse(struct MsgBuf *msgbuf, char *line); + +/* + * unparse a pure MsgBuf into a buffer. + * if origin is NULL, me.name will be used. + * cmd may not be NULL. + * returns 0 on success, 1 on error. + */ +int msgbuf_unparse(char *buf, size_t buflen, const struct MsgBuf *msgbuf, unsigned int capmask); /* * unparse a MsgBuf header plus payload into a buffer. @@ -54,7 +90,32 @@ int msgbuf_parse(struct MsgBuf *msgbuf, const char *line); * cmd may not be NULL. * returns 0 on success, 1 on error. */ -int msgbuf_unparse(char *buf, struct MsgBuf *head, const char *fmt, ...) AFP(3, 4); -int msgbuf_vunparse(char *buf, struct MsgBuf *head, const char *fmt, va_list va); +int msgbuf_unparse_fmt(char *buf, size_t buflen, const struct MsgBuf *head, unsigned int capmask, const char *fmt, ...) AFP(5, 6); +int msgbuf_vunparse_fmt(char *buf, size_t buflen, const struct MsgBuf *head, unsigned int capmask, const char *fmt, va_list va); + +int msgbuf_unparse_linebuf_tags(char *buf, size_t buflen, void *data); +int msgbuf_unparse_prefix(char *buf, size_t *buflen, const struct MsgBuf *msgbuf, unsigned int capmask); + +void msgbuf_cache_init(struct MsgBuf_cache *cache, const struct MsgBuf *msgbuf, const rb_strf_t *message); +void msgbuf_cache_initf(struct MsgBuf_cache *cache, const struct MsgBuf *msgbuf, const rb_strf_t *message, const char *format, ...) AFP(4, 5); +buf_head_t *msgbuf_cache_get(struct MsgBuf_cache *cache, unsigned int caps); +void msgbuf_cache_free(struct MsgBuf_cache *cache); + +static inline void +msgbuf_init(struct MsgBuf *msgbuf) +{ + memset(msgbuf, 0, sizeof(*msgbuf)); +} + +static inline void +msgbuf_append_tag(struct MsgBuf *msgbuf, const char *key, const char *value, unsigned int capmask) +{ + if (msgbuf->n_tags < MAXPARA) { + msgbuf->tags[msgbuf->n_tags].key = key; + msgbuf->tags[msgbuf->n_tags].value = value; + msgbuf->tags[msgbuf->n_tags].capmask = capmask; + msgbuf->n_tags++; + } +} #endif