// SPDX-License-Identifier: GPL-2.0+
/*
 * Implementation of configuration editor
 *
 * Copyright 2023 Google LLC
 * Written by Simon Glass <sjg@chromium.org>
 */

#define LOG_CATEGORY LOGC_EXPO

#include <abuf.h>
#include <cedit.h>
#include <cli.h>
#include <dm.h>
#include <env.h>
#include <expo.h>
#include <malloc.h>
#include <menu.h>
#include <rtc.h>
#include <video.h>
#include <linux/delay.h>
#include "scene_internal.h"
#include <u-boot/schedule.h>

enum {
	CMOS_MAX_BITS	= 2048,
	CMOS_MAX_BYTES	= CMOS_MAX_BITS / 8,
};

#define CMOS_BYTE(bit)	((bit) / 8)
#define CMOS_BIT(bit)	((bit) % 8)

/**
 * struct cedit_iter_priv - private data for cedit operations
 *
 * @buf: Buffer to use when writing settings to the devicetree
 * @node: Node to read from when reading settings from devicetree
 * @verbose: true to show writing to environment variables
 * @mask: Mask bits for the CMOS RAM. If a bit is set the byte containing it
 * will be written
 * @value: Value bits for CMOS RAM. This is the actual value written
 * @dev: RTC device to write to
 */
struct cedit_iter_priv {
	struct abuf *buf;
	ofnode node;
	bool verbose;
	u8 *mask;
	u8 *value;
	struct udevice *dev;
};

int cedit_arange(struct expo *exp, struct video_priv *vpriv, uint scene_id)
{
	struct expo_arrange_info arr;
	struct scene_obj_txt *txt;
	struct scene_obj *obj;
	struct scene *scn;
	int y, ret;

	scn = expo_lookup_scene_id(exp, scene_id);
	if (!scn)
		return log_msg_ret("scn", -ENOENT);

	txt = scene_obj_find_by_name(scn, "prompt");
	if (txt)
		scene_obj_set_pos(scn, txt->obj.id, 0, vpriv->ysize - 50);

	txt = scene_obj_find_by_name(scn, "title");
	if (txt)
		scene_obj_set_pos(scn, txt->obj.id, 200, 10);

	memset(&arr, '\0', sizeof(arr));
	ret = scene_calc_arrange(scn, &arr);
	if (ret < 0)
		return log_msg_ret("arr", ret);

	y = 100;
	list_for_each_entry(obj, &scn->obj_head, sibling) {
		switch (obj->type) {
		case SCENEOBJT_NONE:
		case SCENEOBJT_IMAGE:
		case SCENEOBJT_TEXT:
			break;
		case SCENEOBJT_MENU:
			scene_obj_set_pos(scn, obj->id, 50, y);
			scene_menu_arrange(scn, &arr,
					   (struct scene_obj_menu *)obj);
			y += 50;
			break;
		case SCENEOBJT_TEXTLINE:
			scene_obj_set_pos(scn, obj->id, 50, y);
			scene_textline_arrange(scn, &arr,
					(struct scene_obj_textline *)obj);
			y += 50;
			break;
		}
	}

	return 0;
}

int cedit_prepare(struct expo *exp, struct video_priv **vid_privp,
		  struct scene **scnp)
{
	struct video_priv *vid_priv;
	struct udevice *dev;
	struct scene *scn;
	uint scene_id;
	int ret;

	/* For now we only support a video console */
	ret = uclass_first_device_err(UCLASS_VIDEO, &dev);
	if (ret)
		return log_msg_ret("vid", ret);
	ret = expo_set_display(exp, dev);
	if (ret)
		return log_msg_ret("dis", ret);

	ret = expo_first_scene_id(exp);
	if (ret < 0)
		return log_msg_ret("scn", ret);
	scene_id = ret;

	ret = expo_set_scene_id(exp, scene_id);
	if (ret)
		return log_msg_ret("sid", ret);

	exp->popup = true;

	/* This is not supported for now */
	if (0)
		expo_set_text_mode(exp, true);

	vid_priv = dev_get_uclass_priv(dev);

	scn = expo_lookup_scene_id(exp, scene_id);
	scene_highlight_first(scn);

	cedit_arange(exp, vid_priv, scene_id);

	ret = expo_calc_dims(exp);
	if (ret)
		return log_msg_ret("dim", ret);

