static void * nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep) { unsigned char *buf, *ptr; size_t left, size; const nvlist_t *tmpnvl; nvpair_t *nvp, *tmpnvp; void *cookie; NVLIST_ASSERT(nvl); if (nvl->nvl_error != 0) { ERRNO_SET(nvl->nvl_error); return (NULL); } size = nvlist_size(nvl); buf = nv_malloc(size); if (buf == NULL) return (NULL); ptr = buf; left = size; ptr = nvlist_pack_header(nvl, ptr, &left); nvp = nvlist_first_nvpair(nvl); while (nvp != NULL) { NVPAIR_ASSERT(nvp); nvpair_init_datasize(nvp); ptr = nvpair_pack_header(nvp, ptr, &left); if (ptr == NULL) { nv_free(buf); return (NULL); } switch (nvpair_type(nvp)) { case NV_TYPE_NULL: ptr = nvpair_pack_null(nvp, ptr, &left); break; case NV_TYPE_BOOL: ptr = nvpair_pack_bool(nvp, ptr, &left); break; case NV_TYPE_NUMBER: ptr = nvpair_pack_number(nvp, ptr, &left); break; case NV_TYPE_STRING: ptr = nvpair_pack_string(nvp, ptr, &left); break; case NV_TYPE_NVLIST: tmpnvl = nvpair_get_nvlist(nvp); ptr = nvlist_pack_header(tmpnvl, ptr, &left); if (ptr == NULL) goto out; tmpnvp = nvlist_first_nvpair(tmpnvl); if (tmpnvp != NULL) { nvl = tmpnvl; nvp = tmpnvp; continue; } ptr = nvpair_pack_nvlist_up(ptr, &left); break; #ifndef _KERNEL case NV_TYPE_DESCRIPTOR: ptr = nvpair_pack_descriptor(nvp, ptr, fdidxp, &left); break; #endif case NV_TYPE_BINARY: ptr = nvpair_pack_binary(nvp, ptr, &left); break; default: PJDLOG_ABORT("Invalid type (%d).", nvpair_type(nvp)); } if (ptr == NULL) { nv_free(buf); return (NULL); } while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) { cookie = NULL; nvl = nvlist_get_parent(nvl, &cookie); if (nvl == NULL) goto out; nvp = cookie; ptr = nvpair_pack_nvlist_up(ptr, &left); if (ptr == NULL) goto out; } } out: if (sizep != NULL) *sizep = size; return (buf); }
static void * nvlist_xpack(const nvlist_t *nvl, int64_t *fdidxp, size_t *sizep) { unsigned char *buf, *ptr; size_t left, size; const nvlist_t *tmpnvl; nvpair_t *nvp, *tmpnvp; void *cookie; NVLIST_ASSERT(nvl); if (nvl->nvl_error != 0) { ERRNO_SET(nvl->nvl_error); return (NULL); } size = nvlist_size(nvl); buf = nv_malloc(size); if (buf == NULL) return (NULL); ptr = buf; left = size; ptr = nvlist_pack_header(nvl, ptr, &left); nvp = nvlist_first_nvpair(nvl); while (nvp != NULL) { NVPAIR_ASSERT(nvp); nvpair_init_datasize(nvp); ptr = nvpair_pack_header(nvp, ptr, &left); if (ptr == NULL) goto fail; switch (nvpair_type(nvp)) { case NV_TYPE_NULL: ptr = nvpair_pack_null(nvp, ptr, &left); break; case NV_TYPE_BOOL: ptr = nvpair_pack_bool(nvp, ptr, &left); break; case NV_TYPE_NUMBER: ptr = nvpair_pack_number(nvp, ptr, &left); break; case NV_TYPE_STRING: ptr = nvpair_pack_string(nvp, ptr, &left); break; case NV_TYPE_NVLIST: tmpnvl = nvpair_get_nvlist(nvp); ptr = nvlist_pack_header(tmpnvl, ptr, &left); if (ptr == NULL) goto fail; tmpnvp = nvlist_first_nvpair(tmpnvl); if (tmpnvp != NULL) { nvl = tmpnvl; nvp = tmpnvp; continue; } ptr = nvpair_pack_nvlist_up(ptr, &left); break; #ifndef _KERNEL case NV_TYPE_DESCRIPTOR: ptr = nvpair_pack_descriptor(nvp, ptr, fdidxp, &left); break; case NV_TYPE_DESCRIPTOR_ARRAY: ptr = nvpair_pack_descriptor_array(nvp, ptr, fdidxp, &left); break; #endif case NV_TYPE_BINARY: ptr = nvpair_pack_binary(nvp, ptr, &left); break; case NV_TYPE_BOOL_ARRAY: ptr = nvpair_pack_bool_array(nvp, ptr, &left); break; case NV_TYPE_NUMBER_ARRAY: ptr = nvpair_pack_number_array(nvp, ptr, &left); break; case NV_TYPE_STRING_ARRAY: ptr = nvpair_pack_string_array(nvp, ptr, &left); break; case NV_TYPE_NVLIST_ARRAY: { const nvlist_t * const * value; size_t nitems; unsigned int ii; tmpnvl = NULL; value = nvpair_get_nvlist_array(nvp, &nitems); for (ii = 0; ii < nitems; ii++) { ptr = nvlist_pack_header(value[ii], ptr, &left); if (ptr == NULL) goto out; tmpnvp = nvlist_first_nvpair(value[ii]); if (tmpnvp != NULL) { tmpnvl = value[ii]; break; } ptr = nvpair_pack_nvlist_array_next(ptr, &left); if (ptr == NULL) goto out; } if (tmpnvl != NULL) { nvl = tmpnvl; nvp = tmpnvp; continue; } break; } default: PJDLOG_ABORT("Invalid type (%d).", nvpair_type(nvp)); } if (ptr == NULL) goto fail; while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) { do { cookie = NULL; if (nvlist_in_array(nvl)) { ptr = nvpair_pack_nvlist_array_next(ptr, &left); if (ptr == NULL) goto fail; } nvl = nvlist_get_pararr(nvl, &cookie); if (nvl == NULL) goto out; if (nvlist_in_array(nvl) && cookie == NULL) { nvp = nvlist_first_nvpair(nvl); ptr = nvlist_pack_header(nvl, ptr, &left); if (ptr == NULL) goto fail; } else if (nvpair_type((nvpair_t *)cookie) != NV_TYPE_NVLIST_ARRAY) { ptr = nvpair_pack_nvlist_up(ptr, &left); if (ptr == NULL) goto fail; nvp = cookie; } else { nvp = cookie; } } while (nvp == NULL); if (nvlist_in_array(nvl) && cookie == NULL) break; } } out: if (sizep != NULL) *sizep = size; return (buf); fail: nv_free(buf); return (NULL); }