mirror of
https://github.com/neovim/neovim.git
synced 2024-12-23 20:55:18 -07:00
refactor(typval): don't use msgpack_packer for msgpackdump()
Step towords completely eliminating msgpack_packer.
This commit is contained in:
parent
da4e8dc5b0
commit
2bb1a18631
@ -28,6 +28,7 @@ typedef struct {
|
||||
#endif
|
||||
|
||||
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
|
||||
#define TYPVAL_ENCODE_CHECK_BEFORE
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_NIL(tv) \
|
||||
kvi_push(edata->stack, NIL)
|
||||
@ -217,6 +218,7 @@ static inline void typval_encode_dict_end(EncodedData *const edata)
|
||||
#undef TYPVAL_ENCODE_CONV_LIST_START
|
||||
#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
|
||||
#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
|
||||
#undef TYPVAL_ENCODE_CHECK_BEFORE
|
||||
#undef TYPVAL_ENCODE_CONV_NIL
|
||||
#undef TYPVAL_ENCODE_CONV_BOOL
|
||||
#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "klib/kvec.h"
|
||||
#include "msgpack/pack.h"
|
||||
#include "nvim/api/private/helpers.h"
|
||||
#include "nvim/ascii_defs.h"
|
||||
#include "nvim/eval.h"
|
||||
#include "nvim/eval/encode.h"
|
||||
@ -28,6 +28,7 @@
|
||||
#include "nvim/mbyte.h"
|
||||
#include "nvim/memory.h"
|
||||
#include "nvim/message.h"
|
||||
#include "nvim/msgpack_rpc/packer.h"
|
||||
#include "nvim/strings.h"
|
||||
#include "nvim/types_defs.h"
|
||||
#include "nvim/vim_defs.h" // For _()
|
||||
@ -412,6 +413,8 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
|
||||
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
|
||||
ga_concat(gap, "{}")
|
||||
|
||||
#define TYPVAL_ENCODE_CHECK_BEFORE
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_NIL(tv) \
|
||||
ga_concat(gap, "v:null")
|
||||
|
||||
@ -536,6 +539,8 @@ int encode_read_from_list(ListReaderState *const state, char *const buf, const s
|
||||
#undef TYPVAL_ENCODE_ALLOW_SPECIALS
|
||||
#define TYPVAL_ENCODE_ALLOW_SPECIALS true
|
||||
|
||||
#define TYPVAL_ENCODE_CHECK_BEFORE
|
||||
|
||||
#undef TYPVAL_ENCODE_CONV_NIL
|
||||
#define TYPVAL_ENCODE_CONV_NIL(tv) \
|
||||
ga_concat(gap, "null")
|
||||
@ -821,6 +826,7 @@ bool encode_check_json_key(const typval_T *const tv)
|
||||
#undef TYPVAL_ENCODE_CONV_LIST_START
|
||||
#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
|
||||
#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
|
||||
#undef TYPVAL_ENCODE_CHECK_BEFORE
|
||||
#undef TYPVAL_ENCODE_CONV_NIL
|
||||
#undef TYPVAL_ENCODE_CONV_BOOL
|
||||
#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
|
||||
@ -913,52 +919,22 @@ char *encode_tv2json(typval_T *tv, size_t *len)
|
||||
}
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_STRING(tv, buf, len) \
|
||||
do { \
|
||||
if ((buf) == NULL) { \
|
||||
msgpack_pack_bin(packer, 0); \
|
||||
} else { \
|
||||
const size_t len_ = (len); \
|
||||
msgpack_pack_bin(packer, len_); \
|
||||
msgpack_pack_bin_body(packer, buf, len_); \
|
||||
} \
|
||||
} while (0)
|
||||
mpack_bin(buf, (len), packer); \
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_STR_STRING(tv, buf, len) \
|
||||
do { \
|
||||
if ((buf) == NULL) { \
|
||||
msgpack_pack_str(packer, 0); \
|
||||
} else { \
|
||||
const size_t len_ = (len); \
|
||||
msgpack_pack_str(packer, len_); \
|
||||
msgpack_pack_str_body(packer, buf, len_); \
|
||||
} \
|
||||
} while (0)
|
||||
mpack_str(cbuf_as_string(buf, (len)), packer); \
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_EXT_STRING(tv, buf, len, type) \
|
||||
do { \
|
||||
if ((buf) == NULL) { \
|
||||
msgpack_pack_ext(packer, 0, (int8_t)(type)); \
|
||||
} else { \
|
||||
const size_t len_ = (len); \
|
||||
msgpack_pack_ext(packer, len_, (int8_t)(type)); \
|
||||
msgpack_pack_ext_body(packer, buf, len_); \
|
||||
} \
|
||||
} while (0)
|
||||
mpack_ext(buf, (len), (int8_t)(type), packer); \
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_BLOB(tv, blob, len) \
|
||||
do { \
|
||||
const size_t len_ = (size_t)(len); \
|
||||
msgpack_pack_bin(packer, len_); \
|
||||
if (len_ > 0) { \
|
||||
msgpack_pack_bin_body(packer, (blob)->bv_ga.ga_data, len_); \
|
||||
} \
|
||||
} while (0)
|
||||
mpack_bin((blob) ? (blob)->bv_ga.ga_data : NULL, (size_t)(len), packer); \
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
|
||||
msgpack_pack_int64(packer, (int64_t)(num))
|
||||
mpack_integer(&packer->ptr, (Integer)(num))
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \
|
||||
msgpack_pack_double(packer, (double)(flt))
|
||||
mpack_float8(&packer->ptr, (double)(flt))
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_FUNC_START(tv, fun) \
|
||||
return conv_error(_("E5004: Error while dumping %s, %s: " \
|
||||
@ -970,33 +946,30 @@ char *encode_tv2json(typval_T *tv, size_t *len)
|
||||
#define TYPVAL_ENCODE_CONV_FUNC_END(tv)
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_EMPTY_LIST(tv) \
|
||||
msgpack_pack_array(packer, 0)
|
||||
mpack_array(&packer->ptr, 0)
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_LIST_START(tv, len) \
|
||||
msgpack_pack_array(packer, (size_t)(len))
|
||||
mpack_array(&packer->ptr, (uint32_t)(len))
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, mpsv)
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_EMPTY_DICT(tv, dict) \
|
||||
msgpack_pack_map(packer, 0)
|
||||
mpack_map(&packer->ptr, 0)
|
||||
|
||||
#define TYPVAL_ENCODE_CHECK_BEFORE \
|
||||
mpack_check_buffer(packer)
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_NIL(tv) \
|
||||
msgpack_pack_nil(packer)
|
||||
mpack_nil(&packer->ptr)
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
|
||||
do { \
|
||||
if (num) { \
|
||||
msgpack_pack_true(packer); \
|
||||
} else { \
|
||||
msgpack_pack_false(packer); \
|
||||
} \
|
||||
} while (0)
|
||||
mpack_bool(&packer->ptr, (bool)num); \
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER(tv, num) \
|
||||
msgpack_pack_uint64(packer, (num))
|
||||
mpack_uint64(&packer->ptr, (num))
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_DICT_START(tv, dict, len) \
|
||||
msgpack_pack_map(packer, (size_t)(len))
|
||||
mpack_map(&packer->ptr, (uint32_t)(len))
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_REAL_DICT_AFTER_START(tv, dict, mpsv)
|
||||
|
||||
@ -1021,7 +994,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)
|
||||
|
||||
#define TYPVAL_ENCODE_SCOPE
|
||||
#define TYPVAL_ENCODE_NAME msgpack
|
||||
#define TYPVAL_ENCODE_FIRST_ARG_TYPE msgpack_packer *const
|
||||
#define TYPVAL_ENCODE_FIRST_ARG_TYPE PackerBuffer *const
|
||||
#define TYPVAL_ENCODE_FIRST_ARG_NAME packer
|
||||
#include "nvim/eval/typval_encode.c.h"
|
||||
#undef TYPVAL_ENCODE_SCOPE
|
||||
@ -1043,6 +1016,7 @@ char *encode_tv2json(typval_T *tv, size_t *len)
|
||||
#undef TYPVAL_ENCODE_CONV_LIST_START
|
||||
#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
|
||||
#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
|
||||
#undef TYPVAL_ENCODE_CHECK_BEFORE
|
||||
#undef TYPVAL_ENCODE_CONV_NIL
|
||||
#undef TYPVAL_ENCODE_CONV_BOOL
|
||||
#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "nvim/eval/typval_defs.h"
|
||||
#include "nvim/garray_defs.h"
|
||||
#include "nvim/msgpack_rpc/packer_defs.h"
|
||||
|
||||
/// Convert Vimscript value to msgpack string
|
||||
///
|
||||
@ -13,7 +14,7 @@
|
||||
/// @param[in] objname Object name, used for error message.
|
||||
///
|
||||
/// @return OK in case of success, FAIL otherwise.
|
||||
int encode_vim_to_msgpack(msgpack_packer *packer, typval_T *tv, const char *objname);
|
||||
int encode_vim_to_msgpack(PackerBuffer *packer, typval_T *tv, const char *objname);
|
||||
|
||||
/// Convert Vimscript value to :echo output
|
||||
///
|
||||
|
@ -94,6 +94,7 @@
|
||||
#include "nvim/move.h"
|
||||
#include "nvim/msgpack_rpc/channel.h"
|
||||
#include "nvim/msgpack_rpc/channel_defs.h"
|
||||
#include "nvim/msgpack_rpc/packer.h"
|
||||
#include "nvim/msgpack_rpc/server.h"
|
||||
#include "nvim/normal.h"
|
||||
#include "nvim/normal_defs.h"
|
||||
@ -5501,15 +5502,7 @@ static void f_msgpackdump(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
return;
|
||||
}
|
||||
list_T *const list = argvars[0].vval.v_list;
|
||||
msgpack_packer *packer;
|
||||
if (argvars[1].v_type != VAR_UNKNOWN
|
||||
&& strequal(tv_get_string(&argvars[1]), "B")) {
|
||||
tv_blob_alloc_ret(rettv);
|
||||
packer = msgpack_packer_new(rettv->vval.v_blob, &encode_blob_write);
|
||||
} else {
|
||||
packer = msgpack_packer_new(tv_list_alloc_ret(rettv, kListLenMayKnow),
|
||||
&encode_list_write);
|
||||
}
|
||||
PackerBuffer packer = packer_string_buffer();
|
||||
const char *const msg = _("msgpackdump() argument, index %i");
|
||||
// Assume that translation will not take more then 4 times more space
|
||||
char msgbuf[sizeof("msgpackdump() argument, index ") * 4 + NUMBUFLEN];
|
||||
@ -5517,11 +5510,20 @@ static void f_msgpackdump(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
TV_LIST_ITER(list, li, {
|
||||
vim_snprintf(msgbuf, sizeof(msgbuf), msg, idx);
|
||||
idx++;
|
||||
if (encode_vim_to_msgpack(packer, TV_LIST_ITEM_TV(li), msgbuf) == FAIL) {
|
||||
if (encode_vim_to_msgpack(&packer, TV_LIST_ITEM_TV(li), msgbuf) == FAIL) {
|
||||
break;
|
||||
}
|
||||
});
|
||||
msgpack_packer_free(packer);
|
||||
String data = packer_take_string(&packer);
|
||||
if (argvars[1].v_type != VAR_UNKNOWN && strequal(tv_get_string(&argvars[1]), "B")) {
|
||||
blob_T *b = tv_blob_alloc_ret(rettv);
|
||||
b->bv_ga.ga_data = data.data;
|
||||
b->bv_ga.ga_len = (int)data.size;
|
||||
b->bv_ga.ga_maxlen = (int)(packer.endptr - packer.startptr);
|
||||
} else {
|
||||
encode_list_write(tv_list_alloc_ret(rettv, kListLenMayKnow), data.data, data.size);
|
||||
api_free_string(data);
|
||||
}
|
||||
}
|
||||
|
||||
static int msgpackparse_convert_item(const msgpack_object data, const msgpack_unpack_return result,
|
||||
|
@ -3064,8 +3064,7 @@ void f_blob2list(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
/// list2blob() function
|
||||
void f_list2blob(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
{
|
||||
tv_blob_alloc_ret(rettv);
|
||||
blob_T *const blob = rettv->vval.v_blob;
|
||||
blob_T *blob = tv_blob_alloc_ret(rettv);
|
||||
|
||||
if (tv_check_for_list_arg(argvars, 0) == FAIL) {
|
||||
return;
|
||||
@ -3252,11 +3251,12 @@ void tv_dict_remove(typval_T *argvars, typval_T *rettv, const char *arg_errmsg)
|
||||
/// Also sets reference count.
|
||||
///
|
||||
/// @param[out] ret_tv Structure where blob is saved.
|
||||
void tv_blob_alloc_ret(typval_T *const ret_tv)
|
||||
blob_T *tv_blob_alloc_ret(typval_T *const ret_tv)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
blob_T *const b = tv_blob_alloc();
|
||||
tv_blob_set_ret(ret_tv, b);
|
||||
return b;
|
||||
}
|
||||
|
||||
/// Copy a blob typval to a different typval.
|
||||
@ -3284,6 +3284,7 @@ void tv_blob_copy(blob_T *const from, typval_T *const to)
|
||||
|
||||
//{{{3 Clear
|
||||
#define TYPVAL_ENCODE_ALLOW_SPECIALS false
|
||||
#define TYPVAL_ENCODE_CHECK_BEFORE
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_NIL(tv) \
|
||||
do { \
|
||||
@ -3500,6 +3501,7 @@ static inline void _nothing_conv_dict_end(typval_T *const tv, dict_T **const dic
|
||||
#undef TYPVAL_ENCODE_FIRST_ARG_NAME
|
||||
|
||||
#undef TYPVAL_ENCODE_ALLOW_SPECIALS
|
||||
#undef TYPVAL_ENCODE_CHECK_BEFORE
|
||||
#undef TYPVAL_ENCODE_CONV_NIL
|
||||
#undef TYPVAL_ENCODE_CONV_BOOL
|
||||
#undef TYPVAL_ENCODE_CONV_NUMBER
|
||||
|
@ -6,6 +6,11 @@
|
||||
/// something else. For these macros to work the following macros must be
|
||||
/// defined:
|
||||
|
||||
/// @def TYPVAL_ENCODE_CHECK_BEFORE
|
||||
/// @brief Macro used before any specific CONV function
|
||||
///
|
||||
/// can be used for a common check, like flushing a buffer if necessary
|
||||
|
||||
/// @def TYPVAL_ENCODE_CONV_NIL
|
||||
/// @brief Macros used to convert NIL value
|
||||
///
|
||||
@ -323,6 +328,7 @@ static int TYPVAL_ENCODE_CONVERT_ONE_VALUE(
|
||||
TYPVAL_ENCODE_FIRST_ARG_TYPE TYPVAL_ENCODE_FIRST_ARG_NAME, MPConvStack *const mpstack,
|
||||
MPConvStackVal *const cur_mpsv, typval_T *const tv, const int copyID, const char *const objname)
|
||||
{
|
||||
TYPVAL_ENCODE_CHECK_BEFORE;
|
||||
switch (tv->v_type) {
|
||||
case VAR_STRING:
|
||||
TYPVAL_ENCODE_CONV_STRING(tv, tv->vval.v_string, tv_strlen(tv));
|
||||
@ -420,6 +426,7 @@ static int TYPVAL_ENCODE_CONVERT_ONE_VALUE(
|
||||
break;
|
||||
}
|
||||
}
|
||||
TYPVAL_ENCODE_CHECK_BEFORE;
|
||||
if (i == ARRAY_SIZE(eval_msgpack_type_lists)) {
|
||||
goto _convert_one_value_regular_dict;
|
||||
}
|
||||
|
@ -425,6 +425,8 @@ static bool typval_conv_special = false;
|
||||
|
||||
#define TYPVAL_ENCODE_ALLOW_SPECIALS true
|
||||
|
||||
#define TYPVAL_ENCODE_CHECK_BEFORE
|
||||
|
||||
#define TYPVAL_ENCODE_CONV_NIL(tv) \
|
||||
do { \
|
||||
if (typval_conv_special) { \
|
||||
@ -574,6 +576,7 @@ static bool typval_conv_special = false;
|
||||
#undef TYPVAL_ENCODE_CONV_LIST_START
|
||||
#undef TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START
|
||||
#undef TYPVAL_ENCODE_CONV_EMPTY_DICT
|
||||
#undef TYPVAL_ENCODE_CHECK_BEFORE
|
||||
#undef TYPVAL_ENCODE_CONV_NIL
|
||||
#undef TYPVAL_ENCODE_CONV_BOOL
|
||||
#undef TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER
|
||||
|
@ -8,7 +8,7 @@
|
||||
# include "msgpack_rpc/packer.c.generated.h"
|
||||
#endif
|
||||
|
||||
static void check_buffer(PackerBuffer *packer)
|
||||
void mpack_check_buffer(PackerBuffer *packer)
|
||||
{
|
||||
if (mpack_remaining(packer) < MPACK_ITEM_SIZE) {
|
||||
packer->packer_flush(packer);
|
||||
@ -87,7 +87,25 @@ void mpack_str(String str, PackerBuffer *packer)
|
||||
mpack_raw(str.data, len, packer);
|
||||
}
|
||||
|
||||
void mpack_raw(char *data, size_t len, PackerBuffer *packer)
|
||||
void mpack_bin(const char *data, size_t len, PackerBuffer *packer)
|
||||
{
|
||||
if (len < 0xff) {
|
||||
mpack_w(&packer->ptr, 0xc4);
|
||||
mpack_w(&packer->ptr, len);
|
||||
} else if (len < 0xffff) {
|
||||
mpack_w(&packer->ptr, 0xc5);
|
||||
mpack_w2(&packer->ptr, (uint32_t)len);
|
||||
} else if (len < 0xffffffff) {
|
||||
mpack_w(&packer->ptr, 0xc6);
|
||||
mpack_w4(&packer->ptr, (uint32_t)len);
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
|
||||
mpack_raw(data, len, packer);
|
||||
}
|
||||
|
||||
void mpack_raw(const char *data, size_t len, PackerBuffer *packer)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while (pos < len) {
|
||||
@ -103,6 +121,27 @@ void mpack_raw(char *data, size_t len, PackerBuffer *packer)
|
||||
}
|
||||
}
|
||||
|
||||
void mpack_ext(char *buf, size_t len, int8_t type, PackerBuffer *packer)
|
||||
{
|
||||
if (len == 1) {
|
||||
mpack_w(&packer->ptr, 0xd4);
|
||||
} else if (len == 2) {
|
||||
mpack_w(&packer->ptr, 0xd5);
|
||||
} else if (len <= 0xff) {
|
||||
mpack_w(&packer->ptr, 0xc7);
|
||||
} else if (len < 0xffff) {
|
||||
mpack_w(&packer->ptr, 0xc8);
|
||||
mpack_w2(&packer->ptr, (uint32_t)len);
|
||||
} else if (len < 0xffffffff) {
|
||||
mpack_w(&packer->ptr, 0xc9);
|
||||
mpack_w4(&packer->ptr, (uint32_t)len);
|
||||
} else {
|
||||
abort();
|
||||
}
|
||||
mpack_w(&packer->ptr, type);
|
||||
mpack_raw(buf, len, packer);
|
||||
}
|
||||
|
||||
void mpack_handle(ObjectType type, handle_T handle, PackerBuffer *packer)
|
||||
{
|
||||
char exttype = (char)(type - EXT_OBJECT_TYPE_SHIFT);
|
||||
@ -156,7 +195,7 @@ void mpack_object_inner(Object *current, Object *container, size_t container_idx
|
||||
kvi_init(stack);
|
||||
|
||||
while (true) {
|
||||
check_buffer(packer);
|
||||
mpack_check_buffer(packer);
|
||||
switch (current->type) {
|
||||
case kObjectTypeLuaRef:
|
||||
// TODO(bfredl): could also be an error. Though kObjectTypeLuaRef
|
||||
@ -231,7 +270,7 @@ void mpack_object_inner(Object *current, Object *container, size_t container_idx
|
||||
} else {
|
||||
Dictionary dict = container->data.dictionary;
|
||||
KeyValuePair *it = &dict.items[container_idx++];
|
||||
check_buffer(packer);
|
||||
mpack_check_buffer(packer);
|
||||
mpack_str(it->key, packer);
|
||||
current = &it->value;
|
||||
if (container_idx >= dict.size) {
|
||||
@ -241,3 +280,32 @@ void mpack_object_inner(Object *current, Object *container, size_t container_idx
|
||||
}
|
||||
kvi_destroy(stack);
|
||||
}
|
||||
|
||||
PackerBuffer packer_string_buffer(void)
|
||||
{
|
||||
const size_t initial_size = 64; // must be larger than SHADA_MPACK_FREE_SPACE
|
||||
char *alloc = xmalloc(initial_size);
|
||||
return (PackerBuffer) {
|
||||
.startptr = alloc,
|
||||
.ptr = alloc,
|
||||
.endptr = alloc + initial_size,
|
||||
.packer_flush = flush_string_buffer,
|
||||
};
|
||||
}
|
||||
|
||||
static void flush_string_buffer(PackerBuffer *buffer)
|
||||
{
|
||||
size_t current_capacity = (size_t)(buffer->endptr - buffer->startptr);
|
||||
size_t new_capacity = 2 * current_capacity;
|
||||
size_t len = (size_t)(buffer->ptr - buffer->startptr);
|
||||
|
||||
buffer->startptr = xrealloc(buffer->startptr, new_capacity);
|
||||
buffer->ptr = buffer->startptr + len;
|
||||
buffer->endptr = buffer->startptr + new_capacity;
|
||||
}
|
||||
|
||||
/// can only be used with a PackerBuffer from `packer_string_buffer`
|
||||
String packer_take_string(PackerBuffer *buffer)
|
||||
{
|
||||
return (String){ .data = buffer->startptr, .size = (size_t)(buffer->ptr - buffer->startptr) };
|
||||
}
|
||||
|
@ -1354,6 +1354,12 @@ static char *shada_filename(const char *file)
|
||||
|
||||
#define SHADA_MPACK_FREE_SPACE (4 * MPACK_ITEM_SIZE)
|
||||
|
||||
static int mpack_raw_wrapper(void *cookie, const char *data, size_t len)
|
||||
{
|
||||
mpack_raw(data, len, (PackerBuffer *)cookie);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Write single ShaDa entry
|
||||
///
|
||||
/// @param[in] packer Packer used to write entry.
|
||||
@ -1367,14 +1373,13 @@ static ShaDaWriteResult shada_pack_entry(PackerBuffer *const packer, ShadaEntry
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
ShaDaWriteResult ret = kSDWriteFailed;
|
||||
msgpack_sbuffer sbuf;
|
||||
msgpack_sbuffer_init(&sbuf);
|
||||
msgpack_packer *spacker = msgpack_packer_new(&sbuf, &msgpack_sbuffer_write);
|
||||
PackerBuffer sbuf = packer_string_buffer();
|
||||
msgpack_packer *spacker = msgpack_packer_new(&sbuf, &mpack_raw_wrapper);
|
||||
#define DUMP_ADDITIONAL_ELEMENTS(src, what) \
|
||||
do { \
|
||||
if ((src) != NULL) { \
|
||||
TV_LIST_ITER((src), li, { \
|
||||
if (encode_vim_to_msgpack(spacker, TV_LIST_ITEM_TV(li), \
|
||||
if (encode_vim_to_msgpack(&sbuf, TV_LIST_ITEM_TV(li), \
|
||||
_("additional elements of ShaDa " what)) \
|
||||
== FAIL) { \
|
||||
goto shada_pack_entry_error; \
|
||||
@ -1394,7 +1399,7 @@ static ShaDaWriteResult shada_pack_entry(PackerBuffer *const packer, ShadaEntry
|
||||
const size_t key_len = strlen(hi->hi_key); \
|
||||
msgpack_pack_str(spacker, key_len); \
|
||||
msgpack_pack_str_body(spacker, hi->hi_key, key_len); \
|
||||
if (encode_vim_to_msgpack(spacker, &di->di_tv, \
|
||||
if (encode_vim_to_msgpack(&sbuf, &di->di_tv, \
|
||||
_("additional data of ShaDa " what)) \
|
||||
== FAIL) { \
|
||||
goto shada_pack_entry_error; \
|
||||
@ -1460,7 +1465,7 @@ static ShaDaWriteResult shada_pack_entry(PackerBuffer *const packer, ShadaEntry
|
||||
char vardesc[256] = "variable g:";
|
||||
memcpy(&vardesc[sizeof("variable g:") - 1], varname.data,
|
||||
varname.size + 1);
|
||||
if (encode_vim_to_msgpack(spacker, &entry.data.global_var.value, vardesc)
|
||||
if (encode_vim_to_msgpack(&sbuf, &entry.data.global_var.value, vardesc)
|
||||
== FAIL) {
|
||||
ret = kSDWriteIgnError;
|
||||
semsg(_(WERR "Failed to write variable %s"),
|
||||
@ -1645,7 +1650,8 @@ static ShaDaWriteResult shada_pack_entry(PackerBuffer *const packer, ShadaEntry
|
||||
}
|
||||
#undef CHECK_DEFAULT
|
||||
#undef ONE_IF_NOT_DEFAULT
|
||||
if (!max_kbyte || sbuf.size <= max_kbyte * 1024) {
|
||||
String packed = packer_take_string(&sbuf);
|
||||
if (!max_kbyte || packed.size <= max_kbyte * 1024) {
|
||||
if (mpack_remaining(packer) < SHADA_MPACK_FREE_SPACE) {
|
||||
packer->packer_flush(packer);
|
||||
}
|
||||
@ -1656,9 +1662,9 @@ static ShaDaWriteResult shada_pack_entry(PackerBuffer *const packer, ShadaEntry
|
||||
mpack_uint64(&packer->ptr, (uint64_t)entry.type);
|
||||
}
|
||||
mpack_uint64(&packer->ptr, (uint64_t)entry.timestamp);
|
||||
if (sbuf.size > 0) {
|
||||
mpack_uint64(&packer->ptr, (uint64_t)sbuf.size);
|
||||
mpack_raw(sbuf.data, sbuf.size, packer);
|
||||
if (packed.size > 0) {
|
||||
mpack_uint64(&packer->ptr, (uint64_t)packed.size);
|
||||
mpack_raw(packed.data, packed.size, packer);
|
||||
}
|
||||
|
||||
if (packer->anyint != 0) { // error code
|
||||
@ -1668,7 +1674,7 @@ static ShaDaWriteResult shada_pack_entry(PackerBuffer *const packer, ShadaEntry
|
||||
ret = kSDWriteSuccessful;
|
||||
shada_pack_entry_error:
|
||||
msgpack_packer_free(spacker);
|
||||
msgpack_sbuffer_destroy(&sbuf);
|
||||
xfree(sbuf.startptr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -3960,34 +3966,6 @@ static inline size_t shada_init_jumps(PossiblyFreedShadaEntry *jumps,
|
||||
return jumps_size;
|
||||
}
|
||||
|
||||
static PackerBuffer packer_string_buffer(void)
|
||||
{
|
||||
const size_t initial_size = 64; // must be larger than SHADA_MPACK_FREE_SPACE
|
||||
char *alloc = xmalloc(initial_size);
|
||||
return (PackerBuffer) {
|
||||
.startptr = alloc,
|
||||
.ptr = alloc,
|
||||
.endptr = alloc + initial_size,
|
||||
.packer_flush = flush_string_buffer,
|
||||
};
|
||||
}
|
||||
|
||||
static void flush_string_buffer(PackerBuffer *buffer)
|
||||
{
|
||||
size_t current_capacity = (size_t)(buffer->endptr - buffer->startptr);
|
||||
size_t new_capacity = 2 * current_capacity;
|
||||
size_t len = (size_t)(buffer->ptr - buffer->startptr);
|
||||
|
||||
buffer->startptr = xrealloc(buffer->startptr, new_capacity);
|
||||
buffer->ptr = buffer->startptr + len;
|
||||
buffer->endptr = buffer->startptr + new_capacity;
|
||||
}
|
||||
|
||||
static String packer_take_string(PackerBuffer *buffer)
|
||||
{
|
||||
return (String){ .data = buffer->startptr, .size = (size_t)(buffer->ptr - buffer->startptr) };
|
||||
}
|
||||
|
||||
/// Write registers ShaDa entries in given msgpack_sbuffer.
|
||||
///
|
||||
/// @param[in] sbuf target msgpack_sbuffer to write to.
|
||||
|
Loading…
Reference in New Issue
Block a user