/* vi:set ts=8 sts=4 sw=4 noet:
 *
 * VIM - Vi IMproved	by Bram Moolenaar
 *
 * Do ":help uganda"  in Vim to read copying and usage conditions.
 * Do ":help credits" in Vim to see a list of people who contributed.
 * See README.txt for an overview of the Vim source code.
 */

/*
 * blob.c: Blob support by Yasuhiro Matsumoto
 */

#include "vim.h"

#if defined(FEAT_EVAL) || defined(PROTO)

/*
 * Allocate an empty blob.
 * Caller should take care of the reference count.
 */
    blob_T *
blob_alloc(void)
{
    blob_T *blob = ALLOC_CLEAR_ONE(blob_T);

    if (blob != NULL)
	ga_init2(&blob->bv_ga, 1, 100);
    return blob;
}

/*
 * Allocate an empty blob for a return value, with reference count set.
 * Returns OK or FAIL.
 */
    int
rettv_blob_alloc(typval_T *rettv)
{
    blob_T	*b = blob_alloc();

    if (b == NULL)
	return FAIL;

    rettv_blob_set(rettv, b);
    return OK;
}

/*
 * Set a blob as the return value.
 */
    void
rettv_blob_set(typval_T *rettv, blob_T *b)
{
    rettv->v_type = VAR_BLOB;
    rettv->vval.v_blob = b;
    if (b != NULL)
	++b->bv_refcount;
}

    int
blob_copy(blob_T *from, typval_T *to)
{
    int	    ret = OK;

    to->v_type = VAR_BLOB;
    to->v_lock = 0;
    if (from == NULL)
	to->vval.v_blob = NULL;
    else if (rettv_blob_alloc(to) == FAIL)
	ret = FAIL;
    else
    {
	int  len = from->bv_ga.ga_len;

	if (len > 0)
	{
	    to->vval.v_blob->bv_ga.ga_data =
					 vim_memsave(from->bv_ga.ga_data, len);
	    if (to->vval.v_blob->bv_ga.ga_data == NULL)
		len = 0;
	}
	to->vval.v_blob->bv_ga.ga_len = len;
	to->vval.v_blob->bv_ga.ga_maxlen = len;
    }
    return ret;
}

    void
blob_free(blob_T *b)
{
    ga_clear(&b->bv_ga);
    vim_free(b);
}

/*
 * Unreference a blob: decrement the reference count and free it when it
 * becomes zero.
 */
    void
blob_unref(blob_T *b)
{
    if (b != NULL && --b->bv_refcount <= 0)
	blob_free(b);
}

/*
 * Get the length of data.
 */
    long
blob_len(blob_T *b)
{
    if (b == NULL)
	return 0L;
    return b->bv_ga.ga_len;
}

/*
 * Get byte "idx" in blob "b".
 * Caller must check that "idx" is valid.
 */
    int
blob_get(blob_T *b, int idx)
{
    return ((char_u*)b->bv_ga.ga_data)[idx];
}

/*
 * Store one byte "byte" in blob "blob" at "idx".
 * Caller must make sure that "idx" is valid.
 */
    void
blob_set(blob_T *blob, int idx, int byte)
{
    ((char_u*)blob->bv_ga.ga_data)[idx] = byte;
}

/*
 * Store one byte "byte" in blob "blob" at "idx".
 * Append one byte if needed.
 */
    void
blob_set_append(blob_T *blob, int idx, int byte)
{
    garray_T *gap = &blob->bv_ga;

    // Allow for appending a byte.  Setting a byte beyond
    // the end is an error otherwise.
    if (idx < gap->ga_len
	    || (idx == gap->ga_len && ga_grow(gap, 1) == OK))
    {
	blob_set(blob, idx, byte);
	if (idx == gap->ga_len)
	    ++gap->ga_len;
    }
}

/*
 * Return TRUE when two blobs have exactly the same values.
 */
    int
