Commit e5eb6225 by Maarten L. Hekkelman

started with validator, running into the ground

parent 98ff7943
......@@ -214,6 +214,9 @@ set(project_sources
${PROJECT_SOURCE_DIR}/src/Structure.cpp
${PROJECT_SOURCE_DIR}/src/Symmetry.cpp
${PROJECT_SOURCE_DIR}/src/TlsParser.cpp
${PROJECT_SOURCE_DIR}/src/v2/dictionary_parser.cpp
${PROJECT_SOURCE_DIR}/src/v2/validate.cpp
)
set(project_headers
......
......@@ -26,6 +26,8 @@
#pragma once
#include <cif++/v2/forward_decl.hpp>
#include <cif++/v2/condition.hpp>
#include <cif++/v2/iterator.hpp>
#include <cif++/v2/row.hpp>
......@@ -35,8 +37,7 @@ namespace cif::v2
// --------------------------------------------------------------------
template <
typename Alloc = std::allocator<std::byte>>
template <typename Alloc>
class category_t
{
private:
......@@ -106,7 +107,6 @@ class category_t
class row
{
public:
row() = default;
private:
......@@ -611,10 +611,9 @@ class category_t
// for (auto &cr : rows)
// cr.assign(childTag, value, false);
// }
// }
// }
}
private:
using char_allocator_type = typename std::allocator_traits<Alloc>::template rebind_alloc<char>;
using char_allocator_traits = std::allocator_traits<char_allocator_type>;
......@@ -706,7 +705,7 @@ class category_t
delete_row(result);
throw;
}
return result;
}
......
......@@ -26,6 +26,7 @@
#pragma once
#include <cassert>
#include <functional>
#include <iostream>
#include <regex>
......@@ -119,8 +120,8 @@ class condition_t
bool operator()(const category_type &c, const row_type &r) const
{
assert(m_impl);
assert(m_prepared);
assert(this->m_impl != nullptr);
assert(this->m_prepared);
return m_impl ? m_impl->test(c, r) : false;
}
......@@ -448,27 +449,26 @@ struct empty
inline constexpr empty null = empty();
template <typename Category>
struct key_t
struct key
{
explicit key_t(const std::string &itemTag)
explicit key(const std::string &itemTag)
: m_item_tag(itemTag)
{
}
explicit key_t(const char *itemTag)
explicit key(const char *itemTag)
: m_item_tag(itemTag)
{
}
key_t(const key_t &) = delete;
key_t &operator=(const key_t &) = delete;
key(const key &) = delete;
key &operator=(const key &) = delete;
std::string m_item_tag;
};
template <typename Category, typename T>
condition_t<Category> operator==(const key_t<Category> &key, const T &v)
condition_t<Category> operator==(const key &key, const T &v)
{
using category_type = Category;
using row_type = row_handle<category_type>;
......@@ -483,7 +483,7 @@ condition_t<Category> operator==(const key_t<Category> &key, const T &v)
}
template <typename Category>
inline condition_t<Category> operator==(const key_t<Category> &key, const char *value)
inline condition_t<Category> operator==(const key &key, const char *value)
{
using category_type = Category;
using row_type = row_handle<category_type>;
......@@ -512,20 +512,20 @@ inline condition_t<Category> operator==(const key_t<Category> &key, const char *
// }
template <typename Category, typename T>
condition_t<Category> operator!=(const key_t<Category> &key, const T &v)
condition_t<Category> operator!=(const key &key, const T &v)
{
return condition_t<Category>(new detail::not_condition_impl<Category>(operator==(key, v)));
}
template <typename Category>
inline condition_t<Category> operator!=(const key_t<Category> &key, const char *v)
inline condition_t<Category> operator!=(const key &key, const char *v)
{
std::string value(v ? v : "");
return condition_t<Category>(new detail::not_condition_impl<Category>(operator==(key, value)));
}
template <typename Category, typename T>
condition_t<Category> operator>(const key_t<Category> &key, const T &v)
condition_t<Category> operator>(const key &key, const T &v)
{
using category_type = Category;
using row_type = row_handle<category_type>;
......@@ -540,7 +540,7 @@ condition_t<Category> operator>(const key_t<Category> &key, const T &v)
}
template <typename Category, typename T>
condition_t<Category> operator>=(const key_t<Category> &key, const T &v)
condition_t<Category> operator>=(const key &key, const T &v)
{
using category_type = Category;
using row_type = row_handle<category_type>;
......@@ -555,7 +555,7 @@ condition_t<Category> operator>=(const key_t<Category> &key, const T &v)
}
template <typename Category, typename T>
condition_t<Category> operator<(const key_t<Category> &key, const T &v)
condition_t<Category> operator<(const key &key, const T &v)
{
using category_type = Category;
using row_type = row_handle<category_type>;
......@@ -570,7 +570,7 @@ condition_t<Category> operator<(const key_t<Category> &key, const T &v)
}
template <typename Category, typename T>
condition_t<Category> operator<=(const key_t<Category> &key, const T &v)
condition_t<Category> operator<=(const key &key, const T &v)
{
using category_type = Category;
using row_type = row_handle<category_type>;
......@@ -585,13 +585,13 @@ condition_t<Category> operator<=(const key_t<Category> &key, const T &v)
}
template <typename Category>
inline condition_t<Category> operator==(const key_t<Category> &key, const std::regex &rx)
inline condition_t<Category> operator==(const key &key, const std::regex &rx)
{
return condition_t<Category>(new detail::keyMatchescondition_impl<Category>(key.m_item_tag, rx));
}
template <typename Category>
inline condition_t<Category> operator==(const key_t<Category> &key, const empty &)
inline condition_t<Category> operator==(const key &key, const empty &)
{
return condition_t<Category>(new detail::keyIsemptycondition_impl<Category>(key.m_item_tag));
}
......@@ -626,12 +626,10 @@ inline condition_t<Category> all()
namespace literals
{
// template<typename Category>
// inline key_t<Category> operator""_key(const char *text, size_t length)
// {
// return key<Category>(std::string(text, length));
// }
inline key operator""_key(const char *text, size_t length)
{
return key(std::string(text, length));
}
inline constexpr empty null = empty();
......
......@@ -26,6 +26,8 @@
#pragma once
#include <cif++/v2/forward_decl.hpp>
#include <cif++/v2/category.hpp>
namespace cif::v2
......@@ -33,9 +35,7 @@ namespace cif::v2
// --------------------------------------------------------------------
template <
typename Alloc = std::allocator<void>,
typename Category = category_t<Alloc>>
template <typename Alloc, typename Category>
class datablock_t
{
public:
......@@ -48,6 +48,8 @@ class datablock_t
using iterator = category_type_list::iterator;
using const_iterator = category_type_list::const_iterator;
using reference = typename category_type_list::reference;
datablock_t(std::string_view name, const allocator_type &alloc = allocator_type())
: m_categories(alloc)
, m_name(name)
......@@ -81,11 +83,28 @@ class datablock_t
// --------------------------------------------------------------------
bool empty() const { return m_categories.empty(); }
size_t size() const { return m_categories.size(); }
reference front() { return m_categories.front(); }
reference back() { return m_categories.back(); }
iterator begin() { return m_categories.begin(); }
iterator end() { return m_categories.end(); }
const_iterator cbegin() { return m_categories.cbegin(); }
const_iterator cend() { return m_categories.cend(); }
const_iterator begin() const { return m_categories.begin(); }
const_iterator end() const { return m_categories.end(); }
// --------------------------------------------------------------------
category_type &operator[](std::string_view name)
{
auto i = std::find_if(m_categories.begin(), m_categories.end(), [name](const category_type &c)
{ return iequals(c.name(), name); });
if (i != m_categories.end())
return *i;
......@@ -133,7 +152,7 @@ class datablock_t
// cat.updateLinks();
}
return std::make_tuple(m_categories.begin(), is_new);
return std::make_tuple(m_categories.begin(), is_new);
}
void write(std::ostream &os) const
......@@ -185,4 +204,4 @@ class datablock_t
using datablock = datablock_t<>;
}
\ No newline at end of file
} // namespace cif::v2
\ No newline at end of file
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <cif++/v2/validate.hpp>
namespace cif::v2
{
Validator parse_dictionary(std::string_view name, std::istream &is);
} // namespace cif::v2
......@@ -26,8 +26,10 @@
#pragma once
#include "datablock.hpp"
#include "parser.hpp"
#include <cif++/v2/forward_decl.hpp>
#include <cif++/v2/datablock.hpp>
#include <cif++/v2/parser.hpp>
namespace cif::v2
{
......@@ -35,9 +37,9 @@ namespace cif::v2
// --------------------------------------------------------------------
template <
typename Alloc = std::allocator<void>,
typename Datablock = datablock_t<Alloc>,
typename Category = typename Datablock::category_type>
typename Alloc,
typename Datablock,
typename Category>
class file_t
{
public:
......@@ -56,7 +58,7 @@ class file_t
using iterator = datablock_list::iterator;
using const_iterator = datablock_list::const_iterator;
using parser_type = parser_t<file_t, datablock_type, category_type>;
using parser_type = parser_t<allocator_type, file_t, datablock_type, category_type>;
file_t() = default;
......
/*-
* SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2020 NKI/AVL, Netherlands Cancer Institute
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#pragma once
#include <memory>
namespace cif::v2
{
template <typename Alloc = std::allocator<void>>
class category_t;
template <typename Alloc = std::allocator<void>, typename Category = category_t<Alloc>>
class datablock_t;
template <typename Alloc = std::allocator<void>, typename Datablock = datablock_t<Alloc>, typename Category = typename Datablock::category_type>
class file_t;
template <typename Alloc = std::allocator<void>, typename File = file_t<Alloc>, typename Datablock = datablock_t<Alloc>, typename Category = typename Datablock::category_type>
class parser_t;
} // namespace cif::v2
\ No newline at end of file
......@@ -192,7 +192,7 @@ struct item_handle
void swap(item_handle &b);
template <typename T = std::string>
auto as() const
auto as() const -> T
{
using value_type = std::remove_cv_t<std::remove_reference_t<T>>;
return item_value_as<value_type>::convert(*this);
......@@ -398,10 +398,10 @@ template <typename Row>
template <size_t N>
struct item_handle<Row>::item_value_as<char[N]>
{
static std::string_view convert(const item_handle &ref)
{
return ref.text();
}
// static std::string_view convert(const item_handle &ref)
// {
// return ref.text();
// }
static int compare(const item_handle &ref, const char (&value)[N], bool icase)
{
......@@ -413,10 +413,10 @@ template <typename Row>
template <typename T>
struct item_handle<Row>::item_value_as<T, std::enable_if_t<std::is_same_v<T, const char *>>>
{
static std::string_view convert(const item_handle &ref)
{
return ref.text();
}
// static std::string_view convert(const item_handle &ref)
// {
// return ref.text();
// }
static int compare(const item_handle &ref, const char *value, bool icase)
{
......@@ -428,9 +428,10 @@ template <typename Row>
template <typename T>
struct item_handle<Row>::item_value_as<T, std::enable_if_t<std::is_same_v<T, std::string>>>
{
static std::string_view convert(const item_handle &ref)
static std::string convert(const item_handle &ref)
{
return ref.text();
std::string_view txt = ref.text();
return { txt.data(), txt.size() };
}
static int compare(const item_handle &ref, const std::string &value, bool icase)
......
......@@ -26,8 +26,19 @@
#pragma once
#include <cassert>
#include <iostream>
#include <map>
#include <stack>
#include <regex>
#include <cif++/v2/forward_decl.hpp>
#include <cif++/CifUtils.hpp>
namespace cif
{
extern int VERBOSE;
}
namespace cif::v2
{
......@@ -955,10 +966,7 @@ class sac_parser
// --------------------------------------------------------------------
template <
typename File,
typename Datablock,
typename Category>
template <typename Alloc, typename File, typename Datablock, typename Category>
class parser_t : public sac_parser
{
public:
......@@ -975,7 +983,8 @@ class parser_t : public sac_parser
void produce_datablock(const std::string &name) override
{
std::tie(m_datablock, std::ignore) = m_file.emplace(name);
const auto &[iter, ignore] = m_file.emplace(name);
m_datablock = &(*iter);
}
void produce_category(const std::string &name) override
......@@ -1009,31 +1018,9 @@ class parser_t : public sac_parser
protected:
file_type &m_file;
file_type::iterator m_datablock;
datablock_type *m_datablock;
datablock_type::iterator m_category;
row_handle_type m_row;
};
// --------------------------------------------------------------------
// class DictParser : public Parser
// {
// public:
// DictParser(Validator &validator, std::istream &is);
// ~DictParser();
// void loadDictionary();
// private:
// virtual void parse_save_frame();
// bool collectItemTypes();
// void linkItems();
// Validator &mValidator;
// File mFile;
// struct DictParserDataImpl *mImpl;
// bool mCollectedItemTypes = false;
// };
} // namespace cif::v2
......@@ -26,14 +26,20 @@
#pragma once
#include <filesystem>
// duh.. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86164
// #include <regex>
#include <boost/regex.hpp>
#include <set>
// TODO: get rid of boost::iostreams
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/regex.hpp>
#include <cif++/CifUtils.hpp>
namespace io = boost::iostreams;
namespace cif::v2
{
......@@ -155,8 +161,11 @@ struct ValidateLink
class Validator
{
public:
Validator(std::string_view name)
: m_name(name)
{
}
Validator(std::string_view name, std::istream &is);
~Validator();
Validator(const Validator &rhs) = delete;
......@@ -165,8 +174,8 @@ class Validator
Validator(Validator &&rhs);
Validator &operator=(Validator &&rhs);
friend class DictParser;
friend class ValidatorFactory;
friend class dictionary_parser;
// friend class ValidatorFactory;
void addTypeValidator(ValidateType &&v);
const ValidateType *getValidatorForType(std::string_view typeCode) const;
......@@ -180,47 +189,45 @@ class Validator
void reportError(const std::string &msg, bool fatal) const;
std::string dictName() const { return mName; }
void dictName(const std::string &name) { mName = name; }
const std::string &dictName() const { return m_name; }
void dictName(const std::string &name) { m_name = name; }
std::string dictVersion() const { return mVersion; }
void dictVersion(const std::string &version) { mVersion = version; }
const std::string &dictVersion() const { return m_version; }
void dictVersion(const std::string &version) { m_version = version; }
private:
// name is fully qualified here:
ValidateItem *getValidatorForItem(std::string_view name) const;
std::string mName;
std::string mVersion;
std::string m_name;
std::string m_version;
bool mStrict = false;
// std::set<uint32_t> mSubCategories;
std::set<ValidateType> mTypeValidators;
std::set<ValidateCategory> mCategoryValidators;
std::vector<ValidateLink> mLinkValidators;
};
// --------------------------------------------------------------------
class ValidatorFactory
{
public:
static ValidatorFactory &instance()
{
return sInstance;
static ValidatorFactory s_instance;
return s_instance;
}
const Validator &operator[](std::string_view dictionary);
const Validator &operator[](std::string_view dictionary_name);
private:
void construct_validator(std::string_view name, std::istream &is);
static ValidatorFactory sInstance;
// --------------------------------------------------------------------
ValidatorFactory();
ValidatorFactory() = default;
std::mutex mMutex;
std::list<Validator> mValidators;
};
} // namespace cif
} // namespace cif::v2
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment