/* vi:set ts=8 sts=4 sw=4:
 *
 * 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.
 */

/*
 * json.c: Encoding and decoding JSON.
 *
 * Follows this standard: https://tools.ietf.org/html/rfc7159.html
 */
#define USING_FLOAT_STUFF

#include "vim.h"

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

static int json_encode_item(garray_T *gap, typval_T *val, int copyID, int options);
static int json_decode_item(js_read_T *reader, typval_T *res, int options);

/*
 * Encode "val" into a JSON format string.
 * The result is in allocated memory.
 * The result is empty when encoding fails.
 * "options" can be JSON_JS or zero;
 */
    char_u *
json_encode(typval_T *val, int options)
{
    garray_T ga;

    /* Store bytes in the growarray. */
    ga_init2(&ga, 1, 4000);
    if (json_encode_item(&ga, val, get_copyID(), options) == FAIL)
    {
	vim_free(ga.ga_data);
	return vim_strsave((char_u *)"");
    }
    return ga.ga_data;
}

/*
 * Encode ["nr", "val"] into a JSON format string in allocated memory.
 * "options" can be JSON_JS or zero;
 * Returns NULL when out of memory.
 */
    char_u *
json_encode_nr_expr(int nr, typval_T *val, int options)
{
    typval_T	listtv;
    typval_T	nrtv;
    char_u	*text;

    nrtv.v_type = VAR_NUMBER;
    nrtv.vval.v_number = nr;
    if (rettv_list_alloc(&listtv) == FAIL)
	return NULL;
    if (list_append_tv(listtv.vval.v_list, &nrtv) == FAIL
	    || list_append_tv(listtv.vval.v_list, val) == FAIL)
    {
	list_unref(listtv.vval.v_list);
	return NULL;
    }

    text = json_encode(&listtv, options);
    list_unref(listtv.vval.v_list);
    return text;
}

    static void
write_string(garray_T *gap, char_u *str)
{
    char_u	*res = str;
    char_u	numbuf[NUMBUFLEN];

    if (res == NULL)
	ga_concat(gap, (char_u *)"null");
    else
    {
#if defined(FEAT_MBYTE) && defined(USE_ICONV)
	vimconv_T   conv;
	char_u	    *converted = NULL;

	if (!enc_utf8)
	{
	    /* Convert the text from 'encoding' to utf-8, the JSON string is
	     * always utf-8. */
	    conv.vc_type = CONV_NONE;
	    convert_setup(&conv, p_enc, (char_u*)"utf-8");
	    if (conv.vc_type != CONV_NONE)
		converted = res = string_convert(&conv, res, NULL);
	    convert_setup(&conv, NULL, NULL);
	}
#endif
	ga_append(gap, '"');
	while (*res != NUL)
	{
	    int c;
#ifdef FEAT_MBYTE
	    /* always use utf-8 encoding, ignore 'encoding' */
	    c = utf_ptr2char(res);
#else
	    c = *res;
#endif

	    switch (c)
	    {
		case 0x08:
		    ga_append(gap, '\\'); ga_append(gap, 'b'); break;
		case 0x09:
		    ga_append(gap, '\\'); ga_append(gap, 't'); break;
		case 0x0a:
		    ga_append(gap, '\\'); ga_append(gap, 'n'); break;
		case 0x0c:
		    ga_append(gap, '\\'); ga_append(gap, 'f'); break;
		case 0x0d:
		    ga_append(gap, '\\'); ga_append(gap, 'r'); break;
		case 0x22: /* " */
		case 0x5c: /* \ */
		    ga_append(gap, '\\');
		    ga_append(gap, c);
		    break;
		default:
		    if (c >= 0x20)
		    {
#ifdef FEAT_MBYTE
			numbuf[utf_char2bytes(c, numbuf)] = NUL;
#else
			numbuf[0] = c;
			numbuf[1] = NUL;
#endif
			ga_concat(gap, numbuf);
		    }
		    else
		    {
			vim_snprintf((char *)numbuf, NUMBUFLEN,
							 "\\u%04lx", (long)c);
			ga_concat(gap, numbuf);
		    }
	    }
#ifdef FEAT_MBYTE
	    res += utf_ptr2len(res);
#else
	    ++res;
#endif
	}
	ga_append(gap, '"');
#if defined(FEAT_MBYTE) && defined(USE_ICONV)
	vim_free(converted);
#endif
    }
}

