diff options
author | Thiago de Arruda <tpadilha84@gmail.com> | 2014-10-20 07:35:10 -0300 |
---|---|---|
committer | Thiago de Arruda <tpadilha84@gmail.com> | 2014-10-21 11:05:49 -0300 |
commit | b280308ac649da61e2a0f40a222eae21af5352c9 (patch) | |
tree | 1ef8433c2aa55e1a5013c05836dc0cbf931a101c | |
parent | 6e268cd0d40a3652a68b486bdbb421d39295ab48 (diff) | |
download | rneovim-b280308ac649da61e2a0f40a222eae21af5352c9.tar.gz rneovim-b280308ac649da61e2a0f40a222eae21af5352c9.tar.bz2 rneovim-b280308ac649da61e2a0f40a222eae21af5352c9.zip |
msgpack-rpc: Create subdirectory for msgpack-rpc modules
Create the msgpack_rpc subdirectory and move all modules that deal with
msgpack-rpc to it. Also merge msgpack_rpc.c into msgpack_rpc/helpers.c
-rw-r--r-- | clint-files.txt | 12 | ||||
-rw-r--r-- | scripts/msgpack-gen.lua | 6 | ||||
-rw-r--r-- | src/nvim/CMakeLists.txt | 8 | ||||
-rw-r--r-- | src/nvim/api/vim.c | 2 | ||||
-rw-r--r-- | src/nvim/eval.c | 2 | ||||
-rw-r--r-- | src/nvim/main.c | 2 | ||||
-rw-r--r-- | src/nvim/map.c | 2 | ||||
-rw-r--r-- | src/nvim/map.h | 2 | ||||
-rw-r--r-- | src/nvim/msgpack_rpc/channel.c (renamed from src/nvim/os/channel.c) | 7 | ||||
-rw-r--r-- | src/nvim/msgpack_rpc/channel.h (renamed from src/nvim/os/channel.h) | 8 | ||||
-rw-r--r-- | src/nvim/msgpack_rpc/defs.h (renamed from src/nvim/os/msgpack_rpc.h) | 25 | ||||
-rw-r--r-- | src/nvim/msgpack_rpc/helpers.c (renamed from src/nvim/os/msgpack_rpc_helpers.c) | 178 | ||||
-rw-r--r-- | src/nvim/msgpack_rpc/helpers.h | 17 | ||||
-rw-r--r-- | src/nvim/msgpack_rpc/server.c (renamed from src/nvim/os/server.c) | 6 | ||||
-rw-r--r-- | src/nvim/msgpack_rpc/server.h | 7 | ||||
-rw-r--r-- | src/nvim/os/event.c | 12 | ||||
-rw-r--r-- | src/nvim/os/msgpack_rpc.c | 188 | ||||
-rw-r--r-- | src/nvim/os/msgpack_rpc_helpers.h | 16 | ||||
-rw-r--r-- | src/nvim/os/provider.c | 2 | ||||
-rw-r--r-- | src/nvim/os/server.h | 7 | ||||
-rw-r--r-- | src/nvim/os/server_defs.h | 7 | ||||
-rw-r--r-- | src/nvim/os_unix.c | 6 |
22 files changed, 244 insertions, 278 deletions
diff --git a/clint-files.txt b/clint-files.txt index d6bf7b8807..99f2fecc7c 100644 --- a/clint-files.txt +++ b/clint-files.txt @@ -32,8 +32,6 @@ src/nvim/os/job.c src/nvim/os/job.h src/nvim/os/job_defs.h src/nvim/os/mem.c -src/nvim/os/msgpack_rpc.c -src/nvim/os/msgpack_rpc.h src/nvim/os/os.h src/nvim/os/rstream.c src/nvim/os/rstream.h @@ -44,10 +42,12 @@ src/nvim/os/signal.c src/nvim/os/signal.h src/nvim/os/time.c src/nvim/os/time.h -src/nvim/os/server.c -src/nvim/os/server.h -src/nvim/os/channel.c -src/nvim/os/channel.h +src/nvim/msgpack_rpc/server.c +src/nvim/msgpack_rpc/server.h +src/nvim/msgpack_rpc/channel.c +src/nvim/msgpack_rpc/channel.h +src/nvim/msgpack_rpc/helpers.c +src/nvim/msgpack_rpc/helpers.h src/nvim/tempfile.c src/nvim/tempfile.h src/nvim/profile.c diff --git a/scripts/msgpack-gen.lua b/scripts/msgpack-gen.lua index 916597afda..856b61630f 100644 --- a/scripts/msgpack-gen.lua +++ b/scripts/msgpack-gen.lua @@ -92,8 +92,8 @@ output:write([[ #include "nvim/map.h" #include "nvim/log.h" #include "nvim/vim.h" -#include "nvim/os/msgpack_rpc.h" -#include "nvim/os/msgpack_rpc_helpers.h" +#include "nvim/msgpack_rpc/helpers.h" +#include "nvim/msgpack_rpc/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/api/private/defs.h" ]]) @@ -249,7 +249,7 @@ end output:write([[ static Map(String, rpc_method_handler_fn) *methods = NULL; -void msgpack_rpc_init(void) +void msgpack_rpc_init_method_table(void) { methods = map_new(String, rpc_method_handler_fn)(); diff --git a/src/nvim/CMakeLists.txt b/src/nvim/CMakeLists.txt index 208df31596..1cedeebb37 100644 --- a/src/nvim/CMakeLists.txt +++ b/src/nvim/CMakeLists.txt @@ -3,7 +3,7 @@ include(CheckLibraryExists) set(GENERATED_DIR ${PROJECT_BINARY_DIR}/src/nvim/auto) set(DISPATCH_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/msgpack-gen.lua) file(GLOB API_HEADERS api/*.h) -set(MSGPACK_RPC_HEADER ${PROJECT_SOURCE_DIR}/src/nvim/os/msgpack_rpc.h) +file(GLOB MSGPACK_RPC_HEADERS msgpack_rpc/*.h) set(MSGPACK_DISPATCH ${GENERATED_DIR}/msgpack_dispatch.c) set(HEADER_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gendeclarations.lua) set(GENERATED_INCLUDES_DIR ${PROJECT_BINARY_DIR}/include) @@ -19,12 +19,14 @@ file(MAKE_DIRECTORY ${GENERATED_DIR}) file(MAKE_DIRECTORY ${GENERATED_DIR}/os) file(MAKE_DIRECTORY ${GENERATED_DIR}/api) file(MAKE_DIRECTORY ${GENERATED_DIR}/api/private) +file(MAKE_DIRECTORY ${GENERATED_DIR}/msgpack_rpc) file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}) file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/os) file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/api) file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/api/private) +file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/msgpack_rpc) -file(GLOB NEOVIM_SOURCES *.c os/*.c api/*.c api/private/*.c) +file(GLOB NEOVIM_SOURCES *.c os/*.c api/*.c api/private/*.c msgpack_rpc/*.c) file(GLOB_RECURSE NEOVIM_HEADERS *.h) foreach(sfile ${NEOVIM_SOURCES}) @@ -126,7 +128,7 @@ add_custom_command(OUTPUT ${MSGPACK_DISPATCH} COMMAND ${LUA_PRG} ${DISPATCH_GENERATOR} ${API_HEADERS} ${MSGPACK_DISPATCH} DEPENDS ${API_HEADERS} - ${MSGPACK_RPC_HEADER} + ${MSGPACK_RPC_HEADERS} ${DISPATCH_GENERATOR} ) diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 5e0f3e0c32..c7b5b1cfbf 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -10,7 +10,7 @@ #include "nvim/api/private/helpers.h" #include "nvim/api/private/defs.h" #include "nvim/api/buffer.h" -#include "nvim/os/channel.h" +#include "nvim/msgpack_rpc/channel.h" #include "nvim/os/provider.h" #include "nvim/vim.h" #include "nvim/buffer.h" diff --git a/src/nvim/eval.c b/src/nvim/eval.c index e3bd37a03f..c8f0799d5a 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -81,7 +81,7 @@ #include "nvim/os/rstream.h" #include "nvim/os/rstream_defs.h" #include "nvim/os/time.h" -#include "nvim/os/channel.h" +#include "nvim/msgpack_rpc/channel.h" #include "nvim/api/private/helpers.h" #include "nvim/api/vim.h" #include "nvim/os/dl.h" diff --git a/src/nvim/main.c b/src/nvim/main.c index 128d1a784c..a63ffb4a31 100644 --- a/src/nvim/main.c +++ b/src/nvim/main.c @@ -59,7 +59,7 @@ #include "nvim/os/input.h" #include "nvim/os/os.h" #include "nvim/os/signal.h" -#include "nvim/os/msgpack_rpc_helpers.h" +#include "nvim/msgpack_rpc/helpers.h" #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" diff --git a/src/nvim/map.c b/src/nvim/map.c index 24aa38d67d..24a869e2e6 100644 --- a/src/nvim/map.c +++ b/src/nvim/map.c @@ -6,7 +6,7 @@ #include "nvim/map_defs.h" #include "nvim/vim.h" #include "nvim/memory.h" -#include "nvim/os/msgpack_rpc.h" +#include "nvim/msgpack_rpc/defs.h" #include "nvim/lib/khash.h" diff --git a/src/nvim/map.h b/src/nvim/map.h index 616516c3e1..78f4218a72 100644 --- a/src/nvim/map.h +++ b/src/nvim/map.h @@ -5,7 +5,7 @@ #include "nvim/map_defs.h" #include "nvim/api/private/defs.h" -#include "nvim/os/msgpack_rpc.h" +#include "nvim/msgpack_rpc/defs.h" #define MAP_DECLS(T, U) \ KHASH_DECLARE(T##_##U##_map, T, U) \ diff --git a/src/nvim/os/channel.c b/src/nvim/msgpack_rpc/channel.c index 959fbc6e73..dcd7e41737 100644 --- a/src/nvim/os/channel.c +++ b/src/nvim/msgpack_rpc/channel.c @@ -7,7 +7,7 @@ #include "nvim/api/private/helpers.h" #include "nvim/api/vim.h" -#include "nvim/os/channel.h" +#include "nvim/msgpack_rpc/channel.h" #include "nvim/os/event.h" #include "nvim/os/rstream.h" #include "nvim/os/rstream_defs.h" @@ -15,8 +15,7 @@ #include "nvim/os/wstream_defs.h" #include "nvim/os/job.h" #include "nvim/os/job_defs.h" -#include "nvim/os/msgpack_rpc.h" -#include "nvim/os/msgpack_rpc_helpers.h" +#include "nvim/msgpack_rpc/helpers.h" #include "nvim/vim.h" #include "nvim/ascii.h" #include "nvim/memory.h" @@ -60,7 +59,7 @@ static PMap(cstr_t) *event_strings = NULL; static msgpack_sbuffer out_buffer; #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "os/channel.c.generated.h" +# include "msgpack_rpc/channel.c.generated.h" #endif /// Initializes the module diff --git a/src/nvim/os/channel.h b/src/nvim/msgpack_rpc/channel.h index bb409bfde9..df742fe368 100644 --- a/src/nvim/os/channel.h +++ b/src/nvim/msgpack_rpc/channel.h @@ -1,5 +1,5 @@ -#ifndef NVIM_OS_CHANNEL_H -#define NVIM_OS_CHANNEL_H +#ifndef NVIM_MSGPACK_RPC_CHANNEL_H +#define NVIM_MSGPACK_RPC_CHANNEL_H #include <stdbool.h> #include <uv.h> @@ -10,6 +10,6 @@ #define METHOD_MAXLEN 512 #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "os/channel.h.generated.h" +# include "msgpack_rpc/channel.h.generated.h" #endif -#endif // NVIM_OS_CHANNEL_H +#endif // NVIM_MSGPACK_RPC_CHANNEL_H diff --git a/src/nvim/os/msgpack_rpc.h b/src/nvim/msgpack_rpc/defs.h index 3476d791ea..5eec4ced54 100644 --- a/src/nvim/os/msgpack_rpc.h +++ b/src/nvim/msgpack_rpc/defs.h @@ -1,19 +1,8 @@ -#ifndef NVIM_OS_MSGPACK_RPC_H -#define NVIM_OS_MSGPACK_RPC_H - -#include <stdint.h> +#ifndef NVIM_MSGPACK_RPC_DEFS_H +#define NVIM_MSGPACK_RPC_DEFS_H #include <msgpack.h> -#include "nvim/func_attr.h" -#include "nvim/api/private/defs.h" -#include "nvim/os/wstream.h" - -typedef enum { - kUnpackResultOk, /// Successfully parsed a document - kUnpackResultFail, /// Got unexpected input - kUnpackResultNeedMore /// Need more data -} UnpackResult; /// The rpc_method_handlers table, used in msgpack_rpc_dispatch(), stores /// functions of this type. @@ -21,9 +10,8 @@ typedef Object (*rpc_method_handler_fn)(uint64_t channel_id, msgpack_object *req, Error *error); - /// Initializes the msgpack-rpc method table -void msgpack_rpc_init(void); +void msgpack_rpc_init_method_table(void); void msgpack_rpc_init_function_metadata(Dictionary *metadata); @@ -43,9 +31,4 @@ Object msgpack_rpc_dispatch(uint64_t channel_id, Error *error) FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_NONNULL_ARG(3); - -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "os/msgpack_rpc.h.generated.h" -#endif - -#endif // NVIM_OS_MSGPACK_RPC_H +#endif // NVIM_MSGPACK_RPC_DEFS_H diff --git a/src/nvim/os/msgpack_rpc_helpers.c b/src/nvim/msgpack_rpc/helpers.c index b14de8245c..4b96e4985e 100644 --- a/src/nvim/os/msgpack_rpc_helpers.c +++ b/src/nvim/msgpack_rpc/helpers.c @@ -1,14 +1,18 @@ #include <stdint.h> #include <stdbool.h> +#include <inttypes.h> #include <msgpack.h> -#include "nvim/os/msgpack_rpc_helpers.h" +#include "nvim/api/private/helpers.h" +#include "nvim/msgpack_rpc/helpers.h" +#include "nvim/msgpack_rpc/defs.h" #include "nvim/vim.h" +#include "nvim/log.h" #include "nvim/memory.h" #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "os/msgpack_rpc_helpers.c.generated.h" +# include "msgpack_rpc/helpers.c.generated.h" #endif static msgpack_zone zone; @@ -287,3 +291,173 @@ void msgpack_rpc_from_dictionary(Dictionary result, msgpack_packer *res) msgpack_rpc_from_object(result.items[i].value, res); } } + +/// Validates the basic structure of the msgpack-rpc call and fills `res` +/// with the basic response structure. +/// +/// @param channel_id The channel id +/// @param req The parsed request object +/// @param res A packer that contains the response +WBuffer *msgpack_rpc_call(uint64_t channel_id, + msgpack_object *req, + msgpack_sbuffer *sbuffer) + FUNC_ATTR_NONNULL_ARG(2) + FUNC_ATTR_NONNULL_ARG(3) +{ + uint64_t response_id; + Error error = ERROR_INIT; + msgpack_rpc_validate(&response_id, req, &error); + + if (error.set) { + return serialize_response(response_id, &error, NIL, sbuffer); + } + + // dispatch the call + Object rv = msgpack_rpc_dispatch(channel_id, req, &error); + // send the response + msgpack_packer response; + msgpack_packer_init(&response, sbuffer, msgpack_sbuffer_write); + + if (error.set) { + ELOG("Error dispatching msgpack-rpc call: %s(request: id %" PRIu64 ")", + error.msg, + response_id); + return serialize_response(response_id, &error, NIL, sbuffer); + } + + DLOG("Successfully completed mspgack-rpc call(request id: %" PRIu64 ")", + response_id); + return serialize_response(response_id, &error, rv, sbuffer); +} + +/// Finishes the msgpack-rpc call with an error message. +/// +/// @param msg The error message +/// @param res A packer that contains the response +void msgpack_rpc_error(char *msg, msgpack_packer *res) + FUNC_ATTR_NONNULL_ALL +{ + size_t len = strlen(msg); + + // error message + msgpack_pack_bin(res, len); + msgpack_pack_bin_body(res, msg, len); + // Nil result + msgpack_pack_nil(res); +} + +/// Handler executed when an invalid method name is passed +Object msgpack_rpc_handle_missing_method(uint64_t channel_id, + msgpack_object *req, + Error *error) +{ + snprintf(error->msg, sizeof(error->msg), "Invalid method name"); + error->set = true; + return NIL; +} + +/// Serializes a msgpack-rpc request or notification(id == 0) +WBuffer *serialize_request(uint64_t request_id, + String method, + Array args, + msgpack_sbuffer *sbuffer, + size_t refcount) + FUNC_ATTR_NONNULL_ARG(4) +{ + msgpack_packer pac; + msgpack_packer_init(&pac, sbuffer, msgpack_sbuffer_write); + msgpack_pack_array(&pac, request_id ? 4 : 3); + msgpack_pack_int(&pac, request_id ? 0 : 2); + + if (request_id) { + msgpack_pack_uint64(&pac, request_id); + } + + msgpack_pack_bin(&pac, method.size); + msgpack_pack_bin_body(&pac, method.data, method.size); + msgpack_rpc_from_array(args, &pac); + WBuffer *rv = wstream_new_buffer(xmemdup(sbuffer->data, sbuffer->size), + sbuffer->size, + refcount, + free); + api_free_array(args); + msgpack_sbuffer_clear(sbuffer); + return rv; +} + +/// Serializes a msgpack-rpc response +WBuffer *serialize_response(uint64_t response_id, + Error *err, + Object arg, + msgpack_sbuffer *sbuffer) + FUNC_ATTR_NONNULL_ARG(2, 4) +{ + msgpack_packer pac; + msgpack_packer_init(&pac, sbuffer, msgpack_sbuffer_write); + msgpack_pack_array(&pac, 4); + msgpack_pack_int(&pac, 1); + msgpack_pack_uint64(&pac, response_id); + + if (err->set) { + // error represented by a [type, message] array + msgpack_pack_array(&pac, 2); + msgpack_rpc_from_integer(err->type, &pac); + msgpack_rpc_from_string(cstr_as_string(err->msg), &pac); + // Nil result + msgpack_pack_nil(&pac); + } else { + // Nil error + msgpack_pack_nil(&pac); + // Return value + msgpack_rpc_from_object(arg, &pac); + } + + WBuffer *rv = wstream_new_buffer(xmemdup(sbuffer->data, sbuffer->size), + sbuffer->size, + 1, // responses only go though 1 channel + free); + api_free_object(arg); + msgpack_sbuffer_clear(sbuffer); + return rv; +} + +void msgpack_rpc_validate(uint64_t *response_id, + msgpack_object *req, + Error *err) +{ + // response id not known yet + + *response_id = 0; + // Validate the basic structure of the msgpack-rpc payload + if (req->type != MSGPACK_OBJECT_ARRAY) { + api_set_error(err, Validation, _("Request is not an array")); + } + + if (req->via.array.size != 4) { + api_set_error(err, Validation, _("Request array size should be 4")); + } + + if (req->via.array.ptr[1].type != MSGPACK_OBJECT_POSITIVE_INTEGER) { + api_set_error(err, Validation, _("Id must be a positive integer")); + } + + // Set the response id, which is the same as the request + *response_id = req->via.array.ptr[1].via.u64; + + if (req->via.array.ptr[0].type != MSGPACK_OBJECT_POSITIVE_INTEGER) { + api_set_error(err, Validation, _("Message type must be an integer")); + } + + if (req->via.array.ptr[0].via.u64 != 0) { + api_set_error(err, Validation, _("Message type must be 0")); + } + + if (req->via.array.ptr[2].type != MSGPACK_OBJECT_BIN + && req->via.array.ptr[2].type != MSGPACK_OBJECT_STR) { + api_set_error(err, Validation, _("Method must be a string")); + } + + if (req->via.array.ptr[3].type != MSGPACK_OBJECT_ARRAY) { + api_set_error(err, Validation, _("Paremeters must be an array")); + } +} diff --git a/src/nvim/msgpack_rpc/helpers.h b/src/nvim/msgpack_rpc/helpers.h new file mode 100644 index 0000000000..bf161d54e0 --- /dev/null +++ b/src/nvim/msgpack_rpc/helpers.h @@ -0,0 +1,17 @@ +#ifndef NVIM_MSGPACK_RPC_HELPERS_H +#define NVIM_MSGPACK_RPC_HELPERS_H + +#include <stdint.h> +#include <stdbool.h> + +#include <msgpack.h> + +#include "nvim/os/wstream.h" +#include "nvim/api/private/defs.h" + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "msgpack_rpc/helpers.h.generated.h" +#endif + +#endif // NVIM_MSGPACK_RPC_HELPERS_H + diff --git a/src/nvim/os/server.c b/src/nvim/msgpack_rpc/server.c index 9f7f5b34da..33e01fe562 100644 --- a/src/nvim/os/server.c +++ b/src/nvim/msgpack_rpc/server.c @@ -5,8 +5,8 @@ #include <uv.h> -#include "nvim/os/channel.h" -#include "nvim/os/server.h" +#include "nvim/msgpack_rpc/channel.h" +#include "nvim/msgpack_rpc/server.h" #include "nvim/os/os.h" #include "nvim/ascii.h" #include "nvim/vim.h" @@ -46,7 +46,7 @@ typedef struct { static PMap(cstr_t) *servers = NULL; #ifdef INCLUDE_GENERATED_DECLARATIONS -# include "os/server.c.generated.h" +# include "msgpack_rpc/server.c.generated.h" #endif /// Initializes the module diff --git a/src/nvim/msgpack_rpc/server.h b/src/nvim/msgpack_rpc/server.h new file mode 100644 index 0000000000..f1a6703938 --- /dev/null +++ b/src/nvim/msgpack_rpc/server.h @@ -0,0 +1,7 @@ +#ifndef NVIM_MSGPACK_RPC_SERVER_H +#define NVIM_MSGPACK_RPC_SERVER_H + +#ifdef INCLUDE_GENERATED_DECLARATIONS +# include "msgpack_rpc/server.h.generated.h" +#endif +#endif // NVIM_MSGPACK_RPC_SERVER_H diff --git a/src/nvim/os/event.c b/src/nvim/os/event.c index a460b2db96..f20d43c6a4 100644 --- a/src/nvim/os/event.c +++ b/src/nvim/os/event.c @@ -7,8 +7,10 @@ #include "nvim/os/event.h" #include "nvim/os/input.h" -#include "nvim/os/channel.h" -#include "nvim/os/server.h" +#include "nvim/msgpack_rpc/defs.h" +#include "nvim/msgpack_rpc/channel.h" +#include "nvim/msgpack_rpc/server.h" +#include "nvim/msgpack_rpc/helpers.h" #include "nvim/os/provider.h" #include "nvim/os/signal.h" #include "nvim/os/rstream.h" @@ -41,6 +43,9 @@ static EventSource *immediate_sources = NULL; void event_init(void) { + // early msgpack-rpc initialization + msgpack_rpc_init_method_table(); + msgpack_rpc_helpers_init(); // Initialize the event queues deferred_events = kl_init(Event); immediate_events = kl_init(Event); @@ -52,9 +57,8 @@ void event_init(void) signal_init(); // Jobs job_init(); - // Channels + // finish mspgack-rpc initialization channel_init(); - // Servers server_init(); // Providers provider_init(); diff --git a/src/nvim/os/msgpack_rpc.c b/src/nvim/os/msgpack_rpc.c deleted file mode 100644 index 55bc006ad1..0000000000 --- a/src/nvim/os/msgpack_rpc.c +++ /dev/null @@ -1,188 +0,0 @@ -#include <stdint.h> -#include <stdbool.h> -#include <inttypes.h> - -#include <msgpack.h> - -#include "nvim/vim.h" -#include "nvim/log.h" -#include "nvim/memory.h" -#include "nvim/os/wstream.h" -#include "nvim/os/msgpack_rpc.h" -#include "nvim/os/msgpack_rpc_helpers.h" -#include "nvim/api/private/helpers.h" -#include "nvim/func_attr.h" - -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "os/msgpack_rpc.c.generated.h" -#endif - -/// Validates the basic structure of the msgpack-rpc call and fills `res` -/// with the basic response structure. -/// -/// @param channel_id The channel id -/// @param req The parsed request object -/// @param res A packer that contains the response -WBuffer *msgpack_rpc_call(uint64_t channel_id, - msgpack_object *req, - msgpack_sbuffer *sbuffer) - FUNC_ATTR_NONNULL_ARG(2) - FUNC_ATTR_NONNULL_ARG(3) -{ - uint64_t response_id; - Error error = ERROR_INIT; - msgpack_rpc_validate(&response_id, req, &error); - - if (error.set) { - return serialize_response(response_id, &error, NIL, sbuffer); - } - - // dispatch the call - Object rv = msgpack_rpc_dispatch(channel_id, req, &error); - // send the response - msgpack_packer response; - msgpack_packer_init(&response, sbuffer, msgpack_sbuffer_write); - - if (error.set) { - ELOG("Error dispatching msgpack-rpc call: %s(request: id %" PRIu64 ")", - error.msg, - response_id); - return serialize_response(response_id, &error, NIL, sbuffer); - } - - DLOG("Successfully completed mspgack-rpc call(request id: %" PRIu64 ")", - response_id); - return serialize_response(response_id, &error, rv, sbuffer); -} - -/// Finishes the msgpack-rpc call with an error message. -/// -/// @param msg The error message -/// @param res A packer that contains the response -void msgpack_rpc_error(char *msg, msgpack_packer *res) - FUNC_ATTR_NONNULL_ALL -{ - size_t len = strlen(msg); - - // error message - msgpack_pack_bin(res, len); - msgpack_pack_bin_body(res, msg, len); - // Nil result - msgpack_pack_nil(res); -} - -/// Handler executed when an invalid method name is passed -Object msgpack_rpc_handle_missing_method(uint64_t channel_id, - msgpack_object *req, - Error *error) -{ - snprintf(error->msg, sizeof(error->msg), "Invalid method name"); - error->set = true; - return NIL; -} - -/// Serializes a msgpack-rpc request or notification(id == 0) -WBuffer *serialize_request(uint64_t request_id, - String method, - Array args, - msgpack_sbuffer *sbuffer, - size_t refcount) - FUNC_ATTR_NONNULL_ARG(4) -{ - msgpack_packer pac; - msgpack_packer_init(&pac, sbuffer, msgpack_sbuffer_write); - msgpack_pack_array(&pac, request_id ? 4 : 3); - msgpack_pack_int(&pac, request_id ? 0 : 2); - - if (request_id) { - msgpack_pack_uint64(&pac, request_id); - } - - msgpack_pack_bin(&pac, method.size); - msgpack_pack_bin_body(&pac, method.data, method.size); - msgpack_rpc_from_array(args, &pac); - WBuffer *rv = wstream_new_buffer(xmemdup(sbuffer->data, sbuffer->size), - sbuffer->size, - refcount, - free); - api_free_array(args); - msgpack_sbuffer_clear(sbuffer); - return rv; -} - -/// Serializes a msgpack-rpc response -WBuffer *serialize_response(uint64_t response_id, - Error *err, - Object arg, - msgpack_sbuffer *sbuffer) - FUNC_ATTR_NONNULL_ARG(2, 4) -{ - msgpack_packer pac; - msgpack_packer_init(&pac, sbuffer, msgpack_sbuffer_write); - msgpack_pack_array(&pac, 4); - msgpack_pack_int(&pac, 1); - msgpack_pack_uint64(&pac, response_id); - - if (err->set) { - // error represented by a [type, message] array - msgpack_pack_array(&pac, 2); - msgpack_rpc_from_integer(err->type, &pac); - msgpack_rpc_from_string(cstr_as_string(err->msg), &pac); - // Nil result - msgpack_pack_nil(&pac); - } else { - // Nil error - msgpack_pack_nil(&pac); - // Return value - msgpack_rpc_from_object(arg, &pac); - } - - WBuffer *rv = wstream_new_buffer(xmemdup(sbuffer->data, sbuffer->size), - sbuffer->size, - 1, // responses only go though 1 channel - free); - api_free_object(arg); - msgpack_sbuffer_clear(sbuffer); - return rv; -} - -static void msgpack_rpc_validate(uint64_t *response_id, - msgpack_object *req, - Error *err) -{ - // response id not known yet - - *response_id = 0; - // Validate the basic structure of the msgpack-rpc payload - if (req->type != MSGPACK_OBJECT_ARRAY) { - api_set_error(err, Validation, _("Request is not an array")); - } - - if (req->via.array.size != 4) { - api_set_error(err, Validation, _("Request array size should be 4")); - } - - if (req->via.array.ptr[1].type != MSGPACK_OBJECT_POSITIVE_INTEGER) { - api_set_error(err, Validation, _("Id must be a positive integer")); - } - - // Set the response id, which is the same as the request - *response_id = req->via.array.ptr[1].via.u64; - - if (req->via.array.ptr[0].type != MSGPACK_OBJECT_POSITIVE_INTEGER) { - api_set_error(err, Validation, _("Message type must be an integer")); - } - - if (req->via.array.ptr[0].via.u64 != 0) { - api_set_error(err, Validation, _("Message type must be 0")); - } - - if (req->via.array.ptr[2].type != MSGPACK_OBJECT_BIN - && req->via.array.ptr[2].type != MSGPACK_OBJECT_STR) { - api_set_error(err, Validation, _("Method must be a string")); - } - - if (req->via.array.ptr[3].type != MSGPACK_OBJECT_ARRAY) { - api_set_error(err, Validation, _("Paremeters must be an array")); - } -} diff --git a/src/nvim/os/msgpack_rpc_helpers.h b/src/nvim/os/msgpack_rpc_helpers.h deleted file mode 100644 index aede6b1587..0000000000 --- a/src/nvim/os/msgpack_rpc_helpers.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef NVIM_OS_MSGPACK_RPC_HELPERS_H -#define NVIM_OS_MSGPACK_RPC_HELPERS_H - -#include <stdint.h> -#include <stdbool.h> - -#include <msgpack.h> - -#include "nvim/api/private/defs.h" - -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "os/msgpack_rpc_helpers.h.generated.h" -#endif - -#endif // NVIM_OS_MSGPACK_RPC_HELPERS_H - diff --git a/src/nvim/os/provider.c b/src/nvim/os/provider.c index d4fffaa053..414c8841fa 100644 --- a/src/nvim/os/provider.c +++ b/src/nvim/os/provider.c @@ -8,7 +8,7 @@ #include "nvim/api/vim.h" #include "nvim/api/private/helpers.h" #include "nvim/api/private/defs.h" -#include "nvim/os/channel.h" +#include "nvim/msgpack_rpc/channel.h" #include "nvim/os/shell.h" #include "nvim/os/os.h" #include "nvim/log.h" diff --git a/src/nvim/os/server.h b/src/nvim/os/server.h deleted file mode 100644 index 43592a91e4..0000000000 --- a/src/nvim/os/server.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef NVIM_OS_SERVER_H -#define NVIM_OS_SERVER_H - -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "os/server.h.generated.h" -#endif -#endif // NVIM_OS_SERVER_H diff --git a/src/nvim/os/server_defs.h b/src/nvim/os/server_defs.h deleted file mode 100644 index 08cdf55428..0000000000 --- a/src/nvim/os/server_defs.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef NVIM_OS_SERVER_DEFS_H -#define NVIM_OS_SERVER_DEFS_H - -typedef struct server Server; - -#endif // NVIM_OS_SERVER_DEFS_H - diff --git a/src/nvim/os_unix.c b/src/nvim/os_unix.c index 52f57f8262..0ad15bc433 100644 --- a/src/nvim/os_unix.c +++ b/src/nvim/os_unix.c @@ -54,8 +54,8 @@ #include "nvim/os/shell.h" #include "nvim/os/signal.h" #include "nvim/os/job.h" -#include "nvim/os/msgpack_rpc.h" -#include "nvim/os/msgpack_rpc_helpers.h" +#include "nvim/msgpack_rpc/helpers.h" +#include "nvim/msgpack_rpc/defs.h" #if defined(HAVE_SYS_IOCTL_H) # include <sys/ioctl.h> @@ -166,8 +166,6 @@ void mch_init(void) mac_conv_init(); #endif - msgpack_rpc_init(); - msgpack_rpc_helpers_init(); event_init(); } |