aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2024-06-15 19:50:44 +0200
committerbfredl <bjorn.linse@gmail.com>2024-06-24 10:38:36 +0200
commit2bb1a18631c4035e4a582b7d995968acbac874bf (patch)
tree91cbe1813e2b1c6f3b940c21aced43d36cab8366
parentda4e8dc5b04a82c6dd483f6c5345a81d8b375bec (diff)
downloadrneovim-2bb1a18631c4035e4a582b7d995968acbac874bf.tar.gz
rneovim-2bb1a18631c4035e4a582b7d995968acbac874bf.tar.bz2
rneovim-2bb1a18631c4035e4a582b7d995968acbac874bf.zip
refactor(typval): don't use msgpack_packer for msgpackdump()
Step towords completely eliminating msgpack_packer.
-rw-r--r--src/nvim/api/private/converter.c2
-rw-r--r--src/nvim/eval/encode.c76
-rw-r--r--src/nvim/eval/encode.h3
-rw-r--r--src/nvim/eval/funcs.c24
-rw-r--r--src/nvim/eval/typval.c8
-rw-r--r--src/nvim/eval/typval_encode.c.h7
-rw-r--r--src/nvim/lua/converter.c3
-rw-r--r--src/nvim/msgpack_rpc/packer.c76
-rw-r--r--src/nvim/shada.c56
9 files changed, 146 insertions, 109 deletions
diff --git a/src/nvim/api/private/converter.c b/src/nvim/api/private/converter.c
index a78d78c057..0a4daf1dae 100644
--- a/src/nvim/api/private/converter.c
+++ b/src/nvim/api/private/converter.c
@@ -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
diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c
index e216dbdaa6..eb70b0534d 100644
--- a/src/nvim/eval/encode.c
+++ b/src/nvim/eval/encode.c
@@ -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
diff --git a/src/nvim/eval/encode.h b/src/nvim/eval/encode.h
index 6d1c0b61c5..efccfcb5a6 100644
--- a/src/nvim/eval/encode.h
+++ b/src/nvim/eval/encode.h
@@ -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
///
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 666d46cdad..9cb504c074 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -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,
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index 13b31ab30f..f9eb5c33c0 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -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
diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h
index c0cd0ce557..afee6dab18 100644
--- a/src/nvim/eval/typval_encode.c.h
+++ b/src/nvim/eval/typval_encode.c.h
@@ -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;
}
diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c
index 38ccb03cfc..1b1794e244 100644
--- a/src/nvim/lua/converter.c
+++ b/src/nvim/lua/converter.c
@@ -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
diff --git a/src/nvim/msgpack_rpc/packer.c b/src/nvim/msgpack_rpc/packer.c
index 58318b88b0..279cbb3925 100644
--- a/src/nvim/msgpack_rpc/packer.c
+++ b/src/nvim/msgpack_rpc/packer.c
@@ -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) };
+}
diff --git a/src/nvim/shada.c b/src/nvim/shada.c
index 5736ea0f09..34e1590458 100644
--- a/src/nvim/shada.c
+++ b/src/nvim/shada.c
@@ -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.