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
This commit is contained in:
Thiago de Arruda 2014-10-20 07:35:10 -03:00
parent 6e268cd0d4
commit b280308ac6
22 changed files with 244 additions and 278 deletions

View File

@ -32,8 +32,6 @@ src/nvim/os/job.c
src/nvim/os/job.h src/nvim/os/job.h
src/nvim/os/job_defs.h src/nvim/os/job_defs.h
src/nvim/os/mem.c 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/os.h
src/nvim/os/rstream.c src/nvim/os/rstream.c
src/nvim/os/rstream.h src/nvim/os/rstream.h
@ -44,10 +42,12 @@ src/nvim/os/signal.c
src/nvim/os/signal.h src/nvim/os/signal.h
src/nvim/os/time.c src/nvim/os/time.c
src/nvim/os/time.h src/nvim/os/time.h
src/nvim/os/server.c src/nvim/msgpack_rpc/server.c
src/nvim/os/server.h src/nvim/msgpack_rpc/server.h
src/nvim/os/channel.c src/nvim/msgpack_rpc/channel.c
src/nvim/os/channel.h 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.c
src/nvim/tempfile.h src/nvim/tempfile.h
src/nvim/profile.c src/nvim/profile.c

View File

@ -92,8 +92,8 @@ output:write([[
#include "nvim/map.h" #include "nvim/map.h"
#include "nvim/log.h" #include "nvim/log.h"
#include "nvim/vim.h" #include "nvim/vim.h"
#include "nvim/os/msgpack_rpc.h" #include "nvim/msgpack_rpc/helpers.h"
#include "nvim/os/msgpack_rpc_helpers.h" #include "nvim/msgpack_rpc/defs.h"
#include "nvim/api/private/helpers.h" #include "nvim/api/private/helpers.h"
#include "nvim/api/private/defs.h" #include "nvim/api/private/defs.h"
]]) ]])
@ -249,7 +249,7 @@ end
output:write([[ output:write([[
static Map(String, rpc_method_handler_fn) *methods = NULL; 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)(); methods = map_new(String, rpc_method_handler_fn)();

View File

@ -3,7 +3,7 @@ include(CheckLibraryExists)
set(GENERATED_DIR ${PROJECT_BINARY_DIR}/src/nvim/auto) set(GENERATED_DIR ${PROJECT_BINARY_DIR}/src/nvim/auto)
set(DISPATCH_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/msgpack-gen.lua) set(DISPATCH_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/msgpack-gen.lua)
file(GLOB API_HEADERS api/*.h) 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(MSGPACK_DISPATCH ${GENERATED_DIR}/msgpack_dispatch.c)
set(HEADER_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gendeclarations.lua) set(HEADER_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/gendeclarations.lua)
set(GENERATED_INCLUDES_DIR ${PROJECT_BINARY_DIR}/include) 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}/os)
file(MAKE_DIRECTORY ${GENERATED_DIR}/api) file(MAKE_DIRECTORY ${GENERATED_DIR}/api)
file(MAKE_DIRECTORY ${GENERATED_DIR}/api/private) 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})
file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/os) file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/os)
file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/api) file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/api)
file(MAKE_DIRECTORY ${GENERATED_INCLUDES_DIR}/api/private) 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) file(GLOB_RECURSE NEOVIM_HEADERS *.h)
foreach(sfile ${NEOVIM_SOURCES}) foreach(sfile ${NEOVIM_SOURCES})
@ -126,7 +128,7 @@ add_custom_command(OUTPUT ${MSGPACK_DISPATCH}
COMMAND ${LUA_PRG} ${DISPATCH_GENERATOR} ${API_HEADERS} ${MSGPACK_DISPATCH} COMMAND ${LUA_PRG} ${DISPATCH_GENERATOR} ${API_HEADERS} ${MSGPACK_DISPATCH}
DEPENDS DEPENDS
${API_HEADERS} ${API_HEADERS}
${MSGPACK_RPC_HEADER} ${MSGPACK_RPC_HEADERS}
${DISPATCH_GENERATOR} ${DISPATCH_GENERATOR}
) )

View File

@ -10,7 +10,7 @@
#include "nvim/api/private/helpers.h" #include "nvim/api/private/helpers.h"
#include "nvim/api/private/defs.h" #include "nvim/api/private/defs.h"
#include "nvim/api/buffer.h" #include "nvim/api/buffer.h"
#include "nvim/os/channel.h" #include "nvim/msgpack_rpc/channel.h"
#include "nvim/os/provider.h" #include "nvim/os/provider.h"
#include "nvim/vim.h" #include "nvim/vim.h"
#include "nvim/buffer.h" #include "nvim/buffer.h"

View File

@ -81,7 +81,7 @@
#include "nvim/os/rstream.h" #include "nvim/os/rstream.h"
#include "nvim/os/rstream_defs.h" #include "nvim/os/rstream_defs.h"
#include "nvim/os/time.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/private/helpers.h"
#include "nvim/api/vim.h" #include "nvim/api/vim.h"
#include "nvim/os/dl.h" #include "nvim/os/dl.h"

View File

@ -59,7 +59,7 @@
#include "nvim/os/input.h" #include "nvim/os/input.h"
#include "nvim/os/os.h" #include "nvim/os/os.h"
#include "nvim/os/signal.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/defs.h"
#include "nvim/api/private/helpers.h" #include "nvim/api/private/helpers.h"

View File

@ -6,7 +6,7 @@
#include "nvim/map_defs.h" #include "nvim/map_defs.h"
#include "nvim/vim.h" #include "nvim/vim.h"
#include "nvim/memory.h" #include "nvim/memory.h"
#include "nvim/os/msgpack_rpc.h" #include "nvim/msgpack_rpc/defs.h"
#include "nvim/lib/khash.h" #include "nvim/lib/khash.h"

View File

@ -5,7 +5,7 @@
#include "nvim/map_defs.h" #include "nvim/map_defs.h"
#include "nvim/api/private/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) \ #define MAP_DECLS(T, U) \
KHASH_DECLARE(T##_##U##_map, T, U) \ KHASH_DECLARE(T##_##U##_map, T, U) \

View File

@ -7,7 +7,7 @@
#include "nvim/api/private/helpers.h" #include "nvim/api/private/helpers.h"
#include "nvim/api/vim.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/event.h"
#include "nvim/os/rstream.h" #include "nvim/os/rstream.h"
#include "nvim/os/rstream_defs.h" #include "nvim/os/rstream_defs.h"
@ -15,8 +15,7 @@
#include "nvim/os/wstream_defs.h" #include "nvim/os/wstream_defs.h"
#include "nvim/os/job.h" #include "nvim/os/job.h"
#include "nvim/os/job_defs.h" #include "nvim/os/job_defs.h"
#include "nvim/os/msgpack_rpc.h" #include "nvim/msgpack_rpc/helpers.h"
#include "nvim/os/msgpack_rpc_helpers.h"
#include "nvim/vim.h" #include "nvim/vim.h"
#include "nvim/ascii.h" #include "nvim/ascii.h"
#include "nvim/memory.h" #include "nvim/memory.h"
@ -60,7 +59,7 @@ static PMap(cstr_t) *event_strings = NULL;
static msgpack_sbuffer out_buffer; static msgpack_sbuffer out_buffer;
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/channel.c.generated.h" # include "msgpack_rpc/channel.c.generated.h"
#endif #endif
/// Initializes the module /// Initializes the module

View File

@ -1,5 +1,5 @@
#ifndef NVIM_OS_CHANNEL_H #ifndef NVIM_MSGPACK_RPC_CHANNEL_H
#define NVIM_OS_CHANNEL_H #define NVIM_MSGPACK_RPC_CHANNEL_H
#include <stdbool.h> #include <stdbool.h>
#include <uv.h> #include <uv.h>
@ -10,6 +10,6 @@
#define METHOD_MAXLEN 512 #define METHOD_MAXLEN 512
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/channel.h.generated.h" # include "msgpack_rpc/channel.h.generated.h"
#endif #endif
#endif // NVIM_OS_CHANNEL_H #endif // NVIM_MSGPACK_RPC_CHANNEL_H

View File

@ -1,19 +1,8 @@
#ifndef NVIM_OS_MSGPACK_RPC_H #ifndef NVIM_MSGPACK_RPC_DEFS_H
#define NVIM_OS_MSGPACK_RPC_H #define NVIM_MSGPACK_RPC_DEFS_H
#include <stdint.h>
#include <msgpack.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 /// The rpc_method_handlers table, used in msgpack_rpc_dispatch(), stores
/// functions of this type. /// functions of this type.
@ -21,9 +10,8 @@ typedef Object (*rpc_method_handler_fn)(uint64_t channel_id,
msgpack_object *req, msgpack_object *req,
Error *error); Error *error);
/// Initializes the msgpack-rpc method table /// 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); void msgpack_rpc_init_function_metadata(Dictionary *metadata);
@ -43,9 +31,4 @@ Object msgpack_rpc_dispatch(uint64_t channel_id,
Error *error) Error *error)
FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_NONNULL_ARG(3); FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_NONNULL_ARG(3);
#endif // NVIM_MSGPACK_RPC_DEFS_H
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/msgpack_rpc.h.generated.h"
#endif
#endif // NVIM_OS_MSGPACK_RPC_H

View File

@ -1,14 +1,18 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <inttypes.h>
#include <msgpack.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/vim.h"
#include "nvim/log.h"
#include "nvim/memory.h" #include "nvim/memory.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/msgpack_rpc_helpers.c.generated.h" # include "msgpack_rpc/helpers.c.generated.h"
#endif #endif
static msgpack_zone zone; 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); 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"));
}
}

View File

@ -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

View File

@ -5,8 +5,8 @@
#include <uv.h> #include <uv.h>
#include "nvim/os/channel.h" #include "nvim/msgpack_rpc/channel.h"
#include "nvim/os/server.h" #include "nvim/msgpack_rpc/server.h"
#include "nvim/os/os.h" #include "nvim/os/os.h"
#include "nvim/ascii.h" #include "nvim/ascii.h"
#include "nvim/vim.h" #include "nvim/vim.h"
@ -46,7 +46,7 @@ typedef struct {
static PMap(cstr_t) *servers = NULL; static PMap(cstr_t) *servers = NULL;
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "os/server.c.generated.h" # include "msgpack_rpc/server.c.generated.h"
#endif #endif
/// Initializes the module /// Initializes the module

View File

@ -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

View File

@ -7,8 +7,10 @@
#include "nvim/os/event.h" #include "nvim/os/event.h"
#include "nvim/os/input.h" #include "nvim/os/input.h"
#include "nvim/os/channel.h" #include "nvim/msgpack_rpc/defs.h"
#include "nvim/os/server.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/provider.h"
#include "nvim/os/signal.h" #include "nvim/os/signal.h"
#include "nvim/os/rstream.h" #include "nvim/os/rstream.h"
@ -41,6 +43,9 @@ static EventSource *immediate_sources = NULL;
void event_init(void) void event_init(void)
{ {
// early msgpack-rpc initialization
msgpack_rpc_init_method_table();
msgpack_rpc_helpers_init();
// Initialize the event queues // Initialize the event queues
deferred_events = kl_init(Event); deferred_events = kl_init(Event);
immediate_events = kl_init(Event); immediate_events = kl_init(Event);
@ -52,9 +57,8 @@ void event_init(void)
signal_init(); signal_init();
// Jobs // Jobs
job_init(); job_init();
// Channels // finish mspgack-rpc initialization
channel_init(); channel_init();
// Servers
server_init(); server_init();
// Providers // Providers
provider_init(); provider_init();

View File

@ -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"));
}
}

View File

@ -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

View File

@ -8,7 +8,7 @@
#include "nvim/api/vim.h" #include "nvim/api/vim.h"
#include "nvim/api/private/helpers.h" #include "nvim/api/private/helpers.h"
#include "nvim/api/private/defs.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/shell.h"
#include "nvim/os/os.h" #include "nvim/os/os.h"
#include "nvim/log.h" #include "nvim/log.h"

View File

@ -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

View File

@ -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

View File

@ -54,8 +54,8 @@
#include "nvim/os/shell.h" #include "nvim/os/shell.h"
#include "nvim/os/signal.h" #include "nvim/os/signal.h"
#include "nvim/os/job.h" #include "nvim/os/job.h"
#include "nvim/os/msgpack_rpc.h" #include "nvim/msgpack_rpc/helpers.h"
#include "nvim/os/msgpack_rpc_helpers.h" #include "nvim/msgpack_rpc/defs.h"
#if defined(HAVE_SYS_IOCTL_H) #if defined(HAVE_SYS_IOCTL_H)
# include <sys/ioctl.h> # include <sys/ioctl.h>
@ -166,8 +166,6 @@ void mch_init(void)
mac_conv_init(); mac_conv_init();
#endif #endif
msgpack_rpc_init();
msgpack_rpc_helpers_init();
event_init(); event_init();
} }