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