Xcos MVC: fix valgrind detected invalid access
[scilab.git] / scilab / modules / scicos / src / cpp / view_scilab / ModelAdapter.cpp
index c2733aa..5cc7bd8 100644 (file)
@@ -368,520 +368,295 @@ struct dstate
     }
 };
 
-types::InternalType* getPropList(const ModelAdapter& adaptor, const Controller& controller, const object_properties_t prop)
+void decodeDims(std::vector<int>::iterator& prop_it, std::vector<int>& dims)
 {
-    ScicosID adaptee = adaptor.getAdaptee()->id();
+    const int iDims = *prop_it++;
+    dims.resize(iDims);
+
+    memcpy(&dims[0], &(*prop_it), iDims * sizeof(int));
+    prop_it += iDims;
+}
+
+void encodeDims(std::vector<int>& prop_content, types::GenericType* v)
+{
+    const int iDims = v->getDims();
+    prop_content.push_back(iDims);
 
-    std::vector<int> prop_content;
-    controller.getObjectProperty(adaptee, BLOCK, prop, prop_content);
+    const int index = prop_content.size();
+    prop_content.resize(index + iDims);
 
-    if (prop_content.empty())
+    memcpy(&prop_content[index], v->getDimsArray(), iDims * sizeof(int));
+}
+
+/**
+ * Calculate the length increment depending on the ::value_type of the buffer and the type of the Scilab type
+ *
+ * @param V buffer type which must have a ::value_type field
+ * @param T Scilab type
+ * @param v the instance on the Scilab type
+ * @return the number of V elements used to store the data
+ */
+template<typename V, typename T>
+size_t required_length(const V& /*it*/, T* v)
+{
+    const size_t sizeof_prop_value = sizeof(typename V::value_type);
+    if (sizeof(typename T::type) >= sizeof_prop_value)
+    {
+        return v->getSize() * sizeof(typename T::type) / sizeof_prop_value;
+    }
+    else
     {
-        return types::Double::Empty();
+        // increase the size to contain enough space, manage the size_t rounding issue
+        return v->getSize() * sizeof(typename T::type) + (sizeof_prop_value - 1) / sizeof_prop_value;
     }
+}
 
