From 3275dc3ce981900b92e2097180e62aae39a75503 Mon Sep 17 00:00:00 2001 From: Lexi Winter Date: Mon, 24 Mar 2025 23:39:38 +0000 Subject: add iteration for array types --- libnvxx/nvxx_iterator.cc | 52 +++++++++++++++++++++++++++++++++++ libnvxx/nvxx_iterator.h | 7 ++++- libnvxx/tests/nvxx_iterator.cc | 62 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 117 insertions(+), 4 deletions(-) diff --git a/libnvxx/nvxx_iterator.cc b/libnvxx/nvxx_iterator.cc index 9e0781b..7312152 100644 --- a/libnvxx/nvxx_iterator.cc +++ b/libnvxx/nvxx_iterator.cc @@ -156,6 +156,58 @@ nv_list_iterator::__advance() break; } + case NV_TYPE_BOOL_ARRAY: { + auto nitems = std::size_t{}; + auto ptr = cnvlist_get_bool_array(__cookie, &nitems); + auto span = std::span{ptr, nitems}; + __current = std::make_pair(name, span); + break; + } + + case NV_TYPE_NUMBER_ARRAY: { + auto nitems = std::size_t{}; + auto ptr = cnvlist_get_number_array(__cookie, &nitems); + auto span = std::span{ptr, nitems}; + __current = std::make_pair(name, span); + break; + } + + case NV_TYPE_STRING_ARRAY: { + auto nitems = std::size_t{}; + auto ptr = cnvlist_get_string_array(__cookie, &nitems); + auto span = std::span{ptr, nitems}; + auto vector = + span + | std::views::transform([] (char const *ptr) { + return std::string_view(ptr); + }) + | std::ranges::to(); + __current = std::make_pair(name, vector); + break; + } + + case NV_TYPE_DESCRIPTOR_ARRAY: { + auto nitems = std::size_t{}; + auto ptr = cnvlist_get_descriptor_array(__cookie, &nitems); + auto span = std::span{ptr, nitems}; + __current = std::make_pair(name, span); + break; + } + + case NV_TYPE_NVLIST_ARRAY: { + auto nitems = std::size_t{}; + auto ptr = cnvlist_get_nvlist_array(__cookie, &nitems); + auto span = std::span{ptr, nitems}; + auto vector = + span + | std::views::transform([] (::nvlist_t const *ptr) { + return const_nv_list(ptr); + }) + | std::ranges::to(); + __current = std::make_pair(name, vector); + break; + } + default: std::abort(); } diff --git a/libnvxx/nvxx_iterator.h b/libnvxx/nvxx_iterator.h index d626bfd..c65f546 100644 --- a/libnvxx/nvxx_iterator.h +++ b/libnvxx/nvxx_iterator.h @@ -45,7 +45,12 @@ using nv_list_value_t = std::variant< std::string_view, /* string */ const_nv_list, /* nvlist */ int, /* descriptor */ - std::span /* binary */ + std::span, /* binary */ + std::span, /* bool array */ + std::span, /* number array */ + std::vector, /* string array */ + std::span, /* descriptor array */ + std::vector /* nvlist array */ >; // the iterator value type diff --git a/libnvxx/tests/nvxx_iterator.cc b/libnvxx/tests/nvxx_iterator.cc index fd96b38..9f41c9c 100644 --- a/libnvxx/tests/nvxx_iterator.cc +++ b/libnvxx/tests/nvxx_iterator.cc @@ -40,7 +40,8 @@ TEST_CASE(nvxx_basic_iterate) { using namespace std::literals; auto nvl = bsd::nv_list(); - int fds[2]; + auto fds = std::array{}; + auto fds2 = std::array{}; auto binary = std::array{ static_cast(1), @@ -49,22 +50,37 @@ TEST_CASE(nvxx_basic_iterate) static_cast(4) }; - auto ret = ::pipe(fds); + auto ret = ::pipe(&fds[0]); ATF_REQUIRE_EQ(0, ret); + ret = ::pipe(&fds2[0]); + ATF_REQUIRE_EQ(0, ret); + + auto bool_array = std::vector{true, false, false}; + auto number_array = std::vector{2, 3, 4}; + auto string_array = std::vector{"one"sv, "two"sv, "three"sv}; nvl.add_null("a null"); nvl.add_number("a number", 42); nvl.add_string("a string", "a test string"); nvl.add_bool("a bool", true); nvl.add_binary("a binary", binary); + nvl.add_bool_range("a bool array", bool_array); + nvl.add_number_range("a number array", number_array); + nvl.add_string_range("a string array", string_array); auto fdesc = fds[0]; nvl.move_descriptor("an fd", fdesc); + nvl.add_descriptor_range("a descriptor array", fds2); + auto nvl2 = bsd::nv_list(); nvl2.add_number("child number", 666); nvl.add_nvlist("an nvlist", nvl2); + auto nvl3 = bsd::nv_list(); + nvl3.add_number("an array number", 4242); + nvl.add_nvlist_array("an nvlist array", std::span{&nvl3, 1}); + auto begin = std::ranges::begin(nvl); auto end = std::ranges::end(nvl); @@ -107,6 +123,46 @@ TEST_CASE(nvxx_basic_iterate) std::get(value) .get_number("child number")); + } else if (std::holds_alternative< + std::span>(value)) { + ATF_REQUIRE_EQ("a bool array"sv, name); + auto data = std::get>(value); + ATF_REQUIRE_EQ(true, + std::ranges::equal(bool_array, data)); + + } else if (std::holds_alternative< + std::span>(value)) { + ATF_REQUIRE_EQ("a number array"sv, name); + auto data = std::get>(value); + ATF_REQUIRE_EQ(true, + std::ranges::equal(number_array, data)); + + } else if (std::holds_alternative< + std::vector< + std::string_view>>(value)) { + ATF_REQUIRE_EQ("a string array"sv, name); + auto data = std::get>(value); + ATF_REQUIRE_EQ(true, + std::ranges::equal(string_array, data)); + + } else if (std::holds_alternative< + std::span>(value)) { + ATF_REQUIRE_EQ("a descriptor array"sv, name); + auto data = std::get>(value); + ATF_REQUIRE_EQ(2, std::ranges::size(data)); + // XXX: should test we get the actual descriptors + + } else if (std::holds_alternative< + std::vector>(value)) { + ATF_REQUIRE_EQ("an nvlist array"sv, name); + auto data = std::get>(value); + ATF_REQUIRE_EQ(1, std::ranges::size(data)); + auto n = data[0].get_number("an array number"); + ATF_REQUIRE_EQ(4242, n); + } else ATF_REQUIRE_EQ(true, false); @@ -114,7 +170,7 @@ TEST_CASE(nvxx_basic_iterate) ++begin; } - ATF_REQUIRE_EQ(7, i); + ATF_REQUIRE_EQ(12, i); } ATF_INIT_TEST_CASES(tcs) -- cgit v1.2.3