helics  3.5.2
fileConnections.hpp
1 /*
2 Copyright (c) 2017-2024,
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_uninitialized()) {
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().str, connAct[1].as_string().str);
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_uninitialized()) {
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().str, connAct[1].as_string().str);
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_uninitialized()) {
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().str,
116  filtAct[1].as_string().str);
117  } else {
118  std::string fname = getOrDefault(filt, "filter", std::string());
119  if (!fname.empty()) {
120  auto asrc = [brk, &fname](const std::string& ept) {
121  brk->addSourceFilterToEndpoint(fname, ept);
122  };
123  addTargets(filt, "endpoints", asrc);
124  addTargets(filt, "source_endpoints", asrc);
125  addTargets(filt, "sourceEndpoints", asrc);
126  auto adst = [brk, &fname](const std::string& ept) {
127  brk->addDestinationFilterToEndpoint(fname, ept);
128  };
129  addTargets(filt, "dest_endpoints", adst);
130  addTargets(filt, "destEndpoints", adst);
131  }
132  }
133  }
134  }
135  auto globals = toml::find_or(doc, "globals", uVal);
136  if (!globals.is_uninitialized()) {
137  if (globals.is_array()) {
138  for (auto& val : globals.as_array()) {
139  brk->setGlobal(val.as_array()[0].as_string().str,
140  val.as_array()[1].as_string().str);
141  }
142  } else {
143  for (const auto& val : globals.as_table()) {
144  brk->setGlobal(val.first, val.second.as_string().str);
145  }
146  }
147  }
148  auto aliases = toml::find_or(doc, "aliases", uVal);
149  if (!aliases.is_uninitialized()) {
150  if (aliases.is_array()) {
151  for (auto& val : aliases.as_array()) {
152  brk->addAlias(val.as_array()[0].as_string().str, val.as_array()[1].as_string().str);
153  }
154  } else {
155  for (const auto& val : aliases.as_table()) {
156  brk->addAlias(val.first, val.second.as_string().str);
157  }
158  }
159  }
160 }
161 
162 template<class brkX>
163 void makeConnectionsJson(brkX* brk, const std::string& file)
164 {
165  static_assert(std::is_base_of<Broker, brkX>::value || std::is_base_of<Core, brkX>::value,
166  "input must be Core or Broker");
167  Json::Value doc;
168  try {
169  doc = loadJson(file);
170  }
171  catch (const std::invalid_argument& ia) {
172  throw(helics::InvalidParameter(ia.what()));
173  }
174 
175  if (doc.isMember("connections")) {
176  for (const auto& conn : doc["connections"]) {
177  if (conn.isArray() && conn.size() >= 2) {
178  brk->dataLink(conn[0].asString(), conn[1].asString());
179  } else {
180  std::string pub = fileops::getOrDefault(conn, "publication", std::string_view());
181  if (!pub.empty()) {
182  addTargets(conn, "targets", [brk, &pub](std::string_view target) {
183  brk->dataLink(pub, target);
184  });
185  } else {
186  std::string ipt = fileops::getOrDefault(conn, "input", std::string_view());
187  if (!ipt.empty()) {
188  addTargets(conn, "targets", [brk, &ipt](std::string_view target) {
189  brk->dataLink(target, ipt);
190  });
191  addTargets(conn, "sources", [brk, &ipt](std::string_view source) {
192  brk->dataLink(source, ipt);
193  });
194  } else {
195  std::string ept =
196  fileops::getOrDefault(conn, "endpoint", std::string_view());
197  if (!ept.empty()) {
198  addTargets(conn, "targets", [brk, &ept](std::string_view target) {
199  brk->linkEndpoints(ept, target);
200  });
201  addTargets(conn, "sources", [brk, &ept](std::string_view source) {
202  brk->linkEndpoints(source, ept);
203  });
204  }
205  }
206  }
207  }
208  }
209  }
210  if (doc.isMember("links")) {
211  for (const auto& conn : doc["links"]) {
212  if (conn.isArray() && conn.size() >= 2) {
213  brk->linkEndpoints(conn[0].asString(), conn[1].asString());
214  } else {
215  std::string pub = fileops::getOrDefault(conn, "publication", std::string_view());
216  if (!pub.empty()) {
217  addTargets(conn, "targets", [brk, &pub](std::string_view target) {
218  brk->dataLink(pub, target);
219  });
220  } else {
221  std::string ipt = fileops::getOrDefault(conn, "input", std::string());
222  if (!ipt.empty()) {
223  addTargets(conn, "targets", [brk, &ipt](std::string_view target) {
224  brk->dataLink(target, ipt);
225  });
226  addTargets(conn, "sources", [brk, &ipt](std::string_view source) {
227  brk->dataLink(source, ipt);
228  });
229  } else {
230  std::string ept = fileops::getOrDefault(conn, "endpoint", std::string());
231  if (!ept.empty()) {
232  addTargets(conn, "targets", [brk, &ept](std::string_view target) {
233  brk->linkEndpoints(ept, target);
234  });
235  addTargets(conn, "sources", [brk, &ept](std::string_view source) {
236  brk->linkEndpoints(source, ept);
237  });
238  }
239  }
240  }
241  }
242  }
243  }
244  if (doc.isMember("filters")) {
245  for (const auto& filt : doc["filters"]) {
246  if (filt.isArray()) {
247  brk->addSourceFilterToEndpoint(filt[0].asString(), filt[1].asString());
248  } else {
249  std::string fname = fileops::getOrDefault(filt, "filter", std::string_view());
250  if (!fname.empty()) {
251  auto asrc = [brk, &fname](std::string_view ept) {
252  brk->addSourceFilterToEndpoint(fname, ept);
253  };
254  addTargets(filt, "endpoints", asrc);
255  addTargets(filt, "source_endpoints", asrc);
256  addTargets(filt, "sourceEndpoints", asrc);
257  auto adst = [brk, &fname](std::string_view ept) {
258  brk->addDestinationFilterToEndpoint(fname, ept);
259  };
260  addTargets(filt, "dest_endpoints", adst);
261  addTargets(filt, "destEndpoints", adst);
262  }
263  }
264  }
265  }
266  if (doc.isMember("globals")) {
267  if (doc["globals"].isArray()) {
268  for (auto& val : doc["globals"]) {
269  brk->setGlobal(val[0].asString(), val[1].asString());
270  }
271  } else {
272  auto members = doc["globals"].getMemberNames();
273  for (auto& val : members) {
274  brk->setGlobal(val, doc["globals"][val].asString());
275  }
276  }
277  }
278 
279  if (doc.isMember("aliases")) {
280  if (doc["aliases"].isArray()) {
281  for (auto& val : doc["aliases"]) {
282  brk->addAlias(val[0].asString(), val[1].asString());
283  }
284  } else {
285  auto members = doc["aliases"].getMemberNames();
286  for (auto& val : members) {
287  brk->addAlias(val, doc["aliases"][val].asString());
288  }
289  }
290  }
291 
292  if constexpr (std::is_base_of<Core, brkX>::value) {
293  loadTags(doc, [brk](std::string_view tagname, std::string_view tagvalue) {
294  brk->setFederateTag(gLocalCoreId, tagname, tagvalue);
295  });
296  }
297 }
298 } // namespace helics::fileops
toml::value loadToml(const std::string &tomlString)
Definition: core-exceptions.hpp:47
constexpr LocalFederateId gLocalCoreId(-259)