5c6c0286801d0ffafcb4ca8826cf77d636192bd8
[scilab.git] / scilab / modules / string / sci_gateway / cpp / sci_part.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) INRIA - Allan CORNET , Cong WU
4  *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
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.
13  *
14  */
15
16 /* desc : Let  s[k]  stands for the  k  character of Input_StringMatrixings
17   ( or the  white space character if  k >length(s) ).
18   part  returns  c , a matrix of character Input_StringMatrixings, such that
19   c(i,j)  is the Input_StringMatrixing  "s[v(1)]...s[v(n)]"  (  s=mp(i,j)  ).
20                                                                           */
21 /*------------------------------------------------------------------------*/
22 #include "string_gw.hxx"
23 #include "funcmanager.hxx"
24 #include "function.hxx"
25 #include "string.hxx"
26 #include "double.hxx"
27 #include "overload.hxx"
28
29 extern "C"
30 {
31 #include <string.h>
32 #include <stdio.h>
33 #include "Scierror.h"
34 #include "localization.h"
35 #include "freeArrayOfString.h"
36 #include "partfunction.h"
37 }
38 /*--------------------------------------------------------------------------*/
39 types::Function::ReturnValue sci_part(types::typed_list &in, int _iRetCount, types::typed_list &out)
40 {
41     if (in.size() != 2)
42     {
43         Scierror(999, _("%s: Wrong number of input argument(s): %d expected.\n"), "part", 2);
44         return types::Function::Error;
45     }
46
47     if (_iRetCount > 1)
48     {
49         Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "part", 1);
50         return types::Function::Error;
51     }
52
53     //part([], ...
54     if (in[0]->isDouble() && in[0]->getAs<types::Double>()->isEmpty())
55     {
56         out.push_back(types::Double::Empty());
57         return types::Function::OK;
58     }
59
60     if (in[0]->isString() == false)
61     {
62         std::wstring wstFuncName = L"%" + in[0]->getShortTypeStr() + L"_part";
63         return Overload::call(wstFuncName, in, _iRetCount, out);
64     }
65
66     types::String* pS = in[0]->getAs<types::String>();
67
68     if (in[1]->isDouble() == false)
69     {
70         std::wstring wstFuncName = L"%"  + in[1]->getShortTypeStr() + L"_part";
71         return Overload::call(wstFuncName, in, _iRetCount, out);
72     }
73
74     types::Double* pD = in[1]->getAs<types::Double>();
75     if (pD->isVector() == false && pD->isEmpty() == false)
76     {
77         //non vector
78         Scierror(999, _("%s: Wrong size for input argument #%d: A vector expected.\n"), "part", 2);
79         return types::Function::Error;
80     }
81
82     size_t i_len = pD->getSize();
83     std::vector<int> index(i_len);
84     for (int i = 0 ; i < i_len; i++)
85     {
86         int idx = static_cast<int>(pD->get()[i]);
87         if (idx < 1)
88         {
89             Scierror(36, _("%s: Wrong values for input argument #%d: Must be >= 1.\n"), "part", 2);
90             return types::Function::Error;
91         }
92
93         index[i] = idx;
94     }
95
96     //wchar_t** pwstOut = partfunctionW(pS->get(), pS->getRows(), pS->getCols(), piIndex, pD->getSize());
97     types::String* pOut = new types::String(pS->getRows(), pS->getCols());
98     std::wstring string_in;
99     std::wstring string_out;
100
101     for (int i = 0; i < pS->getSize(); ++i)
102     {
103         string_in.assign(pS->get()[i]);
104         size_t s_len = string_in.size();
105         string_out.assign(i_len, L' ');
106
107         for (int j = 0; j < i_len; ++j)
108         {
109             if (index[j] > s_len)
110             {
111                 continue;
112             }
113
114             string_out[j] = string_in[index[j] - 1];
115         }
116
117         pOut->set(i, string_out.data());
118     }
119
120     out.push_back(pOut);
121     return types::Function::OK;
122 }
123 /*--------------------------------------------------------------------------*/