Replace Min, Max and Abs by std::min, std::max and std::abs
[scilab.git] / scilab / modules / ast / src / cpp / types / string.cpp
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2008-2008 - DIGITEO - Antoine ELIAS
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 "core_math.h"
15 #include "string.hxx"
16 #include "tostring_common.hxx"
17 #include "configvariable.hxx"
18
19 extern "C"
20 {
21 #include "charEncoding.h"
22 #include "os_wcsdup.h"
23 #include "sci_malloc.h"
24 }
25
26 using namespace std;
27
28 #define SIZE_BETWEEN_TWO_VALUES                 2
29 #define SPACE_BETWEEN_TWO_VALUES                L"  "
30
31 namespace types
32 {
33 String::~String()
34 {
35     if (isDeletable() == true)
36     {
37         deleteAll();
38     }
39 #ifndef NDEBUG
40     //Inspector::removeItem(this);
41 #endif
42 }
43
44 String::String(int _iDims, int* _piDims)
45 {
46     wchar_t** pwsData = NULL;
47     create(_piDims, _iDims, &pwsData, NULL);
48 #ifndef NDEBUG
49     //Inspector::addItem(this);
50 #endif
51 }
52
53 String::String(const wchar_t* _pwstData)
54 {
55     wchar_t** pwsData = NULL;
56     int piDims[] = {1, 1};
57     create(piDims, 2, &pwsData, NULL);
58     set(0, 0, _pwstData);
59 #ifndef NDEBUG
60     //Inspector::addItem(this);
61 #endif
62 }
63
64 String::String(const char *_pstData)
65 {
66     wchar_t** pwsData = NULL;
67     int piDims[] = {1, 1};
68     create(piDims, 2, &pwsData, NULL);
69     wchar_t* data = to_wide_string(const_cast<char*>(_pstData));
70     set(0, 0, data);
71     FREE(data);
72 #ifndef NDEBUG
73     //Inspector::addItem(this);
74 #endif
75 }
76
77 String::String(int _iRows, int _iCols)
78 {
79     wchar_t** pwsData = NULL;
80     int piDims[] = {_iRows, _iCols};
81     create(piDims, 2, &pwsData, NULL);
82 #ifndef NDEBUG
83     //Inspector::addItem(this);
84 #endif
85 }
86
87 String::String(int _iRows, int _iCols, wchar_t const* const* _pstData)
88 {
89     wchar_t** pwsData = NULL;
90     int piDims[] = {_iRows, _iCols};
91     create(piDims, 2, &pwsData, NULL);
92     for (int i = 0 ; i < m_iSize ; i++)
93     {
94         set(i, os_wcsdup(_pstData[i]));
95     }
96 #ifndef NDEBUG
97     //Inspector::addItem(this);
98 #endif
99 }
100
101 InternalType* String::clone()
102 {
103     String *pstClone = new String(getDims(), getDimsArray());
104     pstClone->set(m_pRealData);
105     return pstClone;
106 }
107
108 void String::whoAmI()
109 {
110     cout << "types::String";
111 }
112
113 void String::deleteString(int _iPos)
114 {
115     if (m_pRealData != NULL)
116     {
117         if (m_pRealData[_iPos] != NULL)
118         {
119             FREE(m_pRealData[_iPos]);
120             m_pRealData[_iPos] = NULL;
121         }
122     }
123 }
124
125 void String::deleteAll()
126 {
127     for (int i = 0 ; i < getSize() ; i++)
128     {
129         deleteString(i);
130     }
131     delete[] m_pRealData;
132     m_pRealData = NULL;
133 }
134
135 void String::deleteImg()
136 {
137     return;
138 }
139
140 bool String::subMatrixToString(wostringstream& ostr, int* _piDims, int _iDims)
141 {
142     int iPrecision = ConfigVariable::getFormatSize();
143     int iLineLen = ConfigVariable::getConsoleWidth();
144     int iMaxLines = ConfigVariable::getConsoleLines();
145     int iCurrentLine = 0;
146
147     if (isScalar())
148     {
149         _piDims[0] = 0;
150         _piDims[1] = 0;
151         int iPos = getIndex(_piDims);
152         ostr << L" " << get(iPos) << endl;
153     }
154     else if (getCols() == 1)
155     {
156         int iMaxLen = 0;
157         for (int i = 0 ; i < getRows() ; i++)
158         {
159             _piDims[1] = 0;
160             _piDims[0] = i;
161             int iPos = getIndex(_piDims);
162             iMaxLen = std::max(iMaxLen, static_cast<int>(wcslen(get(iPos))));
163         }
164
165         iMaxLen += 2;
166
167         for (int i = m_iRows1PrintState ; i < getRows() ; i++)
168         {
169             iCurrentLine += 2;
170             if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) || (iMaxLines != 0 && iCurrentLine >= iMaxLines))
171             {
172                 m_iRows1PrintState = i;
173                 return false;
174             }
175
176             _piDims[1] = 0;
177             _piDims[0] = i;
178             int iPos = getIndex(_piDims);
179
180             ostr << L"!";
181             configureStream(&ostr, iMaxLen, iPrecision, ' ');
182             ostr << left << get(iPos);
183             ostr << L"!" << endl;
184             if ((i + 1) < m_iSize)
185             {
186                 //for all but last one
187                 ostr << L"!";
188                 configureStream(&ostr, iMaxLen, iPrecision, ' ');
189                 ostr << left << L" ";
190                 ostr << L"!" << endl;
191             }
192         }
193     }
194     else if (getRows() == 1)
195     {
196         wostringstream ostemp;
197         int iLastVal = m_iCols1PrintState;
198
199         for (int i = m_iCols1PrintState ; i < getCols() ; i++)
200         {
201             _piDims[0] = 0;
202             _piDims[1] = i;
203             int iPos = getIndex(_piDims);
204
205             int iLen = 0;
206             int iCurLen = static_cast<int>(wcslen(get(iPos)));
207             iLen = iCurLen + SIZE_BETWEEN_TWO_VALUES + static_cast<int>(ostemp.str().size());
208             if (iLen > iLineLen)
209             {
210                 //Max length, new line
211                 iCurrentLine += 4; //"column x to Y" + empty line + value + empty line
212                 if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) || (iMaxLines != 0 && iCurrentLine >= iMaxLines))
213                 {
214                     m_iCols1PrintState = iLastVal;
215                     return false;
216                 }
217
218                 ostr << endl << L"       column " << iLastVal + 1 << L" to " << i << endl << endl;
219                 ostr << L"!" << ostemp.str() << L"!" << endl;
220                 ostemp.str(L"");
221                 iLastVal = i;
222             }
223
224             configureStream(&ostemp, iCurLen + 2, iPrecision, ' ');
225             ostemp << left << get(iPos);
226         }
227
228         if (iLastVal != 0)
229         {
230             ostr << endl << L"       column " << iLastVal + 1 << L" to " << getCols() << endl << endl;
231         }
232         ostr << L"!" << ostemp.str() << L"!" << endl;
233     }
234     else //Matrix
235     {
236         wostringstream ostemp;
237         int iLen = 0;
238         int iLastCol = m_iCols1PrintState;
239
240         //Array with the max printed size of each col
241         int *piSize = new int[getCols()];
242         memset(piSize, 0x00, getCols() * sizeof(int));
243
244         for (int iCols1 = m_iCols1PrintState ; iCols1 < getCols() ; iCols1++)
245         {
246             for (int iRows1 = 0 ; iRows1 < getRows() ; iRows1++)
247             {
248                 _piDims[1] = iCols1;
249                 _piDims[0] = iRows1;
250                 int iPos = getIndex(_piDims);
251                 piSize[iCols1] = std::max(piSize[iCols1], static_cast<int>(wcslen(get(iPos))));
252             }
253
254             if (iLen + piSize[iCols1] > iLineLen)
255             {
256                 //find the limit, print this part
257                 for (int iRows2 = m_iRows2PrintState ; iRows2 < getRows() ; iRows2++)
258                 {
259                     iCurrentLine += 2;
260                     if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) ||
261                             ( (iMaxLines != 0 && iCurrentLine + 3 >= iMaxLines && iRows2 == m_iRows2PrintState) ||
262                               (iMaxLines != 0 && iCurrentLine + 1 >= iMaxLines && iRows2 != m_iRows2PrintState)))
263                     {
264                         if (m_iRows2PrintState == 0 && iRows2 != 0)
265                         {
266                             //add header
267                             ostr << std::endl << L"       column " << iLastCol + 1 << L" to " << iCols1 << std::endl << std::endl;
268                         }
269                         ostr << ostemp.str();
270                         m_iRows2PrintState = iRows2;
271                         m_iCols1PrintState = iLastCol;
272                         return false;
273                     }
274
275                     ostemp << L"!";
276                     for (int iCols2 = iLastCol ; iCols2 < iCols1 ; iCols2++)
277                     {
278                         _piDims[0] = iRows2;
279                         _piDims[1] = iCols2;
280                         int iPos = getIndex(_piDims);
281                         configureStream(&ostemp, piSize[iCols2], iPrecision, ' ');
282                         ostemp << left << get(iPos) << SPACE_BETWEEN_TWO_VALUES;
283                     }
284
285                     ostemp << L"!" << endl;
286                     if ((iRows2 + 1) != m_iRows)
287                     {
288                         ostemp << L"!";
289                         configureStream(&ostemp, iLen, iPrecision, ' ');
290                         ostemp << left << L" ";
291                         ostemp << L"!" << endl;
292                     }
293                 }
294
295                 iLen = 0;
296                 iCurrentLine += 2;
297                 if (m_iRows2PrintState == 0)
298                 {
299                     iCurrentLine += 3;
300                     ostr << std::endl << L"       column " << iLastCol + 1 << L" to " << iCols1 << std::endl << std::endl;
301                 }
302                 ostr << ostemp.str();
303                 ostemp.str(L"");
304                 iLastCol = iCols1;
305                 m_iRows2PrintState = 0;
306                 m_iCols1PrintState = 0;
307             }
308             iLen += piSize[iCols1] + SIZE_BETWEEN_TWO_VALUES;
309         }
310
311         for (int iRows2 = m_iRows2PrintState ; iRows2 < getRows() ; iRows2++)
312         {
313             iCurrentLine += 2;
314             if ((iMaxLines == 0 && iCurrentLine >= MAX_LINES) || (iMaxLines != 0 && iCurrentLine >= iMaxLines))
315             {
316                 if (m_iRows2PrintState == 0 && iLastCol != 0)
317                 {
318                     //add header
319                     ostr << std::endl << L"       column " << iLastCol + 1 << L" to " << getCols() << std::endl << std::endl;
320                 }
321
322                 ostr << ostemp.str();
323                 m_iRows2PrintState = iRows2;
324                 m_iCols1PrintState = iLastCol;
325                 return false;
326             }
327
328             ostemp << L"!";
329             iLen = 0;
330             for (int iCols2 = iLastCol ; iCols2 < getCols() ; iCols2++)
331             {
332                 _piDims[0] = iRows2;
333                 _piDims[1] = iCols2;
334                 int iPos = getIndex(_piDims);
335
336                 configureStream(&ostemp, piSize[iCols2], iPrecision, ' ');
337                 ostemp << left << get(iPos) << SPACE_BETWEEN_TWO_VALUES;
338                 iLen += piSize[iCols2] + SIZE_BETWEEN_TWO_VALUES;
339             }
340             ostemp << L"!" << endl;
341             if ((iRows2 + 1) != m_iRows)
342             {
343                 ostemp << L"!";
344                 configureStream(&ostemp, iLen, iPrecision, ' ');
345                 ostemp << left << L" ";
346                 ostemp << L"!" << endl;
347             }
348         }
349
350         if (m_iRows2PrintState == 0 && iLastCol != 0)
351         {
352             ostr << std::endl << L"       column " << iLastCol + 1 << L" to " << getCols() << std::endl << std::endl;
353         }
354         ostr << ostemp.str();
355     }
356
357     return true;
358 }
359
360 bool String::operator==(const InternalType& it)
361 {
362     if (const_cast<InternalType&>(it).isString() == false)
363     {
364         return false;
365     }
366
367     String* pS = const_cast<InternalType&>(it).getAs<types::String>();
368
369     if (pS->getRows() != getRows() || pS->getCols() != getCols())
370     {
371         return false;
372     }
373
374     wchar_t **p1 = get();
375     wchar_t **p2 = pS->get();
376
377     for (int i = 0 ; i < getSize() ; i++)
378     {
379         if (wcscmp(p1[i], p2[i]) != 0)
380         {
381             return false;
382         }
383     }
384     return true;
385 }
386
387 bool String::operator!=(const InternalType& it)
388 {
389     return !(*this == it);
390 }
391
392 wchar_t* String::getNullValue()
393 {
394     return os_wcsdup(L"");
395 }
396
397 String* String::createEmpty(int _iDims, int* _piDims, bool _bComplex)
398 {
399     return new String(_iDims, _piDims);
400 }
401
402 wchar_t* String::copyValue(wchar_t* _pwstData)
403 {
404     return os_wcsdup(_pwstData);
405 }
406
407 wchar_t* String::copyValue(const wchar_t* _pwstData)
408 {
409     return os_wcsdup(_pwstData);
410 }
411
412 bool String::set(int _iPos, const wchar_t* _pwstData)
413 {
414     if (m_pRealData == NULL || _iPos >= m_iSize)
415     {
416         return false;
417     }
418     m_pRealData[_iPos] = copyValue(_pwstData);
419     return true;
420 }
421
422 bool String::set(int _iRows, int _iCols, const wchar_t* _pwstData)
423 {
424     int piIndexes[2] = {_iRows, _iCols};
425     return set(getIndex(piIndexes), _pwstData);
426 }
427
428 bool String::set(const wchar_t* const* _pwstData)
429 {
430     if (m_pRealData == NULL)
431     {
432         return false;
433     }
434
435     for (int i = 0 ; i < getSize() ; i++)
436     {
437         if (set(i, _pwstData[i]) == false)
438         {
439             return false;
440         }
441     }
442     return true;
443 }
444
445 bool String::set(int _iPos, const char* _pcData)
446 {
447     if (m_pRealData == NULL || _iPos >= m_iSize)
448     {
449         return false;
450     }
451     m_pRealData[_iPos] = to_wide_string(_pcData);
452     return true;
453 }
454
455 bool String::set(int _iRows, int _iCols, const char* _pcData)
456 {
457     int piIndexes[2] = {_iRows, _iCols};
458     return set(getIndex(piIndexes), _pcData);
459 }
460
461 bool String::set(const char* const* _pstrData)
462 {
463     if (m_pRealData == NULL)
464     {
465         return false;
466     }
467
468     for (int i = 0 ; i < getSize() ; i++)
469     {
470         if (set(i, _pstrData[i]) == false)
471         {
472             return false;
473         }
474     }
475     return true;
476 }
477
478 wchar_t** String::allocData(int _iSize)
479 {
480     wchar_t** pStr = new wchar_t*[_iSize];
481     memset(pStr, 0x00, _iSize * sizeof(wchar_t*));
482     return pStr;
483 }
484 }
485