1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
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 #ifndef __SCILABABSTRACTMEMORYALLOCATOR_H__
17 #define __SCILABABSTRACTMEMORYALLOCATOR_H__
18 
19 extern "C"
20 {
21 #include "api_scilab.h"
22 }
23 #include "ScilabAbstractEnvironmentWrapper.hxx"
24 #include "ScilabAbstractEnvironmentException.hxx"
25 
26 #include <iostream>
27 
28 namespace org_modules_external_objects
29 {
30 
31 class ComplexDataPointers
32 {
33 public:
34 
ComplexDataPointers(double * _realPtr,double * _imagPtr)35     ComplexDataPointers(double * _realPtr, double * _imagPtr) : realPtr(_realPtr), imagPtr(_imagPtr) { }
ComplexDataPointers()36     ComplexDataPointers() : realPtr(0), imagPtr(0) { }
~ComplexDataPointers()37     ~ComplexDataPointers() { }
38 
39     double * const realPtr;
40     double * const imagPtr;
41 };
42 
43 class ScilabStackAllocator
44 {
45 
46 public:
47 
ScilabStackAllocator(void * pvCtx,int _position)48     ScilabStackAllocator(void * pvCtx, int _position) : position(_position), pvCtx(pvCtx) { }
49 
~ScilabStackAllocator()50     ~ScilabStackAllocator() { }
51 
52 protected:
53 
54     int position;
55     void * pvCtx;
56 
create(void * pvCtx,const int position,const int rows,const int cols,double * ptr)57     inline static void create(void * pvCtx, const int position, const int rows, const int cols, double * ptr)
58     {
59         SciErr err = createMatrixOfDouble(pvCtx, position, rows, cols, ptr);
60         checkError(err);
61     }
62 
alloc(void * pvCtx,const int position,const int rows,const int cols,double * ptr)63     inline static double * alloc(void * pvCtx, const int position, const int rows, const int cols, double * ptr)
64     {
65         double * _ptr = 0;
66         SciErr err = allocMatrixOfDouble(pvCtx, position, rows, cols, &_ptr);
67         checkError(err);
68 
69         return _ptr;
70     }
71 
create(void * pvCtx,const int position,const int rows,const int cols,float * ptr)72     inline static void create(void * pvCtx, const int position, const int rows, const int cols, float * ptr)
73     {
74         double * _ptr = alloc(pvCtx, position, rows, cols, (double *)0);
75         for (int i = 0; i < rows * cols; i++)
76         {
77             _ptr[i] = static_cast<double>(ptr[i]);
78         }
79     }
80 
alloc(void * pvCtx,const int position,const int rows,const int cols,float * ptr)81     inline static float * alloc(void * pvCtx, const int position, const int rows, const int cols, float * ptr)
82     {
83         return (float *)alloc(pvCtx, position, rows, cols, (double *)0);
84     }
85 
create(void * pvCtx,const int position,const int rows,const int cols,double * re,double * im)86     inline static void create(void * pvCtx, const int position, const int rows, const int cols, double * re, double * im)
87     {
88         SciErr err = createComplexMatrixOfDouble(pvCtx, position, rows, cols, re, im);
89         checkError(err);
90     }
91 
alloc(void * pvCtx,const int position,const int rows,const int cols,double * re,double * im)92     inline static ComplexDataPointers alloc(void * pvCtx, const int position, const int rows, const int cols, double * re, double * im)
93     {
94         double * _re = 0, * _im = 0;
95         SciErr err = allocComplexMatrixOfDouble(pvCtx, position, rows, cols, &_re, &_im);
96         checkError(err);
97 
98         return ComplexDataPointers(_re, _im);
99     }
100 
create(void * pvCtx,const int position,const int rows,const int cols,char * ptr)101     inline static void create(void * pvCtx, const int position, const int rows, const int cols, char * ptr)
102     {
103         SciErr err = createMatrixOfInteger8(pvCtx, position, rows, cols, ptr);
104         checkError(err);
105     }
106 
alloc(void * pvCtx,const int position,const int rows,const int cols,char * ptr)107     inline static char * alloc(void * pvCtx, const int position, const int rows, const int cols, char * ptr)
108     {
109         char * _ptr = 0;
110         SciErr err = allocMatrixOfInteger8(pvCtx, position, rows, cols, &_ptr);
111         checkError(err);
112 
113         return _ptr;
114     }
115 
create(void * pvCtx,const int position,const int rows,const int cols,unsigned char * ptr)116     inline static void create(void * pvCtx, const int position, const int rows, const int cols, unsigned char * ptr)
117     {
118         SciErr err = createMatrixOfUnsignedInteger8(pvCtx, position, rows, cols, ptr);
119         checkError(err);
120     }
121 
alloc(void * pvCtx,const int position,const int rows,const int cols,unsigned char * ptr)122     inline static unsigned char * alloc(void * pvCtx, const int position, const int rows, const int cols, unsigned char * ptr)
123     {
124         unsigned char * _ptr = 0;
125         SciErr err = allocMatrixOfUnsignedInteger8(pvCtx, position, rows, cols, &_ptr);
126         checkError(err);
127 
128         return _ptr;
129     }
130 
create(void * pvCtx,const int position,const int rows,const int cols,short * ptr)131     inline static void create(void * pvCtx, const int position, const int rows, const int cols, short * ptr)
132     {
133         SciErr err = createMatrixOfInteger16(pvCtx, position, rows, cols, ptr);
134         checkError(err);
135     }
136 
alloc(void * pvCtx,const int position,const int rows,const int cols,short * ptr)137     inline static short * alloc(void * pvCtx, const int position, const int rows, const int cols, short * ptr)
138     {
139         short * _ptr = 0;
140         SciErr err = allocMatrixOfInteger16(pvCtx, position, rows, cols, &_ptr);
141         checkError(err);
142 
143         return _ptr;
144     }
145 
create(void * pvCtx,const int position,const int rows,const int cols,unsigned short * ptr)146     inline static void create(void * pvCtx, const int position, const int rows, const int cols, unsigned short * ptr)
147     {
148         SciErr err = createMatrixOfUnsignedInteger16(pvCtx, position, rows, cols, ptr);
149         checkError(err);
150     }
151 
alloc(void * pvCtx,const int position,const int rows,const int cols,unsigned short * ptr)152     inline static unsigned short * alloc(void * pvCtx, const int position, const int rows, const int cols, unsigned short * ptr)
153     {
154         unsigned short * _ptr = 0;
155         SciErr err = allocMatrixOfUnsignedInteger16(pvCtx, position, rows, cols, &_ptr);
156         checkError(err);
157 
158         return _ptr;
159     }
160 
create(void * pvCtx,const int position,const int rows,const int cols,int * ptr)161     inline static void create(void * pvCtx, const int position, const int rows, const int cols, int * ptr)
162     {
163         SciErr err = createMatrixOfInteger32(pvCtx, position, rows, cols, ptr);
164         checkError(err);
165     }
166 
alloc(void * pvCtx,const int position,const int rows,const int cols,int * ptr)167     inline static int * alloc(void * pvCtx, const int position, const int rows, const int cols, int * ptr)
168     {
169         int * _ptr = 0;
170         SciErr err = allocMatrixOfInteger32(pvCtx, position, rows, cols, &_ptr);
171         checkError(err);
172 
173         return _ptr;
174     }
175 
create(void * pvCtx,const int position,const int rows,const int cols,unsigned int * ptr)176     inline static void create(void * pvCtx, const int position, const int rows, const int cols, unsigned int * ptr)
177     {
178         SciErr err = createMatrixOfUnsignedInteger32(pvCtx, position, rows, cols, ptr);
179         checkError(err);
180     }
181 
alloc(void * pvCtx,const int position,const int rows,const int cols,unsigned int * ptr)182     inline static unsigned int * alloc(void * pvCtx, const int position, const int rows, const int cols, unsigned int * ptr)
183     {
184         unsigned int * _ptr = 0;
185         SciErr err = allocMatrixOfUnsignedInteger32(pvCtx, position, rows, cols, &_ptr);
186         checkError(err);
187 
188         return _ptr;
189     }
190 
191 #ifdef __SCILAB_INT64__
192 
create(void * pvCtx,const int position,const int rows,const int cols,long long * ptr)193     inline static void create(void * pvCtx, const int position, const int rows, const int cols, long long * ptr)
194     {
195         SciErr err = createMatrixOfInteger64(pvCtx, position, rows, cols, ptr);
196         checkError(err);
197     }
198 
alloc(void * pvCtx,const int position,const int rows,const int cols,long long * ptr)199     inline static long long * alloc(void * pvCtx, const int position, const int rows, const int cols, long long * ptr)
200     {
201         long long * _ptr = 0;
202         SciErr err = allocMatrixOfInteger64(pvCtx, position, rows, cols, &_ptr);
203         checkError(err);
204 
205         return _ptr;
206     }
207 
create(void * pvCtx,const int position,const int rows,const int cols,unsigned long long * ptr)208     inline static void create(void * pvCtx, const int position, const int rows, const int cols, unsigned long long * ptr)
209     {
210         SciErr err = createMatrixOfUnsignedInteger64(pvCtx, position, rows, cols, ptr);
211         checkError(err);
212     }
213 
alloc(void * pvCtx,const int position,const int rows,const int cols,unsigned long long * ptr)214     inline static unsigned long long * alloc(void * pvCtx, const int position, const int rows, const int cols, unsigned long long * ptr)
215     {
216         unsigned long long * _ptr = 0;
217         SciErr err = allocMatrixOfUnsignedInteger64(pvCtx, position, rows, cols, &_ptr);
218         checkError(err);
219 
220         return _ptr;
221     }
222 
223 #else
224 
create(void * pvCtx,const int position,const int rows,const int cols,long long * ptr)225     inline static void create(void * pvCtx, const int position, const int rows, const int cols, long long * ptr)
226     {
227         int * dataPtr = alloc(pvCtx, position, rows, cols, (int *)0);
228         for (int i = 0; i < rows * cols; i++)
229         {
230             dataPtr[i] = static_cast<int>(ptr[i]);
231         }
232     }
233 
alloc(void * pvCtx,const int position,const int rows,const int cols,long long * ptr)234     inline static long long * alloc(void * pvCtx, const int position, const int rows, const int cols, long long * ptr)
235     {
236         return (long long *)alloc(pvCtx, position, rows, cols, (int *)0);
237     }
238 
create(void * pvCtx,const int position,const int rows,const int cols,unsigned long long * ptr)239     inline static void create(void * pvCtx, const int position, const int rows, const int cols, unsigned long long * ptr)
240     {
241         unsigned int * dataPtr = alloc(pvCtx, position, rows, cols, (unsigned int *)0);
242         for (int i = 0; i < rows * cols; i++)
243         {
244             dataPtr[i] = static_cast<unsigned int>(ptr[i]);
245         }
246     }
247 
alloc(void * pvCtx,const int position,const int rows,const int cols,unsigned long long * ptr)248     inline static unsigned long long * alloc(void * pvCtx, const int position, const int rows, const int cols, unsigned long long * ptr)
249     {
250         return (unsigned long long *)alloc(pvCtx, position, rows, cols, (unsigned int *)0);
251     }
252 
253 #endif
254 
create(void * pvCtx,const int position,const int rows,const int cols,char ** ptr)255     inline static void create(void * pvCtx, const int position, const int rows, const int cols, char ** ptr)
256     {
257         SciErr err = createMatrixOfString(pvCtx, position, rows, cols, const_cast<const char * const *>(ptr));
258         checkError(err);
259     }
260 
alloc(void * pvCtx,const int position,const int rows,const int cols,char ** ptr)261     inline static char ** alloc(void * pvCtx, const int position, const int rows, const int cols, char ** ptr)
262     {
263         throw ScilabAbstractEnvironmentException("Invalid operation: cannot allocate a matrix of String");
264     }
265 
createBool(void * pvCtx,const int position,const int rows,const int cols,int * ptr)266     inline static void createBool(void * pvCtx, const int position, const int rows, const int cols, int * ptr)
267     {
268         SciErr err = createMatrixOfBoolean(pvCtx, position, rows, cols, ptr);
269         checkError(err);
270     }
271 
allocBool(void * pvCtx,const int position,const int rows,const int cols,int * ptr)272     inline static int * allocBool(void * pvCtx, const int position, const int rows, const int cols, int * ptr)
273     {
274         int * _ptr = 0;
275         SciErr err = allocMatrixOfBoolean(pvCtx, position, rows, cols, &_ptr);
276         checkError(err);
277 
278         return _ptr;
279     }
280 
281 
282 private:
283 
checkError(const SciErr & err)284     inline static void checkError(const SciErr & err)
285     {
286         if (err.iErr)
287         {
288             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, "Cannot allocate memory");
289         }
290     }
291 
292 };
293 
294 template <typename T>
295 class ScilabSingleTypeStackAllocator : public ScilabStackAllocator
296 {
297 
298 public:
299 
ScilabSingleTypeStackAllocator(void * _pvCtx,int _position)300     ScilabSingleTypeStackAllocator(void * _pvCtx, int _position) : ScilabStackAllocator(_pvCtx, _position) { }
301 
~ScilabSingleTypeStackAllocator()302     ~ScilabSingleTypeStackAllocator() { }
303 
allocate(const int rows,const int cols,T * dataPtr) const304     virtual T * allocate(const int rows, const int cols, T * dataPtr) const
305     {
306         if (!rows || !cols)
307         {
308             createEmptyMatrix(pvCtx, position);
309             return 0;
310         }
311 
312         if (dataPtr)
313         {
314             create(pvCtx, position, rows, cols, dataPtr);
315             return 0;
316         }
317         else
318         {
319             return alloc(pvCtx, position, rows, cols, dataPtr);
320         }
321     }
322 };
323 
324 typedef ScilabSingleTypeStackAllocator<double> ScilabDoubleStackAllocator;
325 typedef ScilabSingleTypeStackAllocator<char *> ScilabStringStackAllocator;
326 typedef ScilabSingleTypeStackAllocator<char> ScilabCharStackAllocator;
327 typedef ScilabSingleTypeStackAllocator<unsigned char> ScilabUCharStackAllocator;
328 typedef ScilabSingleTypeStackAllocator<short> ScilabShortStackAllocator;
329 typedef ScilabSingleTypeStackAllocator<unsigned short> ScilabUShortStackAllocator;
330 typedef ScilabSingleTypeStackAllocator<int> ScilabIntStackAllocator;
331 typedef ScilabSingleTypeStackAllocator<unsigned int> ScilabUIntStackAllocator;
332 typedef ScilabSingleTypeStackAllocator<long long> ScilabLongStackAllocator;
333 typedef ScilabSingleTypeStackAllocator<unsigned long long> ScilabULongStackAllocator;
334 typedef ScilabSingleTypeStackAllocator<float> ScilabFloatStackAllocator;
335 
336 class ScilabComplexStackAllocator : public ScilabStackAllocator
337 {
338 
339 public:
340 
ScilabComplexStackAllocator(void * _pvCtx,int _position)341     ScilabComplexStackAllocator(void * _pvCtx, int _position) : ScilabStackAllocator(_pvCtx, _position) { }
342 
~ScilabComplexStackAllocator()343     ~ScilabComplexStackAllocator() { }
344 
allocate(const int rows,const int cols,double * realPtr,double * imagPtr) const345     ComplexDataPointers allocate(const int rows, const int cols, double * realPtr, double * imagPtr) const
346     {
347         if (!rows || !cols)
348         {
349             createEmptyMatrix(pvCtx, position);
350             return ComplexDataPointers();
351         }
352 
353         if (realPtr && imagPtr)
354         {
355             create(pvCtx, position, rows, cols, realPtr, imagPtr);
356             return ComplexDataPointers();
357         }
358         else
359         {
360             return alloc(pvCtx, position, rows, cols, realPtr, imagPtr);
361         }
362     }
363 };
364 
365 class ScilabBooleanStackAllocator : public ScilabSingleTypeStackAllocator<int>
366 {
367 
368 public:
369 
ScilabBooleanStackAllocator(void * _pvCtx,int _position)370     ScilabBooleanStackAllocator(void * _pvCtx, int _position) : ScilabSingleTypeStackAllocator<int>(_pvCtx, _position) { }
371 
~ScilabBooleanStackAllocator()372     ~ScilabBooleanStackAllocator() { }
373 
allocate(const int rows,const int cols,int * dataPtr) const374     int * allocate(const int rows, const int cols, int * dataPtr) const
375     {
376         if (!rows || !cols)
377         {
378             createEmptyMatrix(pvCtx, position);
379             return 0;
380         }
381 
382         if (dataPtr)
383         {
384             createBool(pvCtx, position, rows, cols, dataPtr);
385             return 0;
386         }
387         else
388         {
389             return allocBool(pvCtx, position, rows, cols, dataPtr);
390         }
391     }
392 
393     template <typename T>
allocate(const int rows,const int cols,T * dataPtr) const394     int * allocate(const int rows, const int cols, T * dataPtr) const
395     {
396         if (!rows || !cols)
397         {
398             createEmptyMatrix(pvCtx, position);
399             return 0;
400         }
401 
402         if (dataPtr)
403         {
404             int * ptr = 0;
405             allocBool(pvCtx, position, rows, cols, ptr);
406             for (int i = 0; i < rows * cols; i++)
407             {
408                 ptr[i] = static_cast<int>(dataPtr[i]);
409             }
410 
411             return 0;
412         }
413         else
414         {
415             throw ScilabAbstractEnvironmentException(__LINE__, __FILE__, "Invalid operation: cannot allocate a matrix of Boolean");
416         }
417     }
418 };
419 
420 }
421 
422 #endif // __SCILABABSTRACTMEMORYALLOCATOR_H__
423