Fix bugs and it is now possible to read hyperslabs
[scilab.git] / scilab / modules / hdf5 / src / cpp / H5DataFactory.cpp
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 #include "H5DataFactory.hxx"
14
15 namespace org_modules_hdf5
16 {
17
18 H5Data & H5DataFactory::getData(H5Object & parent, const hid_t obj, H5Dataspace * space, hsize_t * selectdims, const bool isAttribute)
19 {
20     const hid_t type = isAttribute ? H5Aget_type(obj) : H5Dget_type(obj);
21     if (type < 0)
22     {
23         throw H5Exception(__LINE__, __FILE__, _("Cannot get the data type"));
24     }
25     H5Data * data = 0;
26     hid_t spaceId = space ? space->getH5Id() : -1;
27
28     // TODO: le type est ferme dans getNativeData: bonne idee ou pas ??
29
30     switch (H5Tget_class(type))
31     {
32         case H5T_INTEGER:
33             data = &getIntegerData(parent, obj, spaceId, selectdims, type, isAttribute);
34             break;
35         case H5T_FLOAT:
36             data = &getFloatingData(parent, obj, spaceId, selectdims, type, isAttribute);
37             break;
38         case H5T_TIME:
39             data = &getTimeData(parent, obj, spaceId, selectdims, type, isAttribute);
40             break;
41         case H5T_STRING:
42             data = &getStringData(parent, obj, spaceId, selectdims, type, isAttribute);
43             break;
44         case H5T_BITFIELD:
45             data = &getBitfieldData(parent, obj, spaceId, selectdims, type, isAttribute);
46             break;
47         case H5T_OPAQUE:
48             data = &getOpaqueData(parent, obj, spaceId, selectdims, type, isAttribute);
49             break;
50         case H5T_COMPOUND:
51             data = &getCompoundData(parent, obj, spaceId, selectdims, type, isAttribute);
52             break;
53         case H5T_REFERENCE:
54             data = &getReferenceData(parent, obj, spaceId, selectdims, type, isAttribute);
55             break;
56         case H5T_ENUM:
57             std::cout << "ENUM" << std::endl;
58             //data = &getEnumData(parent, obj, type, isAttribute);
59             //break;
60         case H5T_VLEN:
61             std::cout << "VLEN" << std::endl;
62
63             //data = &getVlenData(parent, obj, type, isAttribute);
64             //break;
65         case H5T_ARRAY:
66             std::cout << "ARRAY" << std::endl;
67             //data = &getArrayData(parent, obj, type, isAttribute);
68             //break;
69         default:
70             H5Tclose(type);
71             throw H5Exception(__LINE__, __FILE__, _("Cannot get data from an unknown data type."));
72     }
73
74     return *data;
75 }
76
77 H5Data & H5DataFactory::getData(H5Object & parent, const hsize_t totalSize, const hid_t type, hsize_t ndims, hsize_t * dims, void * data, const hsize_t stride, const size_t offset, const bool dataOwner)
78 {
79     hsize_t dataSize = H5Tget_size(type);
80     if (H5Tget_class(type) == H5T_STRING && !H5Tis_variable_str(type))
81     {
82         // We have a C-string so it is null terminated
83         dataSize++;
84     }
85
86     switch (H5Tget_class(type))
87     {
88         case H5T_INTEGER:
89             if (H5Tequal(type, H5T_NATIVE_SCHAR))
90             {
91                 return *new H5CharData(parent, totalSize, dataSize, ndims, dims, (char *)data, stride, offset, false);
92             }
93             else if (H5Tequal(type, H5T_NATIVE_UCHAR))
94             {
95                 return *new H5UnsignedCharData(parent, totalSize, dataSize, ndims, dims, (unsigned char *)data, stride, offset, false);
96             }
97             else if (H5Tequal(type, H5T_NATIVE_SHORT))
98             {
99                 return *new H5BasicData<short>(parent, totalSize, dataSize, ndims, dims, (short *)data, stride, offset, false);
100             }
101             else if (H5Tequal(type, H5T_NATIVE_USHORT))
102             {
103                 return *new H5BasicData<unsigned short>(parent, totalSize, dataSize, ndims, dims, (unsigned short *)data, stride, offset, false);
104             }
105             else if (H5Tequal(type, H5T_NATIVE_INT))
106             {
107                 return *new H5BasicData<int>(parent, totalSize, dataSize, ndims, dims, (int *)data, stride, offset, false);
108             }
109             else if (H5Tequal(type, H5T_NATIVE_UINT))
110             {
111                 return *new H5BasicData<unsigned int>(parent, totalSize, dataSize, ndims, dims, (unsigned int *)data, stride, offset, false);
112             }
113
114 #ifdef __SCILAB_INT64__
115
116             else if (H5Tequal(type, H5T_NATIVE_LONG))
117             {
118                 return *new H5BasicData<long long>(parent, totalSize, dataSize, ndims, dims, (long long *)data, stride, offset, false);
119             }
120             else if (H5Tequal(type, H5T_NATIVE_ULONG))
121             {
122                 return *new H5BasicData<unsigned long long>(parent, totalSize, dataSize, ndims, dims, (unsigned long long *)data, stride, offset, false);
123             }
124 #else
125
126             else if (H5Tequal(type, H5T_NATIVE_LONG))
127             {
128                 return *new H5TransformedData<long long, int>(parent, totalSize, dataSize, ndims, dims, (long long *)data, stride, offset, false);
129             }
130             else if (H5Tequal(type, H5T_NATIVE_ULONG))
131             {
132                 return *new H5TransformedData<unsigned long long, unsigned int>(parent, totalSize, dataSize, ndims, dims, (unsigned long long *)data, stride, offset, false);
133             }
134
135 #endif // __SCILAB_INT64__
136
137             else
138             {
139                 H5Tclose(type);
140                 throw H5Exception(__LINE__, __FILE__, _("Unknown integer datatype."));
141             }
142             break;
143         case H5T_FLOAT:
144             if (H5Tequal(type, H5T_NATIVE_FLOAT))
145             {
146                 //return *new H5FloatData(parent, totalSize, dataSize, ndims, dims, (float *)data, stride, offset, false);
147                 return *new H5TransformedData<float, double>(parent, totalSize, dataSize, ndims, dims, (float *)data, stride, offset, false);
148             }
149             else if (H5Tequal(type, H5T_NATIVE_DOUBLE))
150             {
151                 return *new H5BasicData<double>(parent, totalSize, dataSize, ndims, dims, (double *)data, stride, offset, false);
152             }
153             else
154             {
155                 throw H5Exception(__LINE__, __FILE__, _("Unknown floating-point datatype."));
156             }
157             break;
158         case H5T_TIME:
159             return *new H5TimeData(parent, totalSize, dataSize, ndims, dims, (char *)data, stride, offset, false);
160         case H5T_STRING:
161             if (H5Tis_variable_str(type))
162             {
163                 return *new H5StringData(parent, totalSize, dataSize, ndims, dims, (char **)data, stride, offset, false);
164             }
165             else
166             {
167                 return *new H5StringData(parent, totalSize, dataSize, ndims, dims, (char *)data, stride, offset, false);
168             }
169         case H5T_BITFIELD:
170             return *new H5BitfieldData(parent, totalSize, dataSize, ndims, dims, (char *)data, stride, offset, false);
171         case H5T_OPAQUE:
172             return *new H5OpaqueData(parent, totalSize, dataSize, ndims, dims, (char *)data, stride, offset, false);
173         case H5T_COMPOUND:
174         {
175             const unsigned int nmembers = (unsigned int)H5Tget_nmembers(type);
176             std::string * names = new std::string[nmembers];
177             size_t offs;
178             H5Data ** fields = new H5Data *[nmembers];
179
180             for (unsigned int i = 0; i < nmembers; i++)
181             {
182                 hid_t mtype = H5Tget_member_type(type, i);
183                 char * mname = H5Tget_member_name(type, i);
184                 size_t offs = H5Tget_member_offset(type, i);
185                 names[i] = std::string(mname);
186                 free(mname);
187                 fields[i] = &getData(parent, totalSize, mtype, ndims, dims, data, stride, offset + offs, false);
188             }
189
190             return *new H5CompoundData(parent, totalSize, dataSize, ndims, dims, nmembers, names, fields, (char *)data, dataOwner);
191         }
192         case H5T_REFERENCE:
193             // TODO: virer le false
194             return *new H5ReferenceData(parent, false, totalSize, dataSize, ndims, dims, (char *)data, offset);
195         case H5T_ENUM:
196         {
197             /*int nmembers = H5Tget_nmembers(type);
198               std::string * names = new std::string[nmembers];
199
200               for (unsigned int i = 0; i < nmembers; i++)
201               {
202               char * mname = H5Tget_member_name(type, i);
203               names[i] = std::string(mname);
204               free(mname);
205               }
206               return *new H5EnumData(parent, totalSize, dataSize, ndims, dims, data, offset, names);*/
207         }
208         case H5T_VLEN:
209             //return *new H5VlenData(parent, totalSize, dataSize, ndims, dims, data, offset);
210         case H5T_ARRAY:
211             //return *new H5ArrayData(parent, totalSize, dataSize, ndims, dims, data, offset);
212         default:
213             throw H5Exception(__LINE__, __FILE__, _("Cannot get data from an unknown data type."));
214     }
215
216     throw H5Exception(__LINE__, __FILE__, _("Cannot get data from an unknown data type."));
217 }
218
219 H5Data & H5DataFactory::getIntegerData(H5Object & parent, const hid_t obj, const hid_t space, hsize_t * selectdims, const hid_t type, const bool isAttribute)
220 {
221     hsize_t ndims;
222     hsize_t * dims = 0;
223     hsize_t totalSize;
224     hsize_t dataSize;
225     void * data = 0;
226     H5Data * dataObj = 0;
227     const hid_t nativeType = H5Tget_native_type(type, H5T_DIR_DEFAULT);
228
229     getNativeData(obj, space, selectdims, type, &totalSize, &dataSize, &ndims, &dims, &data, isAttribute);
230
231     if (H5Tequal(nativeType, H5T_NATIVE_SCHAR))
232     {
233         dataObj = new H5CharData(parent, totalSize, dataSize, ndims, dims, (char *)data);
234     }
235     else if (H5Tequal(nativeType, H5T_NATIVE_UCHAR))
236     {
237         dataObj = new H5UnsignedCharData(parent, totalSize, dataSize, ndims, dims, (unsigned char *)data);
238     }
239     else if (H5Tequal(nativeType, H5T_NATIVE_SHORT))
240     {
241         dataObj = new H5BasicData<short>(parent, totalSize, dataSize, ndims, dims, (short *)data);
242     }
243     else if (H5Tequal(nativeType, H5T_NATIVE_USHORT))
244     {
245         dataObj = new H5BasicData<unsigned short>(parent, totalSize, dataSize, ndims, dims, (unsigned short *)data);
246     }
247     else if (H5Tequal(nativeType, H5T_NATIVE_INT))
248     {
249         dataObj = new H5BasicData<int>(parent, totalSize, dataSize, ndims, dims, (int *)data);
250     }
251     else if (H5Tequal(nativeType, H5T_NATIVE_UINT))
252     {
253         dataObj = new H5BasicData<unsigned int>(parent, totalSize, dataSize, ndims, dims, (unsigned int *)data);
254     }
255
256 #ifdef __SCILAB_INT64__
257
258     else if (H5Tequal(nativeType, H5T_NATIVE_LONG))
259     {
260         dataObj = new H5BasicData<long long>(parent, totalSize, dataSize, ndims, dims, (long long *)data);
261     }
262     else if (H5Tequal(nativeType, H5T_NATIVE_ULONG))
263     {
264         dataObj = new H5BasicData<unsigned long long>(parent, totalSize, dataSize, ndims, dims, (unsigned long long *)data);
265     }
266
267 #else
268
269     else if (H5Tequal(nativeType, H5T_NATIVE_LONG))
270     {
271         dataObj = new H5TransformedData<long long, int>(parent, totalSize, dataSize, ndims, dims, (long long *)data);
272     }
273     else if (H5Tequal(nativeType, H5T_NATIVE_ULONG))
274     {
275         dataObj = new H5TransformedData<unsigned long long, unsigned int>(parent, totalSize, dataSize, ndims, dims, (unsigned long long *)data);
276     }
277
278 #endif // __SCILAB_INT64__
279
280     else
281     {
282         H5Tclose(nativeType);
283         delete[] dims;
284         delete[] static_cast<char *>(data);
285         throw H5Exception(__LINE__, __FILE__, _("Unknown integer datatype."));
286     }
287
288     H5Tclose(nativeType);
289
290     return *dataObj;
291 }
292
293 H5Data & H5DataFactory::getFloatingData(H5Object & parent, const hid_t obj, const hid_t space, hsize_t * selectdims, const hid_t type, const bool isAttribute)
294 {
295     hsize_t ndims;
296     hsize_t totalSize;
297     hsize_t dataSize;
298     hsize_t * dims = 0;
299     void * data = 0;
300     H5Data * dataObj = 0;
301     const hid_t nativeType = H5Tget_native_type(type, H5T_DIR_DEFAULT);
302
303     getNativeData(obj, space, selectdims, type, &totalSize, &dataSize, &ndims, &dims, &data, isAttribute);
304
305     if (H5Tequal(nativeType, H5T_NATIVE_FLOAT))
306     {
307         dataObj = new H5TransformedData<float, double>(parent, totalSize, dataSize, ndims, dims, (float *)data);
308     }
309     else if (H5Tequal(nativeType, H5T_NATIVE_DOUBLE))
310     {
311         dataObj = new H5BasicData<double>(parent, totalSize, dataSize, ndims, dims, (double *)data);
312     }
313     else
314     {
315         H5Tclose(nativeType);
316         delete[] dims;
317         delete[] static_cast<char *>(data);
318         throw H5Exception(__LINE__, __FILE__, _("Unknown floating-point datatype."));
319     }
320
321     H5Tclose(nativeType);
322
323     return *dataObj;
324 }
325
326 H5StringData & H5DataFactory::getStringData(H5Object & parent, const hid_t obj, const hid_t space, hsize_t * selectdims, const hid_t type, const bool isAttribute)
327 {
328     hsize_t ndims;
329     hsize_t totalSize;
330     hsize_t dataSize;
331     hsize_t * dims = 0;
332     void * data = 0;
333
334     getNativeData(obj, space, selectdims, type, &totalSize, &dataSize, &ndims, &dims, &data, isAttribute);
335     if (H5Tis_variable_str(type))
336     {
337         return *new H5StringData(parent, totalSize, dataSize, ndims, dims, (char **)data);
338     }
339     else
340     {
341         return *new H5StringData(parent, totalSize, dataSize, ndims, dims, (char *)data);
342     }
343 }
344
345 H5TimeData & H5DataFactory::getTimeData(H5Object & parent, const hid_t obj, const hid_t space, hsize_t * selectdims, const hid_t type, const bool isAttribute)
346 {
347     hsize_t ndims;
348     hsize_t totalSize;
349     hsize_t dataSize;
350     hsize_t * dims = 0;
351     void * data = 0;
352
353     getNativeData(obj, space, selectdims, type, &totalSize, &dataSize, &ndims, &dims, &data, isAttribute);
354
355     return *new H5TimeData(parent, totalSize, dataSize, ndims, dims, static_cast<char *>(data));
356 }
357
358 H5BitfieldData & H5DataFactory::getBitfieldData(H5Object & parent, const hid_t obj, const hid_t space, hsize_t * selectdims, const hid_t type, const bool isAttribute)
359 {
360     hsize_t ndims;
361     hsize_t totalSize;
362     hsize_t dataSize;
363     hsize_t * dims = 0;
364     void * data = 0;
365
366     getNativeData(obj, space, selectdims, type, &totalSize, &dataSize, &ndims, &dims, &data, isAttribute);
367
368     return *new H5BitfieldData(parent, totalSize, dataSize, ndims, dims, static_cast<char *>(data));
369 }
370
371 H5OpaqueData & H5DataFactory::getOpaqueData(H5Object & parent, const hid_t obj, const hid_t space, hsize_t * selectdims, const hid_t type, const bool isAttribute)
372 {
373     hsize_t ndims;
374     hsize_t totalSize;
375     hsize_t dataSize;
376     hsize_t * dims = 0;
377     void * data = 0;
378
379     getNativeData(obj, space, selectdims, type, &totalSize, &dataSize, &ndims, &dims, &data, isAttribute);
380
381     return *new H5OpaqueData(parent, totalSize, dataSize, ndims, dims, static_cast<char *>(data));
382 }
383
384 H5Data & H5DataFactory::getCompoundData(H5Object & parent, const hid_t obj, const hid_t space, hsize_t * selectdims, const hid_t type, const bool isAttribute)
385 {
386     hsize_t ndims;
387     hsize_t totalSize;
388     hsize_t dataSize;
389     hsize_t * dims = 0;
390     void * data = 0;
391     const hid_t nativeType = H5Tget_native_type(type, H5T_DIR_DEFAULT);
392
393     getNativeData(obj, space, selectdims, type, &totalSize, &dataSize, &ndims, &dims, &data, isAttribute);
394
395     try
396     {
397         return getData(parent, totalSize, nativeType, ndims, dims, data, dataSize, 0, true);
398     }
399     catch (const H5Exception & e)
400     {
401         H5Tclose(nativeType);
402         throw;
403     }
404 }
405
406 H5ReferenceData & H5DataFactory::getReferenceData(H5Object & parent, const hid_t obj, const hid_t space, hsize_t * selectdims, const hid_t type, const bool isAttribute)
407 {
408     hsize_t ndims;
409     hsize_t totalSize;
410     hsize_t dataSize;
411     hsize_t * dims = 0;
412     void * data = 0;
413
414     getNativeData(obj, space, selectdims, type, &totalSize, &dataSize, &ndims, &dims, &data, isAttribute);
415     return *new H5ReferenceData(parent, H5Tequal(type, H5T_STD_REF_DSETREG) > 0, totalSize, dataSize, ndims, dims, (char *)data);
416 }
417
418 /*H5EnumData & H5DataFactory::getEnumData(H5Object & parent, const hid_t obj, const hid_t type, const bool isAttribute)
419   {
420   hsize_t ndims;
421   hsize_t totalSize;
422   hisze_t dataSize;
423   hsize_t * dims = 0;
424   void * data = 0;
425   int nmembers = H5Tget_nmembers(type);
426   std::string * names = new std::string[nmembers];
427
428   for (unsigned int i = 0; i < nmembers; i++)
429   {
430   char * mname = H5Tget_member_name(type, i);
431   names[i] = std::string(mname);
432   free(mname);
433   }
434
435   getNativeData(obj, type, &totalSize, &dataSize, &ndims, &dims, &data, isAttribute);
436
437   return *new H5EnumData(parent, totalSize, dataSize, ndims, dims, data, names);
438   }
439
440   H5VlenData & H5DataFactory::getVlenData(H5Object & parent, const hid_t obj, const hid_t type, const bool isAttribute)
441   {
442   hsize_t ndims;
443   hsize_t totalSize;
444   hisze_t dataSize;
445   hsize_t * dims = 0;
446   void * data = 0;
447
448   getNativeData(obj, type, &totalSize, &dataSize, &ndims, &dims, &data, isAttribute);
449
450   return *new H5VlenData(parent, totalSize, dataSize, ndims, dims, data);
451   }
452
453   H5ArrayData & H5DataFactory::getArrayData(H5Object & parent, const hid_t obj, const hid_t type, const bool isAttribute)
454   {
455   hsize_t ndims;
456   hsize_t totalSize;
457   hisze_t dataSize;
458   hsize_t * dims = 0;
459   void * data = 0;
460
461   getNativeData(obj, type, &totalSize, &dataSize, &ndims, &dims, &data, isAttribute);
462
463   return *new H5ArrayData(parent, totalSize, dataSize, ndims, dims, data);
464   }*/
465
466 //  getNativeData(obj, type, &totalSize, &dataSize, &ndims, &dims, &data, isAttribute);
467
468 //return *new H5StringData(parent, totalSize, dataSize, ndims, dims, data);
469
470 /*void H5DataFactory::getNativeData(const hid_t obj, const hid_t type, hsize_t * totalSize, hsize_t * dataSize, hsize_t * ndims, hsize_t ** dims, void ** data, const bool isAttribute)
471 {
472     hid_t nativeType = H5Tget_native_type(type, H5T_DIR_DEFAULT);
473     const hid_t space = isAttribute ? H5Aget_space(obj) : H5Dget_space(obj);
474     hsize_t size = H5Tget_size(nativeType);
475     *totalSize = 1;
476     *dims = new hsize_t[__SCILAB_HDF5_MAX_DIMS__]();
477     *ndims = H5Sget_simple_extent_dims(space, *dims, 0);
478
479     if (H5Tget_class(nativeType) == H5T_STRING && !H5Tis_variable_str(nativeType))
480     {
481         // We have a C-string so it is null terminated
482         size++;
483     }
484
485     *dataSize = size;
486
487     for (unsigned int i = 0; i < *ndims; i++)
488     {
489         *totalSize *= (*dims)[i];
490     }
491
492     size *= *totalSize;
493
494     if ((hsize_t)((size_t)size) != size)
495     {
496         H5Tclose(type);
497         H5Tclose(nativeType);
498         H5Sclose(space);
499         delete[] *dims;
500         throw H5Exception(__LINE__, __FILE__, _("Memory to allocate is too big"));
501     }
502
503     *data = static_cast<void *>(new char[(size_t)size]());
504     if (!*data)
505     {
506         H5Tclose(type);
507         H5Tclose(nativeType);
508         H5Sclose(space);
509         delete[] *dims;
510         throw H5Exception(__LINE__, __FILE__, _("Cannot allocate memory to get the data"));
511     }
512
513     if ((isAttribute && H5Aread(obj, nativeType, *data) < 0)
514         || (!isAttribute && H5Dread(obj, nativeType, H5S_ALL, space, H5P_DEFAULT, *data) < 0))
515     {
516         H5Tclose(type);
517         H5Tclose(nativeType);
518         H5Sclose(space);
519         delete[] static_cast<char *>(*data);
520         delete[] *dims;
521         throw H5Exception(__LINE__, __FILE__, _("Cannot retrieve the data from the attribute"));
522     }
523
524     H5Tclose(nativeType);
525     H5Sclose(space);
526 }
527 */
528
529 void H5DataFactory::getNativeData(const hid_t obj, const hid_t space, hsize_t * selectdims, const hid_t type, hsize_t * totalSize, hsize_t * dataSize, hsize_t * ndims, hsize_t ** dims, void ** data, const bool isAttribute)
530 {
531     hid_t nativeType = H5Tget_native_type(type, H5T_DIR_DEFAULT);
532     hid_t _space = space < 0 ? (isAttribute ? H5Aget_space(obj) : H5Dget_space(obj)) : space;
533     hsize_t size = H5Tget_size(nativeType);
534     H5S_sel_type sel;
535     hid_t targetspace;
536     herr_t err;
537     hsize_t * blockbuf = 0;
538     bool hyperslab = false;
539
540     *totalSize = 1;
541     if (H5Tget_class(nativeType) == H5T_STRING && !H5Tis_variable_str(nativeType))
542     {
543         // We have a C-string so it is null terminated
544         size++;
545     }
546
547     *dataSize = size;
548     *ndims = H5Sget_simple_extent_dims(_space, 0, 0);
549     *dims = new hsize_t[*ndims];
550
551     if (isAttribute)
552     {
553         H5Sget_simple_extent_dims(_space, *dims, 0);
554     }
555     else
556     {
557         sel = H5Sget_select_type(_space);
558         switch (sel)
559         {
560             case H5S_SEL_NONE:
561             case H5S_SEL_ALL:
562                 H5Sget_simple_extent_dims(_space, *dims, 0);
563                 for (unsigned int i = 0; i < *ndims; i++)
564                 {
565                     *totalSize *= (*dims)[i];
566                 }
567                 break;
568             case H5S_SEL_POINTS:
569                 break;
570             case H5S_SEL_HYPERSLABS:
571                 for (unsigned int i = 0; i < *ndims; i++)
572                 {
573                     (*dims)[i] = selectdims[i];
574                     *totalSize *= (*dims)[i];
575                 }
576                 hyperslab = true;
577         }
578     }
579
580     size *= *totalSize;
581
582     if ((hsize_t)((size_t)size) != size)
583     {
584         H5Tclose(type);
585         H5Tclose(nativeType);
586         if (space < 0)
587         {
588             H5Sclose(_space);
589         }
590         delete[] *dims;
591         throw H5Exception(__LINE__, __FILE__, _("Memory to allocate is too big"));
592     }
593
594     *data = static_cast<void *>(new char[(size_t)size]());
595     if (!*data)
596     {
597         H5Tclose(type);
598         H5Tclose(nativeType);
599         if (space < 0)
600         {
601             H5Sclose(_space);
602         }
603         delete[] *dims;
604         throw H5Exception(__LINE__, __FILE__, _("Cannot allocate memory to get the data"));
605     }
606
607     if (hyperslab)
608     {
609         targetspace =  H5Screate_simple(*ndims, *dims, 0);
610         err = H5Dread(obj, nativeType, targetspace, _space, H5P_DEFAULT, *data);
611         H5Sclose(targetspace);
612     }
613     else
614     {
615         if (isAttribute)
616         {
617             err = H5Aread(obj, nativeType, *data);
618         }
619         else
620         {
621             err = H5Dread(obj, nativeType, H5S_ALL, H5S_ALL, H5P_DEFAULT, *data);
622         }
623     }
624
625     if (err < 0)
626     {
627         H5Tclose(type);
628         H5Tclose(nativeType);
629         if (space < 0)
630         {
631             H5Sclose(_space);
632         }
633         delete[] static_cast<char *>(*data);
634         delete[] *dims;
635         throw H5Exception(__LINE__, __FILE__, _("Cannot retrieve the data from the attribute"));
636     }
637
638     H5Tclose(nativeType);
639     if (space < 0)
640     {
641         H5Sclose(_space);
642     }
643 }
644 }