| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #include "cif++/file.hpp" |
| #include "cif++/gzio.hpp" |
|
|
| namespace cif |
| { |
|
|
| |
| void file::set_validator(const validator *v) |
| { |
| m_validator = v; |
| for (auto &db : *this) |
| db.set_validator(v); |
| } |
|
|
| bool file::is_valid() const |
| { |
| if (m_validator == nullptr) |
| std::runtime_error("No validator loaded explicitly, cannot continue"); |
|
|
| bool result = true; |
| for (auto &d : *this) |
| result = d.is_valid() and result; |
|
|
| if (result) |
| result = validate_links(); |
|
|
| return result; |
| } |
|
|
| bool file::is_valid() |
| { |
| if (m_validator == nullptr) |
| { |
| if (VERBOSE > 0) |
| std::cerr << "No dictionary loaded explicitly, loading default\n"; |
|
|
| load_dictionary(); |
| } |
|
|
| bool result = not empty(); |
|
|
| for (auto &d : *this) |
| result = d.is_valid() and result; |
|
|
| if (result) |
| result = validate_links(); |
|
|
| return result; |
| } |
|
|
| bool file::validate_links() const |
| { |
| if (m_validator == nullptr) |
| std::runtime_error("No validator loaded explicitly, cannot continue"); |
| |
| bool result = true; |
|
|
| for (auto &db : *this) |
| result = db.validate_links() and result; |
| |
| return result; |
| } |
|
|
| void file::load_dictionary() |
| { |
| if (not empty()) |
| { |
| auto *audit_conform = front().get("audit_conform"); |
| if (audit_conform and not audit_conform->empty()) |
| { |
| std::string name = audit_conform->front().get<std::string>("dict_name"); |
|
|
| if (name == "mmcif_pdbx_v50") |
| name = "mmcif_pdbx.dic"; |
|
|
| if (not name.empty()) |
| { |
| try |
| { |
| load_dictionary(name); |
| } |
| catch (const std::exception &ex) |
| { |
| if (VERBOSE) |
| std::cerr << "Failed to load dictionary " << std::quoted(name) << ": " << ex.what() << '\n'; |
| } |
| } |
| } |
| } |
|
|
| |
| |
| } |
|
|
| void file::load_dictionary(std::string_view name) |
| { |
| set_validator(&validator_factory::instance()[name]); |
| } |
|
|
| bool file::contains(std::string_view name) const |
| { |
| return std::find_if(begin(), end(), [name](const datablock &db) { return iequals(db.name(), name); }) != end(); |
| } |
|
|
| datablock &file::operator[](std::string_view name) |
| { |
| auto i = std::find_if(begin(), end(), [name](const datablock &c) |
| { return iequals(c.name(), name); }); |
|
|
| if (i != end()) |
| return *i; |
|
|
| emplace_back(name); |
| return back(); |
| } |
|
|
| const datablock &file::operator[](std::string_view name) const |
| { |
| static const datablock s_empty; |
| auto i = std::find_if(begin(), end(), [name](const datablock &c) |
| { return iequals(c.name(), name); }); |
| return i == end() ? s_empty : *i; |
| } |
|
|
| std::tuple<file::iterator, bool> file::emplace(std::string_view name) |
| { |
| bool is_new = true; |
|
|
| auto i = begin(); |
| while (i != end()) |
| { |
| if (iequals(name, i->name())) |
| { |
| is_new = false; |
| break; |
| } |
|
|
| ++i; |
| } |
|
|
| if (is_new) |
| { |
| i = insert(end(), { name }); |
| i->set_validator(m_validator); |
| } |
|
|
| assert(i != end()); |
| return std::make_tuple(i, is_new); |
| } |
|
|
| void file::load(const std::filesystem::path &p) |
| { |
| gzio::ifstream in(p); |
| if (not in.is_open()) |
| throw std::runtime_error("Could not open file '" + p.string() + '\''); |
|
|
| try |
| { |
| load(in); |
| } |
| catch (const std::exception &) |
| { |
| throw_with_nested(std::runtime_error("Error reading file '" + p.string() + '\'')); |
| } |
| } |
|
|
| void file::load(std::istream &is) |
| { |
| auto saved = m_validator; |
| set_validator(nullptr); |
|
|
| parser p(is, *this); |
| p.parse_file(); |
|
|
| if (saved != nullptr) |
| set_validator(saved); |
| else |
| load_dictionary(); |
| } |
|
|
| void file::save(const std::filesystem::path &p) const |
| { |
| gzio::ofstream outFile(p); |
| save(outFile); |
| } |
|
|
| void file::save(std::ostream &os) const |
| { |
| |
| |
|
|
| for (auto &db : *this) |
| db.write(os); |
| } |
|
|
| } |