hdf5: fix crashes on extraction of compound fields integer 64 bits ( signed and
[scilab.git] / scilab / modules / hdf5 / src / cpp / H5DataFactory.cpp
index 28dca85..8f1f9da 100644 (file)
@@ -2,11 +2,14 @@
  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
  *
- * This file must be used under the terms of the CeCILL.
- * This source file is licensed as described in the file COPYING, which
- * you should have received as part of this distribution.  The terms
- * are also available at
- * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ *
+ * This file is hereby licensed under the terms of the GNU GPL v2.0,
+ * pursuant to article 5.3.4 of the CeCILL v.2.1.
+ * This file was originally licensed under the terms of the CeCILL v2.1,
+ * and continues to be available under such terms.
+ * For more information, see the COPYING file which you should have received
+ * along with this program.
  *
  */
 
@@ -39,7 +42,7 @@ H5Data & H5DataFactory::getData(H5Object & parent, const hid_t obj, H5Dataspace
 
         return ret;
     }
-    catch (const H5Exception & e)
+    catch (const H5Exception & /*e*/)
     {
         H5Tclose(type);
         H5Tclose(nativeType);
@@ -88,11 +91,11 @@ H5Data & H5DataFactory::getObjectData(H5Object & parent, const hsize_t totalSize
 
 #ifdef __SCILAB_INT64__
 
-            else if (H5Tequal(type, H5T_NATIVE_LONG))
+            else if (H5Tequal(type, H5T_NATIVE_LLONG))
             {
                 return *new H5BasicData<long long>(parent, totalSize, dataSize, ndims, dims, (long long *)data, stride, offset, dataOwner);
             }
-            else if (H5Tequal(type, H5T_NATIVE_ULONG))
+            else if (H5Tequal(type, H5T_NATIVE_ULLONG))
             {
                 return *new H5BasicData<unsigned long long>(parent, totalSize, dataSize, ndims, dims, (unsigned long long *)data, stride, offset, dataOwner);
             }
@@ -149,7 +152,7 @@ H5Data & H5DataFactory::getObjectData(H5Object & parent, const hsize_t totalSize
                 case 4:
                     return *new H5Bitfield4Data(parent, totalSize, dataSize, ndims, dims, static_cast<unsigned int *>(data), stride, offset, dataOwner);
                 case 8:
-                    //return *new H5BitfieldData<unsigned long long>(parent, totalSize, dataSize, ndims, dims, static_cast<unsigned long long *>(data), stride, offset, false);
+                //return *new H5BitfieldData<unsigned long long>(parent, totalSize, dataSize, ndims, dims, static_cast<unsigned long long *>(data), stride, offset, false);
                 default:
                     throw H5Exception(__LINE__, __FILE__, _("Bitfield is too big"));
             }
@@ -166,14 +169,55 @@ H5Data & H5DataFactory::getObjectData(H5Object & parent, const hsize_t totalSize
             int nmembers = H5Tget_nmembers(type);
             std::string * names = nmembers > 0 ? new std::string[nmembers] : 0;
 
-            for (unsigned int i = 0; i < nmembers; i++)
+            for (int i = 0; i < nmembers; i++)
             {
                 char * mname = H5Tget_member_name(type, i);
                 names[i] = std::string(mname);
+                //HDF5 version > 1.8.13
+                //H5free_memory(mnale);
+
+                //freed memory allocated by H5Tget_member_name trigger a segfault on Windows.
+                //http://lists.hdfgroup.org/pipermail/hdf-forum_lists.hdfgroup.org/2014-September/008061.html
+                //little memory leaks are better then crashs :x
+#ifndef _MSC_VER
                 free(mname);
+#endif
             }
 
-            return *new H5EnumData(parent, totalSize, dataSize, ndims, dims, (unsigned int *)data, nmembers, names, stride, offset, dataOwner);
+            if (H5Tget_sign(type) == H5T_SGN_NONE)
+            {
+                switch (dataSize)
+                {
+                    case 1:
+                        return *new H5EnumData<unsigned char>(parent, totalSize, dataSize, ndims, dims, (unsigned char *)data, type, H5T_NATIVE_UCHAR, nmembers, names, stride, offset, dataOwner);
+                    case 2:
+                        return *new H5EnumData<unsigned short>(parent, totalSize, dataSize, ndims, dims, (unsigned short *)data, type, H5T_NATIVE_USHORT, nmembers, names, stride, offset, dataOwner);
+                    case 4:
+                        return *new H5EnumData<unsigned int>(parent, totalSize, dataSize, ndims, dims, (unsigned int *)data, type, H5T_NATIVE_UINT, nmembers, names, stride, offset, dataOwner);
+#ifdef __SCILAB_INT64__
+                    case 8:
+                        return *new H5EnumData<unsigned long long>(parent, totalSize, dataSize, ndims, dims, (unsigned long long *)data, type, H5T_NATIVE_ULLONG, nmembers, names, stride, offset, dataOwner);
+#endif
+                }
+            }
+            else
+            {
+                switch (dataSize)
+                {
+                    case 1:
+                        return *new H5EnumData<char>(parent, totalSize, dataSize, ndims, dims, (char *)data, type, H5T_NATIVE_CHAR, nmembers, names, stride, offset, dataOwner);
+                    case 2:
+                        return *new H5EnumData<short>(parent, totalSize, dataSize, ndims, dims, (short *)data, type, H5T_NATIVE_SHORT, nmembers, names, stride, offset, dataOwner);
+                    case 4:
+                        return *new H5EnumData<int>(parent, totalSize, dataSize, ndims, dims, (int *)data, type, H5T_NATIVE_INT, nmembers, names, stride, offset, dataOwner);
+#ifdef __SCILAB_INT64__
+                    case 8:
+                        return *new H5EnumData<long long>(parent, totalSize, dataSize, ndims, dims, (long long *)data, type, H5T_NATIVE_LLONG, nmembers, names, stride, offset, dataOwner);
+#endif
+                }
+            }
+
+            return *new H5EnumData<char>(parent, totalSize, dataSize, ndims, dims, (char *)data, type, H5T_NATIVE_CHAR, nmembers, names, stride, offset, dataOwner);
         }
         case H5T_VLEN:
             return *new H5VlenData(parent, totalSize, dataSize, ndims, dims, static_cast<char *>(data), type, stride, offset, dataOwner);
@@ -240,6 +284,9 @@ void H5DataFactory::getNativeData(const hid_t obj, const hid_t space, hsize_t *
                     *totalSize *= (*dims)[i];
                 }
                 hyperslab = true;
+                break;
+            default:
+                break;
         }
     }
 
@@ -258,26 +305,26 @@ void H5DataFactory::getNativeData(const hid_t obj, const hid_t space, hsize_t *
 
     try
     {
-       if (isString)
-       {
-           *data = static_cast<void *>(new char[(size_t)size]());
-       }
-       else
-       {
-           // No need to initialize the array
-           *data = static_cast<void *>(new char[(size_t)size]);
-       }
+        if (isString)
+        {
+            *data = static_cast<void *>(new char[(size_t)size]());
+        }
+        else
+        {
+            // No need to initialize the array
+            *data = static_cast<void *>(new char[(size_t)size]);
+        }
     }
-    catch (const std::bad_alloc & e)
+    catch (const std::bad_alloc & /*e*/)
     {
-       H5Tclose(nativeType);
+        H5Tclose(nativeType);
         if (space < 0)
         {
             H5Sclose(_space);
         }
-       *data = 0;
-       delete[] *dims;
-       *dims = 0;
+        *data = 0;
+        delete[] *dims;
+        *dims = 0;
         throw H5Exception(__LINE__, __FILE__, _("Cannot allocate memory to get the data"));
     }
 
@@ -289,13 +336,13 @@ void H5DataFactory::getNativeData(const hid_t obj, const hid_t space, hsize_t *
             H5Sclose(_space);
         }
         delete[] *dims;
-       *dims = 0;
+        *dims = 0;
         throw H5Exception(__LINE__, __FILE__, _("Cannot allocate memory to get the data"));
     }
 
     if (hyperslab)
     {
-        targetspace =  H5Screate_simple(*ndims, *dims, 0);
+        targetspace =  H5Screate_simple((int) * ndims, *dims, 0);
         err = H5Dread(obj, nativeType, targetspace, _space, H5P_DEFAULT, *data);
         H5Sclose(targetspace);
     }
@@ -319,9 +366,9 @@ void H5DataFactory::getNativeData(const hid_t obj, const hid_t space, hsize_t *
             H5Sclose(_space);
         }
         delete[] static_cast<char *>(*data);
-       *data = 0;
+        *data = 0;
         delete[] *dims;
-       *dims = 0;
+        *dims = 0;
         throw H5Exception(__LINE__, __FILE__, _("Cannot retrieve the data from the attribute"));
     }