/**
 * A generic implementation of bhnd_nvram_data_getvar().
 * 
 * This implementation will call bhnd_nvram_data_getvar_ptr() to fetch
 * a pointer to the variable data and perform data coercion on behalf
 * of the caller.
 *
 * If a variable definition for the requested variable is available via
 * bhnd_nvram_find_vardefn(), the definition will be used to provide a
 * formatting instance to bhnd_nvram_val_init().
 */
int
bhnd_nvram_data_generic_rp_getvar(struct bhnd_nvram_data *nv, void *cookiep,
    void *outp, size_t *olen, bhnd_nvram_type otype)
{
	bhnd_nvram_val			 val;
	const bhnd_nvram_val_fmt	*fmt;
	const void			*vptr;
	bhnd_nvram_type			 vtype;
	size_t				 vlen;
	int				 error;

	BHND_NV_ASSERT(bhnd_nvram_data_caps(nv) & BHND_NVRAM_DATA_CAP_READ_PTR,
	    ("instance does not advertise READ_PTR support"));

	/* Fetch variable data and value format*/
	vptr = bhnd_nvram_data_getvar_ptr_info(nv, cookiep, &vlen, &vtype,
	    &fmt);
	if (vptr == NULL)
		return (EINVAL);

	/* Attempt value coercion */
	error = bhnd_nvram_val_init(&val, fmt, vptr, vlen, vtype,
	    BHND_NVRAM_VAL_BORROW_DATA);
	if (error)
		return (error);

	error = bhnd_nvram_val_encode(&val, outp, olen, otype);

	/* Clean up */
	bhnd_nvram_val_release(&val);
	return (error);
}
/**
 * Coerce value @p inp of type @p itype to @p otype, writing the
 * result to @p outp.
 *
 * @param		inp	The value to be coerced.
 * @param		ilen	The size of @p inp, in bytes.
 * @param		itype	The base data type of @p inp.
 * @param[out]		outp	On success, the value will be written to this 
 *				buffer. This argment may be NULL if the value
 *				is not desired.
 * @param[in,out]	olen	The capacity of @p outp. On success, will be set
 *				to the actual size of the requested value.
 * @param		otype	The data type to be written to @p outp.
 *
 * @retval 0		success
 * @retval ENOMEM	If @p outp is non-NULL and a buffer of @p olen is too
 *			small to hold the requested value.
 * @retval EFTYPE	If the variable data cannot be coerced to @p otype.
 * @retval ERANGE	If value coercion would overflow @p otype.
 */
int
bhnd_nvram_value_coerce(const void *inp, size_t ilen, bhnd_nvram_type itype,
    void *outp, size_t *olen, bhnd_nvram_type otype)
{
	bhnd_nvram_val_t	val;
	int			error;

	/* Wrap input buffer in a value instance */
	error = bhnd_nvram_val_init(&val, NULL, inp, ilen,
	    itype, BHND_NVRAM_VAL_BORROW_DATA|BHND_NVRAM_VAL_FIXED);
	if (error)
		return (error);

	/* Try to encode as requested type */
	error = bhnd_nvram_val_encode(&val, outp, olen, otype);

	/* Clean up and return error */
	bhnd_nvram_val_release(&val);
	return (error);
}