diff options
author | Sean Dewar <seandewar@users.noreply.github.com> | 2020-11-18 03:11:00 +0000 |
---|---|---|
committer | Sean Dewar <seandewar@users.noreply.github.com> | 2021-09-15 21:19:22 +0100 |
commit | 9095101743b2606fb1d5f7a5a1216f22d2fb2b4a (patch) | |
tree | de186e64199ab977e0aa1beca08ac8aee9907a4d /src/nvim/eval/typval.h | |
parent | 685cf398130c61c158401b992a1893c2405cd7d2 (diff) | |
download | rneovim-9095101743b2606fb1d5f7a5a1216f22d2fb2b4a.tar.gz rneovim-9095101743b2606fb1d5f7a5a1216f22d2fb2b4a.tar.bz2 rneovim-9095101743b2606fb1d5f7a5a1216f22d2fb2b4a.zip |
vim-patch:8.1.0735: cannot handle binary data
Problem: Cannot handle binary data.
Solution: Add the Blob type. (Yasuhiro Matsumoto, closes vim/vim#3638)
https://github.com/vim/vim/commit/6e5ea8d2a995b32bbc5972edc4f827b959f2702f
Nvim-specific Blob conversions are implemented in future commits.
Refactor write_blob() to use a FileDescriptor, as f_writefile() was
refactored to use one (does not apply to read_blob()).
Use var_check_lock() in f_add() for Blobs from v8.1.0897.
Add a modeline to test_blob.vim and fix some doc typos.
Include if_perl.txt's VIM::Blob() documentation. Interestingly, this
function already worked before this port, as it just returns a Blob
string literal, not an actual Blob object.
N/A patches for version.c:
vim-patch:8.1.0741: viminfo with Blob is not tested
Problem: Viminfo with Blob is not tested.
Solution: Extend the viminfo test. Fix reading a blob. Fixed storing a
special variable value.
https://github.com/vim/vim/commit/8c8b8bb56c724cc1bfc3d8520eec33f2d399697c
vim-patch:8.1.1022: may use NULL pointer when out of memory
Problem: May use NULL pointer when out of memory. (Coverity)
Solution: Check for blob_alloc() returning NULL.
https://github.com/vim/vim/commit/e142a9467a7f6845a426d8db6efedf246d3c13ac
Diffstat (limited to 'src/nvim/eval/typval.h')
-rw-r--r-- | src/nvim/eval/typval.h | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h index ef49fa1de6..5aecaccee9 100644 --- a/src/nvim/eval/typval.h +++ b/src/nvim/eval/typval.h @@ -64,6 +64,7 @@ enum ListLenSpecials { typedef struct listvar_S list_T; typedef struct dictvar_S dict_T; typedef struct partial_S partial_T; +typedef struct blobvar_S blob_T; typedef struct ufunc ufunc_T; @@ -123,6 +124,7 @@ typedef enum { VAR_SPECIAL, ///< Special value (null), .v_special ///< is used. VAR_PARTIAL, ///< Partial, .v_partial is used. + VAR_BLOB, ///< Blob, .v_blob is used. } VarType; /// Structure that holds an internal variable value @@ -138,6 +140,7 @@ typedef struct { list_T *v_list; ///< List for VAR_LIST, can be NULL. dict_T *v_dict; ///< Dictionary for VAR_DICT, can be NULL. partial_T *v_partial; ///< Closure: function with args. + blob_T *v_blob; ///< Blob for VAR_BLOB, can be NULL. } vval; ///< Actual value. } typval_T; @@ -252,6 +255,13 @@ struct dictvar_S { LuaRef lua_table_ref; }; +/// Structure to hold info about a Blob +struct blobvar_S { + garray_T bv_ga; ///< Growarray with the data. + int bv_refcount; ///< Reference count. + VarLockStatus bv_lock; ///< VAR_UNLOCKED, VAR_LOCKED, VAR_FIXED. +}; + /// Type used for script ID typedef int scid_T; /// Format argument for scid_T @@ -711,6 +721,65 @@ static inline bool tv_dict_is_watched(const dict_T *const d) return d && !QUEUE_EMPTY(&d->watchers); } +static inline void tv_blob_set_ret(typval_T *const tv, blob_T *const b) + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ARG(1); + +/// Set a blob as the return value. +/// +/// Increments the reference count. +/// +/// @param[out] tv Object to receive the blob. +/// @param[in,out] b Blob to pass to the object. +static inline void tv_blob_set_ret(typval_T *const tv, blob_T *const b) +{ + tv->v_type = VAR_BLOB; + tv->vval.v_blob = b; + if (b != NULL) { + b->bv_refcount++; + } +} + +static inline int tv_blob_len(const blob_T *const b) + REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT; + +/// Get the length of the data in the blob, in bytes. +/// +/// @param[in] b Blob to check. +static inline int tv_blob_len(const blob_T *const b) +{ + if (b == NULL) { + return 0; + } + return b->bv_ga.ga_len; +} + +static inline char_u tv_blob_get(const blob_T *const b, int idx) + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT; + +/// Get the byte at index `idx` in the blob. +/// +/// @param[in] b Blob to index. Cannot be NULL. +/// @param[in] idx Index in a blob. Must be valid. +/// +/// @return Byte value at the given index. +static inline char_u tv_blob_get(const blob_T *const b, int idx) +{ + return ((char_u *)b->bv_ga.ga_data)[idx]; +} + +static inline void tv_blob_set(blob_T *const b, int idx, char_u c) + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_NONNULL_ALL; + +/// Store the byte `c` at index `idx` in the blob. +/// +/// @param[in] b Blob to index. Cannot be NULL. +/// @param[in] idx Index in a blob. Must be valid. +/// @param[in] c Value to store. +static inline void tv_blob_set(blob_T *const b, int idx, char_u c) +{ + ((char_u *)b->bv_ga.ga_data)[idx] = c; +} + /// Initialize VimL object /// /// Initializes to unlocked VAR_UNKNOWN object. |