	*vid_privp = vid_priv;
	*scnp = scn;

	return scene_id;
}

int cedit_run(struct expo *exp)
{
	struct cli_ch_state s_cch, *cch = &s_cch;
	struct video_priv *vid_priv;
	uint scene_id;
	struct scene *scn;
	bool done, save;
	int ret;

	cli_ch_init(cch);
	ret = cedit_prepare(exp, &vid_priv, &scn);
	if (ret < 0)
		return log_msg_ret("prep", ret);
	scene_id = ret;

	done = false;
	save = false;
	do {
		struct expo_action act;
		int ichar, key;

		ret = expo_render(exp);
		if (ret)
			break;

		ichar = cli_ch_process(cch, 0);
		if (!ichar) {
			while (!ichar && !tstc()) {
				schedule();
				mdelay(2);
				ichar = cli_ch_process(cch, -ETIMEDOUT);
			}
			if (!ichar) {
				ichar = getchar();
				ichar = cli_ch_process(cch, ichar);
			}
		}

		key = 0;
		if (ichar) {
			key = bootmenu_conv_key(ichar);
			if (key == BKEY_NONE || key >= BKEY_FIRST_EXTRA)
				key = ichar;
		}
		if (!key)
			continue;

		ret = expo_send_key(exp, key);
		if (ret)
			break;

		ret = expo_action_get(exp, &act);
		if (!ret) {
			switch (act.type) {
			case EXPOACT_POINT_OBJ:
				scene_set_highlight_id(scn, act.select.id);
				cedit_arange(exp, vid_priv, scene_id);
				break;
			case EXPOACT_OPEN:
				scene_set_open(scn, act.select.id, true);
				cedit_arange(exp, vid_priv, scene_id);
				switch (scn->highlight_id) {
				case EXPOID_SAVE:
					done = true;
					save = true;
					break;
				case EXPOID_DISCARD:
					done = true;
					break;
				}
				break;
			case EXPOACT_CLOSE:
				scene_set_open(scn, act.select.id, false);
				cedit_arange(exp, vid_priv, scene_id);
				break;
			case EXPOACT_SELECT:
				scene_set_open(scn, scn->highlight_id, false);
				cedit_arange(exp, vid_priv, scene_id);
				break;
			case EXPOACT_QUIT:
				log_debug("quitting\n");
				done = true;
				break;
			default:
				break;
			}
		}
	} while (!done);

	if (ret)
		return log_msg_ret("end", ret);
	if (!save)
		return -EACCES;

	return 0;
}

static int check_space(int ret, struct abuf *buf)
{
	if (ret == -FDT_ERR_NOSPACE) {
		if (!abuf_realloc_inc(buf, CEDIT_SIZE_INC))
			return log_msg_ret("spc", -ENOMEM);
		ret = fdt_resize(abuf_data(buf), abuf_data(buf),
				 abuf_size(buf));
		if (ret)
			return log_msg_ret("res", -EFAULT);
	}

	return 0;
}

/**
 * get_cur_menuitem_text() - Get the text of the currently selected item
 *
 * Looks up the object for the current item, finds text object for it and looks
 * up the string for that text
 *
 * @menu: Menu to look at
 * @strp: Returns a pointer to the next
 * Return: 0 if OK, -ENOENT if something was not found
 */
static int get_cur_menuitem_text(const struct scene_obj_menu *menu,
				 const char **strp)
{
	struct scene *scn = menu->obj.scene;
	const struct scene_menitem *mi;
	const struct scene_obj_txt *txt;
	const char *str;

	mi = scene_menuitem_find(menu, menu->cur_item_id);
	if (!mi)
		return log_msg_ret("mi", -ENOENT);

	txt = scene_obj_find(scn, mi->label_id, SCENEOBJT_TEXT);
	if (!txt)
		return log_msg_ret("txt", -ENOENT);

	str = expo_get_str(scn->expo, txt->str_id);
	if (!str)
		return log_msg_ret("str", -ENOENT);
	*strp = str;

	return 0;
}

/**
 * get_cur_menuitem_val() - Get the value of a menu's current item
 *
 * Obtains the value of the current item in the menu. If no value, then
 * enumerates the items of a menu (0, 1, 2) and returns the sequence number of
 * the currently selected item. If the first item is selected, this returns 0;
 * if the second, 1; etc.
 *
 * @menu: Menu to check
 * @valp: Returns current-item value / sequence number
 * Return: 0 on success, else -ve error value
 */
