2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2011 - DIGITEO - Antoine ELIAS
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
20 #include "localization.hxx"
21 #include "scilabWrite.hxx"
23 #include "types_tools.hxx"
29 m_bDisableCloneInCopyValue = false;
30 SingleStruct** pIT = NULL;
31 int piDims[2] = {0, 0};
32 create(piDims, 2, &pIT, NULL);
34 Inspector::addItem(this);
38 Struct::Struct(int _iRows, int _iCols)
40 m_bDisableCloneInCopyValue = false;
41 SingleStruct** pIT = NULL;
42 SingleStruct *p = new SingleStruct();
43 int piDims[2] = {_iRows, _iCols};
44 create(piDims, 2, &pIT, NULL);
45 for (int i = 0 ; i < getSize() ; i++)
52 Inspector::addItem(this);
56 Struct::Struct(int _iDims, const int* _piDims)
58 m_bDisableCloneInCopyValue = false;
59 SingleStruct** pIT = NULL;
60 SingleStruct *p = new SingleStruct();
61 create(_piDims, _iDims, &pIT, NULL);
62 for (int i = 0 ; i < getSize() ; i++)
69 Inspector::addItem(this);
75 if (isDeletable() == true)
77 for (int i = 0 ; i < m_iSizeMax ; i++)
79 SingleStruct *pStr = m_pRealData[i];
90 Inspector::removeItem(this);
94 Struct::Struct(Struct *_oStructCopyMe)
96 m_bDisableCloneInCopyValue = false;
97 SingleStruct** pIT = NULL;
98 create(_oStructCopyMe->getDimsArray(), _oStructCopyMe->getDims(), &pIT, NULL);
99 for (int i = 0 ; i < getSize() ; i++)
101 pIT[i] = _oStructCopyMe->get(i)->clone();
102 pIT[i]->IncreaseRef();
105 Inspector::addItem(this);
109 bool Struct::getMemory(int* _piSize, int* _piSizePlusType)
112 *_piSizePlusType = 0;
113 SingleStruct** p = get();
114 for (int i = 0; i < getSize(); i++)
117 if (p[i]->getMemory(&piS, &piSPT))
120 *_piSizePlusType += piSPT;
124 *_piSizePlusType += sizeof(Struct);
128 Struct* Struct::clone()
130 return new Struct(this);
133 bool Struct::transpose(InternalType *& out)
143 int piDims[2] = {getCols(), getRows()};
144 Struct * pSt = new Struct(2, piDims);
146 for (int i = 0; i < m_iSize; ++i)
148 pSt->m_pRealData[i]->DecreaseRef();
149 pSt->m_pRealData[i]->killMe();
152 Transposition::transpose_clone(getRows(), getCols(), m_pRealData, pSt->m_pRealData);
160 bool Struct::extract(const std::wstring & name, InternalType *& out)
164 out = extractField(name);
168 wchar_t szError[bsiz];
169 os_swprintf(szError, bsiz, _W("Unknown field : %ls.\n").c_str(), name.c_str());
170 throw std::wstring(szError);
176 bool Struct::invoke(typed_list & in, optional_list & opt, int _iRetCount, typed_list & out, const ast::Exp & e)
183 else if (in.size() == 1)
185 InternalType * arg = in[0];
186 std::vector<InternalType *> _out;
189 std::vector<std::wstring> wstFields;
190 String * pString = arg->getAs<types::String>();
191 for (int i = 0; i < pString->getSize(); ++i)
193 std::wstring wstField(pString->get(i));
194 if (this->exists(wstField))
196 wstFields.push_back(wstField);
200 wchar_t szError[bsiz];
201 os_swprintf(szError, bsiz, _W("Field \"%ls\" does not exists\n").c_str(), wstField.c_str());
202 throw ast::InternalError(szError, 999, e.getLocation());
206 _out = extractFields(wstFields);
207 if (_out.size() == 1)
209 InternalType * pIT = _out[0];
210 if (pIT->isList() && pIT->getAs<List>()->getSize() == 1)
212 out.push_back(pIT->getAs<List>()->get(0));
222 return ArrayOf<SingleStruct*>::invoke(in, opt, _iRetCount, out, e);
225 Struct* Struct::set(int _iRows, int _iCols, SingleStruct* _pIT)
227 if (_iRows < getRows() && _iCols < getCols())
229 return set(_iCols * getRows() + _iRows, _pIT);
234 Struct* Struct::set(int _iRows, int _iCols, const SingleStruct* _pIT)
236 if (_iRows < getRows() && _iCols < getCols())
238 return set(_iCols * getRows() + _iRows, _pIT);
243 Struct* Struct::set(int _iIndex, SingleStruct* _pIT)
245 typedef Struct* (Struct::*set_t)(int, SingleStruct*);
246 Struct* pIT = checkRef(this, (set_t)&Struct::set, _iIndex, _pIT);
252 if (_iIndex < getSize())
254 if (m_bDisableCloneInCopyValue && m_pRealData[_iIndex] == _pIT)
259 InternalType* pOld = m_pRealData[_iIndex];
261 m_pRealData[_iIndex] = copyValue(_pIT);
262 if (m_bDisableCloneInCopyValue == false)
265 m_pRealData[_iIndex]->IncreaseRef();
279 Struct* Struct::set(int _iIndex, const SingleStruct* _pIT)
281 typedef Struct* (Struct::*set_t)(int, const SingleStruct*);
282 Struct* pIT = checkRef(this, (set_t)&Struct::set, _iIndex, _pIT);
288 if (_iIndex < getSize())
290 InternalType* pOld = m_pRealData[_iIndex];
292 m_pRealData[_iIndex] = const_cast<SingleStruct*>(_pIT)->clone();
305 Struct* Struct::set(SingleStruct** _pIT)
307 typedef Struct* (Struct::*set_t)(SingleStruct**);
308 Struct* pIT = checkRef(this, (set_t)&Struct::set, _pIT);
314 for (int i = 0 ; i < getSize() ; i++)
316 if (set(i, _pIT[i]) == NULL)
324 String* Struct::getFieldNames()
328 return get(0)->getFieldNames();
336 bool Struct::exists(const std::wstring& _sKey)
340 return get(0)->exists(_sKey);
348 bool Struct::operator==(const InternalType& it)
350 if (const_cast<InternalType &>(it).isStruct() == false)
355 Struct* pStr = const_cast<InternalType &>(it).getAs<Struct>();
357 for (int i = 0 ; i < getDims() ; i++)
359 if (pStr->getDimsArray()[i] != getDimsArray()[i])
365 for (int i = 0 ; i < getSize() ; i++)
367 if (*get(i) != *pStr->get(i))
375 bool Struct::operator!=(const InternalType& it)
377 return !(*this == it);
380 SingleStruct* Struct::getNullValue()
382 return new SingleStruct();
385 Struct* Struct::createEmpty(int _iDims, int* _piDims, bool /*_bComplex*/)
387 Struct* pStr = new Struct(_iDims, _piDims);
388 pStr->setCloneInCopyValue(!m_bDisableCloneInCopyValue);
392 SingleStruct* Struct::copyValue(SingleStruct* _pData)
394 SingleStruct* pStr = NULL;
395 if (m_bDisableCloneInCopyValue)
399 //std::wcout << L"copyValueWithoutClone -> " << pStr << L" : " << pStr->getRef() << std::endl;
403 pStr = _pData->clone();
409 void Struct::deleteAll()
411 for (int i = 0 ; i < getSize() ; i++)
413 m_pRealData[i]->DecreaseRef();
414 m_pRealData[i]->killMe();
416 delete[] m_pRealData;
420 void Struct::deleteImg()
425 bool Struct::isEmpty()
427 if (getDims() == 2 && getRows() == 0 && getCols() == 0)
434 SingleStruct** Struct::allocData(int _iSize)
436 SingleStruct** pData = new SingleStruct*[_iSize];
437 for (int i = 0 ; i < _iSize ; i++)
444 bool Struct::subMatrixToString(std::wostringstream& /*ostr*/, int* /*_piDims*/, int /*_iDims*/)
449 Struct* Struct::addField(const std::wstring& _sKey)
451 Struct* pIT = checkRef(this, &Struct::addField, _sKey);
459 //change dimension to 1x1 and add field
463 for (int i = 0 ; i < getSize() ; i++)
465 get(i)->addField(_sKey);
471 Struct* Struct::addFieldFront(const std::wstring& _sKey)
473 Struct* pIT = checkRef(this, &Struct::addFieldFront, _sKey);
481 //change dimension to 1x1 and add field
485 for (int i = 0 ; i < getSize() ; i++)
487 get(i)->addFieldFront(_sKey);
493 Struct* Struct::removeField(const std::wstring& _sKey)
495 Struct* pIT = checkRef(this, &Struct::removeField, _sKey);
501 for (int j = 0; j < getSize(); j++)
503 get(j)->removeField(_sKey);
509 bool Struct::toString(std::wostringstream& ostr)
513 ostr << L"0x0 struct array with no field.";
515 else if (getSize() == 1)
517 SingleStruct* pSS = get(0);
518 String* pwstFields = pSS->getFieldNames();
519 if (pwstFields->getSize() == 0)
521 ostr << L"1x1 struct array with no field.";
524 for (int i = 0 ; i < pwstFields->getSize() ; i++)
526 std::wstring wstField(pwstFields->get(i));
527 InternalType* pIT = pSS->get(wstField);
529 // ostr << L" " << wstField << ": ";
530 ostr << L" " << wstField << L": ";
531 ostr << pIT->toStringInLine();
534 pwstFields->killMe();;
539 for (int i = 0 ; i < m_iDims ; i++)
547 ostr << L" struct array with ";
549 String* pwstFields = getFieldNames();
550 ostr << L"fields:" << std::endl;
551 for (int i = 0 ; i < pwstFields->getSize() ; i++)
553 ostr << L" " << pwstFields->get(i) << std::endl;
555 pwstFields->killMe();
561 List* Struct::extractFieldWithoutClone(const std::wstring& _wstField)
563 List* pL = new List();
564 for (int j = 0 ; j < getSize() ; j++)
566 pL->set(j, get(j)->get(_wstField));
572 std::vector<InternalType*> Struct::extractFields(std::vector<std::wstring> _wstFields)
574 std::vector<InternalType*> ResultList;
576 for (int i = 0 ; i < (int)_wstFields.size() ; i++)
578 ResultList.push_back(extractField(_wstFields[i]));
584 InternalType * Struct::extractField(const std::wstring & wstField)
586 if (wstField == L"dims")
588 Int32 * pDims = new Int32(1, getDims());
589 for (int j = 0 ; j < getDims() ; j++)
591 pDims->set(j, getDimsArray()[j]);
600 return get(0)->get(wstField);
604 List * pL = new List();
605 for (int j = 0 ; j < getSize() ; j++)
607 pL->append(get(j)->get(wstField));
615 std::vector<InternalType*> Struct::extractFields(typed_list* _pArgs)
617 std::vector<InternalType*> ResultList;
619 int iDims = (int)_pArgs->size();
622 int* piMaxDim = new int[iDims];
623 int* piCountDim = new int[iDims];
625 int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
632 cleanIndexesArguments(_pArgs, &pArg);
633 ResultList.push_back(createEmptyDouble());
637 Double* pIndex = pArg[0]->getAs<Double>();
639 for (int i = 0 ; i < iSeqCount ; i++)
641 int iIndex = (int)pIndex->get(i);
646 String* pS = getFieldNames();
647 String* pFields = NULL;
650 pFields = new String(1, pS->getSize() + 2);
651 for (int j = 0; j < pS->getSize(); j++)
653 pFields->set(2 + j, pS->get(j));
660 pFields = new String(1, 2);
663 pFields->set(0, L"st");
664 pFields->set(1, L"dims");
666 ResultList.push_back(pFields);
668 else if (iIndex == 2)
671 Int32* pDims = new Int32(1, getDims());
672 for (int j = 0 ; j < getDims() ; j++)
674 pDims->set(j, getDimsArray()[j]);
677 ResultList.push_back(pDims);
679 else if (getSize() == 0)
683 else if (iIndex > (int)get(0)->getNumFields() + 2)
687 else if (getSize() == 1)
690 const std::vector<InternalType*> & pData = get(0)->getData();
691 ResultList.push_back(pData[iIndex - 3]->clone());
695 //return each elements for sub structs in a list
696 List* pL = new List();
698 for (int j = 0 ; j < getSize() ; j++)
700 //-2 for fieldlist and dims, -1 for indexed at 0
701 const std::vector<InternalType*> & pData = get(j)->getData();
702 pL->append(pData[iIndex - 3]->clone());
705 ResultList.push_back(pL);
710 cleanIndexesArguments(_pArgs, &pArg);
714 Struct* Struct::resize(int _iNewRows, int _iNewCols)
716 int piDims[2] = {_iNewRows, _iNewCols};
717 return resize(piDims, 2);
720 Struct* Struct::resize(int* _piDims, int _iDims)
722 typedef Struct* (Struct::*resize_t)(int*, int);
723 Struct* pIT = checkRef(this, (resize_t)&Struct::resize, _piDims, _iDims);
729 m_bDisableCloneInCopyValue = true;
730 Struct* pSRes = ArrayOf<SingleStruct*>::resize(_piDims, _iDims)->getAs<Struct>();
731 m_bDisableCloneInCopyValue = false;
734 // insert field(s) only in new element(s) of current struct
735 String* pFields = getFieldNames();
736 for (int iterField = 0; iterField < pFields->getSize(); iterField++)
738 for (int iterStruct = 0; iterStruct < getSize(); iterStruct++)
740 get(iterStruct)->addField(pFields->get(iterField));
750 InternalType* Struct::insertWithoutClone(typed_list* _pArgs, InternalType* _pSource)
752 //std::wcout << L"insertWithoutClone start" << std::endl;
753 m_bDisableCloneInCopyValue = true;
754 InternalType* pIT = insert(_pArgs, _pSource);
755 _pSource->IncreaseRef();
756 //std::wcout << L"insertWithoutClone -> " << _pSource << L" : " << _pSource->getRef() << std::endl;
757 m_bDisableCloneInCopyValue = false;
758 //std::wcout << L"insertWithoutClone end" << std::endl;
762 InternalType* Struct::extractWithoutClone(typed_list* _pArgs)
764 //std::wcout << L"extractWithoutClone start" << std::endl;
765 m_bDisableCloneInCopyValue = true;
766 InternalType* pIT = extract(_pArgs);
767 m_bDisableCloneInCopyValue = false;
768 //std::wcout << L"extractWithoutClone end" << std::endl;
772 void Struct::setCloneInCopyValue(bool _val)
774 m_bDisableCloneInCopyValue = !_val;
777 void Struct::deleteData(SingleStruct* data)
785 Struct* Struct::createEmpty()