| helics 3.6.1

fileConnections.hpp
1 /*
2 Copyright (c) 2017-2025,
3 Battelle Memorial Institute; Lawrence Livermore National Security, LLC; Alliance for Sustainable
4 Energy, LLC. See the top-level NOTICE for additional details. All rights reserved.
5 SPDX-License-Identifier: BSD-3-Clause
6 */
7 #pragma once
8
9 #include "../common/JsonProcessingFunctions.hpp"
10 #include "../common/TomlProcessingFunctions.hpp"
11 #include "../common/addTargets.hpp"
12 #include "Broker.hpp"
13 #include "Core.hpp"
14 #include "core-exceptions.hpp"
15
16 #include <string>
17 #include <type_traits>
18
19 namespace helics::fileops {
20
21 template<class brkX>
22 void makeConnectionsToml(brkX* brk, const std::string& file)
23 {
24 toml::value uVal;
25 static_assert(std::is_base_of<Broker, brkX>::value || std::is_base_of<Core, brkX>::value,
26 "broker must be Core or broker");
27 toml::value doc;
28 try {
29 doc = loadToml(file);
30 }
31 catch (const std::invalid_argument& ia) {
32 throw(helics::InvalidParameter(ia.what()));
33 }
34
35 auto conns = toml::find_or(doc, "connections", uVal);
36 if (!conns.is_empty()) {
37 auto& connArray = conns.as_array();
38 for (const auto& conn : connArray) {
39 if (conn.is_array()) {
40 auto& connAct = conn.as_array();
41 brk->dataLink(connAct[0].as_string(), connAct[1].as_string());
42 } else {
43 std::string pub = getOrDefault(conn, "publication", std::string());
44 if (!pub.empty()) {
45 addTargets(conn, "targets", [brk, &pub](const std::string& target) {
46 brk->dataLink(pub, target);
47 });
48 } else {
49 std::string ipt = getOrDefault(conn, "input", std::string());
50 if (!ipt.empty()) {
51 addTargets(conn, "targets", [brk, &ipt](const std::string& target) {
52 brk->dataLink(target, ipt);
53 });
54 addTargets(conn, "sources", [brk, &ipt](const std::string& source) {
55 brk->dataLink(source, ipt);
56 });
57 } else {
58 std::string ept = getOrDefault(conn, "endpoint", std::string());
59 if (!ept.empty()) {
60 addTargets(conn, "targets", [brk, &ept](const std::string& target) {
61 brk->linkEndpoints(ept, target);
62 });
63 addTargets(conn, "sources", [brk, &ept](const std::string& source) {
64 brk->linkEndpoints(source, ept);
65 });
66 }
67 }
68 }
69 }
70 }
71 }
72 auto lnks = toml::find_or(doc, "links", uVal);
73 if (!lnks.is_empty()) {
74 auto& connArray = lnks.as_array();
75 for (const auto& conn : connArray) {
76 if (conn.is_array()) {
77 auto& connAct = conn.as_array();
78 brk->linkEndpoints(connAct[0].as_string(), connAct[1].as_string());
79 } else {
80 std::string pub = getOrDefault(conn, "publication", std::string());
81 if (!pub.empty()) {
82 addTargets(conn, "targets", [brk, &pub](const std::string& target) {
83 brk->dataLink(pub, target);
84 });
85 } else {
86 std::string ipt = getOrDefault(conn, "input", std::string());
87 if (!ipt.empty()) {
88 addTargets(conn, "targets", [brk, &ipt](const std::string& target) {
89 brk->dataLink(target, ipt);
90 });
91 addTargets(conn, "sources", [brk, &ipt](const std::string& source) {
92 brk->dataLink(source, ipt);
93 });
94 } else {
95 std::string ept = getOrDefault(conn, "endpoint", std::string());
96 if (!ept.empty()) {
97 addTargets(conn, "targets", [brk, &ept](const std::string& target) {
98 brk->linkEndpoints(ept, target);
99 });
100 addTargets(conn, "sources", [brk, &ept](const std::string& source) {
101 brk->linkEndpoints(source, ept);
102 });
103 }
104 }
105 }
106 }
107 }
108 }
109 auto filts = toml::find_or(doc, "filters", uVal);
110 if (!filts.is_empty()) {
111 auto& filtArray = filts.as_array();
112 for (const auto& filt : filtArray) {
113 if (filt.is_array()) {
114 auto& filtAct = filt.as_array();
115 brk->addSourceFilterToEndpoint(filtAct[0].as_string(), filtAct[1].as_string());
116 } else {
117 std::string fname = getOrDefault(filt, "filter", std::string());
118 if (!fname.empty()) {
119 auto asrc = [brk, &fname](const std::string& ept) {
120 brk->addSourceFilterToEndpoint(fname, ept);
121 };
122 addTargets(filt, "endpoints", asrc);
123 addTargets(filt, "source_endpoints", asrc);
124 addTargets(filt, "sourceEndpoints", asrc);
125 auto adst = [brk, &fname](const std::string& ept) {
126 brk->addDestinationFilterToEndpoint(fname, ept);
127 };
128 addTargets(filt, "dest_endpoints", adst);
129 addTargets(filt, "destEndpoints", adst);
130 }
131 }
132 }
133 }
134 auto globals = toml::find_or(doc, "globals", uVal);
135 if (!globals.is_empty()) {
136 if (globals.is_array()) {
137 for (auto& val : globals.as_array()) {
138 brk->setGlobal(val.as_array()[0].as_string(), val.as_array()[1].as_string());
139 }
140 } else {
141 for (const auto& val : globals.as_table()) {
142 brk->setGlobal(val.first, val.second.as_string());
143 }
144 }
145 }
146 auto aliases = toml::find_or(doc, "aliases", uVal);
147 if (!aliases.is_empty()) {
148 if (aliases.is_array()) {
149 for (auto& val : aliases.as_array()) {
150 brk->addAlias(val.as_array()[0].as_string(), val.as_array()[1].as_string());
151 }
152 } else {
153 for (const auto& val : aliases.as_table()) {
154 brk->addAlias(val.first, val.second.as_string());
155 }
156 }
157 }
158 }
159
160 template<class brkX>
161 void makeConnectionsJson(brkX* brk, const std::string& file)
162 {
163 static_assert(std::is_base_of<Broker, brkX>::value || std::is_base_of<Core, brkX>::value,
164 "input must be Core or Broker");
165 nlohmann::json doc;
166 try {
167 doc = loadJson(file);
168 }
169 catch (const std::invalid_argument& ia) {
170 throw(helics::InvalidParameter(ia.what()));
171 }
172
173 if (doc.contains("connections")) {
174 for (const auto& conn : doc["connections"]) {
175 if (conn.is_array() && conn.size() >= 2) {
176 brk->dataLink(conn[0].get<std::string>(), conn[1].get<std::string>());
177 } else {
178 std::string pub = fileops::getOrDefault(conn, "publication", std::string_view());
179 if (!pub.empty()) {
180 addTargets(conn, "targets", [brk, &pub](std::string_view target) {
181 brk->dataLink(pub, target);
182 });
183 } else {
184 std::string ipt = fileops::getOrDefault(conn, "input", std::string_view());
185 if (!ipt.empty()) {
186 addTargets(conn, "targets", [brk, &ipt](std::string_view target) {
187 brk->dataLink(target, ipt);
188 });
189 addTargets(conn, "sources", [brk, &ipt](std::string_view source) {
190 brk->dataLink(source, ipt);
191 });
192 } else {
193 std::string ept =
194 fileops::getOrDefault(conn, "endpoint", std::string_view());
195 if (!ept.empty()) {
196 addTargets(conn, "targets", [brk, &ept](std::string_view target) {
197 brk->linkEndpoints(ept, target);
198 });
199 addTargets(conn, "sources", [brk, &ept](std::string_view source) {
200 brk->linkEndpoints(source, ept);
201 });
202 }
203 }
204 }
205 }
206 }
207 }
208 if (doc.contains("links")) {
209 for (const auto& conn : doc["links"]) {
210 if (conn.is_array() && conn.size() >= 2) {
211 brk->linkEndpoints(conn[0].get<std::string>(), conn[1].get<std::string>());
212 } else {
213 std::string pub = fileops::getOrDefault(conn, "publication", std::string_view());
214 if (!pub.empty()) {
215 addTargets(conn, "targets", [brk, &pub](std::string_view target) {
216 brk->dataLink(pub, target);
217 });
218 } else {
219 std::string ipt = fileops::getOrDefault(conn, "input", std::string());
220 if (!ipt.empty()) {
221 addTargets(conn, "targets", [brk, &ipt](std::string_view target) {
222 brk->dataLink(target, ipt);
223 });
224 addTargets(conn, "sources", [brk, &ipt](std::string_view source) {
225 brk->dataLink(source, ipt);
226 });
227 } else {
228 std::string ept = fileops::getOrDefault(conn, "endpoint", std::string());
229 if (!ept.empty()) {
230 addTargets(conn, "targets", [brk, &ept](std::string_view target) {
231 brk->linkEndpoints(ept, target);
232 });
233 addTargets(conn, "sources", [brk, &ept](std::string_view source) {
234 brk->linkEndpoints(source, ept);
235 });
236 }
237 }
238 }
239 }
240 }
241 }
242 if (doc.contains("filters")) {
243 for (const auto& filt : doc["filters"]) {
244 if (filt.is_array()) {
245 brk->addSourceFilterToEndpoint(filt[0].get<std::string>(),
246 filt[1].get<std::string>());
247 } else {
248 std::string fname = fileops::getOrDefault(filt, "filter", std::string_view());
249 if (!fname.empty()) {
250 auto asrc = [brk, &fname](std::string_view ept) {
251 brk->addSourceFilterToEndpoint(fname, ept);
252 };
253 addTargets(filt, "endpoints", asrc);
254 addTargets(filt, "source_endpoints", asrc);
255 addTargets(filt, "sourceEndpoints", asrc);
256 auto adst = [brk, &fname](std::string_view ept) {
257 brk->addDestinationFilterToEndpoint(fname, ept);
258 };
259 addTargets(filt, "dest_endpoints", adst);
260 addTargets(filt, "destEndpoints", adst);
261 }
262 }
263 }
264 }
265 if (doc.contains("globals")) {
266 if (doc["globals"].is_array()) {
267 for (const auto& val : doc["globals"]) {
268 brk->setGlobal(val[0].get<std::string>(), val[1].get<std::string>());
269 }
270 } else {
271 for (const auto& member : doc["globals"].items()) {
272 brk->setGlobal(member.key(), member.value().get<std::string>());
273 }
274 }
275 }
276
277 if (doc.contains("aliases")) {
278 if (doc["aliases"].is_array()) {
279 for (const auto& val : doc["aliases"]) {
280 brk->addAlias(val[0].get<std::string>(), val[1].get<std::string>());
281 }
282 } else {
283 for (const auto& member : doc["aliases"].items()) {
284 brk->addAlias(member.key(), member.value().get<std::string>());
285 }
286 }
287 }
288
289 if constexpr (std::is_base_of<Core, brkX>::value) {
290 loadTags(doc, [brk](std::string_view tagname, std::string_view tagvalue) {
291 brk->setFederateTag(gLocalCoreId, tagname, tagvalue);
292 });
293 }
294 }
295 } // namespace helics::fileops
helics::fileops::loadToml
toml::value loadToml(const std::string &tomlString)
helics::InvalidParameter
Definition: core-exceptions.hpp:47
core-exceptions.hpp
helics::gLocalCoreId
constexpr LocalFederateId gLocalCoreId(-259)