aboutsummaryrefslogtreecommitdiff
path: root/src/core/message.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/message.c')
-rw-r--r--src/core/message.c78
1 files changed, 69 insertions, 9 deletions
diff --git a/src/core/message.c b/src/core/message.c
index f1e1fc99..6976f4da 100644
--- a/src/core/message.c
+++ b/src/core/message.c
@@ -27,9 +27,17 @@ struct nng_msg {
nni_chunk m_header;
nni_chunk m_body;
nni_time m_expire; // usec
- nni_pipe * m_pipe; // Pipe message was received on
+ nni_list m_options;
};
+typedef struct {
+ int mo_num;
+ size_t mo_sz;
+ void * mo_val;
+ nni_list_node mo_node;
+} nni_msgopt;
+
+
// nni_chunk_grow increases the underlying space for a chunk. It ensures
// that the desired amount of trailing space (including the length)
// and headroom (excluding the length) are available. It also copies
@@ -238,6 +246,7 @@ nni_msg_alloc(nni_msg **mp, size_t sz)
nni_panic("chunk_append failed");
}
+ NNI_LIST_INIT(&m->m_options, nni_msgopt, mo_node);
*mp = m;
return (0);
}
@@ -246,13 +255,72 @@ nni_msg_alloc(nni_msg **mp, size_t sz)
void
nni_msg_free(nni_msg *m)
{
+ nni_msgopt *mo;
+
nni_chunk_free(&m->m_header);
nni_chunk_free(&m->m_body);
+ while ((mo = nni_list_first(&m->m_options)) != NULL) {
+ nni_list_remove(&m->m_options, mo);
+ nni_free(mo, sizeof (*mo) + mo->mo_sz);
+ }
nni_free(m, sizeof (*m));
}
int
+nni_msg_setopt(nni_msg *m, int opt, const void *val, size_t sz)
+{
+ // Find the existing option if present. Note that if we alter
+ // a value, we can wind up trashing old data due to ENOMEM.
+ nni_msgopt *oldmo, *newmo;
+
+ NNI_LIST_FOREACH (&m->m_options, oldmo) {
+ if (oldmo->mo_num == opt) {
+ if (sz == oldmo->mo_sz) {
+ // nice! we can just overwrite old value
+ memcpy(oldmo->mo_val, val, sz);
+ return (0);
+ }
+ break;
+ }
+ }
+ if ((newmo = nni_alloc(sizeof (*newmo) + sz)) == NULL) {
+ return (NNG_ENOMEM);
+ }
+ newmo->mo_val = ((char *) newmo + sizeof (*newmo));
+ newmo->mo_sz = sz;
+ newmo->mo_num = opt;
+ memcpy(newmo->mo_val, val, sz);
+ if (oldmo != NULL) {
+ nni_list_remove(&m->m_options, oldmo);
+ nni_free(oldmo, sizeof (*oldmo) + oldmo->mo_sz);
+ }
+ nni_list_append(&m->m_options, newmo);
+ return (0);
+}
+
+
+int
+nni_msg_getopt(nni_msg *m, int opt, void *val, size_t *szp)
+{
+ nni_msgopt *mo;
+
+ NNI_LIST_FOREACH (&m->m_options, mo) {
+ if (mo->mo_num == opt) {
+ int sz = *szp;
+ if (sz > mo->mo_sz) {
+ sz = mo->mo_sz;
+ memcpy(val, mo->mo_val, sz);
+ *szp = mo->mo_sz;
+ return (0);
+ }
+ }
+ }
+ return (NNG_ENOTSUP);
+}
+
+
+int
nni_msg_realloc(nni_msg *m, size_t sz)
{
int rv = 0;
@@ -344,11 +412,3 @@ nni_msg_trunc_header(nni_msg *m, size_t len)
{
return (nni_chunk_trunc(&m->m_header, len));
}
-
-
-int
-nni_msg_pipe(nni_msg *m, nni_pipe **pp)
-{
- *pp = m->m_pipe;
- return (0);
-}