static int get_cur_menuitem_val(const struct scene_obj_menu *menu, int *valp)
{
	const struct scene_menitem *mi;
	int seq;

	seq = 0;
	list_for_each_entry(mi, &menu->item_head, sibling) {
		if (mi->id == menu->cur_item_id) {
			*valp = mi->value == INT_MAX ? seq : mi->value;
			return 0;
		}
		seq++;
	}

	return log_msg_ret("nf", -ENOENT);
}

/**
 * write_dt_string() - Write a string to the devicetree, expanding if needed
 *
 * If this fails, it tries again after expanding the devicetree a little
 *
 * @buf: Buffer containing the devicetree
 * @name: Property name to use
 * @str: String value
 * Return: 0 if OK, -EFAULT if something went horribly wrong
 */
static int write_dt_string(struct abuf *buf, const char *name, const char *str)
{
	int ret, i;

	ret = -EAGAIN;
	for (i = 0; ret && i < 2; i++) {
		ret = fdt_property_string(abuf_data(buf), name, str);
		if (!i) {
			ret = check_space(ret, buf);
			if (ret)
				return log_msg_ret("rs2", -ENOMEM);
		}
	}

	/* this should not happen */
	if (ret)
		return log_msg_ret("str", -EFAULT);

	return 0;
}

/**
 * write_dt_u32() - Write an int to the devicetree, expanding if needed
 *
 * If this fails, it tries again after expanding the devicetree a little
 *
 * @buf: Buffer containing the devicetree
 * @name: Property name to use
 * @lva: Integer value
 * Return: 0 if OK, -EFAULT if something went horribly wrong
 */
static int write_dt_u32(struct abuf *buf, const char *name, uint val)
{
	int ret, i;

	/* write the text of the current item */
	ret = -EAGAIN;
	for (i = 0; ret && i < 2; i++) {
		ret = fdt_property_u32(abuf_data(buf), name, val);
		if (!i) {
			ret = check_space(ret, buf);
			if (ret)
				return log_msg_ret("rs2", -ENOMEM);
		}
	}

	/* this should not happen */
	if (ret)
		return log_msg_ret("str", -EFAULT);

	return 0;
}

static int h_write_settings(struct scene_obj *obj, void *vpriv)
{
	struct cedit_iter_priv *priv = vpriv;
	struct abuf *buf = priv->buf;
	int ret;

	switch (obj->type) {
	case SCENEOBJT_NONE:
	case SCENEOBJT_IMAGE:
	case SCENEOBJT_TEXT:
		break;
	case SCENEOBJT_TEXTLINE: {
		const struct scene_obj_textline *tline;

		tline = (struct scene_obj_textline *)obj;
		ret = write_dt_string(buf, obj->name, abuf_data(&tline->buf));
		if (ret)
			return log_msg_ret("wr2", ret);
		break;
	}
	case SCENEOBJT_MENU: {
		const struct scene_obj_menu *menu;
		const char *str;
		char name[80];
		int val;

		/* write the ID of the current item */
		menu = (struct scene_obj_menu *)obj;
		ret = write_dt_u32(buf, obj->name, menu->cur_item_id);
		if (ret)
			return log_msg_ret("wrt", ret);

		snprintf(name, sizeof(name), "%s-value", obj->name);
		ret = get_cur_menuitem_val(menu, &val);
		if (ret < 0)
			return log_msg_ret("cur", ret);
		ret = write_dt_u32(buf, name, val);
		if (ret)
			return log_msg_ret("wr2", ret);

		ret = get_cur_menuitem_text(menu, &str);
		if (ret)
			return log_msg_ret("mis", ret);

		/* write the text of the current item */
		snprintf(name, sizeof(name), "%s-str", obj->name);
		ret = write_dt_string(buf, name, str);
		if (ret)
			return log_msg_ret("wr2", ret);

		break;
	}
	}

	return 0;
}

int cedit_write_settings(struct expo *exp, struct abuf *buf)
{
	struct cedit_iter_priv priv;
	void *fdt;
	int ret;

	abuf_init(buf);
	if (!abuf_realloc(buf, CEDIT_SIZE_INC))
		return log_msg_ret("buf", -ENOMEM);

	fdt = abuf_data(buf);
	ret = fdt_create(fdt, abuf_size(buf));
	if (!ret)
		ret = fdt_finish_reservemap(fdt);
	if (!ret)
		ret = fdt_begin_node(fdt, "");
	if (!ret)
		ret = fdt_begin_node(fdt, CEDIT_NODE_NAME);
	if (ret) {
		log_debug("Failed to start FDT (err=%d)\n", ret);
		return log_msg_ret("sta", -EINVAL);
	}

	/* write out the items */
	priv.buf = buf;
	ret = expo_iter_scene_objs(exp, h_write_settings, &priv);
	if (ret) {
		log_debug("Failed to write settings (err=%d)\n", ret);
		return log_msg_ret("set", ret);
	}

	ret = fdt_end_node(fdt);
	if (!ret)
		ret = fdt_end_node(fdt);
	if (!ret)
		ret = fdt_finish(fdt);
	if (ret) {
		log_debug("Failed to finish FDT (err=%d)\n", ret);
		return log_msg_ret("fin", -EINVAL);
	}

	return 0;
}

static int h_read_settings(struct scene_obj *obj, void *vpriv)
{
	struct cedit_iter_priv *priv = vpriv;
	ofnode node = priv->node;

	switch (obj->type) {
	case SCENEOBJT_NONE:
	case SCENEOBJT_IMAGE:
	case SCENEOBJT_TEXT:
		break;
	case SCENEOBJT_TEXTLINE: {
		const struct scene_obj_textline *tline;
		const char *val;
		int len;

		tline = (struct scene_obj_textline *)obj;

		val = ofnode_read_prop(node, obj->name, &len);
		if (len >= tline->max_chars)
			return log_msg_ret("str", -ENOSPC);
		strcpy(abuf_data(&tline->buf), val);
		break;
	}
	case SCENEOBJT_MENU: {
		struct scene_obj_menu *menu;
		uint val;

		if (ofnode_read_u32(node, obj->name, &val))
			return log_msg_ret("rd", -ENOENT);
		menu = (struct scene_obj_menu *)obj;
		menu->cur_item_id = val;

		break;
	}
	}

	return 0;
}

int cedit_read_settings(struct expo *exp, oftree tree)
{
	struct cedit_iter_priv priv;
	ofnode root, node;
	int ret;

	root = oftree_root(tree);
	if (!ofnode_valid(root))
		return log_msg_ret("roo", -ENOENT);
	node = ofnode_find_subnode(root, CEDIT_NODE_NAME);
	if (!ofnode_valid(node))
		return log_msg_ret("pat", -ENOENT);

	/* read in the items */
	priv.node = node;
	ret = expo_iter_scene_objs(exp, h_read_settings, &priv);
	if (ret) {
		log_debug("Failed to read settings (err=%d)\n", ret);
		return log_msg_ret("set", ret);
	}

	return 0;
}

static int h_write_settings_env(struct scene_obj *obj, void *vpriv)
{
	const struct scene_obj_menu *menu;
	struct cedit_iter_priv *priv = vpriv;
	char name[80], var[60];
	const char *str;
	int val, ret;

	if (obj->id < EXPOID_BASE_ID)
		return 0;

	snprintf(var, sizeof(var), "c.%s", obj->name);

	switch (obj->type) {
	case SCENEOBJT_NONE:
	case SCENEOBJT_IMAGE:
	case SCENEOBJT_TEXT:
		break;
	case SCENEOBJT_MENU:
		menu = (struct scene_obj_menu *)obj;
		val = menu->cur_item_id;

		if (priv->verbose)
			printf("%s=%d\n", var, val);

		ret = env_set_ulong(var, val);
		if (ret)
			return log_msg_ret("set", ret);

		ret = get_cur_menuitem_text(menu, &str);
		if (ret)
			return log_msg_ret("mis", ret);

		snprintf(name, sizeof(name), "c.%s-str", obj->name);
		if (priv->verbose)
			printf("%s=%s\n", name, str);

		ret = env_set(name, str);
		if (ret)
			return log_msg_ret("st2", ret);

		ret = get_cur_menuitem_val(menu, &val);
		if (ret < 0)
			return log_msg_ret("cur", ret);
		snprintf(name, sizeof(name), "c.%s-value", obj->name);
		if (priv->verbose)
			printf("%s=%d\n", name, val);

		break;
	case SCENEOBJT_TEXTLINE: {
		const struct scene_obj_textline *tline;

		tline = (struct scene_obj_textline *)obj;
		str = abuf_data(&tline->buf);
		ret = env_set(var, str);
		if (ret)
			return log_msg_ret("set", ret);

		if (priv->verbose)
			printf("%s=%s\n", var, str);

		break;
	}
	}

	return 0;
}

