27 #include "cif++/datablock.hpp" 32 datablock::datablock(
const datablock &db)
33 :
std::list<category>(db)
35 , m_validator(db.m_validator)
37 for (
auto &cat : *
this)
38 cat.update_links(*
this);
41 datablock &datablock::operator=(
const datablock &db)
45 std::list<category>::operator=(db);
47 m_validator = db.m_validator;
49 for (
auto &cat : *
this)
50 cat.update_links(*
this);
56 void datablock::set_validator(
const validator *v)
62 for (
auto &cat : *
this)
63 cat.set_validator(v, *
this);
65 catch (
const std::exception &)
67 throw_with_nested(std::runtime_error(
"Error while setting validator in datablock " + m_name));
71 const validator *datablock::get_validator()
const 76 bool datablock::is_valid()
const 78 if (m_validator ==
nullptr)
79 throw std::runtime_error(
"Validator not specified");
82 for (
auto &cat : *
this)
83 result = cat.is_valid() and result;
88 bool datablock::validate_links()
const 92 for (
auto &cat : *
this)
93 result = cat.validate_links() and result;
100 category &datablock::operator[](std::string_view name)
102 auto i = std::find_if(begin(), end(), [name](
const category &
c)
103 {
return iequals(c.name(), name); });
108 auto &cat = emplace_back(name);
111 cat.set_validator(m_validator, *
this);
116 const category &datablock::operator[](std::string_view name)
const 118 static const category s_empty;
119 auto i = std::find_if(begin(), end(), [name](
const category &c)
120 {
return iequals(c.name(), name); });
121 return i == end() ? s_empty : *
i;
124 category *datablock::get(std::string_view name)
126 auto i = std::find_if(begin(), end(), [name](
const category &c)
127 {
return iequals(c.name(), name); });
128 return i == end() ? nullptr : &*
i;
131 const category *datablock::get(std::string_view name)
const 133 return const_cast<datablock *
>(
this)->
get(name);
136 std::tuple<datablock::iterator, bool> datablock::emplace(std::string_view name)
149 auto n = std::next(
i);
150 splice(begin(), *
this,
i,
n);
161 auto &c = emplace_front(name);
162 c.set_validator(m_validator, *
this);
165 return std::make_tuple(begin(), is_new);
168 std::vector<std::string> datablock::get_tag_order()
const 170 std::vector<std::string> result;
174 auto ci = find_if(begin(), end(), [](
const category &cat) {
return cat.name() ==
"entry"; });
177 auto cto = ci->get_tag_order();
178 result.insert(result.end(), cto.begin(), cto.end());
181 ci = find_if(begin(), end(), [](
const category &cat) {
return cat.name() ==
"audit_conform"; });
184 auto cto = ci->get_tag_order();
185 result.insert(result.end(), cto.begin(), cto.end());
188 for (
auto &cat : *
this)
190 if (cat.name() ==
"entry" or cat.name() ==
"audit_conform")
192 auto cto = cat.get_tag_order();
193 result.insert(result.end(), cto.begin(), cto.end());
201 os <<
"data_" << m_name << std::endl
202 <<
"# " << std::endl;
208 for (
auto &cat : *
this)
210 if (cat.name() !=
"entry")
220 if (
get(
"audit_conform"))
221 get(
"audit_conform")->
write(os);
222 else if (m_validator !=
nullptr and m_validator->get_validator_for_category(
"audit_conform") !=
nullptr)
224 category auditConform(
"audit_conform");
225 auditConform.emplace({
226 {
"dict_name", m_validator->name()},
227 {
"dict_version", m_validator->version()}});
228 auditConform.write(os);
231 for (
auto &cat : *
this)
233 if (cat.name() !=
"entry" and cat.name() !=
"audit_conform")
238 void datablock::write(std::ostream &os,
const std::vector<std::string> &tag_order)
240 os <<
"data_" << m_name << std::endl
241 <<
"# " << std::endl;
243 std::vector<std::string> cat_order;
244 for (
auto &o : tag_order)
246 std::string cat_name, item_name;
248 if (find_if(cat_order.rbegin(), cat_order.rend(), [cat_name](
const std::string &s) ->
bool 249 {
return iequals(cat_name, s); }) == cat_order.rend())
250 cat_order.push_back(cat_name);
253 for (
auto &c : cat_order)
259 std::vector<std::string> items;
260 for (
auto &o : tag_order)
262 std::string cat_name, item_name;
266 items.push_back(item_name);
269 cat->write(os, items);
273 for (
auto &cat : *
this)
275 if (find_if(cat_order.begin(), cat_order.end(), [&](
const std::string &s) ->
bool 276 {
return iequals(cat.name(), s); }) != cat_order.end())
288 std::vector<std::string> catA, catB;
290 for (
auto &cat : dbA)
293 catA.push_back(cat.name());
297 for (
auto &cat : dbB)
300 catB.push_back(cat.name());
307 std::vector<std::string> missingA, missingB;
309 auto catA_i = catA.begin(), catB_i = catB.begin();
311 while (catA_i != catA.end() and catB_i != catB.end())
313 if (not
iequals(*catA_i, *catB_i))
319 if (catA_i != catA.end()
or catB_i != catB.end())
323 catA_i = catA.begin(), catB_i = catB.begin();
325 while (catA_i != catA.end() and catB_i != catB.end())
327 std::string nA = *catA_i;
330 std::string nB = *catB_i;
333 int d = nA.compare(nB);
340 if (not (*dbA.get(*catA_i) == *dbB.get(*catB_i)))
void to_lower(std::string &s)
void write(std::ostream &os, const datablock &db)
bool operator==(faketype, faketype)
bool iequals(std::string_view a, std::string_view b)
std::tuple< std::string, std::string > split_tag_name(std::string_view tag)
void sort(struct DCEL_T *dcel)