X-Git-Url: http://gitweb.scilab.org/?p=scilab.git;a=blobdiff_plain;f=scilab%2Fmodules%2Fscicos%2Fsrc%2Fcpp%2Fview_scilab%2FModelAdapter.cpp;h=5cc7bd8745a11579ef4015d744e27cf9de00b3df;hp=c2733aa835a9762541ef5f6781b1c9943f883ed1;hb=ddab08a5363f37ebc79f5c905c541f6c8e3755e2;hpb=f527cad141eeafd154017240503193c2a11f89bc diff --git a/scilab/modules/scicos/src/cpp/view_scilab/ModelAdapter.cpp b/scilab/modules/scicos/src/cpp/view_scilab/ModelAdapter.cpp index c2733aa..5cc7bd8 100644 --- a/scilab/modules/scicos/src/cpp/view_scilab/ModelAdapter.cpp +++ b/scilab/modules/scicos/src/cpp/view_scilab/ModelAdapter.cpp @@ -368,520 +368,295 @@ struct dstate } }; -types::InternalType* getPropList(const ModelAdapter& adaptor, const Controller& controller, const object_properties_t prop) +void decodeDims(std::vector::iterator& prop_it, std::vector& 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& prop_content, types::GenericType* v) +{ + const int iDims = v->getDims(); + prop_content.push_back(iDims); - std::vector 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 +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 +T* decode(std::vector::iterator& prop_it) +{ + std::vector dims; + decodeDims(prop_it, dims); - int index = 1; // Index to each element of the returned list + T* v = new T(static_cast(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 +bool encode(std::vector& 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::iterator& prop_it) +{ + std::vector 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(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& 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::iterator& prop_it) +{ + std::vector dims; + decodeDims(prop_it, dims); - types::Int32* pInt32 = new types::Int32(iDims, pDims); - delete[] pDims; + types::String* v = new types::String(static_cast(dims.size()), &dims[0]); + // retrieving the first value iterator + std::vector::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(*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(*prop_it) - static_cast(*(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& 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 utf8; + utf8.reserve(v->getSize()); - for (int j = 0; j < iElements; ++j) - { - int strLen = prop_content[index + 2 + iDims + numberOfIntNeeded]; + std::vector 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::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::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(); - if (current->getSize() != 0) + switch (*prop_it++) { - return false; + case types::InternalType::ScilabDouble: + list->set(i, decode(prop_it)); + break; + case types::InternalType::ScilabInt8: + list->set(i, decode(prop_it)); + break; + case types::InternalType::ScilabUInt8: + list->set(i, decode(prop_it)); + break; + case types::InternalType::ScilabInt16: + list->set(i, decode(prop_it)); + break; + case types::InternalType::ScilabUInt16: + list->set(i, decode(prop_it)); + break; + case types::InternalType::ScilabInt32: + list->set(i, decode(prop_it)); + break; + case types::InternalType::ScilabUInt32: + list->set(i, decode(prop_it)); + break; + case types::InternalType::ScilabInt64: + list->set(i, decode(prop_it)); + break; + case types::InternalType::ScilabUInt64: + list->set(i, decode(prop_it)); + break; + case types::InternalType::ScilabString: + list->set(i, decode(prop_it)); + break; + case types::InternalType::ScilabBool: + list->set(i, decode(prop_it)); + break; + case types::InternalType::ScilabList: + list->set(i, decode(prop_it)); + break; } - - std::vector 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(); - - // 'prop_content' will be a buffer containing the elements of the list, copied into 'int' type by bits - std::vector 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& 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(); - 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()); break; - } case types::InternalType::ScilabInt8: - { - types::Int8* pInt8 = list->get(i)->getAs(); - 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()); break; - } case types::InternalType::ScilabUInt8: - { - types::UInt8* pUInt8 = list->get(i)->getAs(); - 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()); break; - } case types::InternalType::ScilabInt16: - { - types::Int16* pInt16 = list->get(i)->getAs(); - 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()); break; - } case types::InternalType::ScilabUInt16: - { - types::UInt16* pUInt16 = list->get(i)->getAs(); - 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()); break; - } case types::InternalType::ScilabInt32: - { - types::Int32* pInt32 = list->get(i)->getAs(); - 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()); break; - } case types::InternalType::ScilabUInt32: - { - types::UInt32* pUInt32 = list->get(i)->getAs(); - 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()); break; - } case types::InternalType::ScilabInt64: + encode(prop_content, list->get(i)->getAs()); + break; case types::InternalType::ScilabUInt64: - // int64 and uint64 are not treated yet - return false; + encode(prop_content, list->get(i)->getAs()); + break; case types::InternalType::ScilabString: - { - types::String* pString = list->get(i)->getAs(); - 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(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()); break; - } case types::InternalType::ScilabBool: - { - types::Bool* pBool = list->get(i)->getAs(); - 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()); 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 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::iterator prop_it = prop_content.begin(); + return decode(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 prop_content; + + // corner-case the empty content is an empty-double + if (v->getType() == types::InternalType::ScilabDouble) + { + types::Double* current = v->getAs(); + 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(); + 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 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::iterator prop_it = prop_content.begin(); + return decode(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 prop_content; + + // corner-case the empty content is an empty-double + if (v->getType() == types::InternalType::ScilabDouble) + { + types::Double* current = v->getAs(); + 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(); + if (!encode(prop_content, list)) + { + return false; + } + + controller.setObjectProperty(adaptee, BLOCK, OPAR, prop_content); + return true; } };