diff options
author | bfredl <bjorn.linse@gmail.com> | 2024-06-15 19:50:44 +0200 |
---|---|---|
committer | bfredl <bjorn.linse@gmail.com> | 2024-06-24 10:38:36 +0200 |
commit | 2bb1a18631c4035e4a582b7d995968acbac874bf (patch) | |
tree | 91cbe1813e2b1c6f3b940c21aced43d36cab8366 | |
parent | da4e8dc5b04a82c6dd483f6c5345a81d8b375bec (diff) | |
download | rneovim-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.c | 2 | ||||
-rw-r--r-- | src/nvim/eval/encode.c | 76 | ||||
-rw-r--r-- | src/nvim/eval/encode.h | 3 | ||||
-rw-r--r-- | src/nvim/eval/funcs.c | 24 | ||||
-rw-r--r-- | src/nvim/eval/typval.c | 8 | ||||
-rw-r--r-- | src/nvim/eval/typval_encode.c.h | 7 | ||||
-rw-r--r-- | src/nvim/lua/converter.c | 3 | ||||
-rw-r--r-- | src/nvim/msgpack_rpc/packer.c | 76 | ||||
-rw-r--r-- | src/nvim/shada.c | 56 |
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. |