Fix bugs and it is now possible to read hyperslabs
[scilab.git] / scilab / modules / hdf5 / src / cpp / HDF5Scilab.hxx
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
4  *
5  * This file must be used under the terms of the CeCILL.
6  * This source file is licensed as described in the file COPYING, which
7  * you should have received as part of this distribution.  The terms
8  * are also available at
9  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #ifndef __HDF5SCILAB_HXX__
14 #define __HDF5SCILAB_HXX__
15
16 #include <vector>
17
18 #include "H5Object.hxx"
19 #include "H5File.hxx"
20 #include "H5Group.hxx"
21 #include "H5Dataset.hxx"
22 #include "H5Dataspace.hxx"
23 #include "H5Attribute.hxx"
24 #include "H5BasicData.hxx"
25 #include "H5Data.hxx"
26 #include "H5VariableScope.hxx"
27
28 extern "C"
29 {
30 #include "api_scilab.h"
31 #include "Scierror.h"
32 #include "HDF5Objects.h"
33 #include "sciprint.h"
34 #include "localization.h"
35 }
36
37 namespace org_modules_hdf5
38 {
39
40 class HDF5Scilab
41 {
42
43 public:
44
45     enum H5ObjectType {
46         H5FILE,
47         H5GROUP,
48         H5DATASET,
49         H5ATTRIBUTE,
50         H5SPACE,
51         H5TYPE,
52         H5REFERENCE,
53         H5LIST
54     };
55
56     static int getH5ObjectId(int * mlist, void * pvApiCtx);
57
58     static H5Object * getH5Object(int * mlist, void * pvApiCtx);
59
60     static bool isH5Object(int * mlist, void * pvApiCtx);
61
62     static void scilabPrint(const std::string & str);
63
64     static void split(const std::string & str, std::vector<std::string> & v, const char c = '\n');
65
66     static void readData(const std::string & filename, const std::string & name, const unsigned int size, const double * start, const double * stride, const double * count, const double * block, int pos, void * pvApiCtx);
67
68     static void readData(H5Object & obj, const std::string & name, const unsigned int size, const double * start, const double * stride, const double * count, const double * block, int pos, void * pvApiCtx);
69
70     static void readAttributeData(H5Object & obj, const std::string & path, const std::string & attrName, int pos, void * pvApiCtx);
71
72     static void readAttributeData(const std::string & filename, const std::string & path, const std::string & attrName, int pos, void * pvApiCtx);
73
74     static void deleteObject(H5Object & parent, const std::string & name);
75
76     static void createLink(H5Object & parent, const std::string & name, const std::string & targetPath, const bool hard);
77
78     static void createLink(H5Object & parent, const std::string & name, H5Object & targetObject, const bool hard);
79
80     static void createLink(H5Object & parent, const std::string & name, const std::string & targetFile, const std::string & targetPath);
81
82     static void createLink(H5Object & parent, const std::string & name, H5Object & targetObject);
83
84     static void copy(H5Object & src, H5Object & dest, const std::string & dlocation);
85
86     static void copy(H5Object & src, const std::string & dfile, const std::string & dlocation);
87
88     static void copy(const std::string & sfile, const std::string & slocation, H5Object & dest, const std::string & dlocation);
89
90     static void copy(const std::string & sfile, const std::string & slocation, const std::string & dfile, const std::string & dlocation);
91
92     static void ls(H5Object & obj, std::string name, int position, void * pvApiCtx);
93
94     static void ls(std::string path, std::string name, int position, void * pvApiCtx);
95
96     static bool checkType(const H5Object & obj, const H5ObjectType type);
97
98     template <typename T, typename U>
99     static U & create(H5Object & parent, const std::string & name, const unsigned int rank, const hsize_t * dims, const hsize_t * maxdims, T * data, const hid_t targetType)
100     {
101         hid_t obj;
102         hid_t space;
103         hid_t type;
104         hid_t targettype;
105         herr_t err;
106         H5Object * loc = 0;
107         hsize_t * _maxdims = 0;
108         bool mustDelete = false;
109         H5T_conv_t conv;
110         H5T_cdata_t * pcdata = 0;
111
112         if (rank > __SCILAB_HDF5_MAX_DIMS__)
113         {
114             throw H5Exception(__LINE__, __FILE__, _("Invalid rank, must be in the interval [0, %d]."), __SCILAB_HDF5_MAX_DIMS__);
115         }
116
117         if (parent.isFile())
118         {
119             loc = &reinterpret_cast<H5File *>(&parent)->getRoot();
120         }
121         else
122         {
123             loc = &parent;
124         }
125
126         type = H5Type::getBaseType(data);
127         if (type < 0)
128         {
129             throw H5Exception(__LINE__, __FILE__, _("Cannot create a data type."));
130         }
131
132         if (targetType == (hid_t) - 1)
133         {
134             targettype = type;
135         }
136         else
137         {
138             targettype = targetType;
139         }
140
141         if (!H5Tfind(type, targettype, &pcdata))
142         {
143             H5Tclose(type);
144             throw H5Exception(__LINE__, __FILE__, _("No converter found for the specified target datatype."));
145         }
146
147         if (!maxdims)
148         {
149             _maxdims = new hsize_t[rank];
150             memcpy(_maxdims, dims, rank * sizeof(hsize_t));
151             mustDelete = true;
152         }
153         else
154         {
155             _maxdims = const_cast<hsize_t *>(maxdims);
156         }
157
158         space = H5Screate_simple(rank, dims, maxdims);
159         if (mustDelete)
160         {
161             delete[] _maxdims;
162         }
163
164         if (space < 0)
165         {
166             H5Tclose(type);
167             throw H5Exception(__LINE__, __FILE__, _("Cannot create a new dataspace."));
168         }
169
170         try
171         {
172             obj = U::create(*loc, name, type, targettype, space, data);
173             H5Tclose(type);
174             H5Sclose(space);
175         }
176         catch (const H5Exception & e)
177         {
178             H5Tclose(type);
179             H5Sclose(space);
180             throw;
181         }
182
183         return *new U(*loc, obj, name);
184     }
185
186     template <typename T, typename U>
187     static U & create(H5Object & parent, const std::string & name, const unsigned int rank, const hsize_t * dims, const hsize_t * maxdims, T * data, const std::string & targetType)
188     {
189         hid_t targettype;
190         if (targetType.empty())
191         {
192             targettype = (hid_t) - 1;
193         }
194         else
195         {
196             targettype = H5Type::getBaseType(targetType);
197             if (targettype < 0)
198             {
199                 throw H5Exception(__LINE__, __FILE__, _("Cannot create the target type."));
200             }
201         }
202
203         try
204         {
205             U & obj = create<T, U>(parent, name, rank, dims, maxdims, data, targettype);
206             if (targettype >= 0)
207             {
208                 H5Tclose(targettype);
209             }
210             return obj;
211         }
212         catch (const H5Exception & e)
213         {
214             if (targettype >= 0)
215             {
216                 H5Tclose(targettype);
217             }
218             throw;
219         }
220     }
221 };
222 }
223
224 #endif // __HDF5SCILAB_HXX__