925ddc7f857af08261a82927bc339bc5b280227a
[scilab.git] / scilab / modules / hdf5 / sci_gateway / cpp / sci_hdf5_load.cpp
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2015 - Scilab Enterprises - 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 "hdf5_gw.hxx"
18 #include "function.hxx"
19 #include "string.hxx"
20 #include "list.hxx"
21 #include "overload.hxx"
22 #include "loadlib.hxx"
23 #include "context.hxx"
24
25 extern "C"
26 {
27 #include "sci_malloc.h"
28 #include "Scierror.h"
29 #include "FileExist.h"
30 #include "expandPathVariable.h"
31 #include "h5_fileManagement.h"
32 #include "h5_attributeConstants.h"
33 #include "h5_readDataFromFile.h"
34 }
35
36 static const std::string fname("load");
37
38 types::Function::ReturnValue sci_hdf5_load(types::typed_list &in, int _iRetCount, types::typed_list& out)
39 {
40     int rhs = static_cast<int>(in.size());
41     if (rhs < 1)
42     {
43         Scierror(999, _("%s: Wrong number of input argument(s): at least %d expected.\n"), fname.data(), 1);
44         return types::Function::Error;
45     }
46
47     if (in[0]->getId() != types::InternalType::IdScalarString)
48     {
49         Scierror(999, _("%s: Wrong size for input argument #%d: string expected.\n"), fname.data(), 1);
50         return types::Function::Error;
51     }
52
53     wchar_t* wcfilename = expandPathVariableW(in[0]->getAs<types::String>()->get()[0]);
54     char* cfilename = wide_string_to_UTF8(wcfilename);
55     std::string filename(cfilename);
56     std::wstring wfilename(wcfilename);
57     FREE(cfilename);
58     FREE(wcfilename);
59
60     if (FileExistW(wfilename.data()) == FALSE)
61     {
62         Scierror(999, _("%s: Unable to open file: '%s'.\n"), fname.data(), filename.data());
63         return types::Function::Error;
64     }
65
66     //library ?
67     if (isHDF5File(filename.data()) == false)
68     {
69         //lib file
70         int err = 0;
71         types::Library* lib = loadlib(in[0]->getAs<types::String>()->get()[0], &err);
72
73         switch (err)
74         {
75             case 0:
76                 break;
77             case 2:
78                 Scierror(999, "%s: %s", fname.data(), _("Redefining permanent variable.\n"));
79                 return types::Function::Error;
80             default:
81                 Scierror(999, _("%s: %s is not a valid lib file.\n"), fname.data(), filename.data());
82                 return types::Function::Error;
83         }
84
85         lib->killMe();
86         return types::Function::OK;
87     }
88
89     int iFile = openHDF5File(filename.data(), 0);
90     if (iFile < 0)
91     {
92         Scierror(999, _("%s: Unable to open file: %s\n"), fname.data(), filename.data());
93         return types::Function::Error;
94     }
95
96     std::wstring wstFuncName;
97     //manage version information
98     int version = getSODFormatAttribute(iFile);
99     closeHDF5File(iFile);
100
101     bool needReprocess = false;
102     switch (version)
103     {
104         case -1:
105         case 1:
106         {
107             wstFuncName = L"hdf5_load_v1";
108             needReprocess = true;
109             break;
110         }
111         case 2:
112         {
113             wstFuncName = L"hdf5_load_v2";
114             needReprocess = true;
115             break;
116         }
117         case 3:
118         {
119             wstFuncName = L"hdf5_load_v3";
120             break;
121         }
122         default :
123         {
124             Scierror(999, _("%s: Wrong SOD file format version. Max Expected: %d Found: %d\n"), fname.data(), SOD_FILE_VERSION, version);
125             return types::Function::Error;
126         }
127     }
128
129     types::typed_list out1;
130     types::Function::ReturnValue ret = Overload::call(wstFuncName, in, _iRetCount, out1);
131
132     if (ret != types::Function::OK)
133     {
134         Scierror(999, _("%s: Unable to load '%s'\n"), fname.data(), filename.data());
135         return types::Function::Error;
136     }
137
138     if (needReprocess)
139     {
140         //call %sodload
141         types::String* vars = out1[0]->getAs<types::String>();
142         vars->IncreaseRef();
143         int size = vars->getSize();
144         types::typed_list in2(1, vars);
145         types::typed_list out2;
146         std::wstring wstFuncName = L"%_sodload";
147         ret = Overload::call(wstFuncName, in2, size, out2);
148         vars->DecreaseRef();
149
150         symbol::Context* ctx = symbol::Context::getInstance();
151         wchar_t** names = vars->get();
152
153         //update context with values return by %_sodload
154         for (int i = 0; i < size; ++i)
155         {
156             ctx->put(symbol::Symbol(names[i]), out2[i]);
157         }
158
159         vars->killMe();
160     }
161     else
162     {
163         out.push_back(out1.front());
164     }
165
166     return ret;
167 }