52inline std::pair<bool, size_t> extract_length(
const internal_json::JsonObjectMap& map) {
75 const auto& metamap = internal_json::extract_typed_object_from_metadata(metadata.
other,
"simple_list");
77 const std::string& vstring = internal_json::extract_string_from_typed_object(metamap,
"version",
"simple_list");
78 auto version = ritsuko::parse_version_string(vstring.c_str(), vstring.size(),
true);
79 if (version.major != 1) {
80 throw std::runtime_error(
"unsupported version string '" + vstring +
"'");
83 std::string format = internal::extract_format(metamap);
85 auto other_dir = path /
"other_contents";
87 if (std::filesystem::exists(other_dir)) {
88 auto status = std::filesystem::status(other_dir);
89 if (status.type() != std::filesystem::file_type::directory) {
90 throw std::runtime_error(
"expected 'other_contents' to be a directory");
93 num_external = internal_other::count_directory_entries(other_dir);
94 for (
int e = 0; e < num_external; ++e) {
95 auto epath = other_dir / std::to_string(e);
96 if (!std::filesystem::exists(epath)) {
97 throw std::runtime_error(
"expected an external list object at '" + std::filesystem::relative(epath, path).
string() +
"'");
102 }
catch (std::exception& e) {
103 throw std::runtime_error(
"failed to validate external list object at '" + std::filesystem::relative(epath, path).
string() +
"'; " + std::string(e.what()));
109 if (format ==
"json.gz") {
110 uzuki2::json::Options opt;
112 auto gzreader = internal_other::open_reader<byteme::GzipFileReader>(path /
"list_contents.json.gz");
113 auto loaded = uzuki2::json::parse<uzuki2::DummyProvisioner>(gzreader, uzuki2::DummyExternals(num_external), std::move(opt));
114 len =
reinterpret_cast<const uzuki2::List*
>(loaded.get())->size();
116 }
else if (format ==
"hdf5") {
117 auto handle = ritsuko::hdf5::open_file(path /
"list_contents.h5");
118 auto ghandle = ritsuko::hdf5::open_group(handle,
"simple_list");
119 auto loaded = uzuki2::hdf5::parse<uzuki2::DummyProvisioner>(ghandle, uzuki2::DummyExternals(num_external));
120 len =
reinterpret_cast<const uzuki2::List*
>(loaded.get())->size();
123 throw std::runtime_error(
"unknown format '" + format +
"'");
126 if (version.ge(1, 1, 0)) {
127 auto len_info = internal::extract_length(metamap);
128 if (len_info.first) {
129 if (len_info.second != len) {
130 throw std::runtime_error(
"'simple_list.length' differs from the length of the list");
143 const auto& metamap = internal_json::extract_typed_object_from_metadata(metadata.
other,
"simple_list");
145 auto len_info = internal::extract_length(metamap);
146 if (len_info.first) {
147 return len_info.second;
150 std::string format = internal::extract_format(metamap);
151 if (format ==
"hdf5") {
152 auto handle = ritsuko::hdf5::open_file(path /
"list_contents.h5");
153 auto lhandle = handle.openGroup(
"simple_list");
154 auto vhandle = lhandle.openGroup(
"data");
155 return vhandle.getNumObjs();
160 auto other_dir = path /
"other_contents";
161 int num_external = 0;
162 if (std::filesystem::exists(other_dir)) {
163 num_external = internal_other::count_directory_entries(other_dir);
166 uzuki2::json::Options opt;
168 auto gzreader = internal_other::open_reader<byteme::GzipFileReader>(path /
"list_contents.json.gz");
169 auto ptr = uzuki2::json::parse<uzuki2::DummyProvisioner>(gzreader, uzuki2::DummyExternals(num_external), std::move(opt));
170 return reinterpret_cast<const uzuki2::List*
>(ptr.get())->size();
size_t height(const std::filesystem::path &path, const ObjectMetadata &metadata, Options &options)
Definition simple_list.hpp:142
void validate(const std::filesystem::path &path, const ObjectMetadata &metadata, Options &options)
Definition _validate.hpp:107