/*
 * Return TRUE if "key" can be used without quotes.
 * That is when it starts with a letter and only contains letters, digits and
 * underscore.
 */
    static int
is_simple_key(char_u *key)
{
    char_u *p;

    if (!ASCII_ISALPHA(*key))
	return FALSE;
    for (p = key + 1; *p != NUL; ++p)
	if (!ASCII_ISALPHA(*p) && *p != '_' && !vim_isdigit(*p))
	    return FALSE;
    return TRUE;
}

/*
 * Encode "val" into "gap".
 * Return FAIL or OK.
 */
    static int
json_encode_item(garray_T *gap, typval_T *val, int copyID, int options)
{
    char_u	numbuf[NUMBUFLEN];
    char_u	*res;
    list_T	*l;
    dict_T	*d;

    switch (val->v_type)
    {
	case VAR_SPECIAL:
	    switch (val->vval.v_number)
	    {
		case VVAL_FALSE: ga_concat(gap, (char_u *)"false"); break;
		case VVAL_TRUE: ga_concat(gap, (char_u *)"true"); break;
		case VVAL_NONE: if ((options & JSON_JS) != 0
					     && (options & JSON_NO_NONE) == 0)
				    /* empty item */
				    break;
				/* FALLTHROUGH */
		case VVAL_NULL: ga_concat(gap, (char_u *)"null"); break;
	    }
	    break;

	case VAR_NUMBER:
	    vim_snprintf((char *)numbuf, NUMBUFLEN, "%ld",
						    (long)val->vval.v_number);
	    ga_concat(gap, numbuf);
	    break;

	case VAR_STRING:
	    res = val->vval.v_string;
	    write_string(gap, res);
	    break;

	case VAR_FUNC:
	case VAR_JOB:
	case VAR_CHANNEL:
	    /* no JSON equivalent TODO: better error */
	    EMSG(_(e_invarg));
	    return FAIL;

	case VAR_LIST:
	    l = val->vval.v_list;
	    if (l == NULL)
		ga_concat(gap, (char_u *)"null");
	    else
	    {
		if (l->lv_copyID == copyID)
		    ga_concat(gap, (char_u *)"[]");
		else
		{
		    listitem_T	*li;

		    l->lv_copyID = copyID;
		    ga_append(gap, '[');
		    for (li = l->lv_first; li != NULL && !got_int; )
		    {
			if (json_encode_item(gap, &li->li_tv, copyID,
						   options & JSON_JS) == FAIL)
			    return FAIL;
			if ((options & JSON_JS)
				&& li->li_next == NULL
				&& li->li_tv.v_type == VAR_SPECIAL
				&& li->li_tv.vval.v_number == VVAL_NONE)
			    /* add an extra comma if the last item is v:none */
			    ga_append(gap, ',');
			li = li->li_next;
			if (li != NULL)
			    ga_append(gap, ',');
		    }
		    ga_append(gap, ']');
		    l->lv_copyID = 0;
		}
	    }
	    break;

	case VAR_DICT:
	    d = val->vval.v_dict;
	    if (d == NULL)
		ga_concat(gap, (char_u *)"null");
	    else
	    {
		if (d->dv_copyID == copyID)
		    ga_concat(gap, (char_u *)"{}");
		else
		{
		    int		first = TRUE;
		    int		todo = (int)d->dv_hashtab.ht_used;
		    hashitem_T	*hi;

		    d->dv_copyID = copyID;
		    ga_append(gap, '{');

		    for (hi = d->dv_hashtab.ht_array; todo > 0 && !got_int;
									 ++hi)
			if (!HASHITEM_EMPTY(hi))
			{
			    --todo;
			    if (first)
				first = FALSE;
			    else
				ga_append(gap, ',');
			    if ((options & JSON_JS)
						 && is_simple_key(hi->hi_key))
				ga_concat(gap, hi->hi_key);
			    else
				write_string(gap, hi->hi_key);
			    ga_append(gap, ':');
			    if (json_encode_item(gap, &dict_lookup(hi)->di_tv,
				      copyID, options | JSON_NO_NONE) == FAIL)
				return FAIL;
			}
		    ga_append(gap, '}');
		    d->dv_copyID = 0;
		}
	    }
	    break;

	case VAR_FLOAT:
#ifdef FEAT_FLOAT
# if defined(HAVE_MATH_H)
	    if (isnan(val->vval.v_float))
		ga_concat(gap, (char_u *)"NaN");
	    else if (isinf(val->vval.v_float))
		ga_concat(gap, (char_u *)"Infinity");
	    else
# endif
	    {
		vim_snprintf((char *)numbuf, NUMBUFLEN, "%g",
							   val->vval.v_float);
		ga_concat(gap, numbuf);
	    }
	    break;
#endif
	case VAR_UNKNOWN:
	    EMSG2(_(e_intern2), "json_encode_item()");
	    return FAIL;
    }
    return OK;
}

