diff options
Diffstat (limited to 'src/core/message.c')
| -rw-r--r-- | src/core/message.c | 78 |
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); -} |
