utf: module string 2
[scilab.git] / scilab / modules / string / sci_gateway / cpp / sci_tokens.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) Digiteo 2011 - Cedric DELAMARRE
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
14 #include "function.hxx"
15 #include "string.hxx"
16 #include "list.hxx"
17 #include "double.hxx"
18 #include "function.hxx"
19 #include "string_gw.hxx"
20
21 extern "C"
22 {
23 #include "sci_malloc.h"
24 #include "os_string.h"
25 #include "tokens.h"
26 #include "core_math.h"
27 #include "localization.h"
28 #include "Scierror.h"
29 #include "charEncoding.h"
30 }
31
32 #include <sciprint.h>
33
34 types::Function::ReturnValue sci_tokens(types::typed_list &in, int _iRetCount, types::typed_list &out)
35 {
36     types::String* pOutString   = NULL;
37     types::String* pString      = NULL;
38     types::String* pCharSample  = NULL;
39     wchar_t* seps = NULL;
40     wchar_t* input = NULL;
41     int sizeSeps = 0;
42
43     if (in.size() > 2 || in.size() == 0)
44     {
45         Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "tokens", 1, 2);
46         return types::Function::Error;
47     }
48     if (_iRetCount != 1)
49     {
50         Scierror(78, _("%s: Wrong number of output argument(s): %d expected.\n"), "tokens", 1);
51         return types::Function::Error;
52     }
53
54     // first arg
55     if (in[0]->isString() == false)
56     {
57         Scierror(999, _("%s: Wrong type for input argument #%d: String expected.\n"), "tokens", 1);
58         return types::Function::Error;
59     }
60     pString = in[0]->getAs<types::String>();
61     if (pString->isScalar() == false)
62     {
63         Scierror(999, _("%s: Wrong size for input argument #%d.\n"), "tokens", 1);
64         return types::Function::Error;
65     }
66     if (strlen(pString->get(0)) == 0)
67     {
68         types::Double* pOutDouble = types::Double::Empty();
69         out.push_back(pOutDouble);
70         return types::Function::OK;
71     }
72
73     // second arg
74     if (in.size() == 2)
75     {
76         if (in[1]->isString() == false)
77         {
78             Scierror(999, _("%s: Wrong type for input argument #%d: String expected.\n"), "tokens", 2);
79             return types::Function::Error;
80         }
81         pCharSample = in[1]->getAs<types::String>();
82
83         if (pCharSample->getSize() == 0)
84         {
85             Scierror(999, _("%s: Wrong size for input argument #%d.\n"), "tokens", 2);
86             return types::Function::Error;
87         }
88         sizeSeps = pCharSample->getSize();
89         seps = (wchar_t*)MALLOC((sizeSeps + 1) * sizeof(wchar_t));
90         for (int i = 0; i < sizeSeps ; i++)
91         {
92             wchar_t* t = to_wide_string(pCharSample->get()[i]);
93             int iLen = (int)wcslen(t);
94             if (iLen > 1 || iLen < 0)
95             {
96                 FREE(t);
97                 FREE(seps);
98                 Scierror(999, _("%s: Wrong type for input argument #%d: Char(s) expected.\n"), "tokens", 2);
99                 delete pOutString;
100                 return types::Function::Error;
101             }
102
103             seps[i] = t[0];
104             FREE(t);
105         }
106     }
107     else // default delimiters are ' ' and Tabulation
108     {
109         sizeSeps = 2;
110         seps = (wchar_t*)MALLOC((sizeSeps + 1) * sizeof(wchar_t));
111         seps[0] = L' ';
112         seps[1] = L'\t';
113     }
114
115     seps[sizeSeps] = '\0';
116
117     // perfom operation
118     int dimsArray[2] = {0, 1};
119     int dims = 2;
120
121     input = to_wide_string(pString->get()[0]);
122     wchar_t** Output_Strings = stringTokens(input, seps, &dimsArray[0]);
123     FREE(seps);
124     if (Output_Strings == NULL)
125     {
126         //return empty matrix
127         out.push_back(types::Double::Empty());
128         return types::Function::OK;
129     }
130     else
131     {
132         pOutString  = new types::String(dims, dimsArray);
133         for (int i = 0 ; i < dimsArray[0] ; i++)
134         {
135             char* c = wide_string_to_UTF8(Output_Strings[i]);
136             pOutString->set(i, c);
137             FREE(Output_Strings[i]);
138             FREE(c);
139         }
140         FREE(Output_Strings);
141     }
142
143     out.push_back(pOutString);
144     return types::Function::OK;
145 }
146