From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp61.i.mail.ru (smtp61.i.mail.ru [217.69.128.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id F0F2044643F for ; Wed, 23 Sep 2020 04:40:36 +0300 (MSK) From: Alexander Turenko Date: Wed, 23 Sep 2020 04:40:20 +0300 Message-Id: <749acf73dff5f8dc1200fca3d30478695af17ed0.1600824556.git.alexander.turenko@tarantool.org> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Tarantool-patches] [PATCH 1.10 07/16] WIP: module api/lua: add luaT_tuple_encode() List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Vladislav Shpilevoy Cc: tarantool-patches@dev.tarantool.org, Alexander Turenko It is the same as luaT_tuple_new(), but returns raw MsgPack data (not ) allocated on Lua shared ibuf (). The reason to introduce this function is to provide ability to use box_tuple_compare_with_key() function from an external module for a key passed as a Lua table. The compare function has the following signature: | API_EXPORT int | box_tuple_compare_with_key(box_tuple_t *tuple_a, const char *key_b, | box_key_def_t *key_def); The second parameter is a key encoded as an MsgPack array, not a tuple structure. So luaT_tuple_new() is not applicable here (it is not worthful to create a tuple structure if we need just MsgPack data). XXX: Add a module API test. Part of #5273 (cherry picked from commit 5cbb2e41bb32a3184d2663f678b705aef823dc85) --- extra/exports | 1 + src/box/lua/tuple.c | 21 +++++++++++++++++---- src/box/lua/tuple.h | 29 +++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/extra/exports b/extra/exports index 7f8a27ea2..7feaaa05e 100644 --- a/extra/exports +++ b/extra/exports @@ -130,6 +130,7 @@ luaL_touint64 luaL_toint64 luaT_pushtuple luaT_istuple +luaT_tuple_encode luaT_tuple_new luaT_error luaT_call diff --git a/src/box/lua/tuple.c b/src/box/lua/tuple.c index 6732ac71a..ddc4f6087 100644 --- a/src/box/lua/tuple.c +++ b/src/box/lua/tuple.c @@ -97,8 +97,8 @@ luaT_istuple(struct lua_State *L, int narg) return *(struct tuple **) data; } -box_tuple_t * -luaT_tuple_new(struct lua_State *L, int idx, box_tuple_format_t *format) +char * +luaT_tuple_encode(struct lua_State *L, int idx, size_t *tuple_len_ptr) { if (idx != 0 && !lua_istable(L, idx) && !luaT_istuple(L, idx)) { diag_set(IllegalParams, "A tuple or a table expected, got %s", @@ -126,8 +126,21 @@ luaT_tuple_new(struct lua_State *L, int idx, box_tuple_format_t *format) luamp_encode_tuple(L, &tuple_serializer, &stream, idx); } mpstream_flush(&stream); - box_tuple_t *tuple = box_tuple_new(format, buf->buf, - buf->buf + ibuf_used(buf)); + if (tuple_len_ptr != NULL) + *tuple_len_ptr = ibuf_used(buf); + return buf->buf; + +} + +box_tuple_t * +luaT_tuple_new(struct lua_State *L, int idx, box_tuple_format_t *format) +{ + size_t tuple_len; + char *tuple_data = luaT_tuple_encode(L, idx, &tuple_len); + if (tuple_data == NULL) + return NULL; + box_tuple_t *tuple = box_tuple_new(format, tuple_data, + tuple_data + tuple_len); if (tuple == NULL) return NULL; ibuf_reinit(tarantool_lua_ibuf); diff --git a/src/box/lua/tuple.h b/src/box/lua/tuple.h index 196a38c2d..fcb7a9d87 100644 --- a/src/box/lua/tuple.h +++ b/src/box/lua/tuple.h @@ -67,6 +67,35 @@ luaT_pushtuple(struct lua_State *L, box_tuple_t *tuple); box_tuple_t * luaT_istuple(struct lua_State *L, int idx); +/** + * Encode a Lua table, a tuple or objects on a Lua stack as raw + * tuple data (MsgPack). + * + * @param L Lua state + * @param idx acceptable index on the Lua stack + * (or zero, see below) + * @param tuple_len_ptr where to store tuple data size in bytes + * (or NULL) + * + * Set idx to zero to create the new tuple from objects on the Lua + * stack. + * + * The data is encoded on the shared buffer: so called + * (it also available as + * in Lua). The data is valid until next similar call. It is + * generally safe to pass the result to a box function (copy it if + * doubt). No need to release this buffer explicitly, it'll be + * reused by later calls. + * + * If encoding fails, raise an error. + * + * In case of any other error set a diag and return NULL. + * + * @sa luaT_tuple_new() + */ +API_EXPORT char * +luaT_tuple_encode(struct lua_State *L, int idx, size_t *tuple_len_ptr); + /** * Create a new tuple with specific format from a Lua table, a * tuple, or objects on the lua stack. -- 2.25.0