blob_equal(
    blob_T	*b1,
    blob_T	*b2)
{
    int	    i;
    int	    len1 = blob_len(b1);
    int	    len2 = blob_len(b2);

    // empty and NULL are considered the same
    if (len1 == 0 && len2 == 0)
	return TRUE;
    if (b1 == b2)
	return TRUE;
    if (len1 != len2)
	return FALSE;

    for (i = 0; i < b1->bv_ga.ga_len; i++)
	if (blob_get(b1, i) != blob_get(b2, i)) return FALSE;
    return TRUE;
}

/*
 * Read "blob" from file "fd".
 * Return OK or FAIL.
 */
    int
read_blob(FILE *fd, blob_T *blob)
{
    struct stat	st;

    if (fstat(fileno(fd), &st) < 0)
	return FAIL;
    if (ga_grow(&blob->bv_ga, st.st_size) == FAIL)
	return FAIL;
    blob->bv_ga.ga_len = st.st_size;
    if (fread(blob->bv_ga.ga_data, 1, blob->bv_ga.ga_len, fd)
						  < (size_t)blob->bv_ga.ga_len)
	return FAIL;
    return OK;
}

/*
 * Write "blob" to file "fd".
 * Return OK or FAIL.
 */
    int
write_blob(FILE *fd, blob_T *blob)
{
    if (fwrite(blob->bv_ga.ga_data, 1, blob->bv_ga.ga_len, fd)
						  < (size_t)blob->bv_ga.ga_len)
    {
	emsg(_(e_error_while_writing));
	return FAIL;
    }
    return OK;
}

/*
 * Convert a blob to a readable form: "0z00112233.44556677.8899"
 */
    char_u *
blob2string(blob_T *blob, char_u **tofree, char_u *numbuf)
{
    int		i;
    garray_T    ga;

    if (blob == NULL)
    {
	*tofree = NULL;
	return (char_u *)"0z";
    }

    // Store bytes in the growarray.
    ga_init2(&ga, 1, 4000);
    ga_concat(&ga, (char_u *)"0z");
    for (i = 0; i < blob_len(blob); i++)
    {
	if (i > 0 && (i & 3) == 0)
	    ga_concat(&ga, (char_u *)".");
	vim_snprintf((char *)numbuf, NUMBUFLEN, "%02X", (int)blob_get(blob, i));
	ga_concat(&ga, numbuf);
    }
    ga_append(&ga, NUL);		// append a NUL at the end
    *tofree = ga.ga_data;
    return *tofree;
}

/*
 * Convert a string variable, in the format of blob2string(), to a blob.
 * Return NULL when conversion failed.
 */
    blob_T *
string2blob(char_u *str)
{
    blob_T  *blob = blob_alloc();
    char_u  *s = str;

    if (blob == NULL)
	return NULL;
    if (s[0] != '0' || (s[1] != 'z' && s[1] != 'Z'))
	goto failed;
    s += 2;
    while (vim_isxdigit(*s))
    {
	if (!vim_isxdigit(s[1]))
	    goto failed;
	ga_append(&blob->bv_ga, (hex2nr(s[0]) << 4) + hex2nr(s[1]));
	s += 2;
	if (*s == '.' && vim_isxdigit(s[1]))
	    ++s;
    }
    if (*skipwhite(s) != NUL)
	goto failed;  // text after final digit

    ++blob->bv_refcount;
    return blob;

failed:
    blob_free(blob);
    return NULL;
}

    int
