aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/msgpack_rpc/helpers.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/msgpack_rpc/helpers.c')
-rw-r--r--src/nvim/msgpack_rpc/helpers.c148
1 files changed, 52 insertions, 96 deletions
diff --git a/src/nvim/msgpack_rpc/helpers.c b/src/nvim/msgpack_rpc/helpers.c
index 0bc58fffba..f805858904 100644
--- a/src/nvim/msgpack_rpc/helpers.c
+++ b/src/nvim/msgpack_rpc/helpers.c
@@ -15,50 +15,13 @@
#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "keysets.generated.h"
# include "msgpack_rpc/helpers.c.generated.h"
#endif
static msgpack_zone zone;
static msgpack_sbuffer sbuffer;
-#define HANDLE_TYPE_CONVERSION_IMPL(t, lt) \
- static bool msgpack_rpc_to_##lt(const msgpack_object *const obj, \
- Integer *const arg) \
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT \
- { \
- if (obj->type != MSGPACK_OBJECT_EXT \
- || obj->via.ext.type + EXT_OBJECT_TYPE_SHIFT != kObjectType##t) { \
- return false; \
- } \
- \
- msgpack_object data; \
- msgpack_unpack_return ret = msgpack_unpack(obj->via.ext.ptr, \
- obj->via.ext.size, \
- NULL, \
- &zone, \
- &data); \
- \
- if (ret != MSGPACK_UNPACK_SUCCESS) { \
- return false; \
- } \
- \
- *arg = (handle_T)data.via.i64; \
- return true; \
- } \
- \
- static void msgpack_rpc_from_##lt(Integer o, msgpack_packer *res) \
-/* uncrustify:indent-off */ \
- FUNC_ATTR_NONNULL_ARG(2) \
-/* uncrustify:indent-on */ \
- { \
- msgpack_packer pac; \
- msgpack_packer_init(&pac, &sbuffer, msgpack_sbuffer_write); \
- msgpack_pack_int64(&pac, (handle_T)o); \
- msgpack_pack_ext(res, sbuffer.size, \
- kObjectType##t - EXT_OBJECT_TYPE_SHIFT); \
- msgpack_pack_ext_body(res, sbuffer.data, sbuffer.size); \
- msgpack_sbuffer_clear(&sbuffer); \
- }
void msgpack_rpc_helpers_init(void)
{
@@ -66,10 +29,6 @@ void msgpack_rpc_helpers_init(void)
msgpack_sbuffer_init(&sbuffer);
}
-HANDLE_TYPE_CONVERSION_IMPL(Buffer, buffer)
-HANDLE_TYPE_CONVERSION_IMPL(Window, window)
-HANDLE_TYPE_CONVERSION_IMPL(Tabpage, tabpage)
-
typedef struct {
const msgpack_object *mobj;
Object *aobj;
@@ -90,11 +49,11 @@ bool msgpack_rpc_to_object(const msgpack_object *const obj, Object *const arg)
kvec_withinit_t(MPToAPIObjectStackItem, 2) stack = KV_INITIAL_VALUE;
kvi_init(stack);
kvi_push(stack, ((MPToAPIObjectStackItem) {
- .mobj = obj,
- .aobj = arg,
- .container = false,
- .idx = 0,
- }));
+ .mobj = obj,
+ .aobj = arg,
+ .container = false,
+ .idx = 0,
+ }));
while (ret && kv_size(stack)) {
MPToAPIObjectStackItem cur = kv_last(stack);
if (!cur.container) {
@@ -154,19 +113,19 @@ case type: { \
cur.idx++;
kv_last(stack) = cur;
kvi_push(stack, ((MPToAPIObjectStackItem) {
- .mobj = &cur.mobj->via.array.ptr[idx],
- .aobj = &cur.aobj->data.array.items[idx],
- .container = false,
- }));
+ .mobj = &cur.mobj->via.array.ptr[idx],
+ .aobj = &cur.aobj->data.array.items[idx],
+ .container = false,
+ }));
}
} else {
*cur.aobj = ARRAY_OBJ(((Array) {
- .size = size,
- .capacity = size,
- .items = (size > 0
+ .size = size,
+ .capacity = size,
+ .items = (size > 0
? xcalloc(size, sizeof(*cur.aobj->data.array.items))
: NULL),
- }));
+ }));
cur.container = true;
kv_last(stack) = cur;
}
@@ -207,48 +166,38 @@ case type: { \
}
if (ret) {
kvi_push(stack, ((MPToAPIObjectStackItem) {
- .mobj = &cur.mobj->via.map.ptr[idx].val,
- .aobj = &cur.aobj->data.dictionary.items[idx].value,
- .container = false,
- }));
+ .mobj = &cur.mobj->via.map.ptr[idx].val,
+ .aobj = &cur.aobj->data.dictionary.items[idx].value,
+ .container = false,
+ }));
}
}
} else {
*cur.aobj = DICTIONARY_OBJ(((Dictionary) {
- .size = size,
- .capacity = size,
- .items = (size > 0
+ .size = size,
+ .capacity = size,
+ .items = (size > 0
? xcalloc(size, sizeof(*cur.aobj->data.dictionary.items))
: NULL),
- }));
+ }));
cur.container = true;
kv_last(stack) = cur;
}
break;
}
case MSGPACK_OBJECT_EXT:
- switch ((ObjectType)(cur.mobj->via.ext.type + EXT_OBJECT_TYPE_SHIFT)) {
- case kObjectTypeBuffer:
- cur.aobj->type = kObjectTypeBuffer;
- ret = msgpack_rpc_to_buffer(cur.mobj, &cur.aobj->data.integer);
- break;
- case kObjectTypeWindow:
- cur.aobj->type = kObjectTypeWindow;
- ret = msgpack_rpc_to_window(cur.mobj, &cur.aobj->data.integer);
- break;
- case kObjectTypeTabpage:
- cur.aobj->type = kObjectTypeTabpage;
- ret = msgpack_rpc_to_tabpage(cur.mobj, &cur.aobj->data.integer);
- break;
- case kObjectTypeNil:
- case kObjectTypeBoolean:
- case kObjectTypeInteger:
- case kObjectTypeFloat:
- case kObjectTypeString:
- case kObjectTypeArray:
- case kObjectTypeDictionary:
- case kObjectTypeLuaRef:
- break;
+ if (0 <= cur.mobj->via.ext.type && cur.mobj->via.ext.type <= EXT_OBJECT_TYPE_MAX) {
+ cur.aobj->type = (ObjectType)(cur.mobj->via.ext.type + EXT_OBJECT_TYPE_SHIFT);
+ msgpack_object data;
+ msgpack_unpack_return status = msgpack_unpack(cur.mobj->via.ext.ptr, cur.mobj->via.ext.size,
+ NULL, &zone, &data);
+
+ if (status != MSGPACK_UNPACK_SUCCESS || data.type != MSGPACK_OBJECT_POSITIVE_INTEGER) {
+ ret = false;
+ break;
+ }
+ cur.aobj->data.integer = (handle_T)data.via.i64;
+ ret = true;
}
break;
#undef STR_CASE
@@ -350,6 +299,17 @@ void msgpack_rpc_from_string(const String result, msgpack_packer *res)
}
}
+static void msgpack_rpc_from_handle(ObjectType type, Integer o, msgpack_packer *res)
+ FUNC_ATTR_NONNULL_ARG(3)
+{
+ msgpack_packer pac;
+ msgpack_packer_init(&pac, &sbuffer, msgpack_sbuffer_write);
+ msgpack_pack_int64(&pac, (handle_T)o);
+ msgpack_pack_ext(res, sbuffer.size, (int8_t)(type - EXT_OBJECT_TYPE_SHIFT));
+ msgpack_pack_ext_body(res, sbuffer.data, sbuffer.size);
+ msgpack_sbuffer_clear(&sbuffer);
+}
+
typedef struct {
const Object *aobj;
bool container;
@@ -394,13 +354,9 @@ void msgpack_rpc_from_object(const Object result, msgpack_packer *const res)
msgpack_rpc_from_string(cur.aobj->data.string, res);
break;
case kObjectTypeBuffer:
- msgpack_rpc_from_buffer(cur.aobj->data.integer, res);
- break;
case kObjectTypeWindow:
- msgpack_rpc_from_window(cur.aobj->data.integer, res);
- break;
case kObjectTypeTabpage:
- msgpack_rpc_from_tabpage(cur.aobj->data.integer, res);
+ msgpack_rpc_from_handle(cur.aobj->type, cur.aobj->data.integer, res);
break;
case kObjectTypeArray: {
const size_t size = cur.aobj->data.array.size;
@@ -412,9 +368,9 @@ void msgpack_rpc_from_object(const Object result, msgpack_packer *const res)
cur.idx++;
kv_last(stack) = cur;
kvi_push(stack, ((APIToMPObjectStackItem) {
- .aobj = &cur.aobj->data.array.items[idx],
- .container = false,
- }));
+ .aobj = &cur.aobj->data.array.items[idx],
+ .container = false,
+ }));
}
} else {
msgpack_pack_array(res, size);
@@ -435,9 +391,9 @@ void msgpack_rpc_from_object(const Object result, msgpack_packer *const res)
msgpack_rpc_from_string(cur.aobj->data.dictionary.items[idx].key,
res);
kvi_push(stack, ((APIToMPObjectStackItem) {
- .aobj = &cur.aobj->data.dictionary.items[idx].value,
- .container = false,
- }));
+ .aobj = &cur.aobj->data.dictionary.items[idx].value,
+ .container = false,
+ }));
}
} else {
msgpack_pack_map(res, size);