-    types::List* list = new types::List();
+template <typename T>
+T* decode(std::vector<int>::iterator& prop_it)
+{
+    std::vector<int> dims;
+    decodeDims(prop_it, dims);
 
-    int index = 1; // Index to each element of the returned list
+    T* v = new T(static_cast<int>(dims.size()), &dims[0]);
+    memcpy(v->get(), &(*prop_it), v->getSize() * sizeof(typename T::type));
 
-    for (int i = 0; i < prop_content[0]; ++i) // 'list' must have exactly 'prop_content[0]' elements
-    {
-        int  iDims;
-        int* pDims;
-        int  iElements = 1;
-        int  numberOfIntNeeded = 0;
-        switch (prop_content[index])
-        {
-            case types::InternalType::ScilabDouble:
-            {
-                iDims = prop_content[index + 1];
-                pDims = new int[iDims];
-                for (int j = 0; j < iDims; ++j)
-                {
-                    pDims[j] = prop_content[index + 2 + j];
-                    iElements *= pDims[j];
-                }
-                if (pDims[0] == 0)
-                {
-                    numberOfIntNeeded = 1; // Only mind the complex flag
-                    list->set(i, types::Double::Empty());
-                    break;
-                }
-                int isComplex = prop_content[index + 2 + iDims];
+    prop_it += required_length(prop_it, v);
+    return v;
+}
 
-                types::Double* pDouble;
+template <typename T>
+bool encode(std::vector<int>& prop_content, T* v)
+{
+    encodeDims(prop_content, v);
 
-                if (isComplex == 0)
-                {
-                    pDouble = new types::Double(iDims, pDims, false);
-                    numberOfIntNeeded = 2 * iElements + 1;
-                    memcpy(pDouble->get(), &prop_content[index + 2 + iDims + 1], iElements * sizeof(double));
-                }
-                else
-                {
-                    pDouble = new types::Double(iDims, pDims, true);
-                    numberOfIntNeeded = 4 * iElements + 1;
-                    memcpy(pDouble->get(), &prop_content[index + 2 + iDims + 1], iElements * sizeof(double));
-                    memcpy(pDouble->getImg(), &prop_content[index + 2 + iDims + 1 + 2 * iElements], iElements * sizeof(double));
-                }
-                delete[] pDims;
+    const int index = prop_content.size();
+    const int len = required_length(prop_content, v);
+    prop_content.resize(index + len);
 
-                list->set(i, pDouble);
-                break;
-            }
-            case types::InternalType::ScilabInt8:
-            {
-                iDims = prop_content[index + 1];
-                pDims = new int[iDims];
-                for (int j = 0; j < iDims; ++j)
-                {
-                    pDims[j] = prop_content[index + 2 + j];
-                    iElements *= pDims[j];
-                }
-                numberOfIntNeeded = ((iElements - 1) / 4) + 1;
+    // Using contiguity of the memory, we save the input into 'prop_content'
+    memcpy(&prop_content[index], v->get(), v->getSize() * sizeof(typename T::type));
+    return true;
+}
 
-                types::Int8* pInt8 = new types::Int8(iDims, pDims);
-                delete[] pDims;
+template<>
+types::Double* decode(std::vector<int>::iterator& prop_it)
+{
+    std::vector<int> dims;
+    decodeDims(prop_it, dims);
 
-                // Use a buffer to prevent copying only parts of integers
-                char* buffer = new char[numberOfIntNeeded * 4];
-                memcpy(buffer, &prop_content[index + 2 + iDims], numberOfIntNeeded * sizeof(int));
-                memcpy(pInt8->get(), buffer, iElements * sizeof(char));
-                delete[] buffer;
+    bool isComplex = *prop_it++;
 
-                list->set(i, pInt8);
-                break;
-            }
-            case types::InternalType::ScilabUInt8:
-            {
-                iDims = prop_content[index + 1];
-                pDims = new int[iDims];
-                for (int j = 0; j < iDims; ++j)
-                {
-                    pDims[j] = prop_content[index + 2 + j];
-                    iElements *= pDims[j];
-                }
-                numberOfIntNeeded = ((iElements - 1) / 4) + 1;
+    types::Double* v = new types::Double(static_cast<int>(dims.size()), &dims[0], isComplex);
+    memcpy(v->getReal(), &(*prop_it), v->getSize() * sizeof(double));
 
-                types::UInt8* pUInt8 = new types::UInt8(iDims, pDims);
-                delete[] pDims;
+    if (isComplex)
+    {
+        prop_it += required_length(prop_it, v);
+        memcpy(v->getImg(), &(*prop_it), v->getSize() * sizeof(double));
+    }
 
-                // Use a buffer to prevent copying only parts of integers
-                unsigned char* buffer = new unsigned char[numberOfIntNeeded * 4];
-                memcpy(buffer, &prop_content[index + 2 + iDims], numberOfIntNeeded * sizeof(int));
-                memcpy(pUInt8->get(), buffer, iElements * sizeof(char));
-                delete[] buffer;
+    prop_it += required_length(prop_it, v);
+    return v;
+}
 
-                list->set(i, pUInt8);
-                break;
-            }
-            case types::InternalType::ScilabInt16:
-            {
-                iDims = prop_content[index + 1];
-                pDims = new int[iDims];
-                for (int j = 0; j < iDims; ++j)
-                {
-                    pDims[j] = prop_content[index + 2 + j];
-                    iElements *= pDims[j];
-                }
-                numberOfIntNeeded = ((iElements - 1) / 2) + 1;
+bool encode(std::vector<int>& prop_content, types::Double* v)
+{
+    encodeDims(prop_content, v);
 
-                types::Int16* pInt16 = new types::Int16(iDims, pDims);
-                delete[] pDims;
+    // Flag for complex
+    prop_content.push_back(v->isComplex());
 
-                // Use a buffer to prevent copying only parts of integers
-                short int* buffer = new short int[numberOfIntNeeded * 2];
-                memcpy(buffer, &prop_content[index + 2 + iDims], numberOfIntNeeded * sizeof(int));
-                memcpy(pInt16->get(), buffer, iElements * sizeof(short int));
-                delete[] buffer;
+    const int index = prop_content.size();
+    const int len = required_length(prop_content, v);
+    prop_content.resize(index + len);
 
-                list->set(i, pInt16);
-                break;
-            }
-            case types::InternalType::ScilabUInt16:
-            {
-                iDims = prop_content[index + 1];
-                pDims = new int[iDims];
-                for (int j = 0; j < iDims; ++j)
-                {
-                    pDims[j] = prop_content[index + 2 + j];
-                    iElements *= pDims[j];
-                }
-                numberOfIntNeeded = ((iElements - 1) / 2) + 1;
+    // Using contiguity of the memory, we save the input into 'prop_content'
+    memcpy(&prop_content[index], v->get(), v->getSize() * sizeof(double));
 
-                types::UInt16* pUInt16 = new types::UInt16(iDims, pDims);
-                delete[] pDims;
+    if (v->isComplex())
+    {
+        prop_content.resize(index + 2 * len);
+        // Using contiguity of the memory, we save the input into 'prop_content'
+        memcpy(&prop_content[index + len], v->getImg(), v->getSize() * sizeof(double));
+    }
 
-                // Use a buffer to prevent copying only parts of integers
-                unsigned short int* buffer = new unsigned short int[numberOfIntNeeded * 2];
-                memcpy(buffer, &prop_content[index + 2 + iDims], numberOfIntNeeded * sizeof(int));
-                memcpy(pUInt16->get(), buffer, iElements * sizeof(unsigned short int));
-                delete[] buffer;
+    return true;
+}
 
-                list->set(i, pUInt16);
-                break;
-            }
-            case types::InternalType::ScilabInt32:
-            {
-                iDims = prop_content[index + 1];
-                pDims = new int[iDims];
-                for (int j = 0; j < iDims; ++j)
-                {
-                    pDims[j] = prop_content[index + 2 + j];
-                    iElements *= pDims[j];
-                }
-                numberOfIntNeeded = iElements;
+template<>
+types::String* decode(std::vector<int>::iterator& prop_it)
+{
+    std::vector<int> dims;
+    decodeDims(prop_it, dims);
 
-                types::Int32* pInt32 = new types::Int32(iDims, pDims);
-                delete[] pDims;
+    types::String* v = new types::String(static_cast<int>(dims.size()), &dims[0]);
+    // retrieving the first value iterator
+    std::vector<int>::iterator strData = prop_it + v->getSize();
 
-                memcpy(pInt32->get(), &prop_content[index + 2 + iDims], iElements * sizeof(int));
+    v->set(0, (char*) & (*strData));
+    strData += static_cast<size_t>(*prop_it++);
+    for (int i = 1; i < v->getSize(); i++)
+    {
+        v->set(i, (char*) & (*strData));
 
-                list->set(i, pInt32);
-                break;
-            }
-            case types::InternalType::ScilabUInt32:
-            {
-                iDims = prop_content[index + 1];
-                pDims = new int[iDims];
-                for (int j = 0; j < iDims; ++j)
-                {
-                    pDims[j] = prop_content[index + 2 + j];
-                    iElements *= pDims[j];
-                }
-                numberOfIntNeeded = iElements;
+        // increment the value iterator by the number of element
+        const size_t numberOfElem = static_cast<size_t>(*prop_it) - static_cast<size_t>(*(prop_it - 1)) ;
+        prop_it++;
+        strData += numberOfElem;
+    }
 
-                types::UInt32* pUInt32 = new types::UInt32(iDims, pDims);
-                delete[] pDims;
+    prop_it = strData;
+    return v;
+}
 
-                memcpy(pUInt32->get(), &prop_content[index + 2 + iDims], iElements * sizeof(unsigned int));
+bool encode(std::vector<int>& prop_content, types::String* v)
+{
+    encodeDims(prop_content, v);
 
-                list->set(i, pUInt32);
-                break;
-            }
-            case types::InternalType::ScilabString:
-            {
-                iDims = prop_content[index + 1];
-                pDims = new int[iDims];
-                for (int j = 0; j < iDims; ++j)
-                {
-                    pDims[j] = prop_content[index + 2 + j];
-                    iElements *= pDims[j];
-                }
+    const int index = prop_content.size();
 
-                types::String* pString = new types::String(iDims, pDims);
-                delete[] pDims;
+    std::vector<char*> utf8;
+    utf8.reserve(v->getSize());
 
-                for (int j = 0; j < iElements; ++j)
-                {
-                    int strLen = prop_content[index + 2 + iDims + numberOfIntNeeded];
+    std::vector<size_t> str_len;
+    str_len.reserve(v->getSize());
 
-                    wchar_t* str = new wchar_t[strLen + 1];
-                    memcpy(str, &prop_content[index + 2 + iDims + numberOfIntNeeded + 1], strLen * sizeof(wchar_t));
-                    str[strLen] = '\0';
-                    pString->set(j, str);
-                    delete[] str;
+    int offset = 0;
+    for (int i = 0; i < v->getSize(); i++)
+    {
+        char* str = wide_string_to_UTF8(v->get(i));
+        utf8.push_back(str);
 
-                    numberOfIntNeeded += 1 + strLen;
-                }
-                list->set(i, pString);
-                break;
-            }
-            case types::InternalType::ScilabBool:
-            {
-                iDims = prop_content[index + 1];
-                pDims = new int[iDims];
-                for (int j = 0; j < iDims; ++j)
-                {
-                    pDims[j] = prop_content[index + 2 + j];
-                    iElements *= pDims[j];
-                }
-                numberOfIntNeeded = iElements;
+        // adding the '\0' byte to the len
+        const size_t len = strlen(str) + 1;
+        str_len.push_back(len);
 
-                types::Bool* pBool = new types::Bool(iDims, pDims);
-                delete[] pDims;
+        offset += (len * sizeof(char) + sizeof(int) - 1) / sizeof(int);
+        prop_content.push_back(offset);
+    }
 
-                memcpy(pBool->get(), &prop_content[index + 2 + iDims], iElements * sizeof(int));
-                list->set(i, pBool);
-                break;
-            }
-            default:
-                return 0;
-        }
+    // reserve space for the string offsets and contents
+    prop_content.resize(index + v->getSize() + offset);
 
-        index += 2 + iDims + numberOfIntNeeded;
+    size_t len = str_len[0];
+    memcpy(&prop_content[index + v->getSize()], &(*utf8[0]), len * sizeof(char));
+    for (int i = 1; i < v->getSize(); i++)
+    {
+        len = str_len[i];
+        memcpy(&prop_content[index + v->getSize() + prop_content[index + i - 1]], &(*utf8[i]), len * sizeof(char));
     }
 
-    return list;
+    // free all the string, after being copied
+    for (std::vector<char*>::iterator it = utf8.begin(); it != utf8.end(); it++)
+    {
+        FREE(*it);
+    }
+
+    return true;
 }
 
-bool setPropList(ModelAdapter& adaptor, Controller& controller, const object_properties_t prop, types::InternalType* v)
+
+template<>
+types::List* decode(std::vector<int>::iterator& prop_it)
 {
-    ScicosID adaptee = adaptor.getAdaptee()->id();
+    int length = *prop_it++;
 
-    if (v->getType() == types::InternalType::ScilabDouble)
+    types::List* list = new types::List();
+    for (int i = 0; i < length; i++)
     {
-        types::Double* current = v->getAs<types::Double>();
-        if (current->getSize() != 0)
+        switch (*prop_it++)
         {
-            return false;
+            case types::InternalType::ScilabDouble:
+                list->set(i, decode<types::Double>(prop_it));
+                break;
+            case types::InternalType::ScilabInt8:
+                list->set(i, decode<types::Int8>(prop_it));
+                break;
+            case types::InternalType::ScilabUInt8:
+                list->set(i, decode<types::UInt8>(prop_it));
+                break;
+            case types::InternalType::ScilabInt16:
+                list->set(i, decode<types::Int16>(prop_it));
+                break;
+            case types::InternalType::ScilabUInt16:
+                list->set(i, decode<types::UInt16>(prop_it));
+                break;
+            case types::InternalType::ScilabInt32:
+                list->set(i, decode<types::Int32>(prop_it));
+                break;
+            case types::InternalType::ScilabUInt32:
+                list->set(i, decode<types::UInt32>(prop_it));
+                break;
+            case types::InternalType::ScilabInt64:
+                list->set(i, decode<types::Int64>(prop_it));
+                break;
+            case types::InternalType::ScilabUInt64:
+                list->set(i, decode<types::UInt64>(prop_it));
+                break;
+            case types::InternalType::ScilabString:
+                list->set(i, decode<types::String>(prop_it));
+                break;
+            case types::InternalType::ScilabBool:
+                list->set(i, decode<types::Bool>(prop_it));
+                break;
+            case types::InternalType::ScilabList:
+                list->set(i, decode<types::List>(prop_it));
+                break;
         }
-
-        std::vector<int> prop_content;
-        controller.setObjectProperty(adaptee, BLOCK, prop, prop_content);
-        return true;
     }
+    return list;
+}
 
-    if (v->getType() != types::InternalType::ScilabList)
-    {
-        return false;
-    }
-
-    types::List* list = v->getAs<types::List>();
-
-    // 'prop_content' will be a buffer containing the elements of the list, copied into 'int' type by bits
-    std::vector<int> prop_content (1, list->getSize()); // Save the number of list elements in the first element
-    int index = 1; // Index to point at every new list element
+bool encode(std::vector<int>& prop_content, types::List* list)
+{
+    // Save the number of list elements in the first element
+    prop_content.push_back(list->getSize());
 
     for (int i = 0; i < list->getSize(); ++i)
     {
-        // Save the variable type
-        prop_content.resize(prop_content.size() + 1);
-        prop_content[index] = list->get(i)->getType();
-        // The two previous lines could be simplified to 'prop_content.push_back(list->get(i)->getType());' but they explicit 'index' role
-
-        int  iDims;
-        int* pDims;
-        int  iElements = 1;
-        int  numberOfIntNeeded = 0;
+        // Insert a new element and save its variable type
+        prop_content.push_back(list->get(i)->getType());
+
         switch (list->get(i)->getType())
         {
             case types::InternalType::ScilabDouble:
-            {
-                types::Double* pDouble = list->get(i)->getAs<types::Double>();
-                iDims = pDouble->getDims();
-                pDims = pDouble->getDimsArray();
-                for (int j = 0; j < iDims; ++j)
-                {
-                    iElements *= pDims[j];
-                }
-
-                if (!pDouble->isComplex())
-                {
-                    // It takes 2 int (4 bytes) to save 1 real (1 double: 8 bytes)
-                    // So reserve '2*iElements', '1 + iDims' integers for the matrix dimensions and 1 for the complexity
-                    numberOfIntNeeded = 1 + 2 * iElements;
-                    prop_content.resize(prop_content.size() + 1 + iDims + numberOfIntNeeded);
-                    prop_content[index + 2 + iDims] = 0; // Flag for real
-
-                    // Using contiguity of the memory, we save the input into 'prop_content'
-                    memcpy(&prop_content[index + 2 + iDims + 1], pDouble->getReal(), iElements * sizeof(double));
-                }
-                else
-                {
-                    // It takes 4 int (4 bytes) to save 1 complex (2 double: 16 bytes)
-                    // So reserve '4*iElements', '1 + iDims' integers for the matrix dimensions and 1 for the complexity
-                    numberOfIntNeeded = 1 + 4 * iElements;
-                    prop_content.resize(prop_content.size() + 1 + iDims + numberOfIntNeeded);
-                    prop_content[index + 2 + iDims] = 1; // Flag for complex
-
-                    // Contiguously save the real and complex parts
-                    memcpy(&prop_content[index + 2 + iDims + 1], pDouble->getReal(), iElements * sizeof(double));
-                    memcpy(&prop_content[index + 2 + iDims + 1 + 2 * iElements], pDouble->getImg(), iElements * sizeof(double));
-                }
+                encode(prop_content, list->get(i)->getAs<types::Double>());
                 break;
-            }
             case types::InternalType::ScilabInt8:
-            {
-                types::Int8* pInt8 = list->get(i)->getAs<types::Int8>();
-                iDims = pInt8->getDims();
-                pDims = pInt8->getDimsArray();
-                for (int j = 0; j < iDims; ++j)
-                {
-                    iElements *= pDims[j];
-                }
-
-                // It takes 1 int (4 bytes) to save 4 char (1 byte)
-                // So reserve 'iElements/4' and '1+iDims' integers for the matrix dimensions
-                numberOfIntNeeded = ((iElements - 1) / 4) + 1;
-                prop_content.resize(prop_content.size() + 1 + iDims + numberOfIntNeeded);
-
-                // Using contiguity of the memory, we save the input into 'prop_content'
-                // Use a buffer to fill the entirety of 'prop_content'
-                char* buffer = new char[numberOfIntNeeded * 4];
-                memcpy(buffer, pInt8->get(), iElements * sizeof(char));
-                memcpy(&prop_content[index + 2 + iDims], buffer, numberOfIntNeeded * sizeof(int));
-                delete[] buffer;
+                encode(prop_content, list->get(i)->getAs<types::Int8>());
                 break;
-            }
             case types::InternalType::ScilabUInt8:
-            {
-                types::UInt8* pUInt8 = list->get(i)->getAs<types::UInt8>();
-                iDims = pUInt8->getDims();
-                pDims = pUInt8->getDimsArray();
-                for (int j = 0; j < iDims; ++j)
-                {
-                    iElements *= pDims[j];
-                }
-
-                // It takes 1 int (4 bytes) to save 4 unsigned char (1 byte)
-                // So reserve 'iElements/4' and '1+iDims' integers for the matrix dimensions
-                numberOfIntNeeded = ((iElements - 1) / 4) + 1;
-                prop_content.resize(prop_content.size() + 1 + iDims + numberOfIntNeeded);
-
-                // Using contiguity of the memory, we save the input into 'prop_content'
-                // Use a buffer to fill the entirety of 'prop_content'
-                unsigned char* buffer = new unsigned char[numberOfIntNeeded * 4];
-                memcpy(buffer, pUInt8->get(), iElements * sizeof(unsigned char));
-                memcpy(&prop_content[index + 2 + iDims], buffer, numberOfIntNeeded * sizeof(int));
-                delete[] buffer;
+                encode(prop_content, list->get(i)->getAs<types::UInt8>());
                 break;
-            }
             case types::InternalType::ScilabInt16:
-            {
-                types::Int16* pInt16 = list->get(i)->getAs<types::Int16>();
-                iDims = pInt16->getDims();
-                pDims = pInt16->getDimsArray();
-                for (int j = 0; j < iDims; ++j)
-                {
-                    iElements *= pDims[j];
-                }
-
-                // It takes 1 int (4 bytes) to save 2 short int (2 bytes)
-                // So reserve 'iElements/2' and '1+iDims' integers for the matrix dimensions
-                numberOfIntNeeded = ((iElements - 1) / 2) + 1;
-                prop_content.resize(prop_content.size() + 1 + iDims + numberOfIntNeeded);
-
-                // Using contiguity of the memory, we save the input into 'prop_content'
-                // Use a buffer to fill the entirety of 'prop_content'
-                short int* buffer = new short int[numberOfIntNeeded * 2];
-                memcpy(buffer, pInt16->get(), iElements * sizeof(short int));
-                memcpy(&prop_content[index + 2 + iDims], buffer, numberOfIntNeeded * sizeof(int));
-                delete[] buffer;
+                encode(prop_content, list->get(i)->getAs<types::Int16>());
                 break;
-            }
             case types::InternalType::ScilabUInt16:
-            {
-                types::UInt16* pUInt16 = list->get(i)->getAs<types::UInt16>();
-                iDims = pUInt16->getDims();
-                pDims = pUInt16->getDimsArray();
-                for (int j = 0; j < iDims; ++j)
-                {
-                    iElements *= pDims[j];
-                }
-
-                // It takes 1 int (4 bytes) to save 2 unsigned short int (2 bytes)
-                // So reserve 'iElements/2' and '1+iDims' integers for the matrix dimensions
-                numberOfIntNeeded = ((iElements - 1) / 2) + 1;
-                prop_content.resize(prop_content.size() + 1 + iDims + numberOfIntNeeded);
-
-                // Using contiguity of the memory, we save the input into prop_content
-                // Use a buffer to fill the entirety of 'prop_content'
-                unsigned short int* buffer = new unsigned short int[numberOfIntNeeded * 2];
-                memcpy(buffer, pUInt16->get(), iElements * sizeof(unsigned short int));
-                memcpy(&prop_content[index + 2 + iDims], buffer, numberOfIntNeeded * sizeof(int));
-                delete[] buffer;
+                encode(prop_content, list->get(i)->getAs<types::UInt16>());
                 break;
-            }
             case types::InternalType::ScilabInt32:
-            {
-                types::Int32* pInt32 = list->get(i)->getAs<types::Int32>();
-                iDims = pInt32->getDims();
-                pDims = pInt32->getDimsArray();
-                for (int j = 0; j < iDims; ++j)
-                {
-                    iElements *= pDims[j];
-                }
-
-                // It takes 1 int (4 bytes) to save 1 int (4 bytes)
-                // So reserve 'iElements' and '1+iDims' integers for the matrix dimensions
-                numberOfIntNeeded = iElements;
-                prop_content.resize(prop_content.size() + 1 + iDims + numberOfIntNeeded);
-
-                // Using contiguity of the memory, we save the input into 'prop_content'
-                memcpy(&prop_content[index + 2 + iDims], pInt32->get(), iElements * sizeof(int));
+                encode(prop_content, list->get(i)->getAs<types::Int32>());
                 break;
-            }
             case types::InternalType::ScilabUInt32:
-            {
-                types::UInt32* pUInt32 = list->get(i)->getAs<types::UInt32>();
-                iDims = pUInt32->getDims();
-                pDims = pUInt32->getDimsArray();
-                for (int j = 0; j < iDims; ++j)
-                {
-                    iElements *= pDims[j];
-                }
-
-                // It takes 1 int (4 bytes) to save 1 unsigned int (4 bytes)
-                // So reserve 'iElements' and '1+iDims' integers for the matrix dimensions
-                numberOfIntNeeded = iElements;
-                prop_content.resize(prop_content.size() + 1 + iDims + numberOfIntNeeded);
-
-                // Using contiguity of the memory, we save the input into 'prop_content'
-                memcpy(&prop_content[index + 2 + iDims], pUInt32->get(), iElements * sizeof(unsigned int));
+                encode(prop_content, list->get(i)->getAs<types::UInt32>());
                 break;
-            }
             case types::InternalType::ScilabInt64:
+                encode(prop_content, list->get(i)->getAs<types::Int64>());
+                break;
             case types::InternalType::ScilabUInt64:
-                // int64 and uint64 are not treated yet
-                return false;
+                encode(prop_content, list->get(i)->getAs<types::UInt64>());
+                break;
             case types::InternalType::ScilabString:
-            {
-                types::String* pString = list->get(i)->getAs<types::String>();
-                iDims = pString->getDims();
-                pDims = pString->getDimsArray();
-                for (int j = 0; j < iDims; ++j)
-                {
-                    iElements *= pDims[j];
-                }
-
-                // For the moment, we don't know how many characters each string is long, so only reserve the matrix size
-                prop_content.resize(prop_content.size() + 1 + iDims);
-
-                for (int j = 0; j < iElements; ++j)
-                {
-                    // Extract the input string length and reserve as many characters in 'prop_content'
-                    int strLen = static_cast<int>(wcslen(pString->get(j)));
-                    prop_content.resize(prop_content.size() + 1 + strLen);
-                    prop_content[index + 2 + iDims + numberOfIntNeeded] = strLen;
-
-                    memcpy(&prop_content[index + 2 + iDims + numberOfIntNeeded + 1], pString->get(j), strLen * sizeof(wchar_t));
-                    numberOfIntNeeded += 1 + strLen;
-                }
+                encode(prop_content, list->get(i)->getAs<types::String>());
                 break;
-            }
             case types::InternalType::ScilabBool:
-            {
-                types::Bool* pBool = list->get(i)->getAs<types::Bool>();
-                iDims = pBool->getDims();
-                pDims = pBool->getDimsArray();
-                for (int j = 0; j < iDims; ++j)
-                {
-                    iElements *= pDims[j];
-                }
-
-                // It takes 1 int (4 bytes) to save 1 bool (1 int: 4 bytes)
-                // So reserve 'iElements' and '1+iDims' integers for the matrix dimensions
-                numberOfIntNeeded = iElements;
-                prop_content.resize(prop_content.size() + 1 + iDims + numberOfIntNeeded);
-
-                // Using contiguity of the memory, we save the input into 'prop_content'
-                memcpy(&prop_content[index + 2 + iDims], pBool->get(), iElements * sizeof(int));
+                encode(prop_content, list->get(i)->getAs<types::Bool>());
                 break;
-            }
             default:
                 return false;
         }
-        // Save the matrix (/hypermatrix) dimensions in 'prop_content' and increment index to match the next list element
-        prop_content[index + 1] = iDims;
-        for (int j = 0; j < iDims; ++j)
-        {
-            prop_content[index + 2 + j] = pDims[j];
-        }
-        index += 2 + iDims + numberOfIntNeeded;
     }
 
-    controller.setObjectProperty(adaptee, BLOCK, prop, prop_content);
     return true;
 }
 
@@ -890,12 +665,54 @@ struct odstate
 
     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
     {
-        return getPropList(adaptor, controller, ODSTATE);
+        ScicosID adaptee = adaptor.getAdaptee()->id();
+
+        std::vector<int> prop_content;
+        controller.getObjectProperty(adaptee, BLOCK, ODSTATE, prop_content);
+
+        // corner-case, the empty content is an empty double
+        if (prop_content.empty())
+        {
+            return types::Double::Empty();
+        }
+
+        // the returned value is a list
+        std::vector<int>::iterator prop_it = prop_content.begin();
+        return decode<types::List>(prop_it);
     }
 
     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        return setPropList(adaptor, controller, ODSTATE, v);
+        ScicosID adaptee = adaptor.getAdaptee()->id();
+        std::vector<int> prop_content;
+
+        // corner-case the empty content is an empty-double
+        if (v->getType() == types::InternalType::ScilabDouble)
+        {
+            types::Double* current = v->getAs<types::Double>();
+            if (current->getSize() != 0)
+            {
+                return false;
+            }
+
+            // propr_content is empty
+            controller.setObjectProperty(adaptee, BLOCK, ODSTATE, prop_content);
+            return true;
+        }
+
+        if (v->getType() != types::InternalType::ScilabList)
+        {
+            return false;
+        }
+
+        types::List* list = v->getAs<types::List>();
+        if (!encode(prop_content, list))
+        {
+            return false;
+        }
+
+        controller.setObjectProperty(adaptee, BLOCK, ODSTATE, prop_content);
+        return true;
     }
 };
 