blob_slice_or_index(
	blob_T		*blob,
	int		is_range,
	varnumber_T	n1,
	varnumber_T	n2,
	int		exclusive,
	typval_T	*rettv)
{
    long	    len = blob_len(blob);

    if (is_range)
    {
	// The resulting variable is a sub-blob.  If the indexes
	// are out of range the result is empty.
	if (n1 < 0)
	{
	    n1 = len + n1;
	    if (n1 < 0)
		n1 = 0;
	}
	if (n2 < 0)
	    n2 = len + n2;
	else if (n2 >= len)
	    n2 = len - (exclusive ? 0 : 1);
	if (exclusive)
	    --n2;
	if (n1 >= len || n2 < 0 || n1 > n2)
	{
	    clear_tv(rettv);
	    rettv->v_type = VAR_BLOB;
	    rettv->vval.v_blob = NULL;
	}
	else
	{
	    blob_T  *new_blob = blob_alloc();
	    long    i;

	    if (new_blob != NULL)
	    {
		if (ga_grow(&new_blob->bv_ga, n2 - n1 + 1) == FAIL)
		{
		    blob_free(new_blob);
		    return FAIL;
		}
		new_blob->bv_ga.ga_len = n2 - n1 + 1;
		for (i = n1; i <= n2; i++)
		    blob_set(new_blob, i - n1, blob_get(blob, i));

		clear_tv(rettv);
		rettv_blob_set(rettv, new_blob);
	    }
	}
    }
    else
    {
	// The resulting variable is a byte value.
	// If the index is too big or negative that is an error.
	if (n1 < 0)
	    n1 = len + n1;
	if (n1 < len && n1 >= 0)
	{
	    int v = blob_get(blob, n1);

	    clear_tv(rettv);
	    rettv->v_type = VAR_NUMBER;
	    rettv->vval.v_number = v;
	}
	else
	{
	    semsg(_(e_blobidx), n1);
	    return FAIL;
	}
    }
    return OK;
}

/*
 * Check if "n1"- is a valid index for a blobl with length "bloblen".
 */
    int
check_blob_index(long bloblen, varnumber_T n1, int quiet)
{
    if (n1 < 0 || n1 > bloblen)
    {
	if (!quiet)
	    semsg(_(e_blobidx), n1);
	return FAIL;
    }
    return OK;
}

/*
 * Check if "n1"-"n2" is a valid range for a blob with length "bloblen".
 */
    int
check_blob_range(long bloblen, varnumber_T n1, varnumber_T n2, int quiet)
{
    if (n2 < 0 || n2 >= bloblen || n2 < n1)
    {
	if (!quiet)
	    semsg(_(e_blobidx), n2);
	return FAIL;
    }
    return OK;
}

/*
 * Set bytes "n1" to "n2" (inclusive) in "dest" to the value of "src".
 * Caller must make sure "src" is a blob.
 * Returns FAIL if the number of bytes does not match.
 */
    int
blob_set_range(blob_T *dest, long n1, long n2, typval_T *src)
{
    int	il, ir;

    if (n2 - n1 + 1 != blob_len(src->vval.v_blob))
    {
	emsg(_("E972: Blob value does not have the right number of bytes"));
	return FAIL;
    }

    ir = 0;
    for (il = n1; il <= n2; il++)
	blob_set(dest, il, blob_get(src->vval.v_blob, ir++));
    return OK;
}

/*
 * "add(blob, item)" function
 */
    void
blob_add(typval_T *argvars, typval_T *rettv)
{
    blob_T	*b = argvars[0].vval.v_blob;
    int		error = FALSE;
    varnumber_T n;

    if (b == NULL)
    {
	if (in_vim9script())
	    emsg(_(e_cannot_add_to_null_blob));
	return;
    }

    if (value_check_lock(b->bv_lock, (char_u *)N_("add() argument"), TRUE))
	return;

    n = tv_get_number_chk(&argvars[1], &error);
    if (error)
	return;

    ga_append(&b->bv_ga, (int)n);
    copy_tv(&argvars[0], rettv);
}

/*
 * "remove({blob}, {idx} [, {end}])" function
 */
    void
