1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2009 - DIGITEO - Antoine ELIAS
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 #include <hdf5.h>
17 #include "context.hxx"
18 #include "list.hxx"
19 #include "struct.hxx"
20 #include "cell.hxx"
21 
22 extern "C"
23 {
24 #include <string.h>
25 #include "gw_hdf5.h"
26 #include "sci_malloc.h"
27 #include "Scierror.h"
28 #include "localization.h"
29 #include "sciprint.h"
30 #include "api_scilab.h"
31 #include "../../../call_scilab/includes/call_scilab.h"
32 #include "h5_fileManagement.h"
33 #include "h5_readDataFromFile.h"
34 #include "h5_attributeConstants.h"
35 #include "expandPathVariable.h"
36 #include "stdlib.h"
37 #include "freeArrayOfString.h"
38 }
39 
40 #include "hdf5_load_v1.hxx"
41 
42 static bool import_variable(int* pvCtx, hid_t _iFile, char* _pstVarName);
43 static bool import_data(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname);
44 static bool import_double(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname);
45 static bool import_string(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname);
46 static bool import_boolean(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname);
47 static bool import_integer(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname);
48 static bool import_sparse(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname);
49 static bool import_boolean_sparse(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname);
50 static bool import_poly(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname);
51 static bool import_list(int* pvCtx, hid_t _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, char *_pstVarname);
52 static bool import_hypermat(int* pvCtx, hid_t _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, char *_pstVarname);
53 static bool import_struct(int* pvCtx, hid_t _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, char *_pstVarname);
54 static bool import_cell(int* pvCtx, hid_t _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, char *_pstVarname);
55 static bool import_void(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname);
56 static bool import_undefined(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname);
57 
58 static const std::string fname("load");
59 
sci_hdf5_load_v2(char * fn,int * pvApiCtx)60 int sci_hdf5_load_v2(char *fn, int* pvApiCtx)
61 {
62     SciErr sciErr;
63 
64     int* piAddr = NULL;
65     char* pstFilename = NULL;
66     char* pstExpandedFilename = NULL;
67     bool bImport = true;
68     const int nbIn = nbInputArgument(pvApiCtx);
69     int iSelectedVar = nbIn - 1;
70 
71     CheckInputArgumentAtLeast(pvApiCtx , 1);
72     CheckOutputArgument(pvApiCtx, 0, 1);
73 
74     sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddr);
75     if (sciErr.iErr)
76     {
77         printError(&sciErr, 0);
78         return 1;
79     }
80 
81     if (getAllocatedSingleString(pvApiCtx, piAddr, &pstFilename))
82     {
83         if (pstFilename)
84         {
85             freeAllocatedSingleString(pstFilename);
86         }
87 
88         Scierror(999, _("%s: Wrong size for input argument #%d: string expected.\n"), fname.data(), 2);
89         return 1;
90     }
91 
92     //open hdf5 file
93     pstExpandedFilename = expandPathVariable(pstFilename);
94     hid_t iFile = openHDF5File(pstExpandedFilename, 0);
95     if (iFile < 0)
96     {
97         Scierror(999, _("%s: Unable to open file: %s\n"), fname.data(), pstFilename);
98         FREE(pstExpandedFilename);
99         FREE(pstFilename);
100         return 1;
101     }
102 
103     FREE(pstExpandedFilename);
104     FREE(pstFilename);
105 
106     //manage version information
107     int iVersion = getSODFormatAttribute(iFile);
108     if (iVersion != SOD_FILE_VERSION)
109     {
110         if (iVersion > SOD_FILE_VERSION)
111         {
112             //can't read file with version newer that me !
113             Scierror(999, _("%s: Wrong SOD file format version. Max Expected: %d Found: %d\n"), fname.data(), SOD_FILE_VERSION, iVersion);
114             return 1;
115         }
116         else
117         {
118             //call older import functions and exit or ... EXIT !
119             if (iVersion == 1 || iVersion == -1)
120             {
121                 return sci_hdf5_load_v1(fn, pvApiCtx);
122             }
123         }
124     }
125 
126     std::vector<wchar_t*> varList;
127     if (iSelectedVar)
128     {
129         //selected variable
130         char* pstVarName = NULL;
131         for (int i = 0 ; i < iSelectedVar ; i++)
132         {
133             sciErr = getVarAddressFromPosition(pvApiCtx, i + 2, &piAddr);
134             if (sciErr.iErr)
135             {
136                 printError(&sciErr, 0);
137                 return 1;
138             }
139 
140             if (getAllocatedSingleString(pvApiCtx, piAddr, &pstVarName))
141             {
142                 if (pstVarName)
143                 {
144                     freeAllocatedSingleString(pstVarName);
145                 }
146 
147                 Scierror(999, _("%s: Wrong size for input argument #%d: string expected.\n"), fname.data(), i + 1);
148                 return 1;
149             }
150 
151             if (import_variable(pvApiCtx, iFile, pstVarName) == false)
152             {
153                 FREE(pstVarName);
154                 bImport = false;
155                 break;
156             }
157 
158             varList.push_back(to_wide_string(pstVarName));
159             FREE(pstVarName);
160             pstVarName = NULL;
161         }
162     }
163     else
164     {
165         //all variables
166         int iNbItem = 0;
167         iNbItem = getVariableNames(iFile, NULL);
168         if (iNbItem != 0)
169         {
170             char **pstVarNameList = (char **)MALLOC(sizeof(char *) * iNbItem);
171 
172             iNbItem = getVariableNames(iFile, pstVarNameList);
173 
174             //import all data
175             for (int i = 0; i < iNbItem; i++)
176             {
177                 if (import_variable(pvApiCtx, iFile, pstVarNameList[i]) == false)
178                 {
179                     bImport = false;
180                     break;
181                 }
182 
183                 varList.push_back(to_wide_string(pstVarNameList[i]));
184             }
185 
186             freeArrayOfString(pstVarNameList, iNbItem);
187         }
188     }
189     //close the file
190     closeHDF5File(iFile);
191 
192     if (bImport == true && varList.size() != 0)
193     {
194         createMatrixOfWideString(pvApiCtx, nbIn + 1, 1, static_cast<int>(varList.size()), varList.data());
195     }
196     else
197     {
198         createEmptyMatrix(pvApiCtx, nbIn + 1);
199     }
200 
201     for (auto & i : varList)
202     {
203         FREE(i);
204     }
205 
206     AssignOutputVariable(pvApiCtx, 1) = nbIn + 1;
207     ReturnArguments(pvApiCtx);
208 
209     //  printf("End gateway !!!\n");
210     return 0;
211 }
212 
import_variable(int * pvCtx,hid_t _iFile,char * _pstVarName)213 static bool import_variable(int* pvCtx, hid_t _iFile, char* _pstVarName)
214 {
215     hid_t iDataSetId = getDataSetIdFromName(_iFile, _pstVarName);
216     if (iDataSetId <= 0)
217     {
218         return false;
219     }
220 
221     return import_data(pvCtx, iDataSetId, 0, NULL, _pstVarName);
222 }
223 
import_data(int * pvCtx,hid_t _iDatasetId,int _iItemPos,int * _piAddress,char * _pstVarname)224 static bool import_data(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname)
225 {
226     bool bRet = false;
227 
228     //get var type
229     int iVarType = getScilabTypeFromDataSet(_iDatasetId);
230 
231     switch (iVarType)
232     {
233         case sci_matrix:
234         {
235             bRet = import_double(pvCtx, _iDatasetId, _iItemPos, _piAddress, _pstVarname);
236             break;
237         }
238         case sci_strings:
239         {
240             bRet = import_string(pvCtx, _iDatasetId, _iItemPos, _piAddress, _pstVarname);
241             break;
242         }
243         case sci_list:
244         case sci_tlist:
245         case sci_mlist:
246         {
247             bRet = import_hypermat(pvCtx, _iDatasetId, iVarType, _iItemPos, _piAddress, _pstVarname);
248             if (bRet == false)
249             {
250                 bRet = import_struct(pvCtx, _iDatasetId, iVarType, _iItemPos, _piAddress, _pstVarname);
251             }
252             if (bRet == false)
253             {
254                 bRet = import_cell(pvCtx, _iDatasetId, iVarType, _iItemPos, _piAddress, _pstVarname);
255             }
256             if (bRet == false)
257             {
258                 bRet = import_list(pvCtx, _iDatasetId, iVarType, _iItemPos, _piAddress, _pstVarname);
259             }
260             break;
261         }
262         case sci_boolean:
263         {
264             bRet = import_boolean(pvCtx, _iDatasetId, _iItemPos, _piAddress, _pstVarname);
265             break;
266         }
267         case sci_poly:
268         {
269             bRet = import_poly(pvCtx, _iDatasetId, _iItemPos, _piAddress, _pstVarname);
270             break;
271         }
272         case sci_ints:
273         {
274             bRet = import_integer(pvCtx, _iDatasetId, _iItemPos, _piAddress, _pstVarname);
275             break;
276         }
277         case sci_sparse:
278         {
279             bRet = import_sparse(pvCtx, _iDatasetId, _iItemPos, _piAddress, _pstVarname);
280             break;
281         }
282         case sci_boolean_sparse:
283         {
284             bRet = import_boolean_sparse(pvCtx, _iDatasetId, _iItemPos, _piAddress, _pstVarname);
285             break;
286         }
287         case sci_void:             //void item only on list variable
288         {
289             bRet = import_void(pvCtx, _iDatasetId, _iItemPos, _piAddress, _pstVarname);
290             break;
291         }
292         case sci_undefined:        //undefined item only on list variable
293         {
294             bRet = import_undefined(pvCtx, _iDatasetId, _iItemPos, _piAddress, _pstVarname);
295             break;
296         }
297         default:
298         {
299             Scierror(999, _("%s: Invalid HDF5 Scilab format.\n"), fname.data());
300         }
301     }
302     return bRet;
303 }
304 
import_void(int * pvCtx,hid_t _iDatasetId,int _iItemPos,int * _piAddress,char * _pstVarname)305 static bool import_void(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname)
306 {
307     SciErr sciErr;
308 
309     if (_piAddress)
310     {
311         sciErr = createVoidInNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos);
312     }
313     else
314     {
315         return false;
316     }
317 
318     if (sciErr.iErr)
319     {
320         printError(&sciErr, 0);
321         return false;
322     }
323 
324     //close void dataset
325     closeDataSet(_iDatasetId);
326     return true;
327 }
328 
import_undefined(int * pvCtx,hid_t _iDatasetId,int _iItemPos,int * _piAddress,char * _pstVarname)329 static bool import_undefined(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname)
330 {
331     SciErr sciErr;
332 
333     if (_piAddress)
334     {
335         sciErr = createUndefinedInNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos);
336     }
337     else
338     {
339         return false;
340     }
341 
342     if (sciErr.iErr)
343     {
344         printError(&sciErr, 0);
345         return false;
346     }
347 
348     //close undefined dataset
349     closeDataSet(_iDatasetId);
350     return true;
351 }
352 
import_double(int * pvCtx,hid_t _iDatasetId,int _iItemPos,int * _piAddress,char * _pstVarname)353 static bool import_double(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname)
354 {
355     SciErr sciErr;
356     int iRet = 0;
357     double *pdblReal = NULL;
358     double *pdblImg = NULL;
359     int iDims = 0;
360     int* piDims = NULL;
361     int iComplex = 0;
362     int iSize = 0;
363 
364     iRet = getDatasetInfo(_iDatasetId, &iComplex, &iDims, NULL);
365     if (iRet < 0)
366     {
367         return false;
368     }
369 
370     if (iDims)
371     {
372         if (iDims > 2)
373         {
374             //hypermatrix
375             return false;
376         }
377 
378         piDims = (int*)MALLOC(sizeof(int) * iDims);
379         iSize = getDatasetInfo(_iDatasetId, &iComplex, &iDims, piDims);
380         if (iSize < 0)
381         {
382             FREE(piDims);
383             return false;
384         }
385 
386         if (iSize > 0)
387         {
388             pdblReal = (double *)MALLOC(iSize * sizeof(double));
389 
390             if (iComplex)
391             {
392                 pdblImg = (double *)MALLOC(iSize * sizeof(double));
393                 iRet = readDoubleComplexMatrix(_iDatasetId, pdblReal, pdblImg);
394             }
395             else
396             {
397                 iRet = readDoubleMatrix(_iDatasetId, pdblReal);
398             }
399             if (iRet < 0)
400             {
401                 FREE(piDims);
402                 FREE(pdblReal);
403                 if (iComplex)
404                 {
405                     FREE(pdblImg);
406                 }
407                 return false;
408             }
409 
410             //to be sure ti have 2 dims
411             if (iDims == 1)
412             {
413                 FREE(piDims);
414                 piDims = (int*)MALLOC(sizeof(int) * 2);
415                 piDims[0] = 1;
416                 piDims[1] = iSize;
417             }
418         }
419     }
420 
421     if (iDims == 0 || iSize == 0) //empty matrix
422     {
423         if (piDims)
424         {
425             FREE(piDims);
426         }
427 
428         /*bug 7224 : to close dataset */
429         iRet = readEmptyMatrix(_iDatasetId);
430         if (iRet)
431         {
432             return false;
433         }
434 
435         // Hack to sure that piDims will not be null at line 372.
436         iDims = 2;
437         piDims = (int*)MALLOC(sizeof(int) * iDims);
438         memset(piDims, 0, sizeof(int) * iDims);
439         pdblReal = (double*)MALLOC(sizeof(double) * 1);
440         pdblReal[0] = 0;
441         iComplex = 0;
442     }
443 
444     if (_piAddress == NULL)
445     {
446         if (iComplex)
447         {
448             sciErr = createNamedComplexMatrixOfDouble(pvCtx, _pstVarname, piDims[0], piDims[1], pdblReal, pdblImg);
449         }
450         else
451         {
452             sciErr = createNamedMatrixOfDouble(pvCtx, _pstVarname, piDims[0], piDims[1], pdblReal);
453         }
454     }
455     else //if not null this variable is in a list
456     {
457         if (iComplex)
458         {
459             sciErr = createComplexMatrixOfDoubleInNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, piDims[0], piDims[1], pdblReal, pdblImg);
460         }
461         else
462         {
463             sciErr = createMatrixOfDoubleInNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, piDims[0], piDims[1], pdblReal);
464         }
465     }
466 
467     FREE(piDims);
468     FREE(pdblReal);
469     if (iComplex)
470     {
471         FREE(pdblImg);
472     }
473 
474     if (sciErr.iErr)
475     {
476         printError(&sciErr, 0);
477         return false;
478     }
479 
480     return true;
481 }
482 
import_string(int * pvCtx,hid_t _iDatasetId,int _iItemPos,int * _piAddress,char * _pstVarname)483 static bool import_string(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname)
484 {
485     SciErr sciErr;
486     int iRet = 0;
487     char **pstData = NULL;
488     int iDims = 0;
489     int* piDims = NULL;
490     int iComplex = 0;
491     int iSize = 0;
492 
493     iRet = getDatasetInfo(_iDatasetId, &iComplex, &iDims, NULL);
494     if (iRet < 0)
495     {
496         return false;
497     }
498 
499     piDims = (int*)MALLOC(sizeof(int) * iDims);
500     iSize = getDatasetInfo(_iDatasetId, &iComplex, &iDims, piDims);
501     if (iSize < 0)
502     {
503         FREE(piDims);
504         return false;
505     }
506 
507     pstData = (char **)MALLOC(iSize * sizeof(char *));
508 
509     iRet = readStringMatrix(_iDatasetId, pstData);
510     if (iRet)
511     {
512         FREE(piDims);
513         return false;
514     }
515 
516     if (_piAddress == NULL)
517     {
518         sciErr = createNamedMatrixOfString(pvCtx, _pstVarname, piDims[0], piDims[1], pstData);
519     }
520     else                        //if not null this variable is in a list
521     {
522         sciErr = createMatrixOfStringInNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, piDims[0], piDims[1], pstData);
523     }
524 
525     if (sciErr.iErr)
526     {
527         printError(&sciErr, 0);
528         FREE(piDims);
529         freeStringMatrix(_iDatasetId, pstData);
530         FREE(pstData);
531         return false;
532     }
533 
534     FREE(piDims);
535     freeStringMatrix(_iDatasetId, pstData);
536     FREE(pstData);
537 
538     return true;
539 }
540 
import_integer(int * pvCtx,hid_t _iDatasetId,int _iItemPos,int * _piAddress,char * _pstVarname)541 static bool import_integer(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname)
542 {
543     int iRet = 0;
544     int iDims = 0;
545     int* piDims = NULL;
546     int iComplex = 0;
547     int iSize = 0;
548     int iPrec = 0;
549     SciErr sciErr;
550 
551     iRet = getDatasetInfo(_iDatasetId, &iComplex, &iDims, NULL);
552     if (iRet < 0)
553     {
554         return false;
555     }
556 
557     piDims = (int*)MALLOC(sizeof(int) * iDims);
558     iSize = getDatasetInfo(_iDatasetId, &iComplex, &iDims, piDims);
559     if (iSize < 0)
560     {
561         FREE(piDims);
562         return false;
563     }
564 
565     iRet = getDatasetPrecision(_iDatasetId, &iPrec);
566     if (iRet)
567     {
568         FREE(piDims);
569         return false;
570     }
571 
572     switch (iPrec)
573     {
574         case SCI_INT8:
575         {
576             char *pcData = NULL;
577 
578             pcData = (char *)MALLOC(sizeof(char) * iSize);
579             iRet = readInteger8Matrix(_iDatasetId, pcData);
580             if (iRet)
581             {
582                 FREE(piDims);
583                 return false;
584             }
585 
586             if (_piAddress == NULL)
587             {
588                 sciErr = createNamedMatrixOfInteger8(pvCtx, _pstVarname, piDims[0], piDims[1], pcData);
589             }
590             else
591             {
592                 sciErr = createMatrixOfInteger8InNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, piDims[0], piDims[1], pcData);
593             }
594 
595             FREE(pcData);
596         }
597         break;
598         case SCI_UINT8:
599         {
600             unsigned char *pucData = NULL;
601 
602             pucData = (unsigned char *)MALLOC(sizeof(unsigned char) * iSize);
603             iRet = readUnsignedInteger8Matrix(_iDatasetId, pucData);
604             if (iRet)
605             {
606                 FREE(piDims);
607                 return false;
608             }
609 
610             if (_piAddress == NULL)
611             {
612                 sciErr = createNamedMatrixOfUnsignedInteger8(pvCtx, _pstVarname, piDims[0], piDims[1], pucData);
613             }
614             else
615             {
616                 sciErr = createMatrixOfUnsignedInteger8InNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, piDims[0], piDims[1], pucData);
617             }
618 
619             FREE(pucData);
620         }
621         break;
622         case SCI_INT16:
623         {
624             short *psData = NULL;
625 
626             psData = (short *)MALLOC(sizeof(short) * iSize);
627             iRet = readInteger16Matrix(_iDatasetId, psData);
628             if (iRet)
629             {
630                 FREE(piDims);
631                 return false;
632             }
633 
634             if (_piAddress == NULL)
635             {
636                 sciErr = createNamedMatrixOfInteger16(pvCtx, _pstVarname, piDims[0], piDims[1], psData);
637             }
638             else
639             {
640                 sciErr = createMatrixOfInteger16InNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, piDims[0], piDims[1], psData);
641             }
642 
643             FREE(psData);
644         }
645         break;
646         case SCI_UINT16:
647         {
648             unsigned short *pusData = NULL;
649 
650             pusData = (unsigned short *)MALLOC(sizeof(unsigned short) * iSize);
651             iRet = readUnsignedInteger16Matrix(_iDatasetId, pusData);
652             if (iRet)
653             {
654                 FREE(piDims);
655                 return false;
656             }
657 
658             if (_piAddress == NULL)
659             {
660                 sciErr = createNamedMatrixOfUnsignedInteger16(pvCtx, _pstVarname, piDims[0], piDims[1], pusData);
661             }
662             else
663             {
664                 sciErr = createMatrixOfUnsignedInteger16InNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, piDims[0], piDims[1], pusData);
665             }
666 
667             FREE(pusData);
668         }
669         break;
670         case SCI_INT32:
671         {
672             int *piData = NULL;
673 
674             piData = (int *)MALLOC(sizeof(int) * iSize);
675             iRet = readInteger32Matrix(_iDatasetId, piData);
676             if (iRet)
677             {
678                 FREE(piDims);
679                 return false;
680             }
681 
682             if (_piAddress == NULL)
683             {
684                 sciErr = createNamedMatrixOfInteger32(pvCtx, _pstVarname, piDims[0], piDims[1], piData);
685             }
686             else
687             {
688                 sciErr = createMatrixOfInteger32InNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, piDims[0], piDims[1], piData);
689             }
690 
691             FREE(piData);
692         }
693         break;
694         case SCI_UINT32:
695         {
696             unsigned int *puiData = NULL;
697 
698             puiData = (unsigned int *)MALLOC(sizeof(unsigned int) * iSize);
699             iRet = readUnsignedInteger32Matrix(_iDatasetId, puiData);
700             if (iRet)
701             {
702                 FREE(piDims);
703                 return false;
704             }
705 
706             if (_piAddress == NULL)
707             {
708                 sciErr = createNamedMatrixOfUnsignedInteger32(pvCtx, _pstVarname, piDims[0], piDims[1], puiData);
709             }
710             else
711             {
712                 sciErr = createMatrixOfUnsignedInteger32InNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, piDims[0], piDims[1], puiData);
713             }
714 
715             FREE(puiData);
716         }
717         break;
718         case SCI_INT64:
719         {
720 #ifdef __SCILAB_INT64__
721             long long *pllData = NULL;
722 
723             pllData = (long long *)MALLOC(sizeof(long long) * iSize);
724             iRet = readInteger64Matrix(_iDatasetId, pllData);
725             if (iRet)
726             {
727                 FREE(piDims);
728                 return false;
729             }
730 
731             if (_piAddress == NULL)
732             {
733                 sciErr = createNamedMatrixOfInteger64(pvCtx, _pstVarname, piDims[0], piDims[1], pllData);
734             }
735             else
736             {
737                 sciErr = createMatrixOfInteger64InNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, piDims[0], piDims[1], pllData);
738             }
739 
740             FREE(pllData);
741 #else
742             FREE(piDims);
743             return false;
744 #endif
745         }
746         break;
747         case SCI_UINT64:
748         {
749 #ifdef __SCILAB_INT64__
750             unsigned long long *pullData = NULL;
751 
752             pullData = (unsigned long long *)MALLOC(sizeof(unsigned long long) * iSize);
753             iRet = readUnsignedInteger64Matrix(_iDatasetId, pullData);
754             if (iRet)
755             {
756                 FREE(piDims);
757                 return false;
758             }
759 
760             if (_piAddress == NULL)
761             {
762                 sciErr = createNamedMatrixOfUnsignedInteger64(pvCtx, _pstVarname, piDims[0], piDims[1], pullData);
763             }
764             else
765             {
766                 sciErr = createMatrixOfUnsignedInteger64InNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, piDims[0], piDims[1], pullData);
767             }
768 
769             FREE(pullData);
770 #else
771             FREE(piDims);
772             return false;
773 #endif
774         }
775         break;
776         default:
777             FREE(piDims);
778             return false;
779     }
780 
781     FREE(piDims);
782 
783     if (sciErr.iErr)
784     {
785         printError(&sciErr, 0);
786         return false;
787     }
788 
789     return true;
790 }
791 
import_boolean(int * pvCtx,hid_t _iDatasetId,int _iItemPos,int * _piAddress,char * _pstVarname)792 static bool import_boolean(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname)
793 {
794     int iRet = 0;
795     int *piData = NULL;
796     int iDims = 0;
797     int* piDims = NULL;
798     int iComplex = 0;
799     int iSize = 0;
800     SciErr sciErr;
801 
802     iRet = getDatasetInfo(_iDatasetId, &iComplex, &iDims, NULL);
803     if (iRet < 0)
804     {
805         return false;
806     }
807 
808     piDims = (int*)MALLOC(sizeof(int) * iDims);
809     iSize = getDatasetInfo(_iDatasetId, &iComplex, &iDims, piDims);
810     if (iSize < 0)
811     {
812         FREE(piDims);
813         return false;
814     }
815 
816     if (iSize == 0)
817     {
818         FREE(piDims);
819         return false;
820     }
821 
822     piData = (int *)MALLOC(iSize * sizeof(int));
823     iRet = readBooleanMatrix(_iDatasetId, piData);
824     if (iRet)
825     {
826         FREE(piData);
827         FREE(piDims);
828         return false;
829     }
830 
831     if (_piAddress == NULL)
832     {
833         sciErr = createNamedMatrixOfBoolean(pvCtx, _pstVarname, piDims[0], piDims[1], piData);
834     }
835     else                        //if not null this variable is in a list
836     {
837         sciErr = createMatrixOfBooleanInNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, piDims[0], piDims[1], piData);
838     }
839 
840     FREE(piDims);
841     if (piData)
842     {
843         FREE(piData);
844     }
845 
846     if (sciErr.iErr)
847     {
848         printError(&sciErr, 0);
849         return false;
850     }
851 
852     return true;
853 }
854 
import_poly(int * pvCtx,hid_t _iDatasetId,int _iItemPos,int * _piAddress,char * _pstVarname)855 static bool import_poly(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname)
856 {
857     int iRet = 0;
858     int iComplex = 0;
859     char pstVarName[64] = { 0 };
860     double **pdblReal = NULL;
861     double **pdblImg = NULL;
862     int *piNbCoef = NULL;
863     int iDims = 0;
864     int* piDims = NULL;
865     int iSize = 0;
866     SciErr sciErr;
867 
868     iRet = getDatasetInfo(_iDatasetId, &iComplex, &iDims, NULL);
869     if (iRet < 0)
870     {
871         return false;
872     }
873 
874     piDims = (int*)MALLOC(sizeof(int) * iDims);
875     iSize = getDatasetInfo(_iDatasetId, &iComplex, &iDims, piDims);
876     if (iSize < 0)
877     {
878         FREE(piDims);
879         return false;
880     }
881 
882     if (iComplex)
883     {
884         piNbCoef = (int *)MALLOC(iSize * sizeof(int));
885         pdblReal = (double **)MALLOC(iSize * sizeof(double *));
886         pdblImg = (double **)MALLOC(iSize * sizeof(double *));
887         iRet = readPolyComplexMatrix(_iDatasetId, pstVarName, iDims, piDims, piNbCoef, pdblReal, pdblImg);
888     }
889     else
890     {
891         piNbCoef = (int *)MALLOC(iSize * sizeof(int));
892         pdblReal = (double **)MALLOC(iSize * sizeof(double *));
893         iRet = readPolyMatrix(_iDatasetId, pstVarName, iDims, piDims, piNbCoef, pdblReal);
894     }
895 
896     if (iRet)
897     {
898         FREE(piDims);
899         FREE(piNbCoef);
900         for (int i = 0; i < iSize; i++)
901         {
902             FREE(pdblReal[i]);
903         }
904         FREE(pdblReal);
905 
906         if (iComplex)
907         {
908             for (int i = 0; i < iSize; i++)
909             {
910                 FREE(pdblImg[i]);
911             }
912             FREE(pdblImg);
913         }
914 
915         return false;
916     }
917 
918     if (_piAddress == NULL)
919     {
920         if (iComplex)
921         {
922             sciErr = createNamedComplexMatrixOfPoly(pvCtx, _pstVarname, pstVarName, piDims[0], piDims[1], piNbCoef, pdblReal, pdblImg);
923         }
924         else
925         {
926             sciErr = createNamedMatrixOfPoly(pvCtx, _pstVarname, pstVarName, piDims[0], piDims[1], piNbCoef, pdblReal);
927         }
928     }
929     else                        //if not null this variable is in a list
930     {
931         if (iComplex)
932         {
933             sciErr =
934                 createComplexMatrixOfPolyInNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, pstVarName, piDims[0], piDims[1], piNbCoef, pdblReal,
935                         pdblImg);
936         }
937         else
938         {
939             sciErr = createMatrixOfPolyInNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, pstVarName, piDims[0], piDims[1], piNbCoef, pdblReal);
940         }
941     }
942 
943     FREE(piDims);
944     FREE(piNbCoef);
945     for (int i = 0; i < iSize; i++)
946     {
947         FREE(pdblReal[i]);
948     }
949 
950     FREE(pdblReal);
951 
952     if (iComplex)
953     {
954         for (int i = 0; i < iSize; i++)
955         {
956             FREE(pdblImg[i]);
957         }
958 
959         FREE(pdblImg);
960     }
961 
962     if (sciErr.iErr)
963     {
964         printError(&sciErr, 0);
965         return false;
966     }
967 
968     return true;
969 }
970 
import_sparse(int * pvCtx,hid_t _iDatasetId,int _iItemPos,int * _piAddress,char * _pstVarname)971 static bool import_sparse(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname)
972 {
973     int iRet = 0;
974     int iRows = 0;
975     int iCols = 0;
976     int iComplex = 0;
977     double *pdblReal = NULL;
978     double *pdblImg = NULL;
979     int iNbItem = 0;
980     int *piNbItemRow = NULL;
981     int *piColPos = NULL;
982     SciErr sciErr;
983 
984     iRet = getSparseDimension(_iDatasetId, &iRows, &iCols, &iNbItem);
985     if (iRet)
986     {
987         return false;
988     }
989 
990     iComplex = isComplexData(_iDatasetId);
991 
992     if (iComplex)
993     {
994         piNbItemRow = (int *)MALLOC(iRows * sizeof(int));
995         piColPos = (int *)MALLOC(iNbItem * sizeof(int));
996         pdblReal = (double *)MALLOC(iNbItem * sizeof(double));
997         pdblImg = (double *)MALLOC(iNbItem * sizeof(double));
998         iRet = readSparseComplexMatrix(_iDatasetId, iRows, iCols, iNbItem, piNbItemRow, piColPos, pdblReal, pdblImg);
999     }
1000     else
1001     {
1002         piNbItemRow = (int *)MALLOC(iRows * sizeof(int));
1003         piColPos = (int *)MALLOC(iNbItem * sizeof(int));
1004         pdblReal = (double *)MALLOC(iNbItem * sizeof(double));
1005         iRet = readSparseMatrix(_iDatasetId, iRows, iCols, iNbItem, piNbItemRow, piColPos, pdblReal);
1006     }
1007 
1008     if (iRet)
1009     {
1010         FREE(piNbItemRow);
1011         FREE(piColPos);
1012         FREE(pdblReal);
1013         if (iComplex)
1014         {
1015             FREE(pdblImg);
1016         }
1017 
1018         return false;
1019     }
1020 
1021     if (_piAddress == NULL)
1022     {
1023         if (iComplex)
1024         {
1025             sciErr = createNamedComplexSparseMatrix(pvCtx, _pstVarname, iRows, iCols, iNbItem, piNbItemRow, piColPos, pdblReal, pdblImg);
1026         }
1027         else
1028         {
1029             sciErr = createNamedSparseMatrix(pvCtx, _pstVarname, iRows, iCols, iNbItem, piNbItemRow, piColPos, pdblReal);
1030         }
1031     }
1032     else //if not null this variable is in a list
1033     {
1034         if (iComplex)
1035         {
1036             sciErr = createComplexSparseMatrixInNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, iRows, iCols, iNbItem, piNbItemRow, piColPos, pdblReal, pdblImg);
1037         }
1038         else
1039         {
1040             sciErr = createSparseMatrixInNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, iRows, iCols, iNbItem, piNbItemRow, piColPos, pdblReal);
1041         }
1042     }
1043 
1044     FREE(piNbItemRow);
1045     FREE(piColPos);
1046     FREE(pdblReal);
1047     if (iComplex)
1048     {
1049         FREE(pdblImg);
1050     }
1051 
1052     if (sciErr.iErr)
1053     {
1054         printError(&sciErr, 0);
1055         return false;
1056     }
1057 
1058     return true;
1059 }
1060 
import_boolean_sparse(int * pvCtx,hid_t _iDatasetId,int _iItemPos,int * _piAddress,char * _pstVarname)1061 static bool import_boolean_sparse(int* pvCtx, hid_t _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname)
1062 {
1063     int iRet = 0;
1064     int iRows = 0;
1065     int iCols = 0;
1066     int iNbItem = 0;
1067     int *piNbItemRow = NULL;
1068     int *piColPos = NULL;
1069     SciErr sciErr;
1070 
1071     iRet = getSparseDimension(_iDatasetId, &iRows, &iCols, &iNbItem);
1072     if (iRet)
1073     {
1074         return false;
1075     }
1076 
1077     piNbItemRow = (int *)MALLOC(iRows * sizeof(int));
1078     piColPos = (int *)MALLOC(iNbItem * sizeof(int));
1079 
1080     iRet = readBooleanSparseMatrix(_iDatasetId, iRows, iCols, iNbItem, piNbItemRow, piColPos);
1081     if (iRet)
1082     {
1083         FREE(piNbItemRow);
1084         return false;
1085     }
1086 
1087     if (_piAddress == NULL)
1088     {
1089         sciErr = createNamedBooleanSparseMatrix(pvCtx, _pstVarname, iRows, iCols, iNbItem, piNbItemRow, piColPos);
1090     }
1091     else                        //if not null this variable is in a list
1092     {
1093         sciErr = createBooleanSparseMatrixInNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, iRows, iCols, iNbItem, piNbItemRow, piColPos);
1094     }
1095 
1096     FREE(piNbItemRow);
1097     FREE(piColPos);
1098 
1099     if (sciErr.iErr)
1100     {
1101         printError(&sciErr, 0);
1102         return false;
1103     }
1104 
1105     return true;
1106 }
1107 
import_list(int * pvCtx,hid_t _iDatasetId,int _iVarType,int _iItemPos,int * _piAddress,char * _pstVarname)1108 static bool import_list(int* pvCtx, hid_t _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, char *_pstVarname)
1109 {
1110     int iRet = 0;
1111     int i = 0;
1112     int iItems = 0;
1113     int *piListAddr = NULL;
1114     hobj_ref_t *piItemRef = NULL;
1115     SciErr sciErr;
1116 
1117     iRet = getListDims(_iDatasetId, &iItems);
1118     if (iRet)
1119     {
1120         return false;
1121     }
1122 
1123     if (iItems == 0)
1124     {
1125         //special case for empty list
1126     }
1127     else
1128     {
1129         iRet = getListItemReferences(_iDatasetId, &piItemRef);
1130         if (iRet)
1131         {
1132             return false;
1133         }
1134     }
1135 
1136     if (_piAddress == 0)
1137     {
1138         switch (_iVarType)
1139         {
1140             case sci_list:
1141                 sciErr = createNamedList(pvCtx, _pstVarname, iItems, &piListAddr);
1142                 break;
1143             case sci_tlist:
1144                 sciErr = createNamedTList(pvCtx, _pstVarname, iItems, &piListAddr);
1145                 break;
1146             case sci_mlist:
1147                 sciErr = createNamedMList(pvCtx, _pstVarname, iItems, &piListAddr);
1148                 break;
1149             default:
1150                 return false;
1151         }
1152     }
1153     else                        //if not null this variable is in a list
1154     {
1155         switch (_iVarType)
1156         {
1157             case sci_list:
1158                 sciErr = createListInNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, iItems, &piListAddr);
1159                 break;
1160             case sci_tlist:
1161                 sciErr = createTListInNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, iItems, &piListAddr);
1162                 break;
1163             case sci_mlist:
1164                 sciErr = createMListInNamedList(pvCtx, _pstVarname, _piAddress, _iItemPos, iItems, &piListAddr);
1165                 break;
1166             default:
1167                 return false;
1168         }
1169     }
1170 
1171     if (sciErr.iErr)
1172     {
1173         printError(&sciErr, 0);
1174         return false;
1175     }
1176 
1177     for (i = 0; i < iItems; i++)
1178     {
1179         hid_t iItemDataset = 0;
1180 
1181         iRet = getListItemDataset(_iDatasetId, piItemRef, i, &iItemDataset);
1182         if (iRet || iItemDataset == 0)
1183         {
1184             return false;
1185         }
1186 
1187         bool bRet = import_data(pvCtx, iItemDataset, i + 1, piListAddr, _pstVarname);
1188 
1189         if (bRet == false)
1190         {
1191             return false;
1192         }
1193     }
1194 
1195     iRet = deleteListItemReferences(_iDatasetId, piItemRef);
1196     if (iRet)
1197     {
1198         return false;
1199     }
1200 
1201     return true;
1202 }
1203 
import_hypermat(int * pvCtx,hid_t _iDatasetId,int _iVarType,int _iItemPos,int * _piAddress,char * _pstVarname)1204 static bool import_hypermat(int* pvCtx, hid_t _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, char *_pstVarname)
1205 {
1206     int iRet = 0;
1207     int iComplex = 0;
1208     int iDims = 0;
1209     int iItems = 0;
1210     hobj_ref_t *piItemRef = NULL;
1211 
1212     // an hypermatrix is stored in an mlist
1213     if (_iVarType != sci_mlist)
1214     {
1215         return false;
1216     }
1217 
1218     iRet = getListDims(_iDatasetId, &iItems);
1219     if (iRet)
1220     {
1221         return false;
1222     }
1223 
1224     if (iItems != 3)
1225     {
1226         // hypermatrix have 3 elements
1227         return false;
1228     }
1229 
1230     iRet = getListItemReferences(_iDatasetId, &piItemRef);
1231     if (iRet)
1232     {
1233         deleteListItemReferences(_iDatasetId, piItemRef);
1234         return false;
1235     }
1236 
1237     // get first item
1238     hid_t iItemDataset = 0;
1239     iRet = getListItemDataset(_iDatasetId, piItemRef, 0, &iItemDataset);
1240     if (iRet || iItemDataset == 0)
1241     {
1242         deleteListItemReferences(_iDatasetId, piItemRef);
1243         return false;
1244     }
1245 
1246     // get first item type
1247     int iItemType = getScilabTypeFromDataSet(iItemDataset);
1248     if (iItemType != sci_strings)
1249     {
1250         deleteListItemReferences(_iDatasetId, piItemRef);
1251         return false;
1252     }
1253 
1254     // get size of first item
1255     iRet = getDatasetInfo(iItemDataset, &iComplex, &iDims, NULL);
1256     if (iRet < 0 || iDims != 2)
1257     {
1258         deleteListItemReferences(_iDatasetId, piItemRef);
1259         return false;
1260     }
1261 
1262     int* piDims = new int[2];
1263     int iSize = getDatasetInfo(iItemDataset, &iComplex, &iDims, piDims);
1264     if (iSize != 3)
1265     {
1266         deleteListItemReferences(_iDatasetId, piItemRef);
1267         delete[] piDims;
1268         return false;
1269     }
1270 
1271     delete[] piDims;
1272     piDims = NULL;
1273 
1274     // get data of first item for check the type of mlist
1275     char** pstData = new char*[iSize];
1276     iRet = readStringMatrix(iItemDataset, pstData);
1277     if (iRet || strcmp(pstData[0], "hm") != 0)
1278     {
1279         // if not the good type, do not h5close (deleteListItemReferences)
1280         FREE(piItemRef);
1281         freeStringMatrix(iItemDataset, pstData);
1282         delete[] pstData;
1283         return false;
1284     }
1285 
1286     freeStringMatrix(iItemDataset, pstData);
1287     delete[] pstData;
1288     pstData = NULL;
1289 
1290     // get second item, the Size of hypermatrix
1291     iRet = getListItemDataset(_iDatasetId, piItemRef, 1, &iItemDataset);
1292     if (iRet)
1293     {
1294         deleteListItemReferences(_iDatasetId, piItemRef);
1295         return false;
1296     }
1297 
1298     iRet = getDatasetInfo(iItemDataset, &iComplex, &iDims, NULL);
1299     if (iRet < 0 || iDims != 2)
1300     {
1301         deleteListItemReferences(_iDatasetId, piItemRef);
1302         return false;
1303     }
1304 
1305     piDims = new int[2];
1306     iSize = getDatasetInfo(iItemDataset, &iComplex, &iDims, piDims);
1307     if (piDims[0] != 1)
1308     {
1309         deleteListItemReferences(_iDatasetId, piItemRef);
1310         delete[] piDims;
1311         return false;
1312     }
1313 
1314     int* piDimsArray = new int[piDims[1]];
1315     iRet = readInteger32Matrix(iItemDataset, piDimsArray);
1316     if (iRet)
1317     {
1318         deleteListItemReferences(_iDatasetId, piItemRef);
1319         delete[] piDims;
1320         delete[] piDimsArray;
1321         return false;
1322     }
1323 
1324     // get third item, the Data of hypermatrix
1325     // import data like a "type" (Double, Int, ...) instead of mlist
1326     iRet = getListItemDataset(_iDatasetId, piItemRef, 2, &iItemDataset);
1327     bool bRet = import_data(pvCtx, iItemDataset, _iItemPos, _piAddress, _pstVarname);
1328     if (bRet == false)
1329     {
1330         deleteListItemReferences(_iDatasetId, piItemRef);
1331         delete[] piDims;
1332         delete[] piDimsArray;
1333         return false;
1334     }
1335 
1336     // get imported hypermatrix from List or Context
1337     types::GenericType* pGT = NULL;
1338     types::InternalType* pIT = NULL;
1339     if (_piAddress)
1340     {
1341         types::List* pL = (types::List*)_piAddress;
1342         pIT = pL->get(_iItemPos - 1);
1343     }
1344     else
1345     {
1346         wchar_t* pwcsName = to_wide_string(_pstVarname);
1347         pIT = symbol::Context::getInstance()->getCurrentLevel(symbol::Symbol(pwcsName));
1348         FREE(pwcsName);
1349     }
1350 
1351     // reshape data with size of hypermatrix
1352     if (pIT->isGenericType() == false)
1353     {
1354         delete[] piDimsArray;
1355         return false;
1356     }
1357 
1358     pGT = pIT->getAs<types::GenericType>();
1359     pGT->reshape(piDimsArray, piDims[1]);
1360 
1361     delete[] piDims;
1362     delete[] piDimsArray;
1363 
1364 
1365     iRet = deleteListItemReferences(_iDatasetId, piItemRef);
1366     if (iRet)
1367     {
1368         return false;
1369     }
1370 
1371     return true;
1372 }
1373 /*--------------------------------------------------------------------------*/
1374 
import_struct(int * pvCtx,hid_t _iDatasetId,int _iVarType,int _iItemPos,int * _piAddress,char * _pstVarname)1375 static bool import_struct(int* pvCtx, hid_t _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, char *_pstVarname)
1376 {
1377     int iRet = 0;
1378     int iComplex = 0;
1379     int iDims = 0;
1380     int iItems = 0;
1381     hobj_ref_t *piItemRef = NULL;
1382 
1383     // an struct is stored in an mlist
1384     if (_iVarType != sci_mlist)
1385     {
1386         return false;
1387     }
1388 
1389     iRet = getListDims(_iDatasetId, &iItems);
1390     if (iRet)
1391     {
1392         return false;
1393     }
1394 
1395     if (iItems < 2)
1396     {
1397         // struct have 2 elements minimal
1398         return false;
1399     }
1400 
1401     iRet = getListItemReferences(_iDatasetId, &piItemRef);
1402     if (iRet)
1403     {
1404         deleteListItemReferences(_iDatasetId, piItemRef);
1405         return false;
1406     }
1407 
1408     // get first item
1409     hid_t iItemDataset = 0;
1410     iRet = getListItemDataset(_iDatasetId, piItemRef, 0, &iItemDataset);
1411     if (iRet || iItemDataset == 0)
1412     {
1413         deleteListItemReferences(_iDatasetId, piItemRef);
1414         return false;
1415     }
1416 
1417     // get first item type
1418     int iItemType = getScilabTypeFromDataSet(iItemDataset);
1419     if (iItemType != sci_strings)
1420     {
1421         deleteListItemReferences(_iDatasetId, piItemRef);
1422         return false;
1423     }
1424 
1425     // get size of first item
1426     iRet = getDatasetInfo(iItemDataset, &iComplex, &iDims, NULL);
1427     if (iRet < 0 || iDims != 2)
1428     {
1429         deleteListItemReferences(_iDatasetId, piItemRef);
1430         return false;
1431     }
1432 
1433     int* piDims = new int[2];
1434     int iSize = getDatasetInfo(iItemDataset, &iComplex, &iDims, piDims);
1435     if (iSize != iItems)
1436     {
1437         deleteListItemReferences(_iDatasetId, piItemRef);
1438         delete[] piDims;
1439         return false;
1440     }
1441 
1442     delete[] piDims;
1443     piDims = NULL;
1444 
1445     // get data of first item for check the type of mlist
1446     char** pstData = new char*[iSize];
1447     char** pstDataSave = new char*[iSize - 2];
1448     iRet = readStringMatrix(iItemDataset, pstData);
1449     if (iRet || strcmp(pstData[0], "st") != 0)
1450     {
1451         // if not the good type, do not h5close (deleteListItemReferences)
1452         FREE(piItemRef);
1453         freeStringMatrix(iItemDataset, pstData);
1454         delete[] pstData;
1455         delete[] pstDataSave;
1456         return false;
1457     }
1458 
1459     for (int i = 2; i < iSize; ++i)
1460     {
1461         pstDataSave[-2 + i] = new char[strlen(pstData[i]) + 1];
1462         strcpy(pstDataSave[-2 + i], pstData[i]);
1463     }
1464 
1465     freeStringMatrix(iItemDataset, pstData);
1466     delete[] pstData;
1467     pstData = NULL;
1468 
1469     // get second item, the Size of struct
1470     iRet = getListItemDataset(_iDatasetId, piItemRef, 1, &iItemDataset);
1471     if (iRet)
1472     {
1473         deleteListItemReferences(_iDatasetId, piItemRef);
1474         for (int i = 0; i < (-2 + iItems); ++i)
1475         {
1476             delete pstDataSave[i];
1477         }
1478         delete[] pstDataSave;
1479         pstDataSave = NULL;
1480         return false;
1481     }
1482 
1483     iRet = getDatasetInfo(iItemDataset, &iComplex, &iDims, NULL);
1484     if (iRet < 0 || iDims != 2)
1485     {
1486         deleteListItemReferences(_iDatasetId, piItemRef);
1487         for (int i = 0; i < (-2 + iItems); ++i)
1488         {
1489             delete pstDataSave[i];
1490         }
1491         delete[] pstDataSave;
1492         pstDataSave = NULL;
1493         return false;
1494     }
1495 
1496     piDims = new int[2];
1497     iSize = getDatasetInfo(iItemDataset, &iComplex, &iDims, piDims);
1498     if (piDims[0] != 1)
1499     {
1500         deleteListItemReferences(_iDatasetId, piItemRef);
1501         for (int i = 0; i < (-2 + iItems); ++i)
1502         {
1503             delete pstDataSave[i];
1504         }
1505         delete[] pstDataSave;
1506         pstDataSave = NULL;
1507         delete[] piDims;
1508         return false;
1509     }
1510 
1511     int* piDimsArray = new int[piDims[1]];
1512     iRet = readInteger32Matrix(iItemDataset, piDimsArray);
1513     if (iRet)
1514     {
1515         deleteListItemReferences(_iDatasetId, piItemRef);
1516         for (int i = 0; i < (-2 + iItems); ++i)
1517         {
1518             delete pstDataSave[i];
1519         }
1520         delete[] pstDataSave;
1521         pstDataSave = NULL;
1522         delete[] piDims;
1523         delete[] piDimsArray;
1524         return false;
1525     }
1526 
1527     types::Struct* pStruct = new types::Struct(piDims[1], piDimsArray);
1528     delete[] piDims;
1529     delete[] piDimsArray;
1530 
1531     wchar_t* pwstName = NULL;
1532     for (int i = 0; i < (-2 + iItems); ++i)
1533     {
1534         pwstName = to_wide_string(pstDataSave[i]);
1535         pStruct->addField(pwstName);
1536         delete pstDataSave[i];
1537         FREE(pwstName);
1538     }
1539 
1540     delete[] pstDataSave;
1541     pstDataSave = NULL;
1542 
1543     types::SingleStruct** ppSStruct =  pStruct->get();
1544     types::String* pStr = pStruct->getFieldNames();
1545 
1546     types::List* pList = new types::List();
1547     // fill the list to avoid api_scilab error about the list size.
1548     pList->set(0, types::Double::Empty());
1549 
1550     if (pStruct->getSize() == 1)
1551     {
1552         types::InternalType* pIT = NULL;
1553         for (int i = 0; i < pStr->getSize(); ++i)
1554         {
1555             hid_t iItemDataset = 0;
1556             iRet = getListItemDataset(_iDatasetId, piItemRef, i + 2, &iItemDataset);
1557             if (iRet || iItemDataset == 0)
1558             {
1559                 deleteListItemReferences(_iDatasetId, piItemRef);
1560                 delete pList;
1561                 delete pStruct;
1562                 return false;
1563             }
1564 
1565             wchar_t* pwcsName = pStr->get(i);
1566             char* pcName = wide_string_to_UTF8(pwcsName);
1567 
1568             bool bRet = import_data(pvCtx, iItemDataset, 1, (int*)pList, pcName);
1569             if (bRet == false)
1570             {
1571                 deleteListItemReferences(_iDatasetId, piItemRef);
1572                 delete pList;
1573                 delete pStruct;
1574                 return false;
1575             }
1576 
1577             pIT = pList->get(0);
1578             ppSStruct[0]->set(pwcsName, pIT);
1579             FREE(pcName);
1580         }
1581     }
1582     else if (pStruct->getSize() > 1)
1583     {
1584         for (int i = 0; i < pStr->getSize(); ++i)
1585         {
1586             hid_t iItemDataset = 0;
1587             iRet = getListItemDataset(_iDatasetId, piItemRef, i + 2, &iItemDataset);
1588             if (iRet || iItemDataset == 0)
1589             {
1590                 deleteListItemReferences(_iDatasetId, piItemRef);
1591                 delete pList;
1592                 delete pStruct;
1593                 return false;
1594             }
1595 
1596             wchar_t* pwcsName = pStr->get(i);
1597             char* pcName = wide_string_to_UTF8(pwcsName);
1598 
1599             bool bRet = import_data(pvCtx, iItemDataset, 1, (int*)pList, pcName);
1600             if (bRet == false)
1601             {
1602                 deleteListItemReferences(_iDatasetId, piItemRef);
1603                 delete pList;
1604                 delete pStruct;
1605                 return false;
1606             }
1607 
1608             types::List* pListData = pList->get(0)->getAs<types::List>();
1609             for (int iWriteData = 0; iWriteData < pStruct->getSize(); ++iWriteData)
1610             {
1611                 ppSStruct[iWriteData]->set(pwcsName, pListData->get(iWriteData));
1612             }
1613 
1614             FREE(pcName);
1615         }
1616 
1617     }
1618 
1619     delete pList;
1620     if (_piAddress == NULL)
1621     {
1622         pwstName = to_wide_string(_pstVarname);
1623         symbol::Context::getInstance()->put(symbol::Symbol(pwstName), pStruct);
1624         FREE(pwstName);
1625     }
1626     else
1627     {
1628         types::List* pParentList = (types::List*)_piAddress;
1629         pParentList->set(_iItemPos - 1, pStruct);
1630     }
1631 
1632     iRet = deleteListItemReferences(_iDatasetId, piItemRef);
1633     if (iRet)
1634     {
1635         return false;
1636     }
1637 
1638     return true;
1639 }
1640 /*--------------------------------------------------------------------------*/
1641 
1642 
import_cell(int * pvCtx,hid_t _iDatasetId,int _iVarType,int _iItemPos,int * _piAddress,char * _pstVarname)1643 static bool import_cell(int* pvCtx, hid_t _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, char *_pstVarname)
1644 {
1645     int iRet = 0;
1646     int iComplex = 0;
1647     int iDims = 0;
1648     int iItems = 0;
1649     hobj_ref_t *piItemRef = NULL;
1650 
1651     // an hypermatrix is stored in an mlist
1652     if (_iVarType != sci_mlist)
1653     {
1654         return false;
1655     }
1656 
1657     iRet = getListDims(_iDatasetId, &iItems);
1658     if (iRet)
1659     {
1660         return false;
1661     }
1662 
1663     if (iItems != 3)
1664     {
1665         // cell have 3 elements
1666         return false;
1667     }
1668 
1669     iRet = getListItemReferences(_iDatasetId, &piItemRef);
1670     if (iRet)
1671     {
1672         deleteListItemReferences(_iDatasetId, piItemRef);
1673         return false;
1674     }
1675 
1676     // get first item
1677     hid_t iItemDataset = 0;
1678     iRet = getListItemDataset(_iDatasetId, piItemRef, 0, &iItemDataset);
1679     if (iRet || iItemDataset == 0)
1680     {
1681         deleteListItemReferences(_iDatasetId, piItemRef);
1682         return false;
1683     }
1684 
1685     // get first item type
1686     int iItemType = getScilabTypeFromDataSet(iItemDataset);
1687     if (iItemType != sci_strings)
1688     {
1689         deleteListItemReferences(_iDatasetId, piItemRef);
1690         return false;
1691     }
1692 
1693     // get size of first item
1694     iRet = getDatasetInfo(iItemDataset, &iComplex, &iDims, NULL);
1695     if (iRet < 0 || iDims != 2)
1696     {
1697         deleteListItemReferences(_iDatasetId, piItemRef);
1698         return false;
1699     }
1700 
1701     int* piDims = new int[2];
1702     int iSize = getDatasetInfo(iItemDataset, &iComplex, &iDims, piDims);
1703     if (iSize != 3)
1704     {
1705         deleteListItemReferences(_iDatasetId, piItemRef);
1706         delete[] piDims;
1707         return false;
1708     }
1709 
1710     delete[] piDims;
1711     piDims = NULL;
1712 
1713     // get data of first item for check the type of mlist
1714     char** pstData = new char*[iSize];
1715     iRet = readStringMatrix(iItemDataset, pstData);
1716     if (iRet || strcmp(pstData[0], "ce") != 0)
1717     {
1718         // if not the good type, do not h5close (deleteListItemReferences)
1719         FREE(piItemRef);
1720         freeStringMatrix(iItemDataset, pstData);
1721         delete[] pstData;
1722         return false;
1723     }
1724 
1725     freeStringMatrix(iItemDataset, pstData);
1726     delete[] pstData;
1727     pstData = NULL;
1728 
1729     // get second item, the Size of cell
1730     iRet = getListItemDataset(_iDatasetId, piItemRef, 1, &iItemDataset);
1731     if (iRet)
1732     {
1733         deleteListItemReferences(_iDatasetId, piItemRef);
1734         return false;
1735     }
1736 
1737     iRet = getDatasetInfo(iItemDataset, &iComplex, &iDims, NULL);
1738     if (iRet < 0 || iDims != 2)
1739     {
1740         deleteListItemReferences(_iDatasetId, piItemRef);
1741         return false;
1742     }
1743 
1744     piDims = new int[2];
1745     iSize = getDatasetInfo(iItemDataset, &iComplex, &iDims, piDims);
1746     if (piDims[0] != 1)
1747     {
1748         deleteListItemReferences(_iDatasetId, piItemRef);
1749         delete[] piDims;
1750         return false;
1751     }
1752 
1753     int* piDimsArray = new int[piDims[1]];
1754     iRet = readInteger32Matrix(iItemDataset, piDimsArray);
1755     if (iRet)
1756     {
1757         deleteListItemReferences(_iDatasetId, piItemRef);
1758         delete[] piDims;
1759         delete[] piDimsArray;
1760         return false;
1761     }
1762 
1763     types::Cell* pCell = new types::Cell(piDims[1], piDimsArray);
1764     delete[] piDims;
1765     delete[] piDimsArray;
1766     types::List* pList = new types::List();
1767     pList->set(0, types::Double::Empty());
1768 
1769     iRet = getListItemDataset(_iDatasetId, piItemRef, 2, &iItemDataset);
1770     if (iRet || iItemDataset == 0)
1771     {
1772         deleteListItemReferences(_iDatasetId, piItemRef);
1773         delete pList;
1774         delete pCell;
1775         return false;
1776     }
1777 
1778     bool bRet = import_data(pvCtx, iItemDataset, 1, (int*)pList, NULL);
1779     if (bRet == false)
1780     {
1781         deleteListItemReferences(_iDatasetId, piItemRef);
1782         delete pList;
1783         delete pCell;
1784         return false;
1785     }
1786 
1787     types::List* pListData = pList->get(0)->getAs<types::List>();
1788     for (int iWriteData = 0; iWriteData < pCell->getSize(); ++iWriteData)
1789     {
1790         pCell->set(iWriteData, pListData->get(iWriteData));
1791     }
1792 
1793     delete pList;
1794 
1795     if (_piAddress == NULL)
1796     {
1797         wchar_t* pwstName = to_wide_string(_pstVarname);
1798         symbol::Context::getInstance()->put(symbol::Symbol(pwstName), pCell);
1799         FREE(pwstName);
1800     }
1801     else
1802     {
1803         types::List* pParentList = (types::List*)_piAddress;
1804         pParentList->set(_iItemPos - 1, pCell);
1805     }
1806 
1807     iRet = deleteListItemReferences(_iDatasetId, piItemRef);
1808 
1809     if (iRet)
1810     {
1811         return false;
1812     }
1813 
1814     return true;
1815 }
1816 /*--------------------------------------------------------------------------*/
1817 
1818