From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> To: tarantool-patches@freelists.org Cc: kostja@tarantool.org Subject: [tarantool-patches] [PATCH 5/7] msgpack: allow to pass 'struct ibuf *' into encode() Date: Wed, 15 May 2019 02:06:23 +0300 [thread overview] Message-ID: <0dbad1e482562fbed3492a9e5d7861a0e8a8ae2f.1557875116.git.v.shpilevoy@tarantool.org> (raw) In-Reply-To: <cover.1557875116.git.v.shpilevoy@tarantool.org> Before the patch msgpack Lua module provided a method encode() able to take a custom buffer to encode into. But it should be of type 'struct ibuf', what made it impossible to use buffer.IBUF_SHARED as a buffer, because its type is 'struct ibuf *'. Strangely, but FFI can't convert these types automatically. This commit allows to use 'struct ibuf *' as well, and moves this functionality into a function in utils.h. Now both msgpack and merger modules can use ibuf directly and by pointer. --- src/box/lua/merger.c | 24 ++---------------------- src/lua/msgpack.c | 12 +++--------- src/lua/utils.c | 25 +++++++++++++++++++++++++ src/lua/utils.h | 8 ++++++++ test/app/msgpack.result | 26 +++++++++++++++++++++++++- test/app/msgpack.test.lua | 9 +++++++++ 6 files changed, 72 insertions(+), 32 deletions(-) diff --git a/src/box/lua/merger.c b/src/box/lua/merger.c index a61adb389..1b155152b 100644 --- a/src/box/lua/merger.c +++ b/src/box/lua/merger.c @@ -59,7 +59,6 @@ #include "box/merger.h" /* merge_source_*, merger_*() */ static uint32_t CTID_STRUCT_MERGE_SOURCE_REF = 0; -static uint32_t CTID_STRUCT_IBUF = 0; /** * A type of a function to create a source from a Lua iterator on @@ -72,22 +71,6 @@ typedef struct merge_source *(*luaL_merge_source_new_f)(struct lua_State *L); /* {{{ Helpers */ -/** - * Extract an ibuf object from the Lua stack. - */ -static struct ibuf * -luaT_check_ibuf(struct lua_State *L, int idx) -{ - if (lua_type(L, idx) != LUA_TCDATA) - return NULL; - - uint32_t cdata_type; - struct ibuf *ibuf_ptr = luaL_checkcdata(L, idx, &cdata_type); - if (ibuf_ptr == NULL || cdata_type != CTID_STRUCT_IBUF) - return NULL; - return ibuf_ptr; -} - /** * Extract a merge source from the Lua stack. */ @@ -446,7 +429,7 @@ luaL_merge_source_buffer_fetch(struct merge_source_buffer *source) source->ref = 0; } lua_pushvalue(L, -nresult + 1); /* Popped by luaL_ref(). */ - source->buf = luaT_check_ibuf(L, -1); + source->buf = luaL_checkibuf(L, -1); if (source->buf == NULL) { diag_set(IllegalParams, "Expected <state>, <buffer>"); return -1; @@ -1082,7 +1065,7 @@ lbox_merge_source_select(struct lua_State *L) lua_pushstring(L, "buffer"); lua_gettable(L, 2); if (!lua_isnil(L, -1)) { - if ((output_buffer = luaT_check_ibuf(L, -1)) == NULL) + if ((output_buffer = luaL_checkibuf(L, -1)) == NULL) return lbox_merge_source_select_usage(L, "buffer"); } @@ -1116,10 +1099,7 @@ LUA_API int luaopen_merger(struct lua_State *L) { luaL_cdef(L, "struct merge_source;"); - luaL_cdef(L, "struct ibuf;"); - CTID_STRUCT_MERGE_SOURCE_REF = luaL_ctypeid(L, "struct merge_source&"); - CTID_STRUCT_IBUF = luaL_ctypeid(L, "struct ibuf"); /* Export C functions to Lua. */ static const struct luaL_Reg meta[] = { diff --git a/src/lua/msgpack.c b/src/lua/msgpack.c index d3cfc0e2b..73bda80ea 100644 --- a/src/lua/msgpack.c +++ b/src/lua/msgpack.c @@ -51,7 +51,6 @@ luamp_error(void *error_ctx) } static uint32_t CTID_CHAR_PTR; -static uint32_t CTID_STRUCT_IBUF; struct luaL_serializer *luaL_msgpack_default = NULL; @@ -301,11 +300,11 @@ lua_msgpack_encode(lua_State *L) struct ibuf *buf; if (index > 1) { - uint32_t ctypeid; - buf = luaL_checkcdata(L, 2, &ctypeid); - if (ctypeid != CTID_STRUCT_IBUF) + buf = luaL_checkibuf(L, 2); + if (buf == NULL) { return luaL_error(L, "msgpack.encode: argument 2 " "must be of type 'struct ibuf'"); + } } else { buf = tarantool_lua_ibuf; ibuf_reset(buf); @@ -526,11 +525,6 @@ lua_msgpack_new(lua_State *L) LUALIB_API int luaopen_msgpack(lua_State *L) { - int rc = luaL_cdef(L, "struct ibuf;"); - assert(rc == 0); - (void) rc; - CTID_STRUCT_IBUF = luaL_ctypeid(L, "struct ibuf"); - assert(CTID_STRUCT_IBUF != 0); CTID_CHAR_PTR = luaL_ctypeid(L, "char *"); assert(CTID_CHAR_PTR != 0); luaL_msgpack_default = luaL_newserializer(L, "msgpack", msgpacklib); diff --git a/src/lua/utils.c b/src/lua/utils.c index 192912ab8..f53d7e588 100644 --- a/src/lua/utils.c +++ b/src/lua/utils.c @@ -41,6 +41,9 @@ int luaL_nil_ref = LUA_REFNIL; int luaL_map_metatable_ref = LUA_REFNIL; int luaL_array_metatable_ref = LUA_REFNIL; +static uint32_t CTID_STRUCT_IBUF; +static uint32_t CTID_STRUCT_IBUF_PTR; + void * luaL_pushcdata(struct lua_State *L, uint32_t ctypeid) { @@ -1059,6 +1062,20 @@ luaL_iscallable(lua_State *L, int idx) return res; } +struct ibuf * +luaL_checkibuf(struct lua_State *L, int idx) +{ + if (lua_type(L, idx) != LUA_TCDATA) + return NULL; + uint32_t cdata_type; + void *cdata = luaL_checkcdata(L, idx, &cdata_type); + if (cdata_type == CTID_STRUCT_IBUF) + return (struct ibuf *) cdata; + if (cdata_type == CTID_STRUCT_IBUF_PTR && cdata != NULL) + return *(struct ibuf **) cdata; + return NULL; +} + lua_State * luaT_state(void) { @@ -1185,5 +1202,13 @@ tarantool_lua_utils_init(struct lua_State *L) lua_setfield(L, -2, "__newindex"); luaL_array_metatable_ref = luaL_ref(L, LUA_REGISTRYINDEX); + int rc = luaL_cdef(L, "struct ibuf;"); + assert(rc == 0); + (void) rc; + CTID_STRUCT_IBUF = luaL_ctypeid(L, "struct ibuf"); + assert(CTID_STRUCT_IBUF != 0); + CTID_STRUCT_IBUF_PTR = luaL_ctypeid(L, "struct ibuf *"); + assert(CTID_STRUCT_IBUF_PTR != 0); + return 0; } diff --git a/src/lua/utils.h b/src/lua/utils.h index a22492227..cf51eb132 100644 --- a/src/lua/utils.h +++ b/src/lua/utils.h @@ -536,6 +536,14 @@ luaL_checkfinite(struct lua_State *L, struct luaL_serializer *cfg, luaL_error(L, "number must not be NaN or Inf"); } +/** + * Check if a value on @a L stack by index @a idx is an ibuf + * object. Both 'struct ibuf' and 'struct ibuf *' are accepted. + * Returns NULL, if can't convert - not an ibuf object. + */ +struct ibuf * +luaL_checkibuf(struct lua_State *L, int idx); + /* {{{ Helper functions to interact with a Lua iterator from C */ /** diff --git a/test/app/msgpack.result b/test/app/msgpack.result index b1fe4e53b..9fc42fc3c 100644 --- a/test/app/msgpack.result +++ b/test/app/msgpack.result @@ -14,7 +14,7 @@ msgpack.encode() ... msgpack.encode('test', 'str') --- -- error: expected cdata as 2 argument +- error: 'msgpack.encode: argument 2 must be of type ''struct ibuf''' ... msgpack.encode('test', buf.buf) --- @@ -202,3 +202,27 @@ msgpack.decode(buf.rpos, buf:size() - 1) --- - error: 'msgpack.decode: invalid MsgPack' ... +-- Provide a buffer. Try both 'struct ibuf' and 'struct ibuf *'. +buf = buffer.IBUF_SHARED +--- +... +buf:reset() +--- +... +size = msgpack.encode({a = 1, b = 2}, buf) +--- +... +(msgpack.decode(buf.rpos, size)) +--- +- {'a': 1, 'b': 2} +... +buf = buffer.ibuf() +--- +... +size = msgpack.encode({c = 3, d = 4}, buf) +--- +... +(msgpack.decode(buf.rpos, size)) +--- +- {'c': 3, 'd': 4} +... diff --git a/test/app/msgpack.test.lua b/test/app/msgpack.test.lua index 09c3dec5d..0920fa507 100644 --- a/test/app/msgpack.test.lua +++ b/test/app/msgpack.test.lua @@ -62,3 +62,12 @@ msgpack.decode(s) buf = buffer.ibuf() msgpack.encode({1, 2, 3}, buf) msgpack.decode(buf.rpos, buf:size() - 1) + +-- Provide a buffer. Try both 'struct ibuf' and 'struct ibuf *'. +buf = buffer.IBUF_SHARED +buf:reset() +size = msgpack.encode({a = 1, b = 2}, buf) +(msgpack.decode(buf.rpos, size)) +buf = buffer.ibuf() +size = msgpack.encode({c = 3, d = 4}, buf) +(msgpack.decode(buf.rpos, size)) -- 2.20.1 (Apple Git-117)
next prev parent reply other threads:[~2019-05-14 23:06 UTC|newest] Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-05-14 23:06 [tarantool-patches] [PATCH 0/7] swim lua preparation, again Vladislav Shpilevoy 2019-05-14 23:06 ` [tarantool-patches] [PATCH 1/7] swim: drop swim_info() function Vladislav Shpilevoy 2019-05-15 2:00 ` [tarantool-patches] " Konstantin Osipov 2019-05-14 23:06 ` [tarantool-patches] [PATCH 2/7] swim: encapsulate 'uint16' payload size inside swim.c Vladislav Shpilevoy 2019-05-15 2:02 ` [tarantool-patches] " Konstantin Osipov 2019-05-14 23:06 ` [tarantool-patches] [PATCH 3/7] swim: do not rebind when new 'port' is 0 Vladislav Shpilevoy 2019-05-15 2:02 ` [tarantool-patches] " Konstantin Osipov 2019-05-14 23:06 ` [tarantool-patches] [PATCH 4/7] swim: set 'left' status in self on swim_quit() Vladislav Shpilevoy 2019-05-15 2:03 ` [tarantool-patches] " Konstantin Osipov 2019-05-14 23:06 ` Vladislav Shpilevoy [this message] 2019-05-15 2:05 ` [tarantool-patches] Re: [PATCH 5/7] msgpack: allow to pass 'struct ibuf *' into encode() Konstantin Osipov 2019-05-14 23:06 ` [tarantool-patches] [PATCH 6/7] msgpack: allow to pass 'const char *' into decode() Vladislav Shpilevoy 2019-05-15 2:05 ` [tarantool-patches] " Konstantin Osipov 2019-05-14 23:06 ` [tarantool-patches] [PATCH 7/7] Drop an unused function and class Vladislav Shpilevoy 2019-05-15 2:06 ` [tarantool-patches] " Konstantin Osipov 2019-05-15 10:02 ` [tarantool-patches] Re: [PATCH 0/7] swim lua preparation, again Vladislav Shpilevoy
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=0dbad1e482562fbed3492a9e5d7861a0e8a8ae2f.1557875116.git.v.shpilevoy@tarantool.org \ --to=v.shpilevoy@tarantool.org \ --cc=kostja@tarantool.org \ --cc=tarantool-patches@freelists.org \ --subject='Re: [tarantool-patches] [PATCH 5/7] msgpack: allow to pass '\''struct ibuf *'\'' into encode()' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox