40c78c620f2ea641f6204663139c14bb218e0d13
[scilab.git] / scilab / modules / string / sci_gateway / cpp / sci_ascii.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) INRIA - Cong WU
4 *  Copyright (C) 2010 - DIGITEO - Antoine ELIAS
5  *
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at
10  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11  *
12  */
13
14 /* desc : This function convert Scilab string to a vector of ascii code  */
15 /*        or vector of ascii code to Scilab strings.                     */
16 /*        If  txt  is a matrix of string,  ascii(txt)  is equivalent to  */
17 /*          ascii(strcat(txt))                                           */
18 /*-----------------------------------------------------------------------*/
19
20 #include "string_gw.hxx"
21 #include "function.hxx"
22 #include "string.hxx"
23 #include "double.hxx"
24 #include "int.hxx"
25
26 extern "C"
27 {
28 #include <ctype.h>
29 #include "sci_malloc.h"
30 #include "Scierror.h"
31 #include "localization.h"
32 #include "sciprint.h"
33 #include "configvariable_interface.h"
34 }
35
36 #define MAX_ASCII 255
37 /* Benchmark
38 str_test_mat =  ["abscefghijklmnopqrstuvxyz","abscefghijklmnopqrstuvxyz", ..
39 "abscefghijklmnopqrstuvxyz","abscefghijklmnopqrstuvxyz"; ..
40 "abscefghijklmnopqrstuvxyz","abscefghijklmnopqrstuvxyz", ..
41 "abscefghijklmnopqrstuvxyz","abscefghijklmnopqrstuvxyz"];
42
43 tic();
44 for i=1:10000000
45 ascii(["abscefghijklmnopqrstuvxyz","abscefghijklmnopqrstuvxyz"]);
46 end
47 duree = toc();
48
49 printf("\nDUREE 1 = %d seconds\n\n",duree);
50 */
51
52 /* on windows 17 3770 @ 3.4 GHz */
53 /* scilab 4.1.2 : 17 s */
54 /* scilab 5.4.0 : 32 s */
55 /* scilab 6 dev : 15 s */
56
57 /*----------------------------------------------------------------------------*/
58 types::Double* StringToDouble(types::String* _pst);
59 template <typename Y, class T>
60 types::String* TypeToString(T* _pI);
61 /*----------------------------------------------------------------------------*/
62 types::Function::ReturnValue sci_ascii(types::typed_list &in, int _iRetCount, types::typed_list &out)
63 {
64     if (in.size() != 1)
65     {
66         Scierror(77, _("%s: Wrong number of input argument(s): %d expected.\n"), "ascii", 1);
67         return types::Function::Error;
68     }
69
70     types::InternalType* pOut;
71     switch (in[0]->getType())
72     {
73         case types::InternalType::ScilabDouble :
74             pOut = TypeToString<double>(in[0]->getAs<types::Double>());
75             break;
76         case types::InternalType::ScilabString :
77             pOut = StringToDouble(in[0]->getAs<types::String>());
78             break;
79         case types::InternalType::ScilabInt8 :
80             pOut = TypeToString<char>(in[0]->getAs<types::Int8>());
81             break;
82         case types::InternalType::ScilabUInt8 :
83             pOut = TypeToString<unsigned char>(in[0]->getAs<types::UInt8>());
84             break;
85         case types::InternalType::ScilabInt16 :
86             pOut = TypeToString<short>(in[0]->getAs<types::Int16>());
87             break;
88         case types::InternalType::ScilabUInt16 :
89             pOut = TypeToString<unsigned short>(in[0]->getAs<types::UInt16>());
90             break;
91         case types::InternalType::ScilabInt32 :
92             pOut = TypeToString<int>(in[0]->getAs<types::Int32>());
93             break;
94         case types::InternalType::ScilabUInt32 :
95             pOut = TypeToString<unsigned int>(in[0]->getAs<types::UInt32>());
96             break;
97         case types::InternalType::ScilabInt64 :
98             pOut = TypeToString<long long>(in[0]->getAs<types::Int64>());
99             break;
100         case types::InternalType::ScilabUInt64 :
101             pOut = TypeToString<unsigned long long>(in[0]->getAs<types::UInt64>());
102             break;
103         default :
104             Scierror(999, _("%s: Wrong type for argument #%d: Matrix of strings or Integer matrix expected.\n"), "ascii", 1);
105             return types::Function::Error;
106     }
107
108     if (pOut == NULL)
109     {
110         Scierror(999, _("%s : wrong UTF-8 sequence.\n"), "ascii");
111         return types::Function::Error;
112     }
113
114     out.push_back(pOut);
115     return types::Function::OK;
116 }
117 /*--------------------------------------------------------------------------*/
118 template <typename Y, class T>
119 types::String* TypeToString(T* _pI)
120 {
121     types::String* pOut = NULL;
122     int len = _pI->getSize();
123     char* pcText = new char[len + 1];
124     Y* p = _pI->get();
125
126     bool bWarning = getWarningMode() == 0;
127     for (int i = 0; i < len; i++)
128     {
129         if (bWarning == false && p[i] > MAX_ASCII)
130         {
131             sciprint(_("WARNING : \n"));
132             sciprint(_("%s: Wrong value for input argument #%d: Must be between %d and %d.\n"), "ascii", 1, 0, MAX_ASCII);
133             bWarning = true;
134         }
135
136         pcText[i] = static_cast<char>(p[i]);
137
138     }
139     pcText[len] = '\0';
140
141     pOut = new types::String(pcText);
142
143     delete[] pcText;
144     return pOut;
145 }
146 /*--------------------------------------------------------------------------*/
147 types::Double* StringToDouble(types::String* _pst)
148 {
149     types::Double* pOut = NULL;
150     /*compute total length*/
151     int iTotalLen = 0;
152     int iSize = _pst->getSize();
153
154     char** pst = new char*[iSize];
155     int* pstLen = new int[iSize];
156     for (int i = 0 ; i < iSize ; i++)
157     {
158         pst[i] = os_strdup(_pst->get(i));
159         pstLen[i] = (int)strlen(pst[i]);
160         iTotalLen += pstLen[i];
161     }
162
163     if (iTotalLen == 0)
164     {
165         for (int i = 0; i < iSize; ++i)
166         {
167             if (pst[i])
168             {
169                 FREE(pst[i]);
170             }
171         }
172
173         delete[] pst;
174         delete[] pstLen;
175         return types::Double::Empty();
176     }
177
178     pOut = new types::Double(1, iTotalLen);
179     double* pdbl = pOut->get();
180     int index = 0;
181
182     //for each element of input string matrix
183     for (int i = 0 ; i < iSize ; i++)
184     {
185         //for each character of input string matrix
186         for (int j = 0; j < pstLen[i]; j++, index++)
187         {
188             //transform character value as double.
189             pdbl[index] = (unsigned char)pst[i][j];
190         }
191         FREE(pst[i]);
192     }
193
194     delete[] pstLen;
195     delete[] pst;
196     return pOut;
197 }
198 /*--------------------------------------------------------------------------*/