/*
 * When "reader" has less than NUMBUFLEN bytes available, call the fill
 * callback to get more.
 */
    static void
fill_numbuflen(js_read_T *reader)
{
    if (reader->js_fill != NULL && (int)(reader->js_end - reader->js_buf)
						- reader->js_used < NUMBUFLEN)
    {
	if (reader->js_fill(reader))
	    reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
    }
}

/*
 * Skip white space in "reader".  All characters <= space are considered white
 * space.
 * Also tops up readahead when needed.
 */
    static void
json_skip_white(js_read_T *reader)
{
    int c;

    for (;;)
    {
	c = reader->js_buf[reader->js_used];
	if (reader->js_fill != NULL && c == NUL)
	{
	    if (reader->js_fill(reader))
		reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
	    continue;
	}
	if (c == NUL || c > ' ')
	    break;
	++reader->js_used;
    }
    fill_numbuflen(reader);
}

    static int
json_decode_array(js_read_T *reader, typval_T *res, int options)
{
    char_u	*p;
    typval_T	item;
    listitem_T	*li;
    int		ret;

    if (res != NULL && rettv_list_alloc(res) == FAIL)
    {
	res->v_type = VAR_SPECIAL;
	res->vval.v_number = VVAL_NONE;
	return FAIL;
    }
    ++reader->js_used; /* consume the '[' */

    while (TRUE)
    {
	json_skip_white(reader);
	p = reader->js_buf + reader->js_used;
	if (*p == NUL)
	    return MAYBE;
	if (*p == ']')
	{
	    ++reader->js_used; /* consume the ']' */
	    break;
	}

	ret = json_decode_item(reader, res == NULL ? NULL : &item, options);
	if (ret != OK)
	    return ret;
	if (res != NULL)
	{
	    li = listitem_alloc();
	    if (li == NULL)
	    {
		clear_tv(&item);
		return FAIL;
	    }
	    li->li_tv = item;
	    list_append(res->vval.v_list, li);
	}

	json_skip_white(reader);
	p = reader->js_buf + reader->js_used;
	if (*p == ',')
	    ++reader->js_used;
	else if (*p != ']')
	{
	    if (*p == NUL)
		return MAYBE;
	    return FAIL;
	}
    }
    return OK;
}

    static int
