905c12b8c635b306257d59d4cf113f41e3ea4b3d
[scilab.git] / scilab / modules / types / src / cpp / list.cpp
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2010-2010 - DIGITEO - Bruno JOFRET
4 *
5 *  This file must be used under the terms of the CeCILL.
6 *  This source file is licensed as described in the file COPYING, which
7 *  you should have received as part of this distribution.  The terms
8 *  are also available at
9 *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10 *
11 */
12
13 #include <sstream>
14 #include "double.hxx"
15 #include "list.hxx"
16 #include "listundefined.hxx"
17 #include "listinsert.hxx"
18 #include "types_tools.hxx"
19 #include "scilabexception.hxx"
20
21 #ifndef NDEBUG
22 #include "inspector.hxx"
23 #endif
24
25 extern "C"
26 {
27 #include "localization.h"
28 #include "charEncoding.h"
29 }
30
31 namespace types
32 {
33 /**
34 ** Constructor & Destructor (public)
35 */
36 List::List() : Container()
37 {
38     m_plData = new std::vector<InternalType *>();
39 #ifndef NDEBUG
40     Inspector::addItem(this);
41 #endif
42 }
43
44 List::~List()
45 {
46     if (isDeletable() == true)
47     {
48         std::vector<InternalType *>::iterator itValues;
49         for (itValues = m_plData->begin() ; itValues != m_plData->end() ; ++itValues)
50         {
51             (*itValues)->DecreaseRef();
52             if ((*itValues)->isDeletable())
53             {
54                 delete *itValues;
55             }
56         }
57         delete m_plData;
58     }
59 #ifndef NDEBUG
60     Inspector::removeItem(this);
61 #endif
62 }
63
64 /**
65 ** Private Copy Constructor and data Access
66 */
67 List::List(List *_oListCopyMe)
68 {
69     std::vector<InternalType *>::iterator itValues;
70     m_plData = new std::vector<InternalType *>;
71
72     for (int i = 0 ; i < _oListCopyMe->getData()->size() ; i++)
73     {
74         InternalType* pIT = (*_oListCopyMe->getData())[i];
75         append(pIT);
76     }
77
78     m_iSize = static_cast<int>(m_plData->size());
79 #ifndef NDEBUG
80     Inspector::addItem(this);
81 #endif
82 }
83
84 std::vector<InternalType *> *List::getData()
85 {
86     return m_plData;
87 }
88
89 /**
90 ** size_get
91 ** Return the number of elements in list
92 */
93 int List::getSize()
94 {
95     return static_cast<int>(m_plData->size());
96 }
97
98 /**
99 ** append(InternalType *_typedValue)
100 ** Append the given value to the end of the List
101 */
102 void List::append(InternalType *_typedValue)
103 {
104     _typedValue->IncreaseRef();
105     m_plData->push_back(_typedValue);
106     m_iSize = static_cast<int>(m_plData->size());
107 }
108
109 /**
110 ** Clone
111 ** Create a new List and Copy all values.
112 */
113 InternalType *List::clone()
114 {
115     return new List(this);
116 }
117
118 GenericType* List::getColumnValues(int _iPos)
119 {
120     return NULL;
121 }
122
123 /**
124 ** toString to display Lists
125 ** FIXME : Find a better indentation process
126 */
127 bool List::toString(std::wostringstream& ostr)
128 {
129     if (getSize() == 0)
130     {
131         ostr << L"()" << std::endl;
132     }
133     else
134     {
135         int iPosition = 1;
136         std::vector<InternalType *>::iterator itValues;
137         for (itValues = m_plData->begin() ; itValues != m_plData->end() ; ++itValues, ++iPosition)
138         {
139             ostr << L"     (" << iPosition << L")" << std::endl;
140             //maange lines
141             bool bFinish = (*itValues)->toString(ostr);
142             ostr << std::endl;
143         }
144     }
145     return true;
146 }
147
148 std::vector<InternalType*>      List::extract(typed_list* _pArgs)
149 {
150     std::vector<InternalType*> outList;
151     //check input param
152     if (_pArgs->size() != 1)
153     {
154         return outList;
155     }
156
157     typed_list pArg;
158     int iDims           = (int)_pArgs->size();
159
160     int* piMaxDim       = new int[iDims];
161     int* piCountDim     = new int[iDims];
162
163     //evaluate each argument and replace by appropriate value and compute the count of combinations
164     int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
165     if (iSeqCount == 0)
166     {
167         //outList.push_back(Double::Empty());
168     }
169
170     for (int i = 0 ; i < iSeqCount ; i++)
171     {
172         int idx = (int)pArg[0]->getAs<Double>()->get(i);
173         if (idx > getSize() || idx < 1)
174         {
175             outList.clear();
176             break;
177         }
178         InternalType* pIT = (*m_plData)[idx - 1];
179         outList.push_back(pIT);
180     }
181
182     for (int iArg = 0 ; iArg < pArg.size() ; iArg++)
183     {
184         if (pArg[iArg] != (*_pArgs)[iArg] && pArg[iArg]->isDeletable())
185         {
186             delete pArg[iArg];
187         }
188     }
189     return outList;
190 }
191
192 InternalType* List::insert(typed_list* _pArgs, InternalType* _pSource)
193 {
194     //check input param
195     if (_pArgs->size() != 1)
196     {
197         return NULL;
198     }
199
200     typed_list pArg;
201     int iDims           = (int)_pArgs->size();
202
203     int* piMaxDim       = new int[iDims];
204     int* piCountDim     = new int[iDims];
205
206     int iSeqCount = checkIndexesArguments(this, _pArgs, &pArg, piMaxDim, piCountDim);
207     if (iSeqCount == 0)
208     {
209         //do nothing
210         return this;
211     }
212     else if (iSeqCount > 1)
213     {
214         std::wostringstream os;
215         os << _W("Unable to insert multiple item in a list.\n");
216         throw ast::ScilabError(os.str());
217     }
218
219
220     int idx = (int)pArg[0]->getAs<Double>()->get(0);
221     if (_pSource->isListDelete())
222     {
223         //delete item
224         if (idx == 0)
225         {
226             //do nothing
227             return this;
228         }
229         else if (idx <= m_plData->size())
230         {
231             InternalType* pIT = (*m_plData)[idx - 1];
232             if (pIT)
233             {
234                 pIT->DecreaseRef();
235                 if (pIT->isDeletable())
236                 {
237                     delete pIT;
238                 }
239             }
240             m_plData->erase(m_plData->begin() + idx - 1);
241         }
242     }
243     else if (_pSource->isListInsert())
244     {
245         //insert item
246         if (idx == 0)
247         {
248             std::wostringstream os;
249             os << _W("Index out of bounds.\n");
250             throw ast::ScilabError(os.str());
251         }
252
253         InternalType* pInsert = _pSource->getAs<ListInsert>()->getInsert();
254         pInsert->IncreaseRef();
255         if (idx > m_plData->size())
256         {
257             //try to insert after the last index, increase list size and assign value
258             while (m_plData->size() < idx)
259             {
260                 //incease list size and fill with "Undefined"
261                 InternalType* pUndef = new ListUndefined();
262                 pUndef->IncreaseRef();
263                 m_plData->push_back(new ListUndefined());
264             }
265             (*m_plData)[idx - 1] = pInsert;
266         }
267         else
268         {
269             m_plData->insert(m_plData->begin() + idx - 1, pInsert);
270         }
271     }
272     else if (idx == 0)
273     {
274         //special cazse to insert at the first position
275         InternalType* pInsert = NULL;
276         if (_pSource->isListInsert())
277         {
278             pInsert = _pSource->getAs<ListInsert>()->getInsert();
279         }
280         else
281         {
282             pInsert = _pSource;
283         }
284         pInsert->IncreaseRef();
285         m_plData->insert(m_plData->begin(), pInsert);
286     }
287     else
288     {
289         while (m_plData->size() < idx)
290         {
291             //incease list size and fill with "Undefined"
292             m_plData->push_back(new ListUndefined());
293         }
294
295         InternalType* pIT = (*m_plData)[idx - 1];
296         pIT->DecreaseRef();
297         if (pIT->isDeletable())
298         {
299             delete pIT;
300         }
301
302         _pSource->IncreaseRef();
303         (*m_plData)[idx - 1] = _pSource;
304     }
305
306     m_iSize = (int)m_plData->size();
307     return this;
308 }
309
310 InternalType* List::get(const int _iIndex)
311 {
312     if (_iIndex >= 0 && _iIndex < m_plData->size())
313     {
314         return (*m_plData)[_iIndex];
315     }
316     return NULL;
317 }
318
319 bool List::operator==(const InternalType& it)
320 {
321     if (const_cast<InternalType &>(it).isList() == false)
322     {
323         return false;
324     }
325
326     List* plst = const_cast<InternalType &>(it).getAs<List>();
327
328     if (getSize() != plst->getSize())
329     {
330         return false;
331     }
332
333     for (int i = 0; i < getSize(); i++)
334     {
335         if (*(*m_plData)[i] != *plst->get(i))
336         {
337             return false;
338         }
339     }
340
341     return true;
342 }
343
344 }