1
0
forked from aniani/vim

patch 9.1.1016: Not possible to convert string2blob and blob2string

Problem:  Not possible to convert string2blob and blob2string
Solution: add support for the blob2str() and str2blob() functions

closes: #16373

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Yegappan Lakshmanan
2025-01-14 17:29:42 +01:00
committed by Christian Brabandt
parent 1ac53b84ad
commit 1aefe1de0b
12 changed files with 307 additions and 3 deletions

View File

@@ -1213,6 +1213,146 @@ f_charidx(typval_T *argvars, typval_T *rettv)
rettv->vval.v_number = len > 0 ? len - 1 : 0;
}
/*
* Convert the string "str", from encoding "from" to encoding "to".
*/
static char_u *
convert_string(char_u *str, char_u *from, char_u *to)
{
vimconv_T vimconv;
vimconv.vc_type = CONV_NONE;
if (convert_setup(&vimconv, from, to) == FAIL)
return NULL;
vimconv.vc_fail = TRUE;
if (vimconv.vc_type == CONV_NONE)
str = vim_strsave(str);
else
str = string_convert(&vimconv, str, NULL);
convert_setup(&vimconv, NULL, NULL);
return str;
}
/*
* "blob2str()" function
* Converts a blob to a string, ensuring valid UTF-8 encoding.
*/
void
f_blob2str(typval_T *argvars, typval_T *rettv)
{
blob_T *blob;
char_u *str;
char_u *p;
int blen;
if (check_for_blob_arg(argvars, 0) == FAIL
|| check_for_opt_dict_arg(argvars, 1) == FAIL)
return;
blob = argvars->vval.v_blob;
blen = blob_len(blob);
rettv->v_type = VAR_STRING;
str = alloc(blen + 1);
if (str == NULL)
return;
for (int i = 0; i < blen; i++)
str[i] = (char_u)blob_get(blob, i);
str[blen] = NUL;
p = str;
if (argvars[1].v_type != VAR_UNKNOWN)
{
dict_T *d = argvars[1].vval.v_dict;
if (d != NULL)
{
char_u *enc = dict_get_string(d, "encoding", FALSE);
if (enc != NULL)
{
char_u *from = enc_canonize(enc_skip(enc));
p = convert_string(str, from, p_enc);
vim_free(str);
if (p == NULL)
{
semsg(_(e_str_encoding_failed), "from", from);
vim_free(from);
return;
}
vim_free(from);
}
}
}
if (STRCMP(p_enc, "utf-8") == 0 || STRCMP(p_enc, "utf8") == 0)
{
if (!utf_valid_string(p, NULL))
{
semsg(_(e_str_encoding_failed), "from", p_enc);
vim_free(p);
return;
}
}
rettv->vval.v_string = p;
}
/*
* "str2blob()" function
*/
void
f_str2blob(typval_T *argvars, typval_T *rettv)
{
blob_T *blob;
char_u *p;
size_t len;
if (check_for_string_arg(argvars, 0) == FAIL
|| check_for_opt_dict_arg(argvars, 1) == FAIL)
return;
if (rettv_blob_alloc(rettv) == FAIL)
return;
blob = rettv->vval.v_blob;
p = tv_get_string_chk(&argvars[0]);
if (p == NULL)
return;
int free_str = FALSE;
if (argvars[1].v_type != VAR_UNKNOWN)
{
dict_T *d = argvars[1].vval.v_dict;
if (d != NULL)
{
char_u *enc = dict_get_string(d, "encoding", FALSE);
if (enc != NULL)
{
char_u *to = enc_canonize(enc_skip(enc));
p = convert_string(p, p_enc, to);
if (p == NULL)
{
semsg(_(e_str_encoding_failed), "to", to);
vim_free(to);
return;
}
vim_free(to);
free_str = TRUE;
}
}
}
len = STRLEN(p);
for (size_t i = 0; i < len; i++)
ga_append(&blob->bv_ga, (int)p[i]);
if (free_str)
vim_free(p);
}
/*
* "str2list()" function
*/