diff options
Diffstat (limited to 'src/factory')
-rw-r--r-- | src/factory/RBAAbstractMakerTable.cpp | 38 | ||||
-rw-r--r-- | src/factory/RBAAbstractMakerTable.hpp | 60 | ||||
-rw-r--r-- | src/factory/RBAJsonElement.cpp | 271 | ||||
-rw-r--r-- | src/factory/RBAJsonElement.hpp | 148 | ||||
-rw-r--r-- | src/factory/RBAJsonParser.cpp | 48 | ||||
-rw-r--r-- | src/factory/RBAJsonParserImpl.cpp | 315 | ||||
-rw-r--r-- | src/factory/RBAJsonParserImpl.hpp | 70 | ||||
-rw-r--r-- | src/factory/RBAModelFactory.cpp | 201 | ||||
-rw-r--r-- | src/factory/RBAModelFactory.hpp | 101 |
9 files changed, 1252 insertions, 0 deletions
diff --git a/src/factory/RBAAbstractMakerTable.cpp b/src/factory/RBAAbstractMakerTable.cpp new file mode 100644 index 0000000..b8340a7 --- /dev/null +++ b/src/factory/RBAAbstractMakerTable.cpp @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2019 DENSO CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/// @file RBAAbstractMakerTable.cpp +/// @brief Maker table abstraction class definition + +#include "RBAAbstractMakerTable.hpp" + +namespace rba +{ + +const std::list<std::string>& +RBAAbstractMakerTable::getTags() const +{ + return tags_; +} + +void +RBAAbstractMakerTable::addTag(const std::string& tag) +{ + tags_.push_back(tag); +} + +} + diff --git a/src/factory/RBAAbstractMakerTable.hpp b/src/factory/RBAAbstractMakerTable.hpp new file mode 100644 index 0000000..81b0c09 --- /dev/null +++ b/src/factory/RBAAbstractMakerTable.hpp @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2019 DENSO CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/// @file RBAAbstractMakerTable.hpp +/// @brief Maker table abstraction class header + +#ifndef RBAABSTRACTMAKERTABLE_HPP +#define RBAABSTRACTMAKERTABLE_HPP + +#include <memory> +#include "RBAModelElementMaker.hpp" + +namespace rba +{ + +class DLL_EXPORT RBAAbstractMakerTable +{ +public: + RBAAbstractMakerTable()=default; + RBAAbstractMakerTable(const RBAAbstractMakerTable&)=delete; + RBAAbstractMakerTable(const RBAAbstractMakerTable&&)=delete; + RBAAbstractMakerTable& operator=(const RBAAbstractMakerTable&)=delete; + RBAAbstractMakerTable& operator=(const RBAAbstractMakerTable&&)=delete; + virtual ~RBAAbstractMakerTable()=default; + +public: + virtual std::list<std::unique_ptr<RBAModelElementMaker>> getMakers() const=0; + virtual const std::list<std::string>& getTags() const; + +protected: + void addTag(const std::string& tag); + +private: +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4251) +#endif + std::list<std::string> tags_; +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +}; + +} + +#endif diff --git a/src/factory/RBAJsonElement.cpp b/src/factory/RBAJsonElement.cpp new file mode 100644 index 0000000..9b8f639 --- /dev/null +++ b/src/factory/RBAJsonElement.cpp @@ -0,0 +1,271 @@ +/** + * Copyright (c) 2019 DENSO CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/// @file RBAJsonElement.cpp +/// @brief JSON element class defintion file + +#include "RBAJsonElement.hpp" + +#include "RBAArbitrationPolicy.hpp" +#include "RBAContentLoserType.hpp" +#ifdef RBA_USE_LOG +#include "RBAExpressionType.hpp" +#endif + +namespace rba +{ + +// RBAJsonElement clas + +std::string RBAJsonElement::emptyStr_; + +const std::string& +RBAJsonElement::getString() const +{ + // This function is never called + // because the function of the derived class is called + return emptyStr_; +} + +std::int32_t +RBAJsonElement::getInt() const +{ + // This function is never called + // because the function of the derived class is called + return -99; +} + +RBAArbitrationPolicy +RBAJsonElement::getArbitrationPolicy() const +{ + // This function is never called + // because the function of the derived class is called + return RBAArbitrationPolicy::DEFAULT; +} + +RBAContentLoserType +RBAJsonElement::getLoserType() const +{ + // This function is never called + // because the function of the derived class is called + return RBAContentLoserType::NEVER_GIVEUP; +} + +#ifdef RBA_USE_LOG +RBAExpressionType +RBAJsonElement::getExpressionType() const +{ + // This function is never called + // because the function of the derived class is called + return RBAExpressionType::VALUE; +} +#endif + +void +RBAJsonElement::setName(const std::string& name) +{ + name_ = name; +} + +const std::string& +RBAJsonElement::getName() const +{ + return name_; +} + +void +RBAJsonElement::addChild(std::unique_ptr<RBAJsonElement> child) +{ + children_.push_back(move(child)); +} + +const std::vector<std::unique_ptr<RBAJsonElement>>& +RBAJsonElement::getChildren() const +{ + return children_; +} + +RBAJsonElement* +RBAJsonElement::getChild() const +{ + return children_.front().get(); +} + +const RBAJsonElement* +RBAJsonElement::findChildren(const std::string& name) const +{ + RBAJsonElement* res{nullptr}; + for(const auto& elem : children_) { + if(elem->getName() == name) { + res = elem.get(); + break; + } + } + + return res; +} + +const std::string& +RBAJsonElement::getClassName() const +{ + const RBAJsonElement* const elem {findChildren("class")}; + if(elem != nullptr) { + return elem->getString(); + } + + return emptyStr_; +} + +// RBAJsonElementElement class + +RBAJsonElementElement::RBAJsonElementElement(const std::string& name) + : RBAJsonElement{} +{ + setName(name); +} + +// RBAJsonElementString class + +RBAJsonElementString::RBAJsonElementString(const std::string& name) + : RBAJsonElement{} +{ + setName(name); +} + +RBAArbitrationPolicy +RBAJsonElementString::getArbitrationPolicy() const +{ + if(str_ == "FIRST_COME_FIRST") { + return RBAArbitrationPolicy::FIRST_COME_FIRST; + } + else if(str_ == "LAST_COME_FIRST") { + return RBAArbitrationPolicy::LAST_COME_FIRST; + } + else if(str_ == "PRIORITY_FIRST_COME_FIRST") { + return RBAArbitrationPolicy::PRIORITY_FIRST_COME_FIRST; + } + else if(str_ == "PRIORITY_LAST_COME_FIRST") { + return RBAArbitrationPolicy::PRIORITY_LAST_COME_FIRST; + } + else { + return RBAArbitrationPolicy::DEFAULT; + } +} + +RBAContentLoserType +RBAJsonElementString::getLoserType() const +{ + if(str_ == "GOOD_LOSER") { + return RBAContentLoserType::GOOD_LOSER; + } + else if(str_ == "DO_NOT_GIVEUP_UNTIL_WIN") { + return RBAContentLoserType::DO_NOT_GIVEUP_UNTIL_WIN; + } + else { + return RBAContentLoserType::NEVER_GIVEUP; + } +} + +#ifdef RBA_USE_LOG +RBAExpressionType +RBAJsonElementString::getExpressionType() const +{ + if(str_ == "VALUE") { + return RBAExpressionType::VALUE; + } + else if(str_ == "BOOLEAN") { + return RBAExpressionType::BOOLEAN; + } + else if(str_ == "AREA") { + return RBAExpressionType::AREA; + } + else if(str_ == "CONTENT") { + return RBAExpressionType::CONTENT; + } + else if(str_ == "SOUND") { + return RBAExpressionType::SOUND; + } + else if(str_ == "SET_OF_SOUND") { + return RBAExpressionType::SET_OF_SOUND; + } + else if(str_ == "SET_OF_AREA") { + return RBAExpressionType::SET_OF_AREA; + } + else if(str_ == "SET_OF_CONTENT") { + return RBAExpressionType::SET_OF_CONTENT; + } + else if(str_ == "SET_OF_ZONE") { + return RBAExpressionType::SET_OF_ZONE; + } + else if(str_ == "SCENE") { + return RBAExpressionType::SCENE; + } + else if(str_ == "ZONE") { + return RBAExpressionType::ZONE; + } + else if(str_ == "ACTION") { + return RBAExpressionType::ACTION; + } + else if(str_ == "SET_OF_ACTION") { + return RBAExpressionType::SET_OF_ACTION; + } + else { + return RBAExpressionType::EXTENSION; + } +} +#endif + +const std::string& +RBAJsonElementString::getString() const +{ + return str_; +} + +void +RBAJsonElementString::setString(const std::string& str) +{ + str_ = str; +} + +// RBAJsonElementInt class + +RBAJsonElementInt::RBAJsonElementInt(const std::string& name) + : RBAJsonElement{} +{ + setName(name); +} + +std::int32_t +RBAJsonElementInt::getInt() const +{ + return val_; +} + +void +RBAJsonElementInt::setInt(const std::int32_t val) +{ + val_ = val; +} + +// RBAJsonElementArray class + +RBAJsonElementArray::RBAJsonElementArray(const std::string& name) + : RBAJsonElement{} +{ + setName(name); +} + +} diff --git a/src/factory/RBAJsonElement.hpp b/src/factory/RBAJsonElement.hpp new file mode 100644 index 0000000..a5fcc8e --- /dev/null +++ b/src/factory/RBAJsonElement.hpp @@ -0,0 +1,148 @@ +/** + * Copyright (c) 2019 DENSO CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/// @file RBAJsonElement.hpp +/// @brief JSON element class header file + +#ifndef RBAJSONELEMENT_HPP +#define RBAJSONELEMENT_HPP + +#include <cstdint> +#include <vector> +#include <memory> +#include <string> +#include "RBADllExport.hpp" + +namespace rba +{ + +enum class RBAArbitrationPolicy : std::uint8_t; +enum class RBAContentLoserType : std::uint8_t; +#ifdef RBA_USE_LOG +enum class RBAExpressionType : std::uint8_t; +#endif + +/// @brief JSONエ Element class +class DLL_EXPORT RBAJsonElement +{ +public: + RBAJsonElement()=default; + RBAJsonElement(const RBAJsonElement&)=delete; + RBAJsonElement(const RBAJsonElement&&)=delete; + RBAJsonElement& operator=(const RBAJsonElement&)=delete; + RBAJsonElement& operator=(const RBAJsonElement&&)=delete; + virtual ~RBAJsonElement()=default; + +public: + virtual const std::string& getString() const; + virtual std::int32_t getInt() const; + virtual RBAArbitrationPolicy getArbitrationPolicy() const; + virtual RBAContentLoserType getLoserType() const; +#ifdef RBA_USE_LOG + virtual RBAExpressionType getExpressionType() const; +#endif + + void setName(const std::string& name); + const std::string& getName() const; + void addChild(std::unique_ptr<RBAJsonElement> child); + const std::vector<std::unique_ptr<RBAJsonElement>>& getChildren() const; + RBAJsonElement* getChild() const; + const RBAJsonElement* findChildren(const std::string& name) const; + const std::string& getClassName() const; + +private: +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4251) +#endif + std::string name_ {""}; + std::vector<std::unique_ptr<RBAJsonElement>> children_; + static std::string emptyStr_; +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +}; + +class RBAJsonElementElement : public RBAJsonElement +{ +public: + explicit RBAJsonElementElement(const std::string& name); + RBAJsonElementElement(const RBAJsonElementElement&)=delete; + RBAJsonElementElement(const RBAJsonElementElement&&)=delete; + RBAJsonElementElement& operator=(const RBAJsonElementElement&)=delete; + RBAJsonElementElement& operator=(const RBAJsonElementElement&&)=delete; + virtual ~RBAJsonElementElement()=default; +}; + +class RBAJsonElementString : public RBAJsonElement +{ +public: + explicit RBAJsonElementString(const std::string& name); + RBAJsonElementString(const RBAJsonElementString&)=delete; + RBAJsonElementString(const RBAJsonElementString&&)=delete; + RBAJsonElementString& operator=(const RBAJsonElementString&)=delete; + RBAJsonElementString& operator=(const RBAJsonElementString&&)=delete; + virtual ~RBAJsonElementString()=default; + +public: + RBAArbitrationPolicy getArbitrationPolicy() const override; + RBAContentLoserType getLoserType() const override; +#ifdef RBA_USE_LOG + RBAExpressionType getExpressionType() const override; +#endif + + const std::string& getString() const override; + void setString(const std::string& str); + +private: + std::string str_ {""}; + +}; + +class RBAJsonElementInt : public RBAJsonElement +{ +public: + explicit RBAJsonElementInt(const std::string& name); + RBAJsonElementInt(const RBAJsonElementInt&)=delete; + RBAJsonElementInt(const RBAJsonElementInt&&)=delete; + RBAJsonElementInt& operator=(const RBAJsonElementInt&)=delete; + RBAJsonElementInt& operator=(const RBAJsonElementInt&&)=delete; + virtual ~RBAJsonElementInt()=default; + +public: + std::int32_t getInt() const override; + void setInt(const std::int32_t val); + +private: + std::int32_t val_ {0}; + +}; + +class RBAJsonElementArray : public RBAJsonElement +{ +public: + explicit RBAJsonElementArray(const std::string& name); + RBAJsonElementArray(const RBAJsonElementArray&)=delete; + RBAJsonElementArray(const RBAJsonElementArray&&)=delete; + RBAJsonElementArray& operator=(const RBAJsonElementArray&)=delete; + RBAJsonElementArray& operator=(const RBAJsonElementArray&&)=delete; + virtual ~RBAJsonElementArray()=default; +}; + +} + +#endif diff --git a/src/factory/RBAJsonParser.cpp b/src/factory/RBAJsonParser.cpp new file mode 100644 index 0000000..e0846a5 --- /dev/null +++ b/src/factory/RBAJsonParser.cpp @@ -0,0 +1,48 @@ +/** + * Copyright (c) 2019 DENSO CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/// @file RBAJsonParser.cpp +/// @brief JSON Parser class deginition file + +#include "RBAJsonParser.hpp" +#include "RBAJsonParserImpl.hpp" +#include "RBAExpression.hpp" +#include "RBAModelFactory.hpp" + +namespace rba +{ + +RBAJsonParser::RBAJsonParser() + : impl_{std::make_unique<RBAJsonParser::Impl>()} +{ +}; + +RBAJsonParser::RBAJsonParser(RBAModelFactory* factory) + : impl_{std::make_unique<RBAJsonParser::Impl>(factory)} +{ +}; + +RBAJsonParser::~RBAJsonParser() noexcept +{ +}; + +RBAModel* +RBAJsonParser::parse(const std::string& filename) +{ + return impl_->parse(filename); +} + +} diff --git a/src/factory/RBAJsonParserImpl.cpp b/src/factory/RBAJsonParserImpl.cpp new file mode 100644 index 0000000..db65367 --- /dev/null +++ b/src/factory/RBAJsonParserImpl.cpp @@ -0,0 +1,315 @@ +/** + * Copyright (c) 2019 DENSO CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/// @file RBAJsonParserImpl.cpp +/// @brief JSON Parser implment class defintion file + +#include <fstream> +#include <sstream> +#include <iostream> +#include "RBAJsonParserImpl.hpp" + +#include "RBACommonMakerTable.hpp" +#include "RBAConstraintMap.hpp" +#include "RBAJsonElement.hpp" +#include "RBAModelImpl.hpp" +#include "RBASoundMakerTable.hpp" +#include "RBAViewMakerTable.hpp" + +namespace rba +{ + +RBAJsonParser::Impl:: +Impl(RBAModelFactory* const factory) + : orgFactory_{factory}, + factory_{nullptr} +{ +} + +RBAModel* +RBAJsonParser::Impl:: +parse(const std::string& filename) +{ + const std::unique_ptr<RBAJsonElement> root {readJsonFile(filename)}; + if(root == nullptr) { + return nullptr; + } + + const std::lock_guard<std::mutex> lock{mutex_}; + + if(orgFactory_ != nullptr) { + factory_ = orgFactory_; + } + else { + uniqueFactory_ = std::make_unique<RBAModelFactory>(); + factory_ = uniqueFactory_.get(); + } + resetFactory(); + + // get registered tag element + for(const auto& tag : factory_->getTags()) { + const RBAJsonElement* const jsonElems {root->findChildren(tag)}; + if(jsonElems != nullptr) { + for(const auto& elem : jsonElems->getChildren()) { + // Generate Model element + const RBAModelElement* const modelElem {factory_->createElement(tag, elem.get())}; + if(modelElem == nullptr) { + factory_->deleteModel(); + return nullptr; + } + } + } + } + + // Error if there is an exception in Factory + if(factory_->isException()) { + factory_->deleteModel(); + return nullptr; + } + + // Create map between Area and Costraint + createConstraintMap(root->findChildren("area_constraint_map"), + RBAConstraintMap::CONTENT_ALLOCATE_CONSTRAINTS); + createConstraintMap(root->findChildren("area_hidden_true_check_constraint_map"), + RBAConstraintMap::HIDDEN_TRUE_CHECK_CONSTRAINTS); + createConstraintMap(root->findChildren("area_hidden_false_check_constraint_map"), + RBAConstraintMap::HIDDEN_FALSE_CHECK_CONSTRAINTS); + + // Create map between Zone and Costraint + createConstraintMap(root->findChildren("zone_constraint_map"), + RBAConstraintMap::CONTENT_ALLOCATE_CONSTRAINTS); + createConstraintMap(root->findChildren("zone_mute_true_check_constraint_map"), + RBAConstraintMap::HIDDEN_TRUE_CHECK_CONSTRAINTS); + createConstraintMap(root->findChildren("zone_mute_false_check_constraint_map"), + RBAConstraintMap::HIDDEN_FALSE_CHECK_CONSTRAINTS); + createConstraintMap(root->findChildren("zone_attenuate_true_check_constraint_map"), + RBAConstraintMap::ATTENUATE_TRUE_CHECK_CONSTRAINTS); + createConstraintMap(root->findChildren("zone_attenuate_false_check_constraint_map"), + RBAConstraintMap::ATTENUATE_FALSE_CHECK_CONSTRAINTS); + + // Create Allocatable Maps that affect +// createAllocatablesMap(root->findChildren("content_allocatables_map")); +// createAllocatablesMap(root->findChildren("scene_allocatables_map")); +// createAllocatablesMap(root->findChildren("statemachine_allocatables_map")); + + // Error if there is no contents + if((factory_->getModel()->getViewContents().size() == 0U) && + (factory_->getModel()->getSoundContents().size() == 0U)) { + std::cerr << filename << ": ViewContent or SoundContent not found" + << &std::endl; + factory_->deleteModel(); + return nullptr; + } + + return factory_->getModel(); +} + +void +RBAJsonParser::Impl::createConstraintMap(const RBAJsonElement* const constraints, + const RBAConstraintMap& kind) +{ + if (constraints != nullptr) { + for (const auto& constraint : constraints->getChildren()) { + const RBAJsonElement* const elem {constraint->getChildren().front().get()}; + const std::string& allocatableName {elem->getName()}; + for (auto& e : elem->getChildren()) { + factory_->setAllocatableConstraint(allocatableName, e->getName(), kind); + } + } + } +} + +void +RBAJsonParser::Impl::createAllocatablesMap(const RBAJsonElement* const allocMap) +{ + if (allocMap != nullptr) { + RBAModelImpl* const model {dynamic_cast<RBAModelImpl*>(factory_->getModel())}; + for (auto& elem : allocMap->getChildren()) { + // Get the object which influence + const auto owner = elem->getChild(); + const auto ownerObj = model->findModelElementImpl(owner->getName()); + + for (auto& alloc : owner->getChildren()) { + // Get the object which is affected + const auto allocObj = model->findAllocatable(alloc->getName()); + + // Add to map + model->addAffectedAllocsMap(ownerObj, const_cast<RBAAllocatable*>(allocObj)); + } + } + } +} + +std::unique_ptr<RBAJsonElement> +RBAJsonParser::Impl::readJsonFile(const std::string& filename) +{ + std::ifstream ifs{filename}; + if(ifs.fail()) { + std::cerr << filename << ": No such file or directory" << &std::endl; + return nullptr; + } + + std::ostringstream oss; + std::string line; + while(!ifs.eof()) { + ifs >> line; + oss << line; + } + + return readJsonString(oss.str()); +} + +std::unique_ptr<RBAJsonElement> +RBAJsonParser::Impl::readJsonString(const std::string& jsonstring) +{ + std::vector<RBAJsonElement*> queue; + RBAJsonElement* current{nullptr}; + std::unique_ptr<RBAJsonElement> topElement{nullptr}; + Status status{Status::START}; + const std::size_t jsonSize{jsonstring.size()}; + std::size_t tokenPos{0U}; + std::size_t tokenSize{0U}; + std::size_t strPos{0U}; + std::size_t strSize{0U}; + + while (tokenPos < jsonSize) { + auto firstChar = jsonstring[tokenPos]; + if(firstChar == '\"') { + // String + tokenSize = jsonstring.find('\"', tokenPos + 1U) - tokenPos + 1U; + switch(status) { + case Status::START: + strPos = tokenPos + 1U; + strSize = tokenSize - 2U; + break; + case Status::VALUE: + auto elem = std::make_unique<RBAJsonElementString>(jsonstring.substr(strPos, strSize)); + elem->setString(jsonstring.substr(tokenPos + 1U, tokenSize - 2U)); + current->addChild(std::move(elem)); + strSize = 0U; + status = Status::START; + break; + } + } + else if(firstChar == ':') { + // Value mode + tokenSize = 1U; + status = Status::VALUE; + } + else if(firstChar == ',') { + tokenSize = 1U; + if(strSize > 0U) { + current->addChild(std::make_unique<RBAJsonElementString>(jsonstring.substr(strPos, strSize))); + strSize = 0U; + status = Status::START; + } + } + else if(firstChar == '{') { + // Start Element + tokenSize = 1U; + if(status == Status::START) { + if(current != nullptr) { + auto elem = std::make_unique<RBAJsonElementElement>(jsonstring.substr(strPos, strSize)); + auto elemPtr = elem.get(); + current->addChild(std::move(elem)); + current = elemPtr; + queue.push_back(current); + strSize = 0U; + } + } else { + // status is Status::VALUE + auto elem = std::make_unique<RBAJsonElementElement>(jsonstring.substr(strPos, strSize)); + auto elemPtr = elem.get(); + if(current != nullptr) { + current->addChild(std::move(elem)); + } else { + topElement = std::move(elem); + } + current = elemPtr; + queue.push_back(current); + strSize = 0U; + status = Status::START; + } + } + else if(firstChar == '}') { + // End Element + tokenSize = 1U; + if (!queue.empty()) { + queue.pop_back(); + } + current = queue.empty() ? nullptr : queue.back(); + } + else if(firstChar == '[') { + // Satrt array + tokenSize = 1U; + auto elem = std::make_unique<RBAJsonElementArray>(jsonstring.substr(strPos, strSize)); + auto elemPtr = elem.get(); + current->addChild(std::move(elem)); + current = elemPtr; + queue.push_back(current); + strSize = 0U; + status = Status::START; + } + else if(firstChar == ']') { + // End array + tokenSize = 1U; + if(strSize > 0U) { + current->addChild(std::make_unique<RBAJsonElementString>(jsonstring.substr(strPos, strSize))); + strSize = 0U; + status = Status::START; + } + queue.pop_back(); + current = queue.empty() ? nullptr : queue.back(); + } + else if((firstChar == '-') || isdigit(firstChar)) { + // Numerical value + tokenSize = jsonstring.find_first_of(",}]", tokenPos + 1U) - tokenPos; + auto elem = std::make_unique<RBAJsonElementInt>(jsonstring.substr(strPos, strSize)); + elem->setInt(std::stoi(jsonstring.substr(tokenPos, tokenSize))); + current->addChild(std::move(elem)); + strSize = 0U; + status = Status::START; + } + else if((static_cast<std::int32_t>(firstChar) <= 0x20)) { + // skip + tokenSize = 1U; + } + else { + tokenSize = 1U; + std::cerr << "[ERROR] '" << jsonstring.substr(tokenPos, tokenSize) + << "' :Unknown token" << &std::endl; + } + tokenPos += tokenSize; + } + + return topElement; +} + +void +RBAJsonParser::Impl::resetFactory() +{ + // Set if Maker is not registered + if(!factory_->hasMaker()) { + // Models such as area and zone should be registered first. + factory_->addMakerTable(RBAViewMakerTable()); + factory_->addMakerTable(RBASoundMakerTable()); + factory_->addMakerTable(RBACommonMakerTable()); + } + + factory_->resetException(); +} + +} diff --git a/src/factory/RBAJsonParserImpl.hpp b/src/factory/RBAJsonParserImpl.hpp new file mode 100644 index 0000000..533f894 --- /dev/null +++ b/src/factory/RBAJsonParserImpl.hpp @@ -0,0 +1,70 @@ +/** + * Copyright (c) 2019 DENSO CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/// @file RBAJsonParserImpl.hpp +/// @brief JSON Parser implementation class header file + +#ifndef RBAJSONPARSERIMPL_HPP +#define RBAJSONPARSERIMPL_HPP + +#include <mutex> +#include "RBAJsonParser.hpp" +#include "RBAModelFactory.hpp" + +namespace rba +{ + +class RBAJsonElement; +enum class RBAConstraintMap : std::uint8_t; + +/// @brief JSON Parser implementation class +class RBAJsonParser::Impl +{ +public: + Impl(RBAModelFactory* const factory=nullptr); + Impl(const Impl&)=delete; + Impl(const Impl&&)=delete; + Impl& operator=(const Impl&)=delete; + Impl& operator=(const Impl&&)=delete; + virtual ~Impl()=default; + +public: + RBAModel* parse(const std::string& filename); + +private: + virtual void resetFactory(); + +private: + void createConstraintMap(const RBAJsonElement* const constraints, + const RBAConstraintMap& kind); + void createAllocatablesMap(const RBAJsonElement* const allocMap); + std::unique_ptr<RBAJsonElement> readJsonFile(const std::string& filename); + std::unique_ptr<RBAJsonElement> readJsonString(const std::string& jsonstring); + +private: + enum class Status : std::uint8_t { + START, + VALUE, + }; + RBAModelFactory* orgFactory_; + RBAModelFactory* factory_; + std::unique_ptr<RBAModelFactory> uniqueFactory_; + std::mutex mutex_; +}; + +} + +#endif diff --git a/src/factory/RBAModelFactory.cpp b/src/factory/RBAModelFactory.cpp new file mode 100644 index 0000000..28c42e0 --- /dev/null +++ b/src/factory/RBAModelFactory.cpp @@ -0,0 +1,201 @@ +/** + * Copyright (c) 2019 DENSO CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/// @file RBAModelFactory.cpp +/// @brief Model Factory class definition file + +#include <algorithm> +#include "RBAModelFactory.hpp" +#include "RBAModelImpl.hpp" +#include "RBAJsonElement.hpp" +#include "RBAAbstractMakerTable.hpp" +#include "RBAConstraintImpl.hpp" + +namespace rba +{ + +RBAModelFactory::RBAModelFactory(RBAModelImpl* const model) + : model_{nullptr}, + exception_{false} +{ + if(model != nullptr) { + model_ = model; + } + else { + // @Deviation (A18-5-2) + // [Contents that deviate from the rules] + // Operators new and delete shall not be called explicitly. + // [Explain that it is okay to deviate from the rules] + // model_ is not owned by RBAModelFacotry. + // Therefore, it is not managed by the smart pointer. + // There is no problem because it is managed by + // the user side of RBAModelFactory. + model_ = new RBAModelImpl(); + } +} + +RBAModelFactory::~RBAModelFactory() noexcept +{ +} + +RBAModel* const +RBAModelFactory::getModel() const +{ + return model_; +} + +void +RBAModelFactory::deleteModel() +{ + // @Deviation (A18-5-2) + // [Contents that deviate from the rules] + // Operators new and delete shall not be called explicitly. + // [Explain that it is okay to deviate from the rules] + // Since it is managed by the user side of RBAModelFactory, + // there is no problem even if it is deleted from the outside. + delete model_; + model_ = nullptr; +} + +void +RBAModelFactory::addMakerTable(const RBAAbstractMakerTable& makerTable) +{ + for(auto& maker : makerTable.getMakers()) { + maker->setFactory(this); + const std::string label {maker->getLabel()}; + nameToMaker_[label] = maker.get(); + makers_.push_back(std::move(maker)); + } + for(auto& tag : makerTable.getTags()) { + if (std::find(tags_.begin(), tags_.end(), tag) == tags_.end()) { + tags_.push_back(tag); + } + } +} + +void +RBAModelFactory::addMaker(const std::string label, + std::unique_ptr<RBAModelElementMaker> maker) +{ + maker->setFactory(this); + nameToMaker_[label] = maker.get(); + makers_.push_back(std::move(maker)); +} + +bool +RBAModelFactory::hasMaker() const +{ + return !nameToMaker_.empty(); +} + +const std::list<std::string>& +RBAModelFactory::getTags() const +{ + return tags_; +} + +RBAModelElement* +RBAModelFactory::createElement(const std::string& className, + const RBAJsonElement* const jsonElement, + RBAModelElement* const owner) +{ + auto it = nameToMaker_.find(className); + if(it == nameToMaker_.end()) { + const RBAJsonElement* const classElement {jsonElement->findChildren("class")}; + if(classElement != nullptr) { + it = nameToMaker_.find(classElement->getString()); + if(it == nameToMaker_.end()) { + return nullptr; + } + } + else { + return nullptr; + } + } + + return it->second->create(jsonElement, model_, owner); +} + +void +RBAModelFactory::setAllocatableConstraint(const std::string& allocatableName, + const std::string& constraintName, + const RBAConstraintMap& kind) +{ + // Get allocatable + RBAAllocatable* const allocatable + {const_cast<RBAAllocatable*>(model_->findAllocatable(allocatableName))}; + // Get constraint + RBAConstraintImpl* const constraint {model_->findConstraintImpl(constraintName)}; + if ((allocatable != nullptr) && (constraint != nullptr)) { + allocatable->addConstraint(constraint, kind); + } +} + +// Variable can be defined with the same name in different scopes, +// but here we are registering the Variable defined in the scope +// that is being created +void +RBAModelFactory::pushVariable(const RBAVariable* const var) +{ + currentVariables_.push_back(var); +} + +// Variables can be defined with the same name in different scopes, +// but when you leave the scope with a definition, Variable is deleted. +void +RBAModelFactory::popVariable() +{ + if(!currentVariables_.empty()) { + currentVariables_.pop_back(); + } +} + +const RBAVariable* +RBAModelFactory::getVariable(const std::string& varName) +{ + const auto itr = + std::find_if(currentVariables_.rbegin(), currentVariables_.rend(), + [&varName](const RBAVariable* element) -> bool { + return element->getElementName() == varName; + }); + + if (itr != currentVariables_.rend()) + { + return *itr; + } + + return nullptr; +} + +void +RBAModelFactory::resetException() +{ + exception_ = false; +} + +void +RBAModelFactory::setException() +{ + exception_ = true; +} + +bool +RBAModelFactory::isException() const +{ + return exception_; +} + +} diff --git a/src/factory/RBAModelFactory.hpp b/src/factory/RBAModelFactory.hpp new file mode 100644 index 0000000..9250f92 --- /dev/null +++ b/src/factory/RBAModelFactory.hpp @@ -0,0 +1,101 @@ +/** + * Copyright (c) 2019 DENSO CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +/// @file RBAModelFactory.hpp +/// @brief Model Factory class header file + +#ifndef RBAMODELFACTORY_HPP +#define RBAMODELFACTORY_HPP + +#include <string> +#include <list> +#include <memory> +#include <unordered_map> +#include "RBADllExport.hpp" + +namespace rba +{ + +class RBAModel; +class RBAModelImpl; +class RBAJsonElement; +class RBAModelElement; +class RBAVariable; +class RBAAbstractMakerTable; +class RBAModelElementMaker; +enum class RBAConstraintMap : std::uint8_t; + +/// @brief Model Factory class +class DLL_EXPORT RBAModelFactory +{ +public: + RBAModelFactory(RBAModelImpl* const model=nullptr); + RBAModelFactory(const RBAModelFactory&)=delete; + RBAModelFactory(const RBAModelFactory&&)=delete; + RBAModelFactory& operator=(const RBAModelFactory&)=delete; + RBAModelFactory& operator=(const RBAModelFactory&&)=delete; + virtual ~RBAModelFactory() noexcept; + + public: + RBAModel* const getModel() const; + void deleteModel(); + void addMakerTable(const RBAAbstractMakerTable& makerTable); + void addMaker(const std::string label, + std::unique_ptr<RBAModelElementMaker> maker); + bool hasMaker() const; + const std::list<std::string>& getTags() const; + + RBAModelElement* createElement(const std::string& className, + const RBAJsonElement* const jsonElement, + RBAModelElement* const owner=nullptr); + + void setAllocatableConstraint(const std::string& allocatableName, + const std::string& constraintName, + const RBAConstraintMap& kind); + + void pushVariable(const RBAVariable* const var); + void popVariable(); + const RBAVariable* getVariable(const std::string& varName); + + void resetException(); + void setException(); + bool isException() const; + +private: + RBAModelImpl* model_; + bool exception_; + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4251) +#endif + std::unordered_map<std::string, RBAModelElementMaker*> nameToMaker_; + // unique_ptr list for storing + std::list<std::unique_ptr<RBAModelElementMaker>> makers_; + // current variable for working + std::list<const RBAVariable*> currentVariables_; + // JSON element tag list, set from the registered MakerTable + std::list<std::string> tags_; +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +}; + +} + +#endif |