@@ -1147,12 +964,54 @@ struct opar
 
     static types::InternalType* get(const ModelAdapter& adaptor, const Controller& controller)
     {
-        return getPropList(adaptor, controller, OPAR);
+        ScicosID adaptee = adaptor.getAdaptee()->id();
+
+        std::vector<int> prop_content;
+        controller.getObjectProperty(adaptee, BLOCK, OPAR, prop_content);
+
+        // corner-case, the empty content is an empty double
+        if (prop_content.empty())
+        {
+            return types::Double::Empty();
+        }
+
+        // the returned value is a list
+        std::vector<int>::iterator prop_it = prop_content.begin();
+        return decode<types::List>(prop_it);
     }
 
     static bool set(ModelAdapter& adaptor, types::InternalType* v, Controller& controller)
     {
-        return setPropList(adaptor, controller, OPAR, v);
+        ScicosID adaptee = adaptor.getAdaptee()->id();
+        std::vector<int> prop_content;
+
+        // corner-case the empty content is an empty-double
+        if (v->getType() == types::InternalType::ScilabDouble)
+        {
+            types::Double* current = v->getAs<types::Double>();
+            if (current->getSize() != 0)
+            {
+                return false;
+            }
+
+            // prop_content should be empty
+            controller.setObjectProperty(adaptee, BLOCK, OPAR, prop_content);
+            return true;
+        }
+
+        if (v->getType() != types::InternalType::ScilabList)
+        {
+            return false;
+        }
+
+        types::List* list = v->getAs<types::List>();
+        if (!encode(prop_content, list))
+        {
+            return false;
+        }
+
+        controller.setObjectProperty(adaptee, BLOCK, OPAR, prop_content);
+        return true;
     }
 };