Xcos ecore: fix implicit, states and solvers
[scilab.git] / scilab / modules / scicos / src / cpp / XMIResource_save.cpp
index 215ea60..ebd1058 100644 (file)
@@ -16,7 +16,7 @@
 #include <string>
 #include <sstream>
 #include <vector>
-#include <cstdio>
+#include <cmath> // for trunc
 
 extern "C" {
 #include "sci_types.h"
@@ -85,6 +85,18 @@ static std::string to_string(int v)
     return std::to_string(v);
 }
 
+static std::string to_string(bool v)
+{
+    if (v)
+    {
+        return "true";
+    }
+    else
+    {
+        return "false";
+    }
+}
+
 static std::string to_string(double v)
 {
     if (std::trunc(v) == v)
@@ -93,11 +105,53 @@ static std::string to_string(double v)
     }
 
     std::string str(15, '\0');
-       // std::snprintf(const_cast<char*>(str.data()), str.size(), "%.6E", v);
+    // std::snprintf(const_cast<char*>(str.data()), str.size(), "%.6E", v);
     std::sprintf(const_cast<char*>(str.data()), "%.6E", v);
     return str;
 }
 
+/* helper function to decode simple string EXPRS */
+static std::vector<std::string> to_string_vector(const std::vector<double>& v)
+{
+    std::vector<std::string> ret;
+    std::vector<double>::const_iterator it = v.begin();
+
+    int strHeader = *it++;
+    if (strHeader != sci_strings)
+    {
+        return ret;
+    }
+    unsigned int iDims = *it++;
+
+    // manage multi-dimensional arrays (will be serialized as a vector)
+    unsigned int iElements = 1;
+    for (unsigned int i = 0; i < iDims; ++i)
+    {
+        iElements *= static_cast<unsigned int>(*it++);
+    }
+
+    // retrieve the length of each encoded string, stored as a stack
+    std::vector<unsigned int> stringsLength;
+    stringsLength.reserve(iElements + 1);
+    stringsLength.push_back(0);
+    for (unsigned int i = 0; i < iElements; ++i)
+    {
+        stringsLength.push_back(*it++);
+    }
+
+    // Retrieving the pointers (already UTF-8 encoded char*) and store them as strings
+    ret.reserve(ret.size() + iElements);
+    for (unsigned int i = 0; i < iElements; ++i)
+    {
+        // push the data
+        const double* strData = &(*(it + stringsLength[i]));
+        ret.emplace_back((char*) strData);
+    }
+
+    return ret;
+}
+
+
 static int writeBase64(xmlTextWriterPtr writer, const char* name, const std::vector<double>& v)
 {
     int status;
@@ -123,12 +177,47 @@ static int writeBase64(xmlTextWriterPtr writer, const char* name, const std::vec
     return status;
 }
 
+int XMIResource::writeDatatype(xmlTextWriterPtr writer, const std::vector<int>& datatype)
+{
+    int status;
+
+    status = xmlTextWriterStartElement(writer, BAD_CAST("datatype"));
+    if (status == -1)
+    {
+        return status;
+    }
+
+    status = xmlTextWriterWriteAttribute(writer, BAD_CAST("type"), BAD_CAST(to_string(datatype[2]).c_str()));
+    if (status == -1)
+    {
+        return status;
+    }
+
+    status = xmlTextWriterWriteAttribute(writer, BAD_CAST("rows"), BAD_CAST(to_string(datatype[0]).c_str()));
+    if (status == -1)
+    {
+        return status;
+    }
+
+    status = xmlTextWriterWriteAttribute(writer, BAD_CAST("columns"), BAD_CAST(to_string(datatype[1]).c_str()));
+    if (status == -1)
+    {
+        return status;
+    }
+
+    status = xmlTextWriterEndElement(writer);
+    if (status == -1)
+    {
+        return status;
+    }
+
+    return status;
+}
 
 int XMIResource::writePoint(xmlTextWriterPtr writer, double x, double y)
 {
     int status;
 
-
     status = xmlTextWriterStartElement(writer, BAD_CAST("controlPoint"));
     if (status == -1)
     {
@@ -317,7 +406,7 @@ int XMIResource::writeDiagram(xmlTextWriterPtr writer)
     {
         return status;
     }
-    status = xmlTextWriterWriteAttributeNS(writer, BAD_CAST("xsi"), BAD_CAST("schemaLocation"), BAD_CAST("http://www.w3.org/2001/XMLSchema-instance"), BAD_CAST("org.scilab.modules.xcos Xcos.xcore#/EPackage"));
+    status = xmlTextWriterWriteAttributeNS(writer, BAD_CAST("xsi"), BAD_CAST("schemaLocation"), BAD_CAST("http://www.w3.org/2001/XMLSchema-instance"), BAD_CAST("org.scilab.modules.xcos xcos.ecore"));
     if (status == -1)
     {
         return status;
@@ -404,7 +493,7 @@ int XMIResource::writeSimulationConfig(xmlTextWriterPtr writer, ScicosID id)
     {
         return -1;
     }
-    status = xmlTextWriterWriteAttribute(writer, BAD_CAST("absoluteTime"), BAD_CAST(to_string(doubleArrayValue[i]).c_str()));
+    status = xmlTextWriterWriteAttribute(writer, BAD_CAST("absoluteTolerance"), BAD_CAST(to_string(doubleArrayValue[i]).c_str()));
     if (status == -1)
     {
         return status;
@@ -426,7 +515,7 @@ int XMIResource::writeSimulationConfig(xmlTextWriterPtr writer, ScicosID id)
     {
         return -1;
     }
-    status = xmlTextWriterWriteAttribute(writer, BAD_CAST("absoluteTolerance"), BAD_CAST(to_string(doubleArrayValue[i]).c_str()));
+    status = xmlTextWriterWriteAttribute(writer, BAD_CAST("timeTolerance"), BAD_CAST(to_string(doubleArrayValue[i]).c_str()));
     if (status == -1)
     {
         return status;
@@ -605,8 +694,7 @@ int XMIResource::writeBlock(xmlTextWriterPtr writer, ScicosID id)
     else if (is_string_vector(doubleArrayValue))
     {
         // if this is a string the expression is used
-        std::vector<std::string> values;
-        controller.getObjectProperty(id, BLOCK, EXPRS, values);
+        std::vector<std::string> values = to_string_vector(doubleArrayValue);
 
         for (const std::string& s : values)
         {
@@ -847,6 +935,14 @@ int XMIResource::writePort(xmlTextWriterPtr writer, enum object_properties_t con
         return status;
     }
 
+    bool implicit;
+    controller.getObjectProperty(id, PORT, IMPLICIT, implicit);
+    status = xmlTextWriterWriteAttribute(writer, BAD_CAST("implicit"), BAD_CAST(to_string(implicit).c_str()));
+    if (status == -1)
+    {
+        return status;
+    }
+
     controller.getObjectProperty(id, PORT, CONNECTED_SIGNALS, idValue);
     if (idValue != 0)
     {
@@ -876,16 +972,9 @@ int XMIResource::writePort(xmlTextWriterPtr writer, enum object_properties_t con
         return status;
     }
 
-    std::vector<double> doubleArrayValue;
-    controller.getObjectProperty(id, BLOCK, DATATYPE, doubleArrayValue);
-    for (double d : doubleArrayValue)
-    {
-        status = xmlTextWriterWriteElement(writer, BAD_CAST("datatype"), BAD_CAST(to_string(d).c_str()));
-        if (status == -1)
-        {
-            return status;
-        }
-    }
+    std::vector<int> intArrayValue;
+    controller.getObjectProperty(id, PORT, DATATYPE, intArrayValue);
+    status = writeDatatype(writer, intArrayValue);
 
     status = xmlTextWriterEndElement(writer);
     if (status == -1)