#include #include #include "function_signature.h" namespace domain { class DivisibleValidator : public FunctionValidator { public: DivisibleValidator() : FunctionValidator("divisible", {Value::INT, Value::INT}) {} bool validate(std::vector values) override { if (validateSignature(values)) { long long first = values[0].asInt(); long long second = values[1].asInt(); return (first % second) == 0; } return false; } void clear() override {} }; class LessThenValidator : public FunctionValidator { public: LessThenValidator() : FunctionValidator("less_then", {Value::INT, Value::INT}) {} bool validate(std::vector values) override { if (validateSignature(values)) { long long first = values[0].asInt(); long long second = values[1].asInt(); return first < second; } return false; } void clear() override {} }; class GreaterThenValidator : public FunctionValidator { public: GreaterThenValidator() : FunctionValidator("greater_then", {Value::INT, Value::INT}) {} bool validate(std::vector values) override { if (validateSignature(values)) { long long first = values[0].asInt(); long long second = values[1].asInt(); return first > second; } return false; } void clear() override {} }; class ContainsAddressValidator : public FunctionValidator { public: ContainsAddressValidator() : FunctionValidator("contains_address", {Value::ADDRESS_SPACE, Value::INT}) {} bool validate(std::vector values) override { if (validateSignature(values)) { AddressSpace space = values[0].asAddressSpace(); long long address = values[1].asInt(); return space.contains(address); } return false; } void clear() override {} }; class ContainsValidator : public FunctionValidator { public: ContainsValidator() : FunctionValidator("contains", {Value::ADDRESS_SPACE, Value::INT, Value::INT}) {} bool validate(std::vector values) override { if (validateSignature(values)) { AddressSpace space = values[0].asAddressSpace(); long long start = values[1].asInt(); long long size = values[1].asInt(); return space.contains(start, start + size); } return false; } void clear() override {} }; class UniqueValidator : public FunctionValidator { private: std::map>> spaces; bool overlaps(long long int start1, long long int end1, long long int start2, long long int end2) { return std::max((long long int) 0, std::min(end1, end2) - std::max(start1, start2)) > 0; } public: UniqueValidator() : FunctionValidator("unique", {Value::ADDRESS_SPACE, Value::INT, Value::INT}) {} bool validate(std::vector values) override { if (validateSignature(values)) { std::string space = values[0].asAddressSpace().getName(); long long int start = values[1].asInt(); long long int end = start + values[2].asInt(); if (spaces.count(space) == 0) { spaces.insert(std::make_pair(space, std::vector>{})); } for (auto &s: spaces[space]) { if (overlaps(s.first, s.second, start, end)) { return false; } } spaces[space].push_back(std::make_pair(start, end)); return true; } return false; } void clear() override { spaces.clear(); } }; std::vector getSupportedValidators() { std::vector validators; validators.push_back(new DivisibleValidator()); validators.push_back(new LessThenValidator()); validators.push_back(new GreaterThenValidator()); validators.push_back(new ContainsAddressValidator()); validators.push_back(new ContainsValidator()); validators.push_back(new UniqueValidator()); return validators; } FunctionValidator::FunctionValidator(std::string name, std::vector signature) : name(std::move(name)), signature(std::move(signature)) {} std::string FunctionValidator::getName() { return name; } std::vector FunctionValidator::getSignature() { return signature; } bool FunctionValidator::validateSignature(std::vector _signature) { if (this->signature.size() != _signature.size()) { return false; } for (int i = 0; i < this->signature.size(); i++) { if (this->signature[i] != _signature[i].getType()) { return false; } } return true; } } // namespace domain