blob_remove(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg)
{
    blob_T	*b = argvars[0].vval.v_blob;
    blob_T	*newblob;
    int		error = FALSE;
    long	idx;
    long	end;
    int		len;
    char_u	*p;

    if (b != NULL && value_check_lock(b->bv_lock, arg_errmsg, TRUE))
	return;

    idx = (long)tv_get_number_chk(&argvars[1], &error);
    if (error)
	return;

    len = blob_len(b);

    if (idx < 0)
	// count from the end
	idx = len + idx;
    if (idx < 0 || idx >= len)
    {
	semsg(_(e_blobidx), idx);
	return;
    }
    if (argvars[2].v_type == VAR_UNKNOWN)
    {
	// Remove one item, return its value.
	p = (char_u *)b->bv_ga.ga_data;
	rettv->vval.v_number = (varnumber_T) *(p + idx);
	mch_memmove(p + idx, p + idx + 1, (size_t)len - idx - 1);
	--b->bv_ga.ga_len;
	return;
    }

    // Remove range of items, return blob with values.
    end = (long)tv_get_number_chk(&argvars[2], &error);
    if (error)
	return;
    if (end < 0)
	// count from the end
	end = len + end;
    if (end >= len || idx > end)
    {
	semsg(_(e_blobidx), end);
	return;
    }
    newblob = blob_alloc();
    if (newblob == NULL)
	return;
    newblob->bv_ga.ga_len = end - idx + 1;
    if (ga_grow(&newblob->bv_ga, end - idx + 1) == FAIL)
    {
	vim_free(newblob);
	return;
    }
    p = (char_u *)b->bv_ga.ga_data;
    mch_memmove((char_u *)newblob->bv_ga.ga_data, p + idx,
	    (size_t)(end - idx + 1));
    ++newblob->bv_refcount;
    rettv->v_type = VAR_BLOB;
    rettv->vval.v_blob = newblob;

    if (len - end - 1 > 0)
	mch_memmove(p + idx, p + end + 1, (size_t)(len - end - 1));
    b->bv_ga.ga_len -= end - idx + 1;
}

/*
 * Implementation of map() and filter() for a Blob.  Apply "expr" to every
 * number in Blob "blob_arg" and return the result in "rettv".
 */
    void
blob_filter_map(
	blob_T		*blob_arg,
	filtermap_T	filtermap,
	typval_T	*expr,
	typval_T	*rettv)
{
    blob_T	*b;
    int		i;
    typval_T	tv;
    varnumber_T	val;
    blob_T	*b_ret;
    int		idx = 0;
    int		rem;

    if (filtermap == FILTERMAP_MAPNEW)
    {
	rettv->v_type = VAR_BLOB;
	rettv->vval.v_blob = NULL;
    }
    if ((b = blob_arg) == NULL)
	return;

    b_ret = b;
    if (filtermap == FILTERMAP_MAPNEW)
    {
	if (blob_copy(b, rettv) == FAIL)
	    return;
	b_ret = rettv->vval.v_blob;
    }

    // set_vim_var_nr() doesn't set the type
    set_vim_var_type(VV_KEY, VAR_NUMBER);

    for (i = 0; i < b->bv_ga.ga_len; i++)
    {
	typval_T newtv;

	tv.v_type = VAR_NUMBER;
	val = blob_get(b, i);
	tv.vval.v_number = val;
	set_vim_var_nr(VV_KEY, idx);
	if (filter_map_one(&tv, expr, filtermap, &newtv, &rem) == FAIL
		|| did_emsg)
	    break;
	if (newtv.v_type != VAR_NUMBER && newtv.v_type != VAR_BOOL)
	{
	    clear_tv(&newtv);
	    emsg(_(e_invalblob));
	    break;
	}
	if (filtermap != FILTERMAP_FILTER)
	{
	    if (newtv.vval.v_number != val)
		blob_set(b_ret, i, newtv.vval.v_number);
	}
	else if (rem)
	{
	    char_u *p = (char_u *)blob_arg->bv_ga.ga_data;

	    mch_memmove(p + i, p + i + 1,
		    (size_t)b->bv_ga.ga_len - i - 1);
	    --b->bv_ga.ga_len;
	    --i;
	}
	++idx;
    }
}

/*
 * "insert(blob, {item} [, {idx}])" function
 */
    void
blob_insert_func(typval_T *argvars, typval_T *rettv)
{
    blob_T	*b = argvars[0].vval.v_blob;
    long	before = 0;
    int		error = FALSE;
    int		val, len;
    char_u	*p;

    if (b == NULL)
    {
	if (in_vim9script())
	    emsg(_(e_cannot_add_to_null_blob));
	return;
    }

    if (value_check_lock(b->bv_lock, (char_u *)N_("insert() argument"), TRUE))
	return;

    len = blob_len(b);
    if (argvars[2].v_type != VAR_UNKNOWN)
    {
	before = (long)tv_get_number_chk(&argvars[2], &error);
	if (error)
	    return;		// type error; errmsg already given
	if (before < 0 || before > len)
	{
	    semsg(_(e_invarg2), tv_get_string(&argvars[2]));
	    return;
	}
    }
    val = tv_get_number_chk(&argvars[1], &error);
    if (error)
	return;
    if (val < 0 || val > 255)
    {
	semsg(_(e_invarg2), tv_get_string(&argvars[1]));
	return;
    }

    if (ga_grow(&b->bv_ga, 1) == FAIL)
	return;
    p = (char_u *)b->bv_ga.ga_data;
    mch_memmove(p + before + 1, p + before, (size_t)len - before);
    *(p + before) = val;
    ++b->bv_ga.ga_len;

    copy_tv(&argvars[0], rettv);
}

/*
 * reduce() Blob argvars[0] using the function 'funcname' with arguments in
 * 'funcexe' starting with the initial value argvars[2] and return the result
 * in 'rettv'.
 */
    void
blob_reduce(
	typval_T	*argvars,
	char_u		*func_name,
	funcexe_T	*funcexe,
	typval_T	*rettv)
{
    blob_T	*b = argvars[0].vval.v_blob;
    int		called_emsg_start = called_emsg;
    int		r;
    typval_T	initial;
    typval_T	argv[3];
    int	i;

    if (argvars[2].v_type == VAR_UNKNOWN)
    {
	if (b == NULL || b->bv_ga.ga_len == 0)
	{
	    semsg(_(e_reduceempty), "Blob");
	    return;
	}
	initial.v_type = VAR_NUMBER;
	initial.vval.v_number = blob_get(b, 0);
	i = 1;
    }
    else if (argvars[2].v_type != VAR_NUMBER)
    {
	emsg(_(e_number_expected));
	return;
    }
    else
    {
	initial = argvars[2];
	i = 0;
    }

    copy_tv(&initial, rettv);
    if (b == NULL)
	return;

    for ( ; i < b->bv_ga.ga_len; i++)
    {
	argv[0] = *rettv;
	argv[1].v_type = VAR_NUMBER;
	argv[1].vval.v_number = blob_get(b, i);
	r = call_func(func_name, -1, rettv, 2, argv, funcexe);
	clear_tv(&argv[0]);
	if (r == FAIL || called_emsg != called_emsg_start)
	    return;
    }
}

/*
 * "reverse({blob})" function
 */
    void
blob_reverse(blob_T *b, typval_T *rettv)
{
    int	i, len = blob_len(b);

    for (i = 0; i < len / 2; i++)
    {
	int tmp = blob_get(b, i);

	blob_set(b, i, blob_get(b, len - i - 1));
	blob_set(b, len - i - 1, tmp);
    }
    rettv_blob_set(rettv, b);
}

/*
 * blob2list() function
 */
    void
f_blob2list(typval_T *argvars, typval_T *rettv)
{
    blob_T	*blob;
    list_T	*l;
    int		i;

    if (rettv_list_alloc(rettv) == FAIL)
	return;

    if (check_for_blob_arg(argvars, 0) == FAIL)
	return;

    blob = argvars->vval.v_blob;
    l = rettv->vval.v_list;
    for (i = 0; i < blob_len(blob); i++)
	list_append_number(l, blob_get(blob, i));
}

/*
 * list2blob() function
 */
    void
f_list2blob(typval_T *argvars, typval_T *rettv)
{
    list_T	*l;
    listitem_T	*li;
    blob_T	*blob;

    if (rettv_blob_alloc(rettv) == FAIL)
	return;
    blob = rettv->vval.v_blob;

    if (check_for_list_arg(argvars, 0) == FAIL)
	return;

    l = argvars->vval.v_list;
    if (l == NULL)
	return;

    CHECK_LIST_MATERIALIZE(l);
    FOR_ALL_LIST_ITEMS(l, li)
    {
	int		error;
	varnumber_T	n;

	error = FALSE;
	n = tv_get_number_chk(&li->li_tv, &error);
	if (error == TRUE || n < 0 || n > 255)
	{
	    if (!error)
		semsg(_(e_invalid_value_for_blob_nr), n);
	    ga_clear(&blob->bv_ga);
	    return;
	}
	ga_append(&blob->bv_ga, n);
    }
}

#endif // defined(FEAT_EVAL)
