52inline std::pair<bool, size_t> extract_length(
const internal_json::JsonObjectMap& map) {
75 const std::string type_name =
"simple_list";
76 const auto& metamap = internal_json::extract_typed_object_from_metadata(metadata.
other, type_name);
78 const std::string version_name =
"version";
79 const std::string& vstring = internal_json::extract_string_from_typed_object(metamap, version_name, type_name);
80 auto version = ritsuko::parse_version_string(vstring.c_str(), vstring.size(),
true);
81 if (version.major != 1) {
82 throw std::runtime_error(
"unsupported version string '" + vstring +
"'");
85 std::string format = internal::extract_format(metamap);
87 auto other_dir = path /
"other_contents";
89 if (std::filesystem::exists(other_dir)) {
90 auto status = std::filesystem::status(other_dir);
91 if (status.type() != std::filesystem::file_type::directory) {
92 throw std::runtime_error(
"expected 'other_contents' to be a directory");
95 num_external = internal_other::count_directory_entries(other_dir);
96 for (
int e = 0; e < num_external; ++e) {
97 auto epath = other_dir / std::to_string(e);
98 if (!std::filesystem::exists(epath)) {
99 throw std::runtime_error(
"expected an external list object at '" + std::filesystem::relative(epath, path).
string() +
"'");
104 }
catch (std::exception& e) {
105 throw std::runtime_error(
"failed to validate external list object at '" + std::filesystem::relative(epath, path).
string() +
"'; " + std::string(e.what()));
111 if (format ==
"json.gz") {
112 uzuki2::json::Options opt;
114 auto gzreader = internal_other::open_reader<byteme::GzipFileReader>(path /
"list_contents.json.gz");
115 auto loaded = uzuki2::json::parse<uzuki2::DummyProvisioner>(gzreader, uzuki2::DummyExternals(num_external), std::move(opt));
116 len =
reinterpret_cast<const uzuki2::List*
>(loaded.get())->size();
118 }
else if (format ==
"hdf5") {
119 auto handle = ritsuko::hdf5::open_file(path /
"list_contents.h5");
120 auto ghandle = ritsuko::hdf5::open_group(handle, type_name.c_str());
121 auto loaded = uzuki2::hdf5::parse<uzuki2::DummyProvisioner>(ghandle, uzuki2::DummyExternals(num_external));
122 len =
reinterpret_cast<const uzuki2::List*
>(loaded.get())->size();
125 throw std::runtime_error(
"unknown format '" + format +
"'");
128 if (version.ge(1, 1, 0)) {
129 auto len_info = internal::extract_length(metamap);
130 if (len_info.first) {
131 if (len_info.second != len) {
132 throw std::runtime_error(
"'simple_list.length' differs from the length of the list");
145 const auto& metamap = internal_json::extract_typed_object_from_metadata(metadata.
other,
"simple_list");
147 auto len_info = internal::extract_length(metamap);
148 if (len_info.first) {
149 return len_info.second;
152 std::string format = internal::extract_format(metamap);
153 if (format ==
"hdf5") {
154 auto handle = ritsuko::hdf5::open_file(path /
"list_contents.h5");
155 auto lhandle = handle.openGroup(
"simple_list");
156 auto vhandle = lhandle.openGroup(
"data");
157 return vhandle.getNumObjs();
162 auto other_dir = path /
"other_contents";
163 int num_external = 0;
164 if (std::filesystem::exists(other_dir)) {
165 num_external = internal_other::count_directory_entries(other_dir);
168 uzuki2::json::Options opt;
170 auto gzreader = internal_other::open_reader<byteme::GzipFileReader>(path /
"list_contents.json.gz");
171 auto ptr = uzuki2::json::parse<uzuki2::DummyProvisioner>(gzreader, uzuki2::DummyExternals(num_external), std::move(opt));
172 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:144
void validate(const std::filesystem::path &path, const ObjectMetadata &metadata, Options &options)
Definition _validate.hpp:107