GPL + CeCILL Header change
[scilab.git] / scilab / modules / scicos / src / cpp / extractblklist.cpp
1 /*  Scicos
2 *
3 *  Copyright (C) INRIA - Alan LAYEC
4 *  Copyright (C) 2013 - Scilab Enterprises - Clement DAVID
5 *  Copyright (C) 2015 - Scilab Enterprises - Antoine ELIAS
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *
21 * See the file ./license.txt
22 */
23 /*--------------------------------------------------------------------------*/
24 #include <cstring>
25
26 #include "internal.hxx"
27 #include "list.hxx"
28 #include "tlist.hxx"
29 #include "double.hxx"
30 #include "string.hxx"
31 #include "int.hxx"
32
33 extern "C"
34 {
35 #include "scicos_block4.h"
36 #include "charEncoding.h"
37 }
38
39 #include "extractblklist.hxx"
40
41 /*--------------------------------------------------------------------------*/
42
43 template <typename T>
44 bool sci2var(T* p, void** dest)
45 {
46     const int size = p->getSize();
47     typename T::type* srcR = p->get();
48
49     if (p->isComplex())
50     {
51         typename T::type* srcI = p->getImg();
52         *dest = (typename T::type*)MALLOC(sizeof(typename T::type) * size * 2);
53         if (*dest == nullptr)
54         {
55             return false;
56         }
57
58         typename T::type* destR = (typename T::type*)*dest;
59         typename T::type* destI = destR + size;
60         for (int i = 0; i < size; ++i)
61         {
62             destR[i] = srcR[i];
63             destI[i] = srcI[i];
64         }
65     }
66     else
67     {
68         *dest = (typename T::type*)MALLOC(sizeof(typename T::type) * size);
69         if (*dest == nullptr)
70         {
71             return false;
72         }
73
74         typename T::type* destR = (typename T::type*)*dest;
75         for (int i = 0; i < size; ++i)
76         {
77             destR[i] = srcR[i];
78         }
79     }
80
81     return true;
82 }
83
84 static bool sci2var(types::InternalType* p, void** dest)
85 {
86     *dest = nullptr;
87     switch (p->getType())
88     {
89         case types::InternalType::ScilabDouble:
90         {
91             return sci2var(p->getAs<types::Double>(), dest);
92         }
93         case types::InternalType::ScilabInt8:
94         {
95             return sci2var(p->getAs<types::Int8>(), dest);
96         }
97         case types::InternalType::ScilabInt16:
98         {
99             return sci2var(p->getAs<types::Int16>(), dest);
100         }
101         case types::InternalType::ScilabInt32:
102         {
103             return sci2var(p->getAs<types::Int32>(), dest);
104         }
105         case types::InternalType::ScilabInt64:
106         {
107             return sci2var(p->getAs<types::Int64>(), dest);
108         }
109         case types::InternalType::ScilabUInt8:
110         {
111             return sci2var(p->getAs<types::UInt8>(), dest);
112         }
113         case types::InternalType::ScilabUInt16:
114         {
115             return sci2var(p->getAs<types::UInt16>(), dest);
116         }
117         case types::InternalType::ScilabUInt32:
118         {
119             return sci2var(p->getAs<types::UInt32>(), dest);
120         }
121         case types::InternalType::ScilabUInt64:
122         {
123             return sci2var(p->getAs<types::UInt64>(), dest);
124         }
125         default:
126             return false;
127     }
128
129     return false;
130 }
131
132 static bool getString(types::InternalType* p, char** dest)
133 {
134     *dest = nullptr;
135
136     if (p == nullptr)
137     {
138         return false;
139     }
140
141     if (p->isString())
142     {
143         types::String* s = p->getAs<types::String>();
144         if (s->isScalar())
145         {
146             *dest = wide_string_to_UTF8(s->get()[0]);
147             return true;
148         }
149     }
150     return false;
151 }
152
153 static bool getDoubleArray(types::InternalType* p, double** dest, const int size)
154 {
155     *dest = nullptr;
156
157     if (p == nullptr)
158     {
159         return false;
160     }
161
162     if (p->isDouble())
163     {
164         types::Double* d = p->getAs<types::Double>();
165         if (d->getSize() == size)
166         {
167             if (size == 0)
168             {
169                 return true;
170             }
171
172             *dest = (double*)MALLOC(sizeof(double) * size);
173             if (*dest == nullptr)
174             {
175                 return false;
176             }
177             memcpy(*dest, d->get(), sizeof(double) * size);
178             return true;
179         }
180     }
181
182     return false;
183 }
184
185 static bool getDoubleArrayAsInt(types::InternalType* p, int** dest, const int size)
186 {
187     *dest = nullptr;
188
189     if (p == nullptr)
190     {
191         return false;
192     }
193
194     if (p->isDouble())
195     {
196         types::Double* d = p->getAs<types::Double>();
197         if (d->getSize() == size)
198         {
199             if (size == 0)
200             {
201                 return true;
202             }
203
204             const double* const dbl = d->get();
205             *dest = (int*)MALLOC(sizeof(int) * size);
206             if (*dest == nullptr)
207             {
208                 return false;
209             }
210
211             for (int i = 0; i < size; ++i)
212             {
213                 (*dest)[i] = static_cast<int>(dbl[i]);
214             }
215             return true;
216         }
217     }
218
219     return false;
220 }
221
222 static bool getDoubleAsInt(types::InternalType* p, int* dest)
223 {
224     if (p == nullptr)
225     {
226         return false;
227     }
228
229     if (p->isDouble())
230     {
231         types::Double* d = p->getAs<types::Double>();
232         if (d->isScalar())
233         {
234             *dest = static_cast<int>(d->get()[0]);
235             return true;
236         }
237     }
238     return false;
239 }
240
241 static bool checkType(const int type, types::InternalType* p)
242 {
243     if (p == nullptr)
244     {
245         return false;
246     }
247
248     switch (type)
249     {
250         case 10:
251             if (p->isDouble())
252             {
253                 return true;
254             }
255         case 11:
256             if (p->isDouble() && p->getAs<types::Double>()->isComplex())
257             {
258                 return true;
259             }
260         case 81:
261             if (p->isInt8())
262             {
263                 return true;
264             }
265         case 82:
266             if (p->isInt16())
267             {
268                 return true;
269             }
270         case 84:
271             if (p->isInt32())
272             {
273                 return true;
274             }
275         case 811:
276             if (p->isUInt8())
277             {
278                 return true;
279             }
280         case 812:
281             if (p->isUInt16())
282             {
283                 return true;
284             }
285         case 814:
286             if (p->isUInt32())
287             {
288                 return true;
289             }
290     }
291
292     return false;
293 }
294
295 bool extractblklist(types::TList* t, scicos_block* const Block)
296 {
297     types::InternalType* pIT = nullptr;
298
299     /* 2 - nevprt */
300     if (getDoubleAsInt(t->getField(L"nevprt"), &Block->nevprt) == false)
301     {
302         return false;
303     }
304
305     /* 3 - funpt */
306     //function ptr hide in double*
307     pIT = t->getField(L"funpt");
308     if (pIT->isDouble())
309     {
310         types::Double* d = pIT->getAs<types::Double>();
311         Block->funpt = (voidg)(long long)d->get()[0];
312     }
313
314     /* 4 - type */
315     if (getDoubleAsInt(t->getField(L"type"), &Block->type) == false)
316     {
317         return false;
318     }
319
320     /* 5 - scsptr */
321     //function ptr hide in double*
322     pIT = t->getField(L"scsptr");
323     if (pIT->isDouble())
324     {
325         types::Double* d = pIT->getAs<types::Double>();
326         Block->scsptr = (void*)(long long)d->get()[0];
327     }
328
329     /* 6 - nz */
330     if (getDoubleAsInt(t->getField(L"nz"), &Block->nz) == false)
331     {
332         return false;
333     }
334
335     /* 7 - z */
336     if (getDoubleArray(t->getField(L"z"), &Block->z, Block->nz) == false)
337     {
338         return false;
339     }
340
341     /* 8 - noz */
342     if (getDoubleAsInt(t->getField(L"noz"), &Block->noz) == false)
343     {
344         return false;
345     }
346
347     /* 9 - ozsz */
348     if (getDoubleArrayAsInt(t->getField(L"ozsz"), &Block->ozsz, Block->noz * 2) == false)
349     {
350         return false;
351     }
352
353     /* 10 - oztyp */
354     if (getDoubleArrayAsInt(t->getField(L"oztyp"), &Block->ozsz, Block->noz) == false)
355     {
356         return false;
357     }
358
359     /* 11 - oz */
360     pIT = t->getField(L"oz");
361     if (pIT->isList())
362     {
363         types::List* ozptr = pIT->getAs<types::List>();
364         if (ozptr->getSize() != Block->noz)
365         {
366             return false;
367         }
368
369         Block->ozptr = (void**)MALLOC(sizeof(void*) * Block->noz);
370         if (Block->ozptr == nullptr)
371         {
372             return false;
373         }
374
375         for (int i = 0; i < Block->noz; ++i)
376         {
377             pIT = ozptr->get(i);
378             if (checkType(Block->oztyp[i], pIT) == false)
379             {
380                 return false;
381             }
382
383             if (sci2var(pIT, &Block->ozptr[i]) == false)
384             {
385                 return false;
386             }
387         }
388     }
389
390     /* 12 - nx */
391     if (getDoubleAsInt(t->getField(L"nx"), &Block->nx) == false)
392     {
393         return false;
394     }
395
396     /* 13 - x */
397     if (getDoubleArray(t->getField(L"x"), &Block->x, Block->nx) == false)
398     {
399         return false;
400     }
401
402     /* 14 - xd */
403     if (getDoubleArray(t->getField(L"xd"), &Block->xd, Block->nx) == false)
404     {
405         return false;
406     }
407
408     /* 15 - res */
409     if (getDoubleArray(t->getField(L"res"), &Block->res, Block->nx) == false)
410     {
411         return false;
412     }
413
414     /* 16 - nin */
415     if (getDoubleAsInt(t->getField(L"nin"), &Block->nin) == false)
416     {
417         return false;
418     }
419
420     /* 17 - insz */
421     if (getDoubleArrayAsInt(t->getField(L"insz"), &Block->insz, Block->nin * 3) == false)
422     {
423         return false;
424     }
425
426     /* 18 - inptr */
427     pIT = t->getField(L"inptr");
428     if (pIT->isList())
429     {
430         types::List* inptr = pIT->getAs<types::List>();
431         if (inptr->getSize() != Block->nin)
432         {
433             return false;
434         }
435
436         Block->inptr = (void**)MALLOC(sizeof(void*) * Block->nin);
437         if (Block->inptr == nullptr)
438         {
439             return false;
440         }
441
442         for (int i = 0; i < Block->nin; ++i)
443         {
444             pIT = inptr->get(i);
445             if (checkType(Block->insz[2 * Block->nin + i], pIT) == false)
446             {
447                 return false;
448             }
449
450             if (sci2var(pIT, &Block->inptr[i]) == false)
451             {
452                 return false;
453             }
454         }
455     }
456
457     /* 19 - nout */
458     if (getDoubleAsInt(t->getField(L"nout"), &Block->nout) == false)
459     {
460         return false;
461     }
462
463     /* 20 - outsz */
464     if (getDoubleArrayAsInt(t->getField(L"outsz"), &Block->outsz, Block->nout * 3) == false)
465     {
466         return false;
467     }
468
469     /* 21 - outptr */
470     pIT = t->getField(L"outptr");
471     if (pIT->isList())
472     {
473         types::List* outptr = pIT->getAs<types::List>();
474         if (outptr->getSize() != Block->nout)
475         {
476             return false;
477         }
478
479         Block->outptr = (void**)MALLOC(sizeof(void*) * Block->nout);
480         if (Block->outptr == nullptr)
481         {
482             return false;
483         }
484
485         for (int i = 0; i < Block->nout; ++i)
486         {
487             pIT = outptr->get(i);
488             if (checkType(Block->outsz[2 * Block->nout + i], pIT) == false)
489             {
490                 return false;
491             }
492
493             if (sci2var(pIT, &Block->outptr[i]) == false)
494             {
495                 return false;
496             }
497         }
498     }
499
500     /* 22 - nevout */
501     if (getDoubleAsInt(t->getField(L"nevout"), &Block->nevout) == false)
502     {
503         return false;
504     }
505
506     /* 23 - evout */
507     if (getDoubleArray(t->getField(L"evout"), &Block->evout, Block->nevout) == false)
508     {
509         return false;
510     }
511
512     /* 24 - nrpar */
513     if (getDoubleAsInt(t->getField(L"nrpar"), &Block->nrpar) == false)
514     {
515         return false;
516     }
517
518     /* 25 - rpar */
519     if (getDoubleArray(t->getField(L"rpar"), &Block->rpar, Block->nrpar) == false)
520     {
521         return false;
522     }
523
524     /* 26 - nipar */
525     if (getDoubleAsInt(t->getField(L"nipar"), &Block->nipar) == false)
526     {
527         return false;
528     }
529
530     /* 27 - ipar */
531     if (getDoubleArrayAsInt(t->getField(L"ipar"), &Block->ipar, Block->nipar) == false)
532     {
533         return false;
534     }
535
536     /* 28 - nopar */
537     if (getDoubleAsInt(t->getField(L"nopar"), &Block->nopar) == false)
538     {
539         return false;
540     }
541
542     /* 29 - oparsz */
543     if (getDoubleArrayAsInt(t->getField(L"oparsz"), &Block->oparsz, 2 * Block->nopar) == false)
544     {
545         return false;
546     }
547
548     /* 30 - opartyp */
549     if (getDoubleArrayAsInt(t->getField(L"opartyp"), &Block->opartyp, Block->nopar) == false)
550     {
551         return false;
552     }
553
554     /* 31 - opar */
555     pIT = t->getField(L"opar");
556     if (pIT->isList())
557     {
558         types::List* opar = pIT->getAs<types::List>();
559         if (opar->getSize() != Block->nopar)
560         {
561             return false;
562         }
563
564         Block->oparptr = (void**)MALLOC(sizeof(void*) * Block->nopar);
565         if (Block->inptr == nullptr)
566         {
567             return false;
568         }
569
570         for (int i = 0; i < Block->nopar; ++i)
571         {
572             pIT = opar->get(i);
573             if (checkType(Block->opartyp[i], pIT) == false)
574             {
575                 return false;
576             }
577
578             if (sci2var(pIT, &Block->oparptr[i]) == false)
579             {
580                 return false;
581             }
582         }
583     }
584
585     /* 32 - ng */
586     if (getDoubleAsInt(t->getField(L"ng"), &Block->ng) == false)
587     {
588         return false;
589     }
590
591     /* 33 - g */
592     if (getDoubleArray(t->getField(L"g"), &Block->g, Block->ng) == false)
593     {
594         return false;
595     }
596
597     /* 34 - ztyp */
598     if (getDoubleAsInt(t->getField(L"ztyp"), &Block->ztyp) == false)
599     {
600         return false;
601     }
602
603     /* 35 - jroot */
604     if (getDoubleArrayAsInt(t->getField(L"jroot"), &Block->jroot, Block->ng) == false)
605     {
606         return false;
607     }
608
609     /* 36 - label */
610     if (getString(t->getField(L"label"), &Block->label) == false)
611     {
612         return false;
613     }
614
615     /* 37 - work*/
616     pIT = t->getField(L"work");
617     if (pIT->isDouble())
618     {
619         types::Double* d = pIT->getAs<types::Double>();
620         Block->work = (void**)(long long)d->get()[0];
621     }
622
623     /* 38 - nmode*/
624     if (getDoubleAsInt(t->getField(L"nmode"), &Block->nmode) == false)
625     {
626         return false;
627     }
628
629     /* 39 - mode */
630     if (getDoubleArrayAsInt(t->getField(L"mode"), &Block->mode, Block->nmode) == false)
631     {
632         return false;
633     }
634
635     /* 40 - xprop */
636     if (getDoubleArrayAsInt(t->getField(L"xprop"), &Block->xprop, Block->nx) == false)
637     {
638         return false;
639     }
640
641     return true;
642 }
643 /*--------------------------------------------------------------------------*/