// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include "JFJochCBFReader.h" #include #include #include #include #include #include #include #include "../common/JFJochException.h" #include "../common/JFJochMath.h" namespace { bool HasCBFExtension(const std::filesystem::path &p) { std::string ext = p.extension().string(); std::transform(ext.begin(), ext.end(), ext.begin(), [](unsigned char c) { return std::tolower(c); }); return ext == ".cbf"; } // The sweep a file belongs to, as a template: everything before the trailing run of digits, the // number of digits, and the extension. "o8_1_0042.cbf" -> {"o8_1_", 4}. A directory can hold several // sweeps ("o8_1_*" beside "o8_2_*"), so collecting every .cbf in it would silently splice two // crystals together; matching the template is what makes "point at any frame" safe. struct Template { std::string prefix; size_t digits = 0; bool Matches(const std::string &name) const { if (name.size() != prefix.size() + digits + 4) // + ".cbf" return false; if (name.compare(0, prefix.size(), prefix) != 0) return false; for (size_t i = 0; i < digits; i++) if (!std::isdigit(static_cast(name[prefix.size() + i]))) return false; return true; } }; std::optional