diff --git a/Test/FMI3/fmi3_import_terminals_and_icons_test.cpp b/Test/FMI3/fmi3_import_terminals_and_icons_test.cpp
index 20e7ec59..f3827ce5 100644
--- a/Test/FMI3/fmi3_import_terminals_and_icons_test.cpp
+++ b/Test/FMI3/fmi3_import_terminals_and_icons_test.cpp
@@ -28,6 +28,20 @@ TEST_CASE("Test parse terminals and icons") {
REQUIRE(xml != nullptr);
REQUIRE(fmi3_import_get_has_terminals_and_icons(xml) != 0);
+ SECTION("Testing graphicalRepresentation") {
+ // TODO: FMI2
+ // TODO
+ ;
+ SECTION("Testing coordinateSystem") {
+ // TODO:
+ ;
+ }
+ SECTION("Testing Icon") {
+ // TODO:
+ ;
+ }
+ }
+
SECTION("Testing getting terminal by name") {
fmi_import_terminal_t* term;
@@ -148,3 +162,67 @@ TEST_CASE("Test clearing of attribute buffer with invalid elements") {
REQUIRE(fmi3_testutil_get_num_problems(tfmu) == 3);
fmi3_testutil_import_free(tfmu);
}
+
+TEST_CASE("Empty graphical representation: Takes default") {
+ const char* xmldir = FMI3_TEST_XML_DIR "/terminals_and_icons/valid/empty_graphicalRepresentation";
+ fmi3_testutil_import_t* tfmu = fmi3_testutil_parse_xml_with_log(xmldir);
+ fmi3_import_t* fmu = tfmu->fmu;
+ REQUIRE(fmu != nullptr); // successful parse of modelDescription
+ REQUIRE(fmi3_import_get_has_terminals_and_icons(fmu) == 1);
+
+ // TODO: Verify default coordinate system + scaling + no icon
+
+ REQUIRE(fmi3_testutil_get_num_problems(tfmu) == 0);
+ fmi3_testutil_import_free(tfmu);
+}
+
+TEST_CASE("Incomplete graphicaRepresentation->coordinateSystem: Takes default") {
+ const char* xmldir = FMI3_TEST_XML_DIR "/terminals_and_icons/invalid/incomplete_coordinateSystem";
+ fmi3_testutil_import_t* tfmu = fmi3_testutil_parse_xml_with_log(xmldir);
+ fmi3_import_t* fmu = tfmu->fmu;
+ REQUIRE(fmu != nullptr); // successful parse of modelDescription
+ REQUIRE(fmi3_import_get_has_terminals_and_icons(fmu) == 1);
+
+ REQUIRE(fmi3_testutil_log_contains(tfmu, "Parsing XML element 'CoordinateSystem': required attribute 'x2' not found"));
+ REQUIRE(fmi3_testutil_log_contains(tfmu, "Parsing XML element 'CoordinateSystem': required attribute 'y2' not found"));
+
+ REQUIRE(fmi3_testutil_log_contains(tfmu, "Failed to parse complete CoordinateSystem, using default system (-100, -100), (100, 100)."));
+
+ // TODO: Verify default coordinate system + no icon
+
+ REQUIRE(fmi3_testutil_get_num_problems(tfmu) == 3);
+ fmi3_testutil_import_free(tfmu);
+}
+
+TEST_CASE("Not well-defined graphicaRepresentation->coordinateSystem") {
+ const char* xmldir = FMI3_TEST_XML_DIR "/terminals_and_icons/invalid/flipped_coordinateSystem";
+ fmi3_testutil_import_t* tfmu = fmi3_testutil_parse_xml_with_log(xmldir);
+ fmi3_import_t* fmu = tfmu->fmu;
+ REQUIRE(fmu != nullptr); // successful parse of modelDescription
+ REQUIRE(fmi3_import_get_has_terminals_and_icons(fmu) == 1);
+
+ REQUIRE(fmi3_testutil_log_contains(tfmu, "'CoordinateSystem' not well-defined, requires x1 = 100.000000 < x2 = -100.000000."));
+ REQUIRE(fmi3_testutil_log_contains(tfmu, "'CoordinateSystem' not well-defined, requires y1 = 100.000000 < y2 = -100.000000."));
+
+ // TODO: Verify coordinates are stored anyways
+
+ REQUIRE(fmi3_testutil_get_num_problems(tfmu) == 2);
+ fmi3_testutil_import_free(tfmu);
+}
+
+TEST_CASE("Incomplete graphicalRepresentation->Icon") {
+ const char* xmldir = FMI3_TEST_XML_DIR "/terminals_and_icons/invalid/incomplete_icon";
+ fmi3_testutil_import_t* tfmu = fmi3_testutil_parse_xml_with_log(xmldir);
+ fmi3_import_t* fmu = tfmu->fmu;
+ REQUIRE(fmu != nullptr); // successful parse of modelDescription
+ REQUIRE(fmi3_import_get_has_terminals_and_icons(fmu) == 1);
+
+ REQUIRE(fmi3_testutil_log_contains(tfmu, "Parsing XML element 'Icon': required attribute 'x2' not found"));
+ REQUIRE(fmi3_testutil_log_contains(tfmu, "Parsing XML element 'Icon': required attribute 'y2' not found"));
+ REQUIRE(fmi3_testutil_log_contains(tfmu, "Failed to parse complete Icon."));
+
+ // TODO: Verify there is no icon
+
+ REQUIRE(fmi3_testutil_get_num_problems(tfmu) == 3);
+ fmi3_testutil_import_free(tfmu);
+}
diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/flipped_coordinateSystem/modelDescription.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/flipped_coordinateSystem/modelDescription.xml
new file mode 100644
index 00000000..4e24d976
--- /dev/null
+++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/flipped_coordinateSystem/modelDescription.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/flipped_coordinateSystem/terminalsAndIcons/terminalsAndIcons.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/flipped_coordinateSystem/terminalsAndIcons/terminalsAndIcons.xml
new file mode 100644
index 00000000..d58d0580
--- /dev/null
+++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/flipped_coordinateSystem/terminalsAndIcons/terminalsAndIcons.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_coordinateSystem/modelDescription.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_coordinateSystem/modelDescription.xml
new file mode 100644
index 00000000..4e24d976
--- /dev/null
+++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_coordinateSystem/modelDescription.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_coordinateSystem/terminalsAndIcons/terminalsAndIcons.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_coordinateSystem/terminalsAndIcons/terminalsAndIcons.xml
new file mode 100644
index 00000000..55ca3a4e
--- /dev/null
+++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_coordinateSystem/terminalsAndIcons/terminalsAndIcons.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_icon/modelDescription.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_icon/modelDescription.xml
new file mode 100644
index 00000000..4e24d976
--- /dev/null
+++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_icon/modelDescription.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_icon/terminalsAndIcons/terminalsAndIcons.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_icon/terminalsAndIcons/terminalsAndIcons.xml
new file mode 100644
index 00000000..072bef7c
--- /dev/null
+++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/invalid/incomplete_icon/terminalsAndIcons/terminalsAndIcons.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/basic/terminalsAndIcons/terminalsAndIcons.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/basic/terminalsAndIcons/terminalsAndIcons.xml
index c2390c33..1551ffeb 100644
--- a/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/basic/terminalsAndIcons/terminalsAndIcons.xml
+++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/basic/terminalsAndIcons/terminalsAndIcons.xml
@@ -1,5 +1,9 @@
+
+
+
+
diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/empty_graphicalRepresentation/modelDescription.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/empty_graphicalRepresentation/modelDescription.xml
new file mode 100644
index 00000000..4e24d976
--- /dev/null
+++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/empty_graphicalRepresentation/modelDescription.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/empty_graphicalRepresentation/terminalsAndIcons/terminalsAndIcons.xml b/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/empty_graphicalRepresentation/terminalsAndIcons/terminalsAndIcons.xml
new file mode 100644
index 00000000..6ad178b9
--- /dev/null
+++ b/Test/FMI3/parser_test_xmls/terminals_and_icons/valid/empty_graphicalRepresentation/terminalsAndIcons/terminalsAndIcons.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/XML/include/FMI/fmi_xml_terminals_and_icons.h b/src/XML/include/FMI/fmi_xml_terminals_and_icons.h
index 966ccc37..99176e77 100644
--- a/src/XML/include/FMI/fmi_xml_terminals_and_icons.h
+++ b/src/XML/include/FMI/fmi_xml_terminals_and_icons.h
@@ -38,6 +38,12 @@ extern "C" {
/* Structure encapsulating terminals and icons information */
typedef struct fmi_xml_terminals_and_icons_t fmi_xml_terminals_and_icons_t;
+/* Structure encapsulating graphicalRepresentation information */
+typedef struct fmi_xml_graphicalRepresentation_t fmi_xml_graphicalRepresentation_t;
+/* Structure encapsulating coordinateSystem information */
+typedef struct fmi_xml_coordinateSystem_t fmi_xml_coordinateSystem_t;
+/* Structure encapsulating icon information */
+typedef struct fmi_xml_icon_t fmi_xml_icon_t;
/* Structure encapsulating terminal information */
typedef struct fmi_xml_terminal_t fmi_xml_terminal_t;
@@ -62,7 +68,22 @@ int fmi2_xml_terminals_and_icons_set_model_description(fmi_xml_terminals_and_ico
int fmi3_xml_terminals_and_icons_set_model_description(fmi_xml_terminals_and_icons_t* termIcon,
fmi3_xml_model_description_t* md);
+/* Top level */
int fmi_xml_get_has_terminals_and_icons(fmi_xml_terminals_and_icons_t* termIcon);
+
+/* Graphical Representation */
+int fmi_xml_get_has_graphical_representation(fmi_xml_terminals_and_icons_t* termIcon);
+/* coordinateSystem*/
+int fmi_xml_get_graphical_representation_system_coordinates(fmi_xml_graphicalRepresentation_t* graphRepr,
+ double* x1, double* y1, double* x2, double* y2);
+int fmi_xml_get_graphical_representation_suggested_scaling(fmi_xml_graphicalRepresentation_t* graphRepr,
+ double* suggested_scaling);
+/* icon */
+int fmi_xml_get_graphical_representation_has_icon(fmi_xml_graphicalRepresentation_t* graphRepr);
+int fmi_xml_get_graphical_representation_icon_coordinates(fmi_xml_graphicalRepresentation_t* graphRepr,
+ double* x1, double* y1, double* x2, double* y2);
+
+/* Terminals */
fmi_xml_terminal_t* fmi_xml_get_terminal_by_name(fmi_xml_terminals_and_icons_t* termIcon, const char* name);
const char* fmi_xml_get_terminal_name(fmi_xml_terminal_t* term);
diff --git a/src/XML/include/FMI/fmi_xml_terminals_and_icons_scheme.h b/src/XML/include/FMI/fmi_xml_terminals_and_icons_scheme.h
index a731b21e..381b159b 100644
--- a/src/XML/include/FMI/fmi_xml_terminals_and_icons_scheme.h
+++ b/src/XML/include/FMI/fmi_xml_terminals_and_icons_scheme.h
@@ -26,11 +26,20 @@ extern "C" {
#define FMI_XML_ATTRLIST_TERM_ICON(EXPAND_XML_ATTRNAME) \
EXPAND_XML_ATTRNAME(fmiVersion) \
EXPAND_XML_ATTRNAME(name) \
- EXPAND_XML_ATTRNAME(description)
+ EXPAND_XML_ATTRNAME(description) \
+ EXPAND_XML_ATTRNAME(x1) \
+ EXPAND_XML_ATTRNAME(y1) \
+ EXPAND_XML_ATTRNAME(x2) \
+ EXPAND_XML_ATTRNAME(y2) \
+ EXPAND_XML_ATTRNAME(suggestedScalingFactorTo_mm)
+
/* Element names found in terminalsAndIcons.xml */
#define FMI_XML_ELMLIST_TERM_ICON(EXPAND_XML_ELMNAME) \
EXPAND_XML_ELMNAME(fmiTerminalsAndIcons) \
+ EXPAND_XML_ELMNAME(GraphicalRepresentation) \
+ EXPAND_XML_ELMNAME(CoordinateSystem) \
+ EXPAND_XML_ELMNAME(Icon) \
EXPAND_XML_ELMNAME(Terminals) \
EXPAND_XML_ELMNAME(Terminal) \
EXPAND_XML_ELMNAME(TerminalMemberVariable) \
@@ -48,14 +57,18 @@ extern "C" {
@multi_elem:
if the parent can have multiple elements of this type
*/
-/* scheme_ID, super_type, parent_ID, sib_idx, multi_elem */
-#define fmi_xml_scheme_termIcon_fmiTerminalsAndIcons {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_none, 0, 0}
-
-#define fmi_xml_scheme_termIcon_Terminals {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_fmiTerminalsAndIcons, 1, 0}
-#define fmi_xml_scheme_termIcon_Terminal {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_Terminals, 0, 1}
-#define fmi_xml_scheme_termIcon_TerminalMemberVariable {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_Terminal, 0, 1}
-#define fmi_xml_scheme_termIcon_TerminalStreamMemberVariable {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_Terminal, 1, 1}
-#define fmi_xml_scheme_termIcon_TerminalGraphicalRepresentation {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_Terminal, 3, 0}
+/* scheme_ID, super_type, parent_ID, sib_idx, multi_elem */
+#define fmi_xml_scheme_termIcon_fmiTerminalsAndIcons {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_none, 0, 0}
+
+#define fmi_xml_scheme_termIcon_GraphicalRepresentation {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_fmiTerminalsAndIcons, 0, 0}
+#define fmi_xml_scheme_termIcon_CoordinateSystem {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_GraphicalRepresentation, 0, 0}
+#define fmi_xml_scheme_termIcon_Icon {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_GraphicalRepresentation, 1, 0}
+
+#define fmi_xml_scheme_termIcon_Terminals {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_fmiTerminalsAndIcons, 1, 0}
+#define fmi_xml_scheme_termIcon_Terminal {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_Terminals, 0, 1}
+#define fmi_xml_scheme_termIcon_TerminalMemberVariable {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_Terminal, 0, 1}
+#define fmi_xml_scheme_termIcon_TerminalStreamMemberVariable {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_Terminal, 1, 1}
+#define fmi_xml_scheme_termIcon_TerminalGraphicalRepresentation {fmi_xml_elmID_termIcon_none, fmi_xml_elmID_termIcon_Terminal, 3, 0}
// Attribute enum
#define FMI_TERMICON_XML_ATTR_ID(attr) fmi_termIcon_attr_id_##attr,
diff --git a/src/XML/src/FMI/fmi_xml_terminals_and_icons.c b/src/XML/src/FMI/fmi_xml_terminals_and_icons.c
index f7ae5f0a..959311e1 100644
--- a/src/XML/src/FMI/fmi_xml_terminals_and_icons.c
+++ b/src/XML/src/FMI/fmi_xml_terminals_and_icons.c
@@ -35,6 +35,8 @@ fmi_xml_terminals_and_icons_t* fmi_xml_allocate_terminals_and_icons(jm_callbacks
jm_vector_init(char)(&termIcon->fmi3_xml_standard_version, 0, cb);
+ termIcon->graphicalRepresentation = NULL;
+
jm_vector_init(jm_voidp)(&termIcon->terminalsOrigOrder, 0, cb);
jm_vector_init(jm_named_ptr)(&termIcon->terminalsByName, 0, cb);
@@ -61,6 +63,13 @@ void fmi_xml_free_terminals_and_icons(fmi_xml_terminals_and_icons_t* termIcon) {
jm_callbacks* callbacks = termIcon->callbacks;
if (termIcon) {
jm_vector_free_data(char)(&(termIcon->fmi3_xml_standard_version));
+
+ // free graphicalDescription
+ if (termIcon->graphicalRepresentation) {
+ callbacks->free(termIcon->graphicalRepresentation->coordinateSystem);
+ callbacks->free(termIcon->graphicalRepresentation->icon);
+ }
+ callbacks->free(termIcon->graphicalRepresentation);
// free terminals
for (size_t i = 0; i < jm_vector_get_size(jm_voidp)(&(termIcon->terminalsOrigOrder)); i++) {
@@ -139,6 +148,102 @@ int fmi_xml_handle_fmiTerminalsAndIcons(fmi3_xml_parser_context_t* context, cons
return 0;
}
+int fmi_xml_handle_GraphicalRepresentation(fmi3_xml_parser_context_t* context, const char* data) {
+ fmi_xml_terminals_and_icons_t* termIcon = context->termIcon;
+ if (!data) {
+ termIcon->graphicalRepresentation = (fmi_xml_graphicalRepresentation_t*)context->callbacks->calloc(1, sizeof(fmi_xml_graphicalRepresentation_t));
+ if (!termIcon->graphicalRepresentation) {
+ fmi3_xml_parse_fatal(context, "Could not allocate memory");
+ return 1;
+ }
+ // GraphicalRepresentation has a default coordinateSystem, allocate here directly
+ termIcon->graphicalRepresentation->coordinateSystem = (fmi_xml_coordinateSystem_t*)context->callbacks->calloc(1, sizeof(fmi_xml_coordinateSystem_t));
+ if (!termIcon->graphicalRepresentation->coordinateSystem) {
+ fmi3_xml_parse_fatal(context, "Could not allocate memory");
+ return 1;
+ }
+ termIcon->graphicalRepresentation->coordinateSystem->x1 = -100;
+ termIcon->graphicalRepresentation->coordinateSystem->y1 = -100;
+ termIcon->graphicalRepresentation->coordinateSystem->x2 = 100;
+ termIcon->graphicalRepresentation->coordinateSystem->y2 = 100;
+ termIcon->graphicalRepresentation->coordinateSystem->suggestedScalingFactorTo_mm = 0.1;
+ } else {
+ ;
+ }
+ return 0;
+}
+
+int fmi_xml_handle_CoordinateSystem(fmi3_xml_parser_context_t* context, const char* data) {
+ fmi_xml_terminals_and_icons_t* termIcon = context->termIcon;
+ fmi_xml_coordinateSystem_t* coordSys = termIcon->graphicalRepresentation->coordinateSystem;
+ if (!data) {
+ // Allocation in GraphicalRepresentation
+ int ret = 0;
+
+ ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_CoordinateSystem),
+ FMI_ATTR_TERMICON(fmi_termIcon_attr_id_x1), 1, &(coordSys->x1), -100);
+ ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_CoordinateSystem),
+ FMI_ATTR_TERMICON(fmi_termIcon_attr_id_y1), 1, &(coordSys->y1), -100);
+ ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_CoordinateSystem),
+ FMI_ATTR_TERMICON(fmi_termIcon_attr_id_x2), 1, &(coordSys->x2), 100);
+ ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_CoordinateSystem),
+ FMI_ATTR_TERMICON(fmi_termIcon_attr_id_y2), 1, &(coordSys->y2), 100);
+ ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_CoordinateSystem),
+ FMI_ATTR_TERMICON(fmi_termIcon_attr_id_suggestedScalingFactorTo_mm), 1, &(coordSys->suggestedScalingFactorTo_mm), 0.1);
+ if (ret) {
+ fmi3_xml_parse_error(context, "Failed to parse complete CoordinateSystem, using default system (-100, -100), (100, 100).");
+ coordSys->x1 = -100;
+ coordSys->y1 = -100;
+ coordSys->x2 = 100;
+ coordSys->y2 = 100;
+ coordSys->suggestedScalingFactorTo_mm = 0.1;
+ return 1;
+ }
+ } else {
+ /* SPEC: [...] where the coordinates of the first point shall be less than the coordinates of the second point. */
+ if (coordSys->x1 >= coordSys->x2) {
+ fmi3_xml_parse_warning(context, "'CoordinateSystem' not well-defined, requires x1 = %f < x2 = %f.",
+ coordSys->x1, coordSys->x2);
+ }
+ if (coordSys->y1 >= coordSys->y2) {
+ fmi3_xml_parse_warning(context, "'CoordinateSystem' not well-defined, requires y1 = %f < y2 = %f.",
+ coordSys->y1, coordSys->y2);
+ }
+ }
+ return 0;
+}
+
+int fmi_xml_handle_Icon(fmi3_xml_parser_context_t* context, const char* data) {
+ fmi_xml_terminals_and_icons_t* termIcon = context->termIcon;
+ fmi_xml_graphicalRepresentation_t* graphRepr = termIcon->graphicalRepresentation;
+ if (!data) {
+ int ret;
+ fmi_xml_icon_t* icon = (fmi_xml_icon_t*)context->callbacks->calloc(1, sizeof(fmi_xml_icon_t));
+ if (!icon) {
+ fmi3_xml_parse_fatal(context, "Could not allocate memory");
+ return 1;
+ }
+ ret = 0;
+ ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_Icon),
+ FMI_ATTR_TERMICON(fmi_termIcon_attr_id_x1), 1, &(icon->x1), 0);
+ ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_Icon),
+ FMI_ATTR_TERMICON(fmi_termIcon_attr_id_y1), 1, &(icon->y1), 0);
+ ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_Icon),
+ FMI_ATTR_TERMICON(fmi_termIcon_attr_id_x2), 1, &(icon->x2), 0);
+ ret |= fmi3_xml_parse_attr_as_float64(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_Icon),
+ FMI_ATTR_TERMICON(fmi_termIcon_attr_id_y2), 1, &(icon->y2), 0);
+ if (ret) {
+ fmi3_xml_parse_error(context, "Failed to parse complete Icon.");
+ context->callbacks->free(icon); // Discard element
+ return 1;
+ }
+ graphRepr->icon = icon;
+ } else {
+ ;
+ }
+ return 0;
+}
+
int fmi_xml_handle_Terminals(fmi3_xml_parser_context_t* context, const char* data) {
fmi_xml_terminals_and_icons_t* termIcon = context->termIcon;
if (!data) {
@@ -192,7 +297,7 @@ int fmi_xml_handle_Terminal(fmi3_xml_parser_context_t* context, const char* data
// parse name
jm_vector(char)* bufName = fmi3_xml_reserve_parse_buffer(context, bufIdx++, 100);
if (!bufName) {return -1;}
- if (fmi3_xml_parse_attr_as_string(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_Terminal), FMI_ATTR_TERMICON(fmi_attr_id_name), 1 /* required */, bufName)) {return -1;}
+ if (fmi3_xml_parse_attr_as_string(context, FMI_ELM_TERMICON(fmi_xml_elmID_termIcon_Terminal), FMI_ATTR_TERMICON(fmi_termIcon_attr_id_name), 1 /* required */, bufName)) {return -1;}
/* Add the name to the terminalsAndIcons-wide set and retrieve the pointer */
if (jm_vector_get_size(char)(bufName)) {
@@ -237,17 +342,69 @@ int fmi_xml_handle_TerminalGraphicalRepresentation(fmi3_xml_parser_context_t* co
return 0;
}
+
+/* Top level*/
int fmi_xml_get_has_terminals_and_icons(fmi_xml_terminals_and_icons_t* termIcon) {
return termIcon ? 1 : 0;
}
-fmi_xml_terminal_t* fmi_xml_get_terminal_by_name(fmi_xml_terminals_and_icons_t* termIcon, const char* name){
- if (!name) return NULL;
+/* Graphical Representation */
+int fmi_xml_get_has_graphical_representation(fmi_xml_terminals_and_icons_t* termIcon) {
+ if (!termIcon) {
+ return 0;
+ }
+ return termIcon->graphicalRepresentation ? 1 : 0;
+}
+
+int fmi_xml_get_graphical_representation_system_coordinates(fmi_xml_graphicalRepresentation_t* graphRepr,
+ double* x1, double* y1, double* x2, double* y2) {
+ if (!graphRepr || (!graphRepr->coordinateSystem)) {
+ return 1;
+ }
+ *x1 = graphRepr->coordinateSystem->x1;
+ *y1 = graphRepr->coordinateSystem->y1;
+ *x2 = graphRepr->coordinateSystem->x2;
+ *y2 = graphRepr->coordinateSystem->y2;
+ return 0;
+}
+
+int fmi_xml_get_graphical_representation_suggested_scaling(fmi_xml_graphicalRepresentation_t* graphRepr,
+ double* suggested_scaling) {
+ if (!graphRepr || (!graphRepr->coordinateSystem)) {
+ return 1;
+ }
+ *suggested_scaling = graphRepr->coordinateSystem->suggestedScalingFactorTo_mm;
+ return 0;
+}
+
+int fmi_xml_get_graphical_representation_has_icon(fmi_xml_graphicalRepresentation_t* graphRepr) {
+ if (!graphRepr) {
+ return 0;
+ }
+ return graphRepr->icon ? 1 : 0;
+}
+
+int fmi_xml_get_graphical_representation_icon_coordinates(fmi_xml_graphicalRepresentation_t* graphRepr,
+ double* x1, double* y1, double* x2, double* y2) {
+ if (!graphRepr || (!graphRepr->icon)) {
+ return 1;
+ }
+ *x1 = graphRepr->icon->x1;
+ *y1 = graphRepr->icon->y1;
+ *x2 = graphRepr->icon->x2;
+ *y2 = graphRepr->icon->y2;
+ return 0;
+}
+
+/* Terminals*/
+fmi_xml_terminal_t* fmi_xml_get_terminal_by_name(fmi_xml_terminals_and_icons_t* termIcon, const char* name) {
+ if (!name) {
+ return NULL;
+ }
jm_named_ptr key, *found;
key.name = name;
found = jm_vector_bsearch(jm_named_ptr)(&termIcon->terminalsByName, &key, jm_compare_named);
- if (!found) return NULL;
- return found->ptr;
+ return found ? found->ptr : NULL;
}
const char* fmi_xml_get_terminal_name(fmi_xml_terminal_t* term) {
diff --git a/src/XML/src/FMI/fmi_xml_terminals_and_icons_impl.h b/src/XML/src/FMI/fmi_xml_terminals_and_icons_impl.h
index 277a64bb..53de2482 100644
--- a/src/XML/src/FMI/fmi_xml_terminals_and_icons_impl.h
+++ b/src/XML/src/FMI/fmi_xml_terminals_and_icons_impl.h
@@ -34,12 +34,28 @@ struct fmi_xml_terminals_and_icons_t {
jm_vector(char) fmi3_xml_standard_version;
+ fmi_xml_graphicalRepresentation_t* graphicalRepresentation;
+
jm_vector(jm_voidp) terminalsOrigOrder;
jm_vector(jm_named_ptr) terminalsByName;
jm_string_set names; // storage for all terminal names
};
+struct fmi_xml_graphicalRepresentation_t {
+ fmi_xml_coordinateSystem_t* coordinateSystem;
+ fmi_xml_icon_t* icon;
+};
+
+struct fmi_xml_coordinateSystem_t {
+ double x1, y1, x2, y2;
+ double suggestedScalingFactorTo_mm;
+};
+
+struct fmi_xml_icon_t {
+ double x1, y1, x2, y2;
+};
+
struct fmi_xml_terminal_t {
const char* name;
// TODO: Currently only supports name; add remaining attributes.