2 * Copyright (c) 2015-2016 Landon Fuller <landonf@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13 * redistribution must be conditioned upon including a substantially
14 * similar Disclaimer requirement for further binary redistribution.
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
22 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
27 * THE POSSIBILITY OF SUCH DAMAGES.
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
33 #include <sys/param.h>
38 #include <sys/systm.h>
49 #include "bhnd_nvram_plistvar.h"
50 #include "bhnd_nvram_private.h"
52 static bhnd_nvram_plist_entry *bhnd_nvram_plist_get_entry(
53 bhnd_nvram_plist *plist, const char *name);
56 * Allocate and initialize a new, empty property list.
58 * The caller is responsible for releasing the returned property value
59 * via bhnd_nvram_plist_release().
61 * @retval non-NULL success
62 * @retval NULL if allocation fails.
65 bhnd_nvram_plist_new(void)
67 bhnd_nvram_plist *plist;
69 plist = bhnd_nv_calloc(1, sizeof(*plist));
73 /* Implicit caller-owned reference */
76 /* Initialize entry list */
77 plist->num_entries = 0;
78 TAILQ_INIT(&plist->entries);
80 /* Initialize entry hash table */
81 for (size_t i = 0; i < nitems(plist->names); i++)
82 LIST_INIT(&plist->names[i]);
88 * Retain a reference and return @p plist to the caller.
90 * The caller is responsible for releasing their reference ownership via
91 * bhnd_nvram_plist_release().
93 * @param plist The property list to be retained.
96 bhnd_nvram_plist_retain(bhnd_nvram_plist *plist)
98 BHND_NV_ASSERT(plist->refs >= 1, ("plist over-released"));
100 refcount_acquire(&plist->refs);
105 * Release a reference to @p plist.
107 * If this is the last reference, all associated resources will be freed.
109 * @param plist The property list to be released.
112 bhnd_nvram_plist_release(bhnd_nvram_plist *plist)
114 bhnd_nvram_plist_entry *ple, *ple_next;
116 BHND_NV_ASSERT(plist->refs >= 1, ("plist over-released"));
119 if (!refcount_release(&plist->refs))
122 /* Free all property entries */
123 TAILQ_FOREACH_SAFE(ple, &plist->entries, pl_link, ple_next) {
124 bhnd_nvram_prop_release(ple->prop);
128 /* Free plist instance */
133 * Return a shallow copy of @p plist.
135 * The caller is responsible for releasing the returned property value
136 * via bhnd_nvram_plist_release().
138 * @retval non-NULL success
139 * @retval NULL if allocation fails.
142 bhnd_nvram_plist_copy(bhnd_nvram_plist *plist)
144 bhnd_nvram_plist *copy;
145 bhnd_nvram_prop *prop;
148 /* Allocate new, empty plist */
149 if ((copy = bhnd_nvram_plist_new()) == NULL)
152 /* Append all properties */
154 while ((prop = bhnd_nvram_plist_next(plist, prop)) != NULL) {
155 error = bhnd_nvram_plist_append(copy, prop);
157 if (error != ENOMEM) {
158 BHND_NV_LOG("error copying property: %d\n",
162 bhnd_nvram_plist_release(copy);
167 /* Return ownership of the copy to our caller */
172 * Return the number of properties in @p plist.
175 bhnd_nvram_plist_count(bhnd_nvram_plist *plist)
177 return (plist->num_entries);
181 * Return true if @p plist contains a property name @p name, false otherwise.
183 * @param plist The property list to be queried.
184 * @param name The property name to be queried.
187 bhnd_nvram_plist_contains(bhnd_nvram_plist *plist, const char *name)
189 if (bhnd_nvram_plist_get_entry(plist, name) != NULL)
196 * Replace the current property value for a property matching the name
197 * of @p prop, maintaining the property's current order in @p plist.
199 * If a matching property is not found in @p plist, @p prop will instead be
202 * @param plist The property list to be modified.
203 * @param prop The replacement property.
206 * @retval ENOMEM if allocation fails.
207 * @retval non-zero if modifying @p plist otherwise fails, a regular unix
208 * error code will be returned.
211 bhnd_nvram_plist_replace(bhnd_nvram_plist *plist, bhnd_nvram_prop *prop)
213 bhnd_nvram_plist_entry *entry;
215 /* Fetch current entry */
216 entry = bhnd_nvram_plist_get_entry(plist, prop->name);
218 /* Not found -- append property instead */
219 return (bhnd_nvram_plist_append(plist, prop));
222 /* Replace the current entry's property reference */
223 bhnd_nvram_prop_release(entry->prop);
224 entry->prop = bhnd_nvram_prop_retain(prop);
230 * Replace the current property value for a property matching @p name,
231 * maintaining the property's order in @p plist.
233 * If @p name is not found in @p plist, a new property will be appended.
235 * @param plist The property list to be modified.
236 * @param name The name of the property to be replaced.
237 * @param val The replacement value for @p name.
240 * @retval ENOMEM if allocation fails.
241 * @retval non-zero if modifying @p plist otherwise fails, a regular unix
242 * error code will be returned.
245 bhnd_nvram_plist_replace_val(bhnd_nvram_plist *plist, const char *name,
248 bhnd_nvram_prop *prop;
251 /* Construct a new property instance for the name and value */
252 if ((prop = bhnd_nvram_prop_new(name, val)) == NULL)
255 /* Attempt replace */
256 error = bhnd_nvram_plist_replace(plist, prop);
257 bhnd_nvram_prop_release(prop);
263 * Replace the current property value for a property matching @p name, copying
264 * the new property value from the given @p inp buffer of @p itype and @p ilen.
266 * The current property order of @p name in @p plist will be maintained.
268 * If @p name is not found in @p plist, a new property will be appended.
270 * @param plist The property list to be modified.
271 * @param name The name of the property to be replaced.
272 * @param inp Input buffer.
273 * @param ilen Input buffer length.
274 * @param itype Input buffer type.
277 * @retval ENOMEM if allocation fails.
278 * @retval non-zero if modifying @p plist otherwise fails, a regular unix
279 * error code will be returned.
282 bhnd_nvram_plist_replace_bytes(bhnd_nvram_plist *plist, const char *name,
283 const void *inp, size_t ilen, bhnd_nvram_type itype)
285 bhnd_nvram_prop *prop;
288 if ((prop = bhnd_nvram_prop_bytes_new(name, inp, ilen, itype)) == NULL)
291 error = bhnd_nvram_plist_replace(plist, prop);
292 bhnd_nvram_prop_release(prop);
298 * Replace the current property value for a property matching @p name, copying
299 * the new property value from @p val.
301 * The current property order of @p name in @p plist will be maintained.
303 * If @p name is not found in @p plist, a new property will be appended.
305 * @param plist The property list to be modified.
306 * @param name The name of the property to be replaced.
307 * @param val The property's replacement string value.
310 * @retval ENOMEM if allocation fails.
311 * @retval non-zero if modifying @p plist otherwise fails, a regular unix
312 * error code will be returned.
315 bhnd_nvram_plist_replace_string(bhnd_nvram_plist *plist, const char *name,
318 return (bhnd_nvram_plist_replace_bytes(plist, name, val, strlen(val)+1,
319 BHND_NVRAM_TYPE_STRING));
323 * Remove the property entry for the property @p name, if any.
325 * @param plist The property list to be modified.
326 * @param name The name of the property to be removed.
329 bhnd_nvram_plist_remove(bhnd_nvram_plist *plist, const char *name)
331 bhnd_nvram_plist_entry *entry;
334 entry = bhnd_nvram_plist_get_entry(plist, name);
338 /* Remove from entry list and hash table */
339 TAILQ_REMOVE(&plist->entries, entry, pl_link);
340 LIST_REMOVE(entry, pl_hash_link);
342 /* Free plist entry */
343 bhnd_nvram_prop_release(entry->prop);
346 /* Decrement entry count */
347 BHND_NV_ASSERT(plist->num_entries > 0, ("entry count over-release"));
348 plist->num_entries--;
352 * Fetch the property list entry for @p name, if any.
354 * @param plist The property list to be queried.
355 * @param name The property name to be queried.
357 * @retval non-NULL if @p name is found.
358 * @retval NULL if @p name is not found.
360 static bhnd_nvram_plist_entry *
361 bhnd_nvram_plist_get_entry(bhnd_nvram_plist *plist, const char *name)
363 bhnd_nvram_plist_entry_list *hash_list;
364 bhnd_nvram_plist_entry *entry;
367 h = hash32_str(name, HASHINIT);
368 hash_list = &plist->names[h % nitems(plist->names)];
370 LIST_FOREACH(entry, hash_list, pl_hash_link) {
371 if (strcmp(entry->prop->name, name) == 0)
380 * Append all properties from @p tail to @p plist.
382 * @param plist The property list to be modified.
383 * @param tail The property list to append.
386 * @retval ENOMEM if allocation fails.
387 * @retval EEXIST an existing property from @p tail was found in @p plist.
390 bhnd_nvram_plist_append_list(bhnd_nvram_plist *plist, bhnd_nvram_plist *tail)
396 while ((p = bhnd_nvram_plist_next(tail, p)) != NULL) {
397 if ((error = bhnd_nvram_plist_append(plist, p)))
405 * Append @p prop to @p plist.
407 * @param plist The property list to be modified.
408 * @param prop The property to append.
411 * @retval ENOMEM if allocation fails.
412 * @retval EEXIST an existing property with @p name was found in @p plist.
415 bhnd_nvram_plist_append(bhnd_nvram_plist *plist, bhnd_nvram_prop *prop)
417 bhnd_nvram_plist_entry_list *hash_list;
418 bhnd_nvram_plist_entry *entry;
421 if (bhnd_nvram_plist_contains(plist, prop->name))
424 /* Have we hit the maximum representable entry count? */
425 if (plist->num_entries == SIZE_MAX)
428 /* Allocate new entry */
429 entry = bhnd_nv_malloc(sizeof(*entry));
433 entry->prop = bhnd_nvram_prop_retain(prop);
435 /* Append to entry list */
436 TAILQ_INSERT_TAIL(&plist->entries, entry, pl_link);
438 /* Add to name-based hash table */
439 h = hash32_str(prop->name, HASHINIT);
440 hash_list = &plist->names[h % nitems(plist->names)];
441 LIST_INSERT_HEAD(hash_list, entry, pl_hash_link);
443 /* Increment entry count */
444 plist->num_entries++;
450 * Append a new property to @p plist with @p name and @p val.
452 * @param plist The property list to be modified.
453 * @param name The name of the property to be appended.
454 * @param val The value of the property to be appended.
457 * @retval ENOMEM if allocation fails.
458 * @retval EEXIST an existing property with @p name was found in @p plist.
461 bhnd_nvram_plist_append_val(bhnd_nvram_plist *plist, const char *name,
464 bhnd_nvram_prop *prop;
467 if ((prop = bhnd_nvram_prop_new(name, val)) == NULL)
470 error = bhnd_nvram_plist_append(plist, prop);
471 bhnd_nvram_prop_release(prop);
477 * Append a new property to @p plist, copying the property value from the
478 * given @p inp buffer of @p itype and @p ilen.
480 * @param plist The property list to be modified.
481 * @param name The name of the property to be appended.
482 * @param inp Input buffer.
483 * @param ilen Input buffer length.
484 * @param itype Input buffer type.
487 * @retval ENOMEM if allocation fails.
488 * @retval EEXIST an existing property with @p name was found in @p plist.
491 bhnd_nvram_plist_append_bytes(bhnd_nvram_plist *plist, const char *name,
492 const void *inp, size_t ilen, bhnd_nvram_type itype)
494 bhnd_nvram_prop *prop;
497 if ((prop = bhnd_nvram_prop_bytes_new(name, inp, ilen, itype)) == NULL)
500 error = bhnd_nvram_plist_append(plist, prop);
501 bhnd_nvram_prop_release(prop);
507 * Append a new string property to @p plist, copying the property value from
510 * @param plist The property list to be modified.
511 * @param name The name of the property to be appended.
512 * @param val The new property's string value.
515 * @retval ENOMEM if allocation fails.
516 * @retval EEXIST an existing property with @p name was found in @p plist.
519 bhnd_nvram_plist_append_string(bhnd_nvram_plist *plist, const char *name,
522 return (bhnd_nvram_plist_append_bytes(plist, name, val, strlen(val)+1,
523 BHND_NVRAM_TYPE_STRING));
527 * Iterate over all properties in @p plist.
529 * @param plist The property list to be iterated.
530 * @param prop A property in @p plist, or NULL to return the first
531 * property in @p plist.
533 * @retval non-NULL A borrowed reference to the next property in @p plist.
534 * @retval NULL If the end of the property list is reached or @p prop
535 * is not found in @p plist.
538 bhnd_nvram_plist_next(bhnd_nvram_plist *plist, bhnd_nvram_prop *prop)
540 bhnd_nvram_plist_entry *entry;
543 if ((entry = TAILQ_FIRST(&plist->entries)) == NULL)
546 return (entry->prop);
549 /* Look up previous property entry by name */
550 if ((entry = bhnd_nvram_plist_get_entry(plist, prop->name)) == NULL)
553 /* The property instance must be identical */
554 if (entry->prop != prop)
557 /* Fetch next entry */
558 if ((entry = TAILQ_NEXT(entry, pl_link)) == NULL)
561 return (entry->prop);
565 * Return a borrowed reference to a named property, or NULL if @p name is
566 * not found in @p plist.
568 * @param plist The property list to be queried.
569 * @param name The name of the property to be returned.
571 * @retval non-NULL if @p name is found.
572 * @retval NULL if @p name is not found.
575 bhnd_nvram_plist_get_prop(bhnd_nvram_plist *plist, const char *name)
577 bhnd_nvram_plist_entry *entry;
579 if ((entry = bhnd_nvram_plist_get_entry(plist, name)) == NULL)
582 return (entry->prop);
586 * Return a borrowed reference to the named property's value, or NULL if
587 * @p name is not found in @p plist.
589 * @param plist The property list to be queried.
590 * @param name The name of the property to be returned.
592 * @retval non-NULL if @p name is found.
593 * @retval NULL if @p name is not found.
596 bhnd_nvram_plist_get_val(bhnd_nvram_plist *plist, const char *name)
598 bhnd_nvram_prop *prop;
600 if ((prop = bhnd_nvram_plist_get_prop(plist, name)) == NULL)
603 return (bhnd_nvram_prop_val(prop));
607 * Attempt to encode a named property's value as @p otype, writing the result
610 * @param plist The property list to be queried.
611 * @param name The name of the property value to be returned.
612 * @param[out] outp On success, the value will be written to this
613 * buffer. This argment may be NULL if the value is
615 * @param[in,out] olen The capacity of @p outp. On success, will be set
616 * to the actual size of the requested value.
617 * @param otype The data type to be written to @p outp.
620 * @retval ENOENT If @p name is not found in @p plist.
621 * @retval ENOMEM If the @p outp is non-NULL, and the provided @p olen
622 * is too small to hold the encoded value.
623 * @retval EFTYPE If value coercion from @p prop to @p otype is
625 * @retval ERANGE If value coercion would overflow (or underflow) the
626 * a @p otype representation.
629 bhnd_nvram_plist_get_encoded(bhnd_nvram_plist *plist, const char *name,
630 void *outp, size_t olen, bhnd_nvram_type otype)
632 bhnd_nvram_prop *prop;
634 if ((prop = bhnd_nvram_plist_get_prop(plist, name)) == NULL)
637 return (bhnd_nvram_prop_encode(prop, outp, &olen, otype));
641 * Return the character representation of a named property's value.
643 * @param plist The property list to be queried.
644 * @param name The name of the property value to be returned.
645 * @param[out] val On success, the character value of @p name.
648 * @retval ENOENT If @p name is not found in @p plist.
649 * @retval EFTYPE If coercion of the property's value to @p val.
650 * @retval ERANGE If coercion of the property's value would overflow
651 * (or underflow) @p val.
654 bhnd_nvram_plist_get_char(bhnd_nvram_plist *plist, const char *name,
657 return (bhnd_nvram_plist_get_encoded(plist, name, val, sizeof(*val),
658 BHND_NVRAM_TYPE_CHAR));
662 * Return the uint8 representation of a named property's value.
664 * @param plist The property list to be queried.
665 * @param name The name of the property value to be returned.
666 * @param[out] val On success, the uint8 value of @p name.
669 * @retval ENOENT If @p name is not found in @p plist.
670 * @retval EFTYPE If coercion of the property's value to @p val.
671 * @retval ERANGE If coercion of the property's value would overflow
672 * (or underflow) @p val.
675 bhnd_nvram_plist_get_uint8(bhnd_nvram_plist *plist, const char *name,
678 return (bhnd_nvram_plist_get_encoded(plist, name, val, sizeof(*val),
679 BHND_NVRAM_TYPE_UINT8));
683 * Return the uint16 representation of a named property's value.
685 * @param plist The property list to be queried.
686 * @param name The name of the property value to be returned.
687 * @param[out] val On success, the uint16 value of @p name.
690 * @retval ENOENT If @p name is not found in @p plist.
691 * @retval EFTYPE If coercion of the property's value to @p val.
692 * @retval ERANGE If coercion of the property's value would overflow
693 * (or underflow) @p val.
696 bhnd_nvram_plist_get_uint16(bhnd_nvram_plist *plist, const char *name,
699 return (bhnd_nvram_plist_get_encoded(plist, name, val, sizeof(*val),
700 BHND_NVRAM_TYPE_UINT16));
704 * Return the uint32 representation of a named property's value.
706 * @param plist The property list to be queried.
707 * @param name The name of the property value to be returned.
708 * @param[out] val On success, the uint32 value of @p name.
711 * @retval ENOENT If @p name is not found in @p plist.
712 * @retval EFTYPE If coercion of the property's value to @p val.
713 * @retval ERANGE If coercion of the property's value would overflow
714 * (or underflow) @p val.
717 bhnd_nvram_plist_get_uint32(bhnd_nvram_plist *plist, const char *name,
720 return (bhnd_nvram_plist_get_encoded(plist, name, val, sizeof(*val),
721 BHND_NVRAM_TYPE_UINT32));
725 * Return the uint64 representation of a named property's value.
727 * @param plist The property list to be queried.
728 * @param name The name of the property value to be returned.
729 * @param[out] val On success, the uint64 value of @p name.
732 * @retval ENOENT If @p name is not found in @p plist.
733 * @retval EFTYPE If coercion of the property's value to @p val.
734 * @retval ERANGE If coercion of the property's value would overflow
735 * (or underflow) @p val.
738 bhnd_nvram_plist_get_uint64(bhnd_nvram_plist *plist, const char *name,
741 return (bhnd_nvram_plist_get_encoded(plist, name, val, sizeof(*val),
742 BHND_NVRAM_TYPE_UINT64));
746 * Return the boolean representation of a named property's value.
748 * @param plist The property list to be queried.
749 * @param name The name of the property value to be returned.
750 * @param[out] val On success, the boolean value of @p name.
753 * @retval ENOENT If @p name is not found in @p plist.
754 * @retval EFTYPE If coercion of the property's value to @p val.
755 * @retval ERANGE If coercion of the property's value would overflow
756 * (or underflow) @p val.
759 bhnd_nvram_plist_get_bool(bhnd_nvram_plist *plist, const char *name,
762 return (bhnd_nvram_plist_get_encoded(plist, name, val, sizeof(*val),
763 BHND_NVRAM_TYPE_BOOL));
767 * Allocate and initialize a new property value.
769 * The caller is responsible for releasing the returned property value
770 * via bhnd_nvram_prop_release().
772 * @param name Property name.
773 * @param val Property value.
775 * @retval non-NULL success
776 * @retval NULL if allocation fails.
778 struct bhnd_nvram_prop *
779 bhnd_nvram_prop_new(const char *name, bhnd_nvram_val *val)
781 struct bhnd_nvram_prop *prop;
783 prop = bhnd_nv_calloc(1, sizeof(*prop));
787 /* Implicit caller-owned reference */
790 if ((prop->name = bhnd_nv_strdup(name)) == NULL)
793 if ((prop->val = bhnd_nvram_val_copy(val)) == NULL)
799 if (prop->name != NULL)
800 bhnd_nv_free(prop->name);
802 if (prop->val != NULL)
803 bhnd_nvram_val_release(prop->val);
810 * Allocate a new property value and attempt to initialize its value from
811 * the given @p inp buffer of @p itype and @p ilen.
813 * The caller is responsible for releasing the returned property value
814 * via bhnd_nvram_prop_release().
816 * @param name Property name.
817 * @param inp Input buffer.
818 * @param ilen Input buffer length.
819 * @param itype Input buffer type.
821 * @retval non-NULL success
822 * @retval NULL if allocation or initialization fails.
825 bhnd_nvram_prop_bytes_new(const char *name, const void *inp, size_t ilen,
826 bhnd_nvram_type itype)
828 bhnd_nvram_prop *prop;
832 /* Construct new value instance */
833 error = bhnd_nvram_val_new(&val, NULL, inp, ilen, itype,
834 BHND_NVRAM_VAL_DYNAMIC);
836 if (error != ENOMEM) {
837 BHND_NV_LOG("invalid input data; initialization "
838 "failed: %d\n", error);
844 /* Delegate to default implementation */
845 prop = bhnd_nvram_prop_new(name, val);
848 bhnd_nvram_val_release(val);
853 * Retain a reference and return @p prop to the caller.
855 * The caller is responsible for releasing their reference ownership via
856 * bhnd_nvram_prop_release().
858 * @param prop The property to be retained.
861 bhnd_nvram_prop_retain(bhnd_nvram_prop *prop)
863 BHND_NV_ASSERT(prop->refs >= 1, ("prop over-released"));
865 refcount_acquire(&prop->refs);
870 * Release a reference to @p prop.
872 * If this is the last reference, all associated resources will be freed.
874 * @param prop The property to be released.
877 bhnd_nvram_prop_release(bhnd_nvram_prop *prop)
879 BHND_NV_ASSERT(prop->refs >= 1, ("prop over-released"));
882 if (!refcount_release(&prop->refs))
885 /* Free property data */
886 bhnd_nvram_val_release(prop->val);
887 bhnd_nv_free(prop->name);
892 * Return a borrowed reference to the property's name.
894 * @param prop The property to query.
897 bhnd_nvram_prop_name(bhnd_nvram_prop *prop)
903 * Return a borrowed reference to the property's value.
905 * @param prop The property to query.
908 bhnd_nvram_prop_val(bhnd_nvram_prop *prop)
914 * Return the property's value type.
916 * @param prop The property to query.
919 bhnd_nvram_prop_type(bhnd_nvram_prop *prop)
921 return (bhnd_nvram_val_type(prop->val));
925 * Return true if @p prop has a NULL value type (BHND_NVRAM_TYPE_NULL), false
928 * @param prop The property to query.
931 bhnd_nvram_prop_is_null(bhnd_nvram_prop *prop)
933 return (bhnd_nvram_prop_type(prop) == BHND_NVRAM_TYPE_NULL);
937 * Return a borrowed reference to the property's internal value representation.
939 * @param prop The property to query.
940 * @param[out] olen The returned data's size, in bytes.
941 * @param[out] otype The returned data's type.
944 bhnd_nvram_prop_bytes(bhnd_nvram_prop *prop, size_t *olen,
945 bhnd_nvram_type *otype)
949 bytes = bhnd_nvram_val_bytes(prop->val, olen, otype);
950 BHND_NV_ASSERT(*otype == bhnd_nvram_prop_type(prop), ("type mismatch"));
956 * Attempt to encode the property's value as @p otype, writing the result
959 * @param prop The property to be encoded.
960 * @param[out] outp On success, the value will be written to this
961 * buffer. This argment may be NULL if the value is
963 * @param[in,out] olen The capacity of @p outp. On success, will be set
964 * to the actual size of the requested value.
965 * @param otype The data type to be written to @p outp.
968 * @retval ENOMEM If the @p outp is non-NULL, and the provided @p olen
969 * is too small to hold the encoded value.
970 * @retval EFTYPE If value coercion from @p prop to @p otype is
972 * @retval ERANGE If value coercion would overflow (or underflow) the
973 * a @p otype representation.
976 bhnd_nvram_prop_encode(bhnd_nvram_prop *prop, void *outp, size_t *olen,
977 bhnd_nvram_type otype)
979 return (bhnd_nvram_val_encode(prop->val, outp, olen, otype));