json_decode_object(js_read_T *reader, typval_T *res, int options)
{
    char_u	*p;
    typval_T	tvkey;
    typval_T	item;
    dictitem_T	*di;
    char_u	buf[NUMBUFLEN];
    char_u	*key = NULL;
    int		ret;

    if (res != NULL && rettv_dict_alloc(res) == FAIL)
    {
	res->v_type = VAR_SPECIAL;
	res->vval.v_number = VVAL_NONE;
	return FAIL;
    }
    ++reader->js_used; /* consume the '{' */

    while (TRUE)
    {
	json_skip_white(reader);
	p = reader->js_buf + reader->js_used;
	if (*p == NUL)
	    return MAYBE;
	if (*p == '}')
	{
	    ++reader->js_used; /* consume the '}' */
	    break;
	}

	if ((options & JSON_JS) && reader->js_buf[reader->js_used] != '"')
	{
	    /* accept a key that is not in quotes */
	    key = p = reader->js_buf + reader->js_used;
	    while (*p != NUL && *p != ':' && *p > ' ')
		++p;
	    tvkey.v_type = VAR_STRING;
	    tvkey.vval.v_string = vim_strnsave(key, (int)(p - key));
	    reader->js_used += (int)(p - key);
	    key = tvkey.vval.v_string;
	}
	else
	{
	    ret = json_decode_item(reader, res == NULL ? NULL : &tvkey,
								     options);
	    if (ret != OK)
		return ret;
	    if (res != NULL)
	    {
		key = get_tv_string_buf_chk(&tvkey, buf);
		if (key == NULL || *key == NUL)
		{
		    clear_tv(&tvkey);
		    return FAIL;
		}
	    }
	}

	json_skip_white(reader);
	p = reader->js_buf + reader->js_used;
	if (*p != ':')
	{
	    if (res != NULL)
		clear_tv(&tvkey);
	    if (*p == NUL)
		return MAYBE;
	    return FAIL;
	}
	++reader->js_used;
	json_skip_white(reader);

	ret = json_decode_item(reader, res == NULL ? NULL : &item, options);
	if (ret != OK)
	{
	    if (res != NULL)
		clear_tv(&tvkey);
	    return ret;
	}

	if (res != NULL)
	{
	    di = dictitem_alloc(key);
	    clear_tv(&tvkey);
	    if (di == NULL)
	    {
		clear_tv(&item);
		return FAIL;
	    }
	    di->di_tv = item;
	    di->di_tv.v_lock = 0;
	    if (dict_add(res->vval.v_dict, di) == FAIL)
	    {
		dictitem_free(di);
		return FAIL;
	    }
	}

	json_skip_white(reader);
	p = reader->js_buf + reader->js_used;
	if (*p == ',')
	    ++reader->js_used;
	else if (*p != '}')
	{
	    if (*p == NUL)
		return MAYBE;
	    return FAIL;
	}
    }
    return OK;
}

    static int
json_decode_string(js_read_T *reader, typval_T *res)
{
    garray_T    ga;
    int		len;
    char_u	*p;
    int		c;
    long	nr;
    char_u	buf[NUMBUFLEN];

    if (res != NULL)
	ga_init2(&ga, 1, 200);

    p = reader->js_buf + reader->js_used + 1; /* skip over " */
    while (*p != '"')
    {
	/* The JSON is always expected to be utf-8, thus use utf functions
	 * here. The string is converted below if needed. */
	if (*p == NUL || p[1] == NUL
#ifdef FEAT_MBYTE
		|| utf_ptr2len(p) < utf_byte2len(*p)
#endif
		)
	{
	    /* Not enough bytes to make a character or end of the string. Get
	     * more if possible. */
	    if (reader->js_fill == NULL)
		break;
	    len = (int)(reader->js_end - p);
	    reader->js_used = (int)(p - reader->js_buf);
	    if (!reader->js_fill(reader))
		break; /* didn't get more */
	    p = reader->js_buf + reader->js_used;
	    reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
	    continue;
	}

	if (*p == '\\')
	{
	    c = -1;
	    switch (p[1])
	    {
		case '\\': c = '\\'; break;
		case '"': c = '"'; break;
		case 'b': c = BS; break;
		case 't': c = TAB; break;
		case 'n': c = NL; break;
		case 'f': c = FF; break;
		case 'r': c = CAR; break;
		case 'u':
		    if (reader->js_fill != NULL
				     && (int)(reader->js_end - p) < NUMBUFLEN)
		    {
			reader->js_used = (int)(p - reader->js_buf);
			if (reader->js_fill(reader))
			{
			    p = reader->js_buf + reader->js_used;
			    reader->js_end = reader->js_buf
						     + STRLEN(reader->js_buf);
			}
		    }
		    nr = 0;
		    len = 0;
		    vim_str2nr(p + 2, NULL, &len,
				     STR2NR_HEX + STR2NR_FORCE, &nr, NULL, 4);
		    p += len + 2;
		    if (0xd800 <= nr && nr <= 0xdfff
			    && (int)(reader->js_end - p) >= 6
			    && *p == '\\' && *(p+1) == 'u')
		    {
			long	nr2 = 0;

			/* decode surrogate pair: \ud812\u3456 */
			len = 0;
			vim_str2nr(p + 2, NULL, &len,
				     STR2NR_HEX + STR2NR_FORCE, &nr2, NULL, 4);
			if (0xdc00 <= nr2 && nr2 <= 0xdfff)
			{
			    p += len + 2;
			    nr = (((nr - 0xd800) << 10) |
				((nr2 - 0xdc00) & 0x3ff)) + 0x10000;
			}
		    }
		    if (res != NULL)
		    {
#ifdef FEAT_MBYTE
			buf[utf_char2bytes((int)nr, buf)] = NUL;
			ga_concat(&ga, buf);
#else
			ga_append(&ga, nr);
#endif
		    }
		    break;
		default:
		    /* not a special char, skip over \ */
		    ++p;
		    continue;
	    }
	    if (c > 0)
	    {
		p += 2;
		if (res != NULL)
		    ga_append(&ga, c);
	    }
	}
	else
	{
#ifdef FEAT_MBYTE
	    len = utf_ptr2len(p);
#else
	    len = 1;
#endif
	    if (res != NULL)
	    {
		if (ga_grow(&ga, len) == FAIL)
		{
		    ga_clear(&ga);
		    return FAIL;
		}
		mch_memmove((char *)ga.ga_data + ga.ga_len, p, (size_t)len);
		ga.ga_len += len;
	    }
	    p += len;
	}
    }

    reader->js_used = (int)(p - reader->js_buf);
    if (*p == '"')
    {
	++reader->js_used;
	if (res != NULL)
	{
	    ga_append(&ga, NUL);
	    res->v_type = VAR_STRING;
#if defined(FEAT_MBYTE) && defined(USE_ICONV)
	    if (!enc_utf8)
	    {
		vimconv_T   conv;

		/* Convert the utf-8 string to 'encoding'. */
		conv.vc_type = CONV_NONE;
		convert_setup(&conv, (char_u*)"utf-8", p_enc);
		if (conv.vc_type != CONV_NONE)
		{
		    res->vval.v_string =
				      string_convert(&conv, ga.ga_data, NULL);
		    vim_free(ga.ga_data);
		}
		convert_setup(&conv, NULL, NULL);
	    }
	    else
#endif
		res->vval.v_string = ga.ga_data;
	}
	return OK;
    }
    if (res != NULL)
    {
	res->v_type = VAR_SPECIAL;
	res->vval.v_number = VVAL_NONE;
	ga_clear(&ga);
    }
    return MAYBE;
}

/*
 * Decode one item and put it in "res".  If "res" is NULL only advance.
 * Must already have skipped white space.
 *
 * Return FAIL for a decoding error.
 * Return MAYBE for an incomplete message.
 */
    static int
json_decode_item(js_read_T *reader, typval_T *res, int options)
{
    char_u	*p;
    int		len;

    fill_numbuflen(reader);
    p = reader->js_buf + reader->js_used;
    switch (*p)
    {
	case '[': /* array */
	    return json_decode_array(reader, res, options);

	case '{': /* object */
	    return json_decode_object(reader, res, options);

	case '"': /* string */
	    return json_decode_string(reader, res);

	case ',': /* comma: empty item */
	    if ((options & JSON_JS) == 0)
		return FAIL;
	    /* FALLTHROUGH */
	case NUL: /* empty */
	    if (res != NULL)
	    {
		res->v_type = VAR_SPECIAL;
		res->vval.v_number = VVAL_NONE;
	    }
	    return OK;

	default:
	    if (VIM_ISDIGIT(*p) || *p == '-')
	    {
#ifdef FEAT_FLOAT
		char_u  *sp = p;

		if (*sp == '-')
		{
		    ++sp;
		    if (*sp == NUL)
			return MAYBE;
		    if (!VIM_ISDIGIT(*sp))
			return FAIL;
		}
		sp = skipdigits(sp);
		if (*sp == '.' || *sp == 'e' || *sp == 'E')
		{
		    if (res == NULL)
		    {
			float_T f;

			len = string2float(p, &f);
		    }
		    else
		    {
			res->v_type = VAR_FLOAT;
			len = string2float(p, &res->vval.v_float);
		    }
		}
		else
#endif
		{
		    long nr;

		    vim_str2nr(reader->js_buf + reader->js_used,
			    NULL, &len, 0, /* what */
			    &nr, NULL, 0);
		    if (res != NULL)
		    {
			res->v_type = VAR_NUMBER;
			res->vval.v_number = nr;
		    }
		}
		reader->js_used += len;
		return OK;
	    }
	    if (STRNICMP((char *)p, "false", 5) == 0)
	    {
		reader->js_used += 5;
		if (res != NULL)
		{
		    res->v_type = VAR_SPECIAL;
		    res->vval.v_number = VVAL_FALSE;
		}
		return OK;
	    }
	    if (STRNICMP((char *)p, "true", 4) == 0)
	    {
		reader->js_used += 4;
		if (res != NULL)
		{
		    res->v_type = VAR_SPECIAL;
		    res->vval.v_number = VVAL_TRUE;
		}
		return OK;
	    }
	    if (STRNICMP((char *)p, "null", 4) == 0)
	    {
		reader->js_used += 4;
		if (res != NULL)
		{
		    res->v_type = VAR_SPECIAL;
		    res->vval.v_number = VVAL_NULL;
		}
		return OK;
	    }
#ifdef FEAT_FLOAT
	    if (STRNICMP((char *)p, "NaN", 3) == 0)
	    {
		reader->js_used += 3;
		if (res != NULL)
		{
		    res->v_type = VAR_FLOAT;
		    res->vval.v_float = NAN;
		}
		return OK;
	    }
	    if (STRNICMP((char *)p, "Infinity", 8) == 0)
	    {
		reader->js_used += 8;
		if (res != NULL)
		{
		    res->v_type = VAR_FLOAT;
		    res->vval.v_float = INFINITY;
		}
		return OK;
	    }
#endif
	    /* check for truncated name */
	    len = (int)(reader->js_end - (reader->js_buf + reader->js_used));
	    if (
		    (len < 5 && STRNICMP((char *)p, "false", len) == 0)
#ifdef FEAT_FLOAT
		    || (len < 8 && STRNICMP((char *)p, "Infinity", len) == 0)
		    || (len < 3 && STRNICMP((char *)p, "NaN", len) == 0)
#endif
		    || (len < 4 && (STRNICMP((char *)p, "true", len) == 0
			       ||  STRNICMP((char *)p, "null", len) == 0)))
		return MAYBE;
	    break;
    }

    if (res != NUL)
    {
	res->v_type = VAR_SPECIAL;
	res->vval.v_number = VVAL_NONE;
    }
    return FAIL;
}

/*
 * Decode the JSON from "reader" and store the result in "res".
 * "options" can be JSON_JS or zero;
 * Return FAIL if not the whole message was consumed.
 */
    int
json_decode_all(js_read_T *reader, typval_T *res, int options)
{
    int ret;

    /* We find the end once, to avoid calling strlen() many times. */
    reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
    json_skip_white(reader);
    ret = json_decode_item(reader, res, options);
    if (ret != OK)
	return FAIL;
    json_skip_white(reader);
    if (reader->js_buf[reader->js_used] != NUL)
	return FAIL;
    return OK;
}

/*
 * Decode the JSON from "reader" and store the result in "res".
 * "options" can be JSON_JS or zero;
 * Return FAIL if the message has a decoding error or the message is
 * truncated.  Consumes the message anyway.
 */
    int
json_decode(js_read_T *reader, typval_T *res, int options)
{
    int ret;

    /* We find the end once, to avoid calling strlen() many times. */
    reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
    json_skip_white(reader);
    ret = json_decode_item(reader, res, options);
    json_skip_white(reader);

    return ret == OK ? OK : FAIL;
}

/*
 * Decode the JSON from "reader" to find the end of the message.
 * "options" can be JSON_JS or zero;
 * Return FAIL if the message has a decoding error.
 * Return MAYBE if the message is truncated, need to read more.
 * This only works reliable if the message contains an object, array or
 * string.  A number might be trucated without knowing.
 * Does not advance the reader.
 */
    int
json_find_end(js_read_T *reader, int options)
{
    int used_save = reader->js_used;
    int ret;

    /* We find the end once, to avoid calling strlen() many times. */
    reader->js_end = reader->js_buf + STRLEN(reader->js_buf);
    json_skip_white(reader);
    ret = json_decode_item(reader, NULL, options);
    reader->js_used = used_save;
    return ret;
}
#endif