int cedit_write_settings_env(struct expo *exp, bool verbose)
{
	struct cedit_iter_priv priv;
	int ret;

	/* write out the items */
	priv.verbose = verbose;
	ret = expo_iter_scene_objs(exp, h_write_settings_env, &priv);
	if (ret) {
		log_debug("Failed to write settings to env (err=%d)\n", ret);
		return log_msg_ret("set", ret);
	}

	return 0;
}

static int h_read_settings_env(struct scene_obj *obj, void *vpriv)
{
	struct cedit_iter_priv *priv = vpriv;
	struct scene_obj_menu *menu;
	char var[60];
	int val;

	if (obj->id < EXPOID_BASE_ID)
		return 0;

	snprintf(var, sizeof(var), "c.%s", obj->name);

	switch (obj->type) {
	case SCENEOBJT_NONE:
	case SCENEOBJT_IMAGE:
	case SCENEOBJT_TEXT:
		break;
	case SCENEOBJT_MENU:
		menu = (struct scene_obj_menu *)obj;
		val = env_get_ulong(var, 10, 0);
		if (priv->verbose)
			printf("%s=%d\n", var, val);
		if (!val)
			return log_msg_ret("get", -ENOENT);

		/*
		 * note that no validation is done here, to make sure the ID is
		 * valid and actually points to a menu item
		 */
		menu->cur_item_id = val;
		break;
	case SCENEOBJT_TEXTLINE: {
		const struct scene_obj_textline *tline;
		const char *value;

		tline = (struct scene_obj_textline *)obj;
		value = env_get(var);
		if (value && strlen(value) >= tline->max_chars)
			return log_msg_ret("str", -ENOSPC);
		if (!value)
			value = "";
		if (priv->verbose)
			printf("%s=%s\n", var, value);
		strcpy(abuf_data(&tline->buf), value);
		break;
	}
	}

	return 0;
}

int cedit_read_settings_env(struct expo *exp, bool verbose)
{
	struct cedit_iter_priv priv;
	int ret;

	/* write out the items */
	priv.verbose = verbose;
	ret = expo_iter_scene_objs(exp, h_read_settings_env, &priv);
	if (ret) {
		log_debug("Failed to read settings from env (err=%d)\n", ret);
		return log_msg_ret("set", ret);
	}

	return 0;
}

static int h_write_settings_cmos(struct scene_obj *obj, void *vpriv)
{
	const struct scene_obj_menu *menu;
	struct cedit_iter_priv *priv = vpriv;
	int val, ret;
	uint i;

	if (obj->type != SCENEOBJT_MENU || obj->id < EXPOID_BASE_ID)
		return 0;

	menu = (struct scene_obj_menu *)obj;
	val = menu->cur_item_id;

	ret = get_cur_menuitem_val(menu, &val);
	if (ret < 0)
		return log_msg_ret("cur", ret);
	log_debug("%s: val=%d\n", menu->obj.name, val);

	/* figure out where to place this item */
	if (!obj->bit_length)
		return log_msg_ret("len", -EINVAL);
	if (obj->start_bit + obj->bit_length > CMOS_MAX_BITS)
		return log_msg_ret("bit", -E2BIG);

	for (i = 0; i < obj->bit_length; i++, val >>= 1) {
		uint bitnum = obj->start_bit + i;

		priv->mask[CMOS_BYTE(bitnum)] |= 1 << CMOS_BIT(bitnum);
		if (val & 1)
			priv->value[CMOS_BYTE(bitnum)] |= BIT(CMOS_BIT(bitnum));
		log_debug("bit %x %x %x\n", bitnum,
			  priv->mask[CMOS_BYTE(bitnum)],
			  priv->value[CMOS_BYTE(bitnum)]);
	}

	return 0;
}

