diff options
Diffstat (limited to 'lib9p')
-rw-r--r-- | lib9p/core.c | 129 |
1 files changed, 56 insertions, 73 deletions
diff --git a/lib9p/core.c b/lib9p/core.c index c777741..a44bab6 100644 --- a/lib9p/core.c +++ b/lib9p/core.c @@ -151,102 +151,85 @@ lo_interface fmt_formatter lo_box_lib9p_msg_as_fmt_formatter(struct lib9p_ctx *c /* main message functions *****************************************************/ -static -ssize_t _lib9p_validate(uint8_t xxx_low_typ_bit, - const char *xxx_errmsg, - const struct _lib9p_recv_tentry xxx_table[LIB9P_VER_NUM][0x80], - struct lib9p_ctx *ctx, uint8_t *net_bytes) { - assert_ver(ctx->version); - /* Inspect the first 5 bytes ourselves. */ - uint32_t net_size = uint32le_decode(net_bytes); - if (net_size < 5) - return lib9p_error(ctx, LIB9P_ERRNO_L_EBADMSG, "message is impossibly short"); - uint8_t typ = net_bytes[4]; - if (typ % 2 != xxx_low_typ_bit) - return lib9p_errorf(ctx, LIB9P_ERRNO_L_EOPNOTSUPP, "%s: message_type=%s", xxx_errmsg, - lib9p_msgtype_str(ctx->version, typ)); - struct _lib9p_recv_tentry tentry = xxx_table[ctx->version][typ/2]; - if (!tentry.validate) - return lib9p_errorf(ctx, LIB9P_ERRNO_L_EOPNOTSUPP, "unknown message type: %s (protocol_version=%s)", - lib9p_msgtype_str(ctx->version, typ), lib9p_version_str(ctx->version)); - - /* Now use the message-type-specific tentry to process the whole thing. */ - return tentry.validate(ctx, net_size, net_bytes); -} +#define _lib9p_validate(LOW_TYP_BIT, ERRMSG, TABLE) do { \ + assert_ver(ctx->version); \ + /* Inspect the first 5 bytes ourselves. */ \ + uint32_t net_size = uint32le_decode(net_bytes); \ + if (net_size < 5) \ + return lib9p_error(ctx, LIB9P_ERRNO_L_EBADMSG, "message is impossibly short"); \ + uint8_t typ = net_bytes[4]; \ + if (typ % 2 != LOW_TYP_BIT) \ + return lib9p_errorf(ctx, LIB9P_ERRNO_L_EOPNOTSUPP, ERRMSG ": message_type=%s", \ + lib9p_msgtype_str(ctx->version, typ)); \ + struct _lib9p_recv_tentry tentry = TABLE[ctx->version][typ/2]; \ + if (!tentry.validate) \ + return lib9p_errorf(ctx, LIB9P_ERRNO_L_EOPNOTSUPP, "unknown message type: %s (protocol_version=%s)", \ + lib9p_msgtype_str(ctx->version, typ), lib9p_version_str(ctx->version)); \ + \ + /* Now use the message-type-specific tentry to process the whole thing. */ \ + return tentry.validate(ctx, net_size, net_bytes); \ +} while (0) ssize_t lib9p_Tmsg_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { - return _lib9p_validate(0, "expected a T-message but got an R-message", _lib9p_table_Tmsg_recv, - ctx, net_bytes); + _lib9p_validate(0, "expected a T-message but got an R-message", _lib9p_table_Tmsg_recv); } ssize_t lib9p_Rmsg_validate(struct lib9p_ctx *ctx, uint8_t *net_bytes) { - return _lib9p_validate(1, "expected an R-message but got a T-message", _lib9p_table_Rmsg_recv, - ctx, net_bytes); + _lib9p_validate(1, "expected an R-message but got a T-message", _lib9p_table_Rmsg_recv); } -static -void _lib9p_unmarshal(const struct _lib9p_recv_tentry xxx_table[LIB9P_VER_NUM][0x80], - struct lib9p_ctx *ctx, uint8_t *net_bytes, - enum lib9p_msg_type *ret_typ, void *ret_body) { - assert_ver(ctx->version); - enum lib9p_msg_type typ = net_bytes[4]; - *ret_typ = typ; - struct _lib9p_recv_tentry tentry = xxx_table[ctx->version][typ/2]; - assert(tentry.unmarshal); - - tentry.unmarshal(ctx, net_bytes, ret_body); -} +#define _lib9p_unmarshal(TABLE) do { \ + assert_ver(ctx->version); \ + enum lib9p_msg_type typ = net_bytes[4]; \ + *ret_typ = typ; \ + struct _lib9p_recv_tentry tentry = TABLE[ctx->version][typ/2]; \ + assert(tentry.unmarshal); \ + \ + tentry.unmarshal(ctx, net_bytes, ret_body); \ +} while (0) void lib9p_Tmsg_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, enum lib9p_msg_type *ret_typ, void *ret_body) { - _lib9p_unmarshal(_lib9p_table_Tmsg_recv, - ctx, net_bytes, ret_typ, ret_body); + _lib9p_unmarshal(_lib9p_table_Tmsg_recv); } void lib9p_Rmsg_unmarshal(struct lib9p_ctx *ctx, uint8_t *net_bytes, enum lib9p_msg_type *ret_typ, void *ret_body) { - _lib9p_unmarshal(_lib9p_table_Rmsg_recv, - ctx, net_bytes, ret_typ, ret_body); + _lib9p_unmarshal(_lib9p_table_Rmsg_recv); } -static -bool _lib9p_marshal(const struct _lib9p_send_tentry xxx_table[LIB9P_VER_NUM][0x80], - struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body, - size_t *ret_iov_cnt, struct iovec *ret_iov, uint8_t *ret_copied) { - assert_ver(ctx->version); - assert_typ(typ); - struct _marshal_ret ret = { - .net_iov_cnt = 1, - .net_iov = ret_iov, - .net_copied_size = 0, - .net_copied = ret_copied, - }; - struct _lib9p_send_tentry tentry = xxx_table[ctx->version][typ/2]; - assert(tentry.marshal); - - bool ret_erred = tentry.marshal(ctx, body, &ret); - if (ret_iov[ret.net_iov_cnt-1].iov_len == 0) - ret.net_iov_cnt--; - *ret_iov_cnt = ret.net_iov_cnt; - return ret_erred; -} +#define _lib9p_marshal(LOW_TYP_BIT, TABLE) do { \ + assert_ver(ctx->version); \ + assert(typ % 2 == LOW_TYP_BIT); \ + assert_typ(typ); \ + \ + memset(ret, 0, sizeof(*ret)); \ + \ + struct _marshal_ret _ret = { \ + .net_iov_cnt = 1, \ + .net_iov = ret->iov, \ + .net_copied_size = 0, \ + .net_copied = ret->copied, \ + }; \ + struct _lib9p_send_tentry tentry = TABLE[ctx->version][typ/2]; \ + assert(tentry.marshal); \ + \ + bool ret_erred = tentry.marshal(ctx, body, &_ret); \ + if (_ret.net_iov[_ret.net_iov_cnt-1].iov_len == 0) \ + _ret.net_iov_cnt--; \ + \ + ret->iov_cnt = _ret.net_iov_cnt; \ + return ret_erred; \ +} while (0) bool lib9p_Tmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body, struct lib9p_Tmsg_send_buf *ret) { - assert(typ % 2 == 0); - memset(ret, 0, sizeof(*ret)); - return _lib9p_marshal(_lib9p_table_Tmsg_send, - ctx, typ, body, - &ret->iov_cnt, ret->iov, ret->copied); + _lib9p_marshal(0, _lib9p_table_Tmsg_send); } bool lib9p_Rmsg_marshal(struct lib9p_ctx *ctx, enum lib9p_msg_type typ, void *body, struct lib9p_Rmsg_send_buf *ret) { - assert(typ % 2 == 1); - memset(ret, 0, sizeof(*ret)); - return _lib9p_marshal(_lib9p_table_Rmsg_send, - ctx, typ, body, - &ret->iov_cnt, ret->iov, ret->copied); + _lib9p_marshal(1, _lib9p_table_Rmsg_send); } /* `struct lib9p_stat` helpers ************************************************/ |