diff options
| -rw-r--r-- | src/nng_compat.c | 146 |
1 files changed, 136 insertions, 10 deletions
diff --git a/src/nng_compat.c b/src/nng_compat.c index 7c0f6871..bed171ac 100644 --- a/src/nng_compat.c +++ b/src/nng_compat.c @@ -173,6 +173,75 @@ nn_shutdown(int s, int ep) } +void * +nn_allocmsg(size_t size, int type) +{ + uintptr_t *ch; + nng_msg *msg; + int rv; + + // Validate type and non-zero size. This also checks for overflow. + if ((type != 0) || (size < 1) || ((size + sizeof (msg) < size))) { + nn_seterror(NNG_EINVAL); + return (NULL); + } + + // So our "messages" from nn are really going to be nng messages + // but to make this work, we use a bit of headroom in the message + // to stash the message header. + if ((rv = nng_msg_alloc(&msg, size + (sizeof (msg)))) != 0) { + nn_seterror(rv); + return (NULL); + } + + memcpy(nng_msg_body(msg), &msg, sizeof (msg)); + + // We are counting on the implementation of nn_msg_trim to not + // reallocate the message but just to leave the prefix inplace. + (void) nng_msg_trim(msg, sizeof (msg)); + + return (nng_msg_body(msg)); +} + + +void +nni_freemsg(void *ptr) +{ + nng_msg *msg; + + memcpy(&msg, ((char *) ptr) - sizeof (msg), sizeof (msg)); + nng_msg_free(msg); +} + + +void * +nni_reallocmsg(void *ptr, size_t len) +{ + nng_msg *msg; + int rv; + + if ((len + sizeof (msg)) < len) { + // overflowed! + nn_seterror(NNG_EINVAL); + return (NULL); + } + + memcpy(&msg, ((char *) ptr) - sizeof (msg), sizeof (msg)); + + // We need to realloc the requested len, plus size for our header. + if ((rv = nng_msg_realloc(msg, len + sizeof (msg))) != 0) { + // We don't free the old message. Code is free to cope + // as it sees fit. + nn_seterror(rv); + return (NULL); + } + // Stash the msg header pointer + memcpy(nng_msg_body(msg), &msg, sizeof (msg)); + nng_msg_trim(msg, sizeof (msg)); + return (nng_msg_body(msg)); +} + + int nn_send(int s, const void *buf, size_t len, int flags) { @@ -189,16 +258,18 @@ nn_send(int s, const void *buf, size_t len, int flags) return (-1); } if (len == NN_MSG) { - // FIX ME -- this is a message allocated another way... - nn_seterror(NNG_ENOTSUP); - return (-1); + nng_msg *msg; + memcpy(&msg, ((char *) buf) - sizeof (msg), sizeof (msg)); + len = nng_msg_len(msg); + rv = nng_sendmsg((nng_socket) s, msg, flags); + } else { + rv = nng_send((nng_socket) s, (void *) buf, len, flags); } - rv = nng_send((nng_socket) s, (void *)buf, len, flags); if (rv != 0) { nn_seterror(rv); return (-1); } - return ((int)len); + return ((int) len); } @@ -206,7 +277,7 @@ int nn_recv(int s, void *buf, size_t len, int flags) { int rv; - + switch (flags) { case NN_DONTWAIT: flags = NNG_FLAG_NONBLOCK; @@ -218,13 +289,68 @@ nn_recv(int s, void *buf, size_t len, int flags) return (-1); } if (len == NN_MSG) { - nn_seterror(NNG_ENOTSUP); - return (-1); + nng_msg *msg; + rv = nng_recvmsg((nng_socket) s, &msg, flags); + if (rv == 0) { + void *body; + // prepend our header to the body... + // Note that this *can* alter the message, + // although for performance reasons it ought not. + // (There should be sufficient headroom.) + nng_msg_prepend(msg, &msg, sizeof (msg)); + // then trim it off :-) + nng_msg_trim(msg, sizeof (msg)); + // store the pointer to the revised body + body = nng_msg_body(msg); + + // arguably we could do this with a pointer store, + // but memcpy gives us extra paranoia in case the + // the receiver is misaligned. + memcpy(buf, &body, sizeof (body)); + len = nng_msg_len(msg); + } + } else { + rv = nng_recv((nng_socket) s, buf, &len, flags); } - rv = nng_recv((nng_socket) s, buf, &len, flags); if (rv != 0) { nn_seterror(rv); return (-1); } - return ((int)len); + return ((int) len); } + + +#if 0 +int +nn_sendmsg(int s, const struct nn_msghdr *mh, int flags) +{ + void *chunk; + + switch (flags) { + case NN_DONTWAIT: + flags = NN_FLAG_NONBLOCK; + break; + case 0: + break; + default: + nn_seterror(NNG_EINVAL); + return (-1); + } + + // Iterate over the iovecs. The first iov may be NN_MSG, + // in which case it must be the only iovec. + + if ((mh->msg_iovlen == 1) && (mh->msg_iov[0].iov_len == NN_MSG)) { + // Chunk is stored at the offset... + chunk = *(void **) mh->msg_iov[0].iov_base; + // Chunk must be aligned + if ((chuink & (sizeof (void *) - 1)) != 0) { + nn_seterror(NNG_EINVAL); + return (-1); + } + size = (size_t) (*(uintptr_t *) (((void **) chunk) - 1)); + } +} + + +#endif |
