示例#1
0
/*
 * The function obtains size of the nvlist after nvlist_pack().
 */
size_t
nvlist_size(const nvlist_t *nvl)
{
	const nvlist_t *tmpnvl;
	const nvpair_t *nvp, *tmpnvp;
	void *cookie;
	size_t size;

	NVLIST_ASSERT(nvl);
	PJDLOG_ASSERT(nvl->nvl_error == 0);

	size = sizeof(struct nvlist_header);
	nvp = nvlist_first_nvpair(nvl);
	while (nvp != NULL) {
		size += nvpair_header_size();
		size += strlen(nvpair_name(nvp)) + 1;
		if (nvpair_type(nvp) == NV_TYPE_NVLIST) {
			size += sizeof(struct nvlist_header);
			size += nvpair_header_size() + 1;
			tmpnvl = nvpair_get_nvlist(nvp);
			PJDLOG_ASSERT(tmpnvl->nvl_error == 0);
			tmpnvp = nvlist_first_nvpair(tmpnvl);
			if (tmpnvp != NULL) {
				nvl = tmpnvl;
				nvp = tmpnvp;
				continue;
			}
		} else {
			size += nvpair_size(nvp);
		}

		while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) {
			cookie = NULL;
			nvl = nvlist_get_parent(nvl, &cookie);
			if (nvl == NULL)
				goto out;
			nvp = cookie;
		}
	}

out:
	return (size);
}
示例#2
0
/*
 * The function obtains size of the nvlist after nvlist_pack().
 * Additional argument 'level' allows to track how deep are we as we obtain
 * size of the NV_TYPE_NVLIST elements using recursion. We allow at most
 * three levels of recursion.
 */
static size_t
nvlist_xsize(const nvlist_t *nvl, int level)
{
	const nvpair_t *nvp;
	size_t size;

	NVLIST_ASSERT(nvl);
	PJDLOG_ASSERT(nvl->nvl_error == 0);
	PJDLOG_ASSERT(level < 3);

	size = sizeof(struct nvlist_header);
	for (nvp = nvlist_first_nvpair(nvl); nvp != NULL;
	    nvp = nvlist_next_nvpair(nvl, nvp)) {
		size += nvpair_header_size();
		size += strlen(nvpair_name(nvp)) + 1;
		if (nvpair_type(nvp) == NV_TYPE_NVLIST)
			size += nvlist_xsize(nvpair_get_nvlist(nvp), level + 1);
		else
			size += nvpair_size(nvp);
	}

	return (size);
}
示例#3
0
/*
 * The function obtains size of the nvlist after nvlist_pack().
 */
size_t
nvlist_size(const nvlist_t *nvl)
{
	const nvlist_t *tmpnvl;
	const nvlist_t * const *nvlarray;
	const nvpair_t *nvp, *tmpnvp;
	void *cookie;
	size_t size, nitems;
	unsigned int ii;

	NVLIST_ASSERT(nvl);
	PJDLOG_ASSERT(nvl->nvl_error == 0);

	size = sizeof(struct nvlist_header);
	nvp = nvlist_first_nvpair(nvl);
	while (nvp != NULL) {
		size += nvpair_header_size();
		size += strlen(nvpair_name(nvp)) + 1;
		if (nvpair_type(nvp) == NV_TYPE_NVLIST) {
			size += sizeof(struct nvlist_header);
			size += nvpair_header_size() + 1;
			tmpnvl = nvpair_get_nvlist(nvp);
			PJDLOG_ASSERT(tmpnvl->nvl_error == 0);
			tmpnvp = nvlist_first_nvpair(tmpnvl);
			if (tmpnvp != NULL) {
				nvl = tmpnvl;
				nvp = tmpnvp;
				continue;
			}
		} else if (nvpair_type(nvp) == NV_TYPE_NVLIST_ARRAY) {
			nvlarray = nvpair_get_nvlist_array(nvp, &nitems);
			PJDLOG_ASSERT(nitems > 0);

			size += (nvpair_header_size() + 1) * nitems;
			size += sizeof(struct nvlist_header) * nitems;

			tmpnvl = NULL;
			tmpnvp = NULL;
			for (ii = 0; ii < nitems; ii++) {
				PJDLOG_ASSERT(nvlarray[ii]->nvl_error == 0);
				tmpnvp = nvlist_first_nvpair(nvlarray[ii]);
				if (tmpnvp != NULL) {
					tmpnvl = nvlarray[ii];
					break;
				}
			}
			if (tmpnvp != NULL) {
				nvp = tmpnvp;
				nvl = tmpnvl;
				continue;
			}

		} else {
			size += nvpair_size(nvp);
		}

		while ((nvp = nvlist_next_nvpair(nvl, nvp)) == NULL) {
			do {
				cookie = NULL;
				nvl = nvlist_get_pararr(nvl, &cookie);
				if (nvl == NULL)
					goto out;
				if (nvlist_in_array(nvl) && cookie == NULL) {
					nvp = nvlist_first_nvpair(nvl);
				} else {
					nvp = cookie;
				}
			} while (nvp == NULL);
			if (nvlist_in_array(nvl) && cookie == NULL)
				break;
		}
	}

out:
	return (size);
}