diff --git a/src/OMSimulatorLib/Component.h b/src/OMSimulatorLib/Component.h index a65cced0e..1baec43df 100644 --- a/src/OMSimulatorLib/Component.h +++ b/src/OMSimulatorLib/Component.h @@ -40,6 +40,7 @@ #include "Logging.h" #include "ResultWriter.h" #include "SignalDerivative.h" +#include "Snapshot.h" #include "Types.h" #include #include @@ -84,7 +85,7 @@ namespace oms oms_status_enu_t addConnectorToTLMBus(const ComRef& busCref, const ComRef& connectorCref, const std::string type); oms_status_enu_t deleteConnectorFromTLMBus(const ComRef& busCref, const ComRef& connectorCref); - virtual oms_status_enu_t exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode) const = 0; + virtual oms_status_enu_t exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode, Snapshot& snapshot) const = 0; virtual oms_status_enu_t exportToSSVTemplate(pugi::xml_node& ssvNode) {return logError_NotImplemented;} virtual oms_status_enu_t exportToSSMTemplate(pugi::xml_node& ssmNode) {return logError_NotImplemented;} virtual oms_status_enu_t instantiate() = 0; diff --git a/src/OMSimulatorLib/ComponentFMUCS.cpp b/src/OMSimulatorLib/ComponentFMUCS.cpp index 9771a0385..ff785ba67 100644 --- a/src/OMSimulatorLib/ComponentFMUCS.cpp +++ b/src/OMSimulatorLib/ComponentFMUCS.cpp @@ -313,7 +313,7 @@ oms::Component* oms::ComponentFMUCS::NewComponent(const pugi::xml_node& node, om return component; } -oms_status_enu_t oms::ComponentFMUCS::exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode) const +oms_status_enu_t oms::ComponentFMUCS::exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode, Snapshot& snapshot) const { #if !defined(NO_TLM) if (tlmbusconnectors[0]) diff --git a/src/OMSimulatorLib/ComponentFMUCS.h b/src/OMSimulatorLib/ComponentFMUCS.h index 3f0a44f4a..f8d504314 100644 --- a/src/OMSimulatorLib/ComponentFMUCS.h +++ b/src/OMSimulatorLib/ComponentFMUCS.h @@ -59,7 +59,7 @@ namespace oms static Component* NewComponent(const pugi::xml_node& node, System* parentSystem, const std::string& sspVersion, const Snapshot& snapshot); const FMUInfo* getFMUInfo() const {return &(this->fmuInfo);} - oms_status_enu_t exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode) const; + oms_status_enu_t exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode, Snapshot& snapshot) const; oms_status_enu_t exportToSSVTemplate(pugi::xml_node& ssvNode); oms_status_enu_t exportToSSMTemplate(pugi::xml_node& ssmNode); oms_status_enu_t instantiate(); diff --git a/src/OMSimulatorLib/ComponentFMUME.cpp b/src/OMSimulatorLib/ComponentFMUME.cpp index be4eb9d54..b733b7ba5 100644 --- a/src/OMSimulatorLib/ComponentFMUME.cpp +++ b/src/OMSimulatorLib/ComponentFMUME.cpp @@ -315,7 +315,7 @@ oms::Component* oms::ComponentFMUME::NewComponent(const pugi::xml_node& node, om return component; } -oms_status_enu_t oms::ComponentFMUME::exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode) const +oms_status_enu_t oms::ComponentFMUME::exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode, Snapshot& snapshot) const { #if !defined(NO_TLM) if (tlmbusconnectors[0]) diff --git a/src/OMSimulatorLib/ComponentFMUME.h b/src/OMSimulatorLib/ComponentFMUME.h index bcc999401..55fe9d580 100644 --- a/src/OMSimulatorLib/ComponentFMUME.h +++ b/src/OMSimulatorLib/ComponentFMUME.h @@ -57,7 +57,7 @@ namespace oms static Component* NewComponent(const pugi::xml_node& node, System* parentSystem, const std::string& sspVersion, const Snapshot& snapshot); const FMUInfo* getFMUInfo() const {return &(this->fmuInfo);} - oms_status_enu_t exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode) const; + oms_status_enu_t exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode, Snapshot& snapshot) const; oms_status_enu_t exportToSSVTemplate(pugi::xml_node& ssvNode); oms_status_enu_t exportToSSMTemplate(pugi::xml_node& ssmNode); oms_status_enu_t instantiate(); diff --git a/src/OMSimulatorLib/ComponentTable.cpp b/src/OMSimulatorLib/ComponentTable.cpp index d688b2d98..b9f3c8a87 100644 --- a/src/OMSimulatorLib/ComponentTable.cpp +++ b/src/OMSimulatorLib/ComponentTable.cpp @@ -161,7 +161,7 @@ oms::Component* oms::ComponentTable::NewComponent(const pugi::xml_node& node, om return component; } -oms_status_enu_t oms::ComponentTable::exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode) const +oms_status_enu_t oms::ComponentTable::exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode, Snapshot& snapshot) const { node.append_attribute("name") = this->getCref().c_str(); node.append_attribute("type") = "application/table"; diff --git a/src/OMSimulatorLib/ComponentTable.h b/src/OMSimulatorLib/ComponentTable.h index 8a858c8f8..e0346cece 100644 --- a/src/OMSimulatorLib/ComponentTable.h +++ b/src/OMSimulatorLib/ComponentTable.h @@ -55,7 +55,7 @@ namespace oms static Component* NewComponent(const oms::ComRef& cref, System* parentSystem, const std::string& path); static Component* NewComponent(const pugi::xml_node& node, System* parentSystem, const std::string& sspVersion, const Snapshot& snapshot); - oms_status_enu_t exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode) const; + oms_status_enu_t exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode, Snapshot& snapshot) const; oms_status_enu_t exportToSSVTemplate(pugi::xml_node& ssvNode) {return oms_status_ok;} oms_status_enu_t exportToSSMTemplate(pugi::xml_node& ssmNode) {return oms_status_ok;} oms_status_enu_t instantiate(); diff --git a/src/OMSimulatorLib/Model.cpp b/src/OMSimulatorLib/Model.cpp index 3c11b698c..4d0070913 100644 --- a/src/OMSimulatorLib/Model.cpp +++ b/src/OMSimulatorLib/Model.cpp @@ -286,6 +286,7 @@ oms_status_enu_t oms::Model::list(const oms::ComRef& cref, char** contents) pugi::xml_document doc; pugi::xml_document ssvdoc; + Snapshot snapshot; // check for toplevelSystem or Model to update parameterbindings in ssd bool isTopSystemOrModel = false; @@ -304,7 +305,7 @@ oms_status_enu_t oms::Model::list(const oms::ComRef& cref, char** contents) { isTopSystemOrModel = true; pugi::xml_node node = doc.append_child(oms::ssp::Draft20180219::ssd::system_structure_description); - exportToSSD(node, node_parameters); + exportToSSD(node, node_parameters, snapshot); // update parameterBindings in ssd pugi::xml_node system_node = node.child(oms::ssp::Draft20180219::ssd::system); updateParameterBindingsToSSD(system_node, node_parameters, isTopSystemOrModel); @@ -323,7 +324,7 @@ oms_status_enu_t oms::Model::list(const oms::ComRef& cref, char** contents) if (subsystem) { pugi::xml_node node = doc.append_child(oms::ssp::Draft20180219::ssd::system); - subsystem->exportToSSD(node, node_parameters); + subsystem->exportToSSD(node, node_parameters, snapshot); // update parameterBindings in ssd updateParameterBindingsToSSD(node, node_parameters, isTopSystemOrModel); } @@ -335,7 +336,7 @@ oms_status_enu_t oms::Model::list(const oms::ComRef& cref, char** contents) return logError("error"); pugi::xml_node node = doc.append_child(oms::ssp::Draft20180219::ssd::system); - component->exportToSSD(node, node_parameters); + component->exportToSSD(node, node_parameters, snapshot); } } @@ -359,64 +360,25 @@ oms_status_enu_t oms::Model::exportSnapshot(const oms::ComRef& cref, char** cont return logError("\"" + std::string(getCref()+std::string(cref)) + "\" is not a top level model"); } - struct xmlStringWriter : pugi::xml_writer - { - std::string result; - virtual void write(const void* data, size_t size) - { - result += std::string(static_cast(data), size); - } - }; + Snapshot snapshot; - xmlStringWriter writer; - pugi::xml_document doc; - pugi::xml_document ssvdoc; + pugi::xml_node oms_ssd = snapshot.newResourceNode("SystemStructure.ssd"); + pugi::xml_node ssdNode = oms_ssd.append_child(oms::ssp::Draft20180219::ssd::system_structure_description); - // generate XML declaration for ssv file - pugi::xml_node ssvDeclarationNode = ssvdoc.append_child(pugi::node_declaration); - ssvDeclarationNode.append_attribute("version") = "1.0"; - ssvDeclarationNode.append_attribute("encoding") = "UTF-8"; + pugi::xml_node ssvNode = snapshot.getTemplateResourceNodeSSV("resources/" + std::string(this->getCref()) + ".ssv"); - pugi::xml_node node_parameterset = ssvdoc.append_child(oms::ssp::Version1_0::ssv::parameter_set); - node_parameterset.append_attribute("xmlns:ssc") = "http://ssp-standard.org/SSP1/SystemStructureCommon"; - node_parameterset.append_attribute("xmlns:ssv") = "http://ssp-standard.org/SSP1/SystemStructureParameterValues"; - node_parameterset.append_attribute("version") = "1.0"; - node_parameterset.append_attribute("name") = "parameters"; - pugi::xml_node node_parameters = node_parameterset.append_child(oms::ssp::Version1_0::ssv::parameters); - - // list model - pugi::xml_node snapshotnode = doc.append_child(oms::ssp::Version1_0::snap_shot); - pugi::xml_node ssdfilenode = snapshotnode.append_child(oms::ssp::Version1_0::oms_file); - ssdfilenode.append_attribute("name") = "SystemStructure.ssd"; - - pugi::xml_node node = ssdfilenode.append_child(oms::ssp::Draft20180219::ssd::system_structure_description); - exportToSSD(node, node_parameters); + exportToSSD(ssdNode, ssvNode, snapshot); // update ssv file if exist if (!Flags::ExportParametersInline()) { // update parameterBindings in ssd - pugi::xml_node system_node = node.child(oms::ssp::Draft20180219::ssd::system); - updateParameterBindingsToSSD(system_node, node_parameters, true); - - // update after - pugi::xml_node last = doc.last_child(); - pugi::xml_node ssvfilenode = last.append_child(oms::ssp::Version1_0::oms_file); - std::string ssvFilePath = "resources/" + std::string(this->getCref()) + ".ssv"; - ssvfilenode.append_attribute("name") = ssvFilePath.c_str(); - // dump all the ssv file contents - ssvfilenode.append_copy(node_parameterset); + pugi::xml_node system_node = ssdNode.child(oms::ssp::Draft20180219::ssd::system); + updateParameterBindingsToSSD(system_node, ssvNode, true); // TODO ssm file } - doc.save(writer); - *contents = (char*) malloc(strlen(writer.result.c_str()) + 1); - if (!*contents) - { - logError("Out of memory"); - return oms_status_fatal; - } - strcpy(*contents, writer.result.c_str()); + snapshot.writeDocument(contents); return oms_status_ok; } @@ -567,7 +529,7 @@ oms_status_enu_t oms::Model::addSystem(const oms::ComRef& cref, oms_system_enu_t return logError("wrong input \"" + std::string(front) + "\" != \"" + std::string(system->getCref()) + "\""); } -oms_status_enu_t oms::Model::exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode) const +oms_status_enu_t oms::Model::exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode, Snapshot& snapshot) const { node.append_attribute("xmlns:ssc") = "http://ssp-standard.org/SSP1/SystemStructureCommon"; node.append_attribute("xmlns:ssd") = "http://ssp-standard.org/SSP1/SystemStructureDescription"; @@ -582,7 +544,7 @@ oms_status_enu_t oms::Model::exportToSSD(pugi::xml_node& node, pugi::xml_node& s if (system) { pugi::xml_node system_node = node.append_child(oms::ssp::Draft20180219::ssd::system); - if (oms_status_ok != system->exportToSSD(system_node, ssvNode)) + if (oms_status_ok != system->exportToSSD(system_node, ssvNode, snapshot)) return logError("export of system failed"); } @@ -765,6 +727,8 @@ oms_status_enu_t oms::Model::exportToFile(const std::string& filename) const pugi::xml_document doc; pugi::xml_document ssvdoc; + Snapshot snapshot; + std::string extension = ""; if (filename.length() > 4) extension = filename.substr(filename.length() - 4); @@ -792,7 +756,7 @@ oms_status_enu_t oms::Model::exportToFile(const std::string& filename) const node_parameterset.append_attribute("name") = "parameters"; pugi::xml_node node_parameters = node_parameterset.append_child(oms::ssp::Version1_0::ssv::parameters); - exportToSSD(node, node_parameters); + exportToSSD(node, node_parameters, snapshot); filesystem::path ssdPath = filesystem::path(tempDir) / "SystemStructure.ssd"; diff --git a/src/OMSimulatorLib/Model.h b/src/OMSimulatorLib/Model.h index 807543af0..829df51ba 100644 --- a/src/OMSimulatorLib/Model.h +++ b/src/OMSimulatorLib/Model.h @@ -72,7 +72,7 @@ namespace oms oms_status_enu_t rename(const ComRef& cref, const ComRef& newCref); oms_status_enu_t list(const ComRef& cref, char** contents); oms_status_enu_t addSystem(const ComRef& cref, oms_system_enu_t type); - oms_status_enu_t exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode) const; + oms_status_enu_t exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode, Snapshot& snapshot) const; oms_status_enu_t exportSnapshot(const ComRef& cref, char** contents); oms_status_enu_t exportSSVTemplate(const ComRef& cref, const std::string& filename); oms_status_enu_t exportSSMTemplate(const ComRef& cref, const std::string& filename); diff --git a/src/OMSimulatorLib/Snapshot.cpp b/src/OMSimulatorLib/Snapshot.cpp index 433f0f654..7225cfe88 100644 --- a/src/OMSimulatorLib/Snapshot.cpp +++ b/src/OMSimulatorLib/Snapshot.cpp @@ -144,3 +144,56 @@ void oms::Snapshot::debugPrintAll() const { doc.save(std::cout, " "); } + +pugi::xml_node oms::Snapshot::getTemplateResourceNodeSSD(const filesystem::path& filename) +{ + pugi::xml_node new_node = newResourceNode(filename); + new_node.append_attribute("xmlns:ssc") = "http://ssp-standard.org/SSP1/SystemStructureCommon"; + new_node.append_attribute("xmlns:ssd") = "http://ssp-standard.org/SSP1/SystemStructureDescription"; + new_node.append_attribute("xmlns:ssv") = "http://ssp-standard.org/SSP1/SystemStructureParameterValues"; + new_node.append_attribute("xmlns:ssm") = "http://ssp-standard.org/SSP1/SystemStructureParameterMapping"; + new_node.append_attribute("xmlns:ssb") = "http://ssp-standard.org/SSP1/SystemStructureSignalDictionary"; + new_node.append_attribute("xmlns:oms") = "https://raw.githubusercontent.com/OpenModelica/OMSimulator/master/schema/oms.xsd"; + // new_node.append_attribute("name") = this->getCref().c_str(); + new_node.append_attribute("version") = "1.0"; + + return new_node; +} + +pugi::xml_node oms::Snapshot::getTemplateResourceNodeSSV(const filesystem::path& filename) +{ + pugi::xml_node new_node = newResourceNode(filename); + pugi::xml_node node_parameterset = new_node.append_child(oms::ssp::Version1_0::ssv::parameter_set); + node_parameterset.append_attribute("xmlns:ssc") = "http://ssp-standard.org/SSP1/SystemStructureCommon"; + node_parameterset.append_attribute("xmlns:ssv") = "http://ssp-standard.org/SSP1/SystemStructureParameterValues"; + node_parameterset.append_attribute("version") = "1.0"; + node_parameterset.append_attribute("name") = "parameters"; + pugi::xml_node node_parameters = node_parameterset.append_child(oms::ssp::Version1_0::ssv::parameters); + + return node_parameters; +} + +oms_status_enu_t oms::Snapshot::writeDocument(char** contents) +{ + struct xmlStringWriter : pugi::xml_writer + { + std::string result; + virtual void write(const void *data, size_t size) + { + result += std::string(static_cast(data), size); + } + }; + + xmlStringWriter writer; + + doc.save(writer); + *contents = (char*) malloc(strlen(writer.result.c_str()) + 1); + if (!*contents) + { + logError("Out of memory"); + return oms_status_fatal; + } + strcpy(*contents, writer.result.c_str()); + + return oms_status_ok; +} \ No newline at end of file diff --git a/src/OMSimulatorLib/Snapshot.h b/src/OMSimulatorLib/Snapshot.h index af862d0b9..7f1aed5b7 100644 --- a/src/OMSimulatorLib/Snapshot.h +++ b/src/OMSimulatorLib/Snapshot.h @@ -59,9 +59,14 @@ namespace oms void getResources(std::vector& resources) const; pugi::xml_node getResourceNode(const filesystem::path& filename) const; + pugi::xml_node getTemplateResourceNodeSSD(const filesystem::path& filename); + pugi::xml_node getTemplateResourceNodeSSV(const filesystem::path& filename); + void debugPrintNode(const filesystem::path& filename) const; void debugPrintAll() const; + oms_status_enu_t writeDocument(char** contents); + private: // stop the compiler generating methods copying the object Snapshot(Snapshot const& copy); ///< not implemented diff --git a/src/OMSimulatorLib/System.cpp b/src/OMSimulatorLib/System.cpp index 46a5cd5ad..21edc3b5e 100644 --- a/src/OMSimulatorLib/System.cpp +++ b/src/OMSimulatorLib/System.cpp @@ -389,7 +389,7 @@ oms_status_enu_t oms::System::listUnconnectedConnectors(char** contents) const return oms_status_ok; } -oms_status_enu_t oms::System::exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode) const +oms_status_enu_t oms::System::exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode, Snapshot& snapshot) const { node.append_attribute("name") = this->getCref().c_str(); @@ -423,13 +423,13 @@ oms_status_enu_t oms::System::exportToSSD(pugi::xml_node& node, pugi::xml_node& for (const auto& subsystem : subsystems) { pugi::xml_node system_node = elements_node.append_child(oms::ssp::Draft20180219::ssd::system); - if (oms_status_ok != subsystem.second->exportToSSD(system_node, ssvNode)) + if (oms_status_ok != subsystem.second->exportToSSD(system_node, ssvNode, snapshot)) return logError("export of system failed"); } for (const auto& component : components) { pugi::xml_node component_node = elements_node.append_child(oms::ssp::Draft20180219::ssd::component); - if (oms_status_ok != component.second->exportToSSD(component_node, ssvNode)) + if (oms_status_ok != component.second->exportToSSD(component_node, ssvNode, snapshot)) return logError("export of component failed"); } } diff --git a/src/OMSimulatorLib/System.h b/src/OMSimulatorLib/System.h index 4fbee6ffc..9bfe2e4cc 100644 --- a/src/OMSimulatorLib/System.h +++ b/src/OMSimulatorLib/System.h @@ -84,7 +84,7 @@ namespace oms oms_status_enu_t addSubSystem(const ComRef& cref, oms_system_enu_t type); oms_status_enu_t addSubModel(const ComRef& cref, const std::string& fmuPath); bool validCref(const ComRef& cref); - oms_status_enu_t exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode) const; + oms_status_enu_t exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode, Snapshot& snapshot) const; oms_status_enu_t importFromSnapshot(const pugi::xml_node& node, const std::string& sspVersion, const Snapshot& snapshot); virtual oms_status_enu_t exportToSSD_SimulationInformation(pugi::xml_node& node) const = 0; virtual oms_status_enu_t importFromSSD_SimulationInformation(const pugi::xml_node& node, const std::string& sspVersion) = 0; diff --git a/src/OMSimulatorLib/TLM/ExternalModel.cpp b/src/OMSimulatorLib/TLM/ExternalModel.cpp index acef05563..4a14fdc0c 100644 --- a/src/OMSimulatorLib/TLM/ExternalModel.cpp +++ b/src/OMSimulatorLib/TLM/ExternalModel.cpp @@ -87,7 +87,7 @@ oms_status_enu_t oms::ExternalModel::getRealParameter(const std::string& var, do return oms_status_error; } -oms_status_enu_t oms::ExternalModel::exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode) const +oms_status_enu_t oms::ExternalModel::exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode, Snapshot& snapshot) const { pugi::xml_node annotations_node = node.append_child(oms::ssp::Draft20180219::ssd::annotations); pugi::xml_node annotation_node = annotations_node.append_child(oms::ssp::Version1_0::ssc::annotation); diff --git a/src/OMSimulatorLib/TLM/ExternalModel.h b/src/OMSimulatorLib/TLM/ExternalModel.h index 731bfd5b1..1dde4fe29 100644 --- a/src/OMSimulatorLib/TLM/ExternalModel.h +++ b/src/OMSimulatorLib/TLM/ExternalModel.h @@ -38,6 +38,7 @@ #include "ExternalModelInfo.h" #include "Option.h" #include "ResultWriter.h" +#include "Snapshot.h" #include "Types.h" #include "Variable.h" #include @@ -59,7 +60,7 @@ namespace oms const std::string getStartScript() const {return externalModelInfo.getStartScript();} const std::map>& getRealParameters() const {return realParameters;} - oms_status_enu_t exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode) const; + oms_status_enu_t exportToSSD(pugi::xml_node& node, pugi::xml_node& ssvNode, Snapshot& snapshot) const; oms_status_enu_t instantiate(); oms_status_enu_t initialize(); oms_status_enu_t terminate();