int cedit_write_settings_cmos(struct expo *exp, struct udevice *dev,
			      bool verbose)
{
	struct cedit_iter_priv priv;
	int ret, i, count, first, last;

	/* write out the items */
	priv.mask = calloc(1, CMOS_MAX_BYTES);
	if (!priv.mask)
		return log_msg_ret("mas", -ENOMEM);
	priv.value = calloc(1, CMOS_MAX_BYTES);
	if (!priv.value) {
		free(priv.mask);
		return log_msg_ret("val", -ENOMEM);
	}

	ret = expo_iter_scene_objs(exp, h_write_settings_cmos, &priv);
	if (ret) {
		log_debug("Failed to write CMOS (err=%d)\n", ret);
		ret = log_msg_ret("set", ret);
		goto done;
	}

	/* write the data to the RTC */
	log_debug("Writing CMOS\n");
	first = CMOS_MAX_BYTES;
	last = -1;
	for (i = 0, count = 0; i < CMOS_MAX_BYTES; i++) {
		if (priv.mask[i]) {
			log_debug("Write byte %x: %x\n", i, priv.value[i]);
			ret = rtc_write8(dev, i, priv.value[i]);
			if (ret) {
				ret = log_msg_ret("wri", ret);
				goto done;
			}
			count++;
			first = min(first, i);
			last = max(last, i);
		}
	}
	if (verbose) {
		printf("Write %d bytes from offset %x to %x\n", count, first,
		       last);
	}

done:
	free(priv.mask);
	free(priv.value);
	return ret;
}

static int h_read_settings_cmos(struct scene_obj *obj, void *vpriv)
{
	struct cedit_iter_priv *priv = vpriv;
	const struct scene_menitem *mi;
	struct scene_obj_menu *menu;
	int val, ret;
	uint i;

	if (obj->type != SCENEOBJT_MENU || obj->id < EXPOID_BASE_ID)
		return 0;

	menu = (struct scene_obj_menu *)obj;

	/* figure out where to place this item */
	if (!obj->bit_length)
		return log_msg_ret("len", -EINVAL);
	if (obj->start_bit + obj->bit_length > CMOS_MAX_BITS)
		return log_msg_ret("bit", -E2BIG);

	val = 0;
	for (i = 0; i < obj->bit_length; i++) {
		uint bitnum = obj->start_bit + i;
		uint offset = CMOS_BYTE(bitnum);

		/* read the byte if not already read */
		if (!priv->mask[offset]) {
			ret = rtc_read8(priv->dev, offset);
			if (ret < 0)
				return  log_msg_ret("rea", ret);
			priv->value[offset] = ret;

			/* mark it as read */
			priv->mask[offset] = 0xff;
		}

		if (priv->value[offset] & BIT(CMOS_BIT(bitnum)))
			val |= BIT(i);
		log_debug("bit %x %x\n", bitnum, val);
	}

	/* update the current item */
	log_debug("look for menuitem value %d in menu %d\n", val, menu->obj.id);
	mi = scene_menuitem_find_val(menu, val);
	if (!mi)
		return log_msg_ret("seq", -ENOENT);

	menu->cur_item_id = mi->id;
	log_debug("Update menu %d cur_item_id %d\n", menu->obj.id, mi->id);

	return 0;
}

int cedit_read_settings_cmos(struct expo *exp, struct udevice *dev,
			     bool verbose)
{
	struct cedit_iter_priv priv;
	int ret, i, count, first, last;

	/* read in the items */
	priv.mask = calloc(1, CMOS_MAX_BYTES);
	if (!priv.mask)
		return log_msg_ret("mas", -ENOMEM);
	priv.value = calloc(1, CMOS_MAX_BYTES);
	if (!priv.value) {
		free(priv.mask);
		return log_msg_ret("val", -ENOMEM);
	}
	priv.dev = dev;

	ret = expo_iter_scene_objs(exp, h_read_settings_cmos, &priv);
	if (ret) {
		log_debug("Failed to read CMOS (err=%d)\n", ret);
		ret = log_msg_ret("set", ret);
		goto done;
	}

	/* indicate what bytes were read from the RTC */
	first = CMOS_MAX_BYTES;
	last = -1;
	for (i = 0, count = 0; i < CMOS_MAX_BYTES; i++) {
		if (priv.mask[i]) {
			log_debug("Read byte %x: %x\n", i, priv.value[i]);
			count++;
			first = min(first, i);
			last = max(last, i);
		}
	}
	if (verbose) {
		printf("Read %d bytes from offset %x to %x\n", count, first,
		       last);
	}

done:
	free(priv.mask);
	free(priv.value);
	return ret;
}
