LCOV - code coverage report
Current view: top level - src/io/mhdf/src - util.c (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 163 373 43.7 %
Date: 2020-12-16 07:07:30 Functions: 22 32 68.8 %
Branches: 64 214 29.9 %

           Branch data     Line data    Source code
       1                 :            : /**
       2                 :            :  * MOAB, a Mesh-Oriented datABase, is a software component for creating,
       3                 :            :  * storing and accessing finite element mesh data.
       4                 :            :  *
       5                 :            :  * Copyright 2004 Sandia Corporation.  Under the terms of Contract
       6                 :            :  * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
       7                 :            :  * retains certain rights in this software.
       8                 :            :  *
       9                 :            :  * This library is free software; you can redistribute it and/or
      10                 :            :  * modify it under the terms of the GNU Lesser General Public
      11                 :            :  * License as published by the Free Software Foundation; either
      12                 :            :  * version 2.1 of the License, or (at your option) any later version.
      13                 :            :  *
      14                 :            :  */
      15                 :            : 
      16                 :            : #include <stdlib.h>
      17                 :            : #include <string.h>
      18                 :            : #include <assert.h>
      19                 :            : #include <ctype.h>
      20                 :            : #include <hdf5.h>
      21                 :            : #include "util.h"
      22                 :            : #include "status.h"
      23                 :            : #include "names-and-paths.h"
      24                 :            : 
      25                 :            : #ifdef VALGRIND
      26                 :            : #include <valgrind/memcheck.h>
      27                 :            : #else
      28                 :            : #define VALGRIND_CHECK_MEM_IS_DEFINED( A, B )
      29                 :            : #define VALGRIND_MAKE_MEM_UNDEFINED( A, B )
      30                 :            : #endif
      31                 :            : 
      32                 :       7513 : void* mhdf_malloc( size_t size, mhdf_Status* status )
      33                 :            : {
      34                 :            :     void* result;
      35                 :       7513 :     result = malloc( size );
      36         [ -  + ]:       7513 :     if( !result ) mhdf_setFail( status, "Allocation of %d bytes failed.\n", (int)size );
      37                 :       7513 :     return result;
      38                 :            : }
      39                 :            : 
      40                 :          0 : void* mhdf_realloc( void* ptr, size_t size, mhdf_Status* status )
      41                 :            : {
      42                 :            :     void* result;
      43                 :          0 :     result = realloc( ptr, size );
      44         [ #  # ]:          0 :     if( !result ) mhdf_setFail( status, "Allocation of %d bytes failed.\n", (int)size );
      45                 :          0 :     return result;
      46                 :            : }
      47                 :            : 
      48                 :      12882 : size_t mhdf_name_to_path( const char* name, char* path, size_t path_len )
      49                 :            : {
      50                 :      12882 :     size_t         length = 1;
      51                 :            :     unsigned char* iter;
      52                 :            : 
      53         [ -  + ]:      12882 :     if( 0 == strcmp( name, "." ) )
      54                 :            :     {
      55         [ #  # ]:          0 :         if( path_len >= 4 ) sprintf( path, "\\%02X", (int)*name );
      56                 :          0 :         return 4;
      57                 :            :     }
      58                 :            : 
      59         [ +  + ]:     141627 :     for( iter = (unsigned char*)name; *iter; ++iter )
      60                 :            :     {
      61 [ +  - ][ +  - ]:     128745 :         if( iscntrl( *iter ) || *iter == '/' || *iter == '\\' || *iter > 127 )
         [ +  - ][ -  + ]
      62                 :          0 :             length += 3;
      63                 :            :         else
      64                 :     128745 :             length += 1;
      65                 :            :     }
      66         [ +  + ]:      12882 :     if( path_len < length ) return length;
      67                 :            : 
      68         [ +  + ]:      70662 :     for( iter = (unsigned char*)name; *iter; ++iter )
      69                 :            :     {
      70 [ +  - ][ +  - ]:      64247 :         if( iscntrl( *iter ) || *iter == '/' || *iter == '\\' || *iter > 127 )
         [ +  - ][ -  + ]
      71                 :            :         {
      72                 :          0 :             sprintf( path, "\\%02X", (int)( *iter ) );
      73                 :          0 :             path += 3;
      74                 :            :         }
      75                 :            :         else
      76                 :            :         {
      77                 :      64247 :             *( path++ ) = *iter;
      78                 :            :         }
      79                 :            :     }
      80                 :            : 
      81                 :       6415 :     *path = '\0';
      82                 :       6415 :     return length;
      83                 :            : }
      84                 :            : 
      85                 :          0 : static int mhdf_hex_char( int c )
      86                 :            : {
      87         [ #  # ]:          0 :     if( isdigit( c ) )
      88                 :          0 :         return c - '0';
      89                 :            :     else
      90                 :          0 :         return toupper( c ) - ( 'A' - 10 );
      91                 :            : }
      92                 :            : 
      93                 :        799 : int mhdf_path_to_name( const char* path, char* name )
      94                 :            : {
      95                 :            :     const char* iter;
      96                 :            :     char        c1, c2;
      97                 :            : 
      98         [ +  + ]:       9333 :     for( iter = path; *iter; ++iter, ++name )
      99                 :            :     {
     100         [ -  + ]:       8534 :         if( *iter == '\\' )
     101                 :            :         {
     102                 :          0 :             c1 = *++iter;
     103                 :          0 :             c2 = *++iter;
     104 [ #  # ][ #  # ]:          0 :             if( !isxdigit( c1 ) || !isxdigit( c2 ) ) return 0;
     105                 :            : 
     106                 :          0 :             *name = (char)( 16 * mhdf_hex_char( c1 ) + mhdf_hex_char( c2 ) );
     107                 :            :         }
     108                 :            :         else
     109                 :            :         {
     110                 :       8534 :             *name = *iter;
     111                 :            :         }
     112                 :            :     }
     113                 :            : 
     114                 :        799 :     *name = '\0';
     115                 :        799 :     return 1;
     116                 :            : }
     117                 :            : 
     118                 :       4153 : char* mhdf_name_to_path_copy( const char* name, mhdf_Status* status )
     119                 :            : {
     120                 :            :     size_t size;
     121                 :            :     char*  buffer;
     122                 :            : 
     123                 :       4153 :     size = mhdf_name_to_path( name, NULL, 0 );
     124                 :       4153 :     buffer = (char*)mhdf_malloc( size, status );
     125         [ -  + ]:       4153 :     if( !buffer ) return NULL;
     126                 :            : 
     127                 :       4153 :     mhdf_name_to_path( name, buffer, size );
     128                 :       4153 :     return buffer;
     129                 :            : }
     130                 :            : 
     131                 :       1872 : char* mhdf_name_to_path_cat( const char* prefix, const char* name, mhdf_Status* status )
     132                 :            : {
     133                 :            :     size_t size, plen;
     134                 :            :     char*  buffer;
     135                 :            : 
     136                 :       1872 :     plen = strlen( prefix );
     137                 :       1872 :     size = mhdf_name_to_path( name, NULL, 0 ) + 1;
     138                 :       1872 :     buffer = (char*)mhdf_malloc( size + plen, status );
     139         [ -  + ]:       1872 :     if( !buffer ) return NULL;
     140                 :            : 
     141                 :       1872 :     memcpy( buffer, prefix, plen );
     142                 :       1872 :     mhdf_name_to_path( name, buffer + plen, size );
     143                 :       1872 :     return buffer;
     144                 :            : }
     145                 :            : 
     146                 :       1872 : hid_t mhdf_elem_group_from_handle( FileHandle* file_ptr, const char* elem_handle, mhdf_Status* status )
     147                 :            : {
     148                 :            :     char* path;
     149                 :            :     hid_t result;
     150                 :            : 
     151                 :       1872 :     path = mhdf_name_to_path_cat( ELEMENT_GROUP, elem_handle, status );
     152         [ -  + ]:       1872 :     if( NULL == path ) return -1;
     153                 :            : 
     154                 :            : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
     155                 :       1872 :     result = H5Gopen2( file_ptr->hdf_handle, path, H5P_DEFAULT );
     156                 :            : #else
     157                 :            :     result = H5Gopen( file_ptr->hdf_handle, path );
     158                 :            : #endif
     159                 :       1872 :     free( path );
     160         [ -  + ]:       1872 :     if( result < 0 ) mhdf_setFail( status, "Failed to open element group: \"%s\"", elem_handle );
     161                 :       1872 :     return result;
     162                 :            : }
     163                 :            : 
     164                 :       1086 : int mhdf_create_scalar_attrib( hid_t object, const char* name, hid_t type, const void* value, mhdf_Status* status )
     165                 :            : {
     166                 :            :     hid_t  dspace_id, attr_id;
     167                 :            :     herr_t rval;
     168                 :            : 
     169                 :       1086 :     dspace_id = H5Screate( H5S_SCALAR );
     170         [ -  + ]:       1086 :     if( dspace_id < 0 )
     171                 :            :     {
     172                 :          0 :         mhdf_setFail( status, "Internal error calling H5Screate_simple." );
     173                 :          0 :         return 0;
     174                 :            :     }
     175                 :            : 
     176                 :            : #if defined( H5Acreate_vers ) && H5Acreate_vers > 1
     177                 :       1086 :     attr_id = H5Acreate2( object, name, type, dspace_id, H5P_DEFAULT, H5P_DEFAULT );
     178                 :            : #else
     179                 :            :     attr_id = H5Acreate( object, name, type, dspace_id, H5P_DEFAULT );
     180                 :            : #endif
     181                 :       1086 :     H5Sclose( dspace_id );
     182         [ -  + ]:       1086 :     if( attr_id < 0 )
     183                 :            :     {
     184                 :          0 :         mhdf_setFail( status, "Failed to create \"%s\" attrib.", name );
     185                 :          0 :         return 0;
     186                 :            :     }
     187                 :            : 
     188                 :            :     VALGRIND_CHECK_MEM_IS_DEFINED( value, H5Tget_size( type ) );
     189                 :       1086 :     rval = H5Awrite( attr_id, type, value );
     190                 :       1086 :     H5Aclose( attr_id );
     191         [ -  + ]:       1086 :     if( rval < 0 )
     192                 :            :     {
     193                 :          0 :         mhdf_setFail( status, "Failed to write \"%s\" attrib.", name );
     194                 :          0 :         return 0;
     195                 :            :     }
     196                 :            : 
     197                 :       1086 :     return 1;
     198                 :            : }
     199                 :            : 
     200                 :       1704 : int mhdf_read_scalar_attrib( hid_t object, const char* name, hid_t type, void* value, mhdf_Status* status )
     201                 :            : {
     202                 :            :     hid_t  attr_id, type_id;
     203                 :            :     herr_t rval;
     204                 :            : 
     205                 :       1704 :     attr_id = H5Aopen_name( object, name );
     206         [ -  + ]:       1704 :     if( attr_id < 0 )
     207                 :            :     {
     208                 :          0 :         mhdf_setFail( status, "Failed to create \"%s\" attrib.", name );
     209                 :          0 :         return 0;
     210                 :            :     }
     211                 :            : 
     212         [ +  - ]:       1704 :     if( type > 0 ) { type_id = type; }
     213                 :            :     else
     214                 :            :     {
     215                 :          0 :         type_id = H5Aget_type( attr_id );
     216         [ #  # ]:          0 :         if( type_id < 0 )
     217                 :            :         {
     218                 :          0 :             H5Aclose( attr_id );
     219                 :          0 :             return 0;
     220                 :            :         }
     221                 :            :     }
     222                 :            : 
     223                 :       1704 :     rval = H5Aread( attr_id, type_id, value );
     224                 :       1704 :     H5Aclose( attr_id );
     225         [ -  + ]:       1704 :     if( type < 1 ) H5Tclose( type_id );
     226         [ -  + ]:       1704 :     if( rval < 0 )
     227                 :            :     {
     228                 :          0 :         mhdf_setFail( status, "Failed to read \"%s\" attrib.", name );
     229                 :          0 :         return 0;
     230                 :            :     }
     231                 :            : 
     232                 :       1704 :     return 1;
     233                 :            : }
     234                 :            : 
     235                 :            : #if defined( H5Aiterate_vers ) && H5Aiterate_vers > 1
     236                 :      17392 : static herr_t find_attr_by_name( hid_t handle, const char* name, const H5A_info_t* info, void* mydata )
     237                 :            : {
     238                 :            :     /* empty statement to remove compiler warning */
     239                 :            :     if( info ) {}
     240                 :            : #else
     241                 :            : static herr_t find_attr_by_name( hid_t handle, const char* name, void* mydata )
     242                 :            : {
     243                 :            : #endif
     244                 :            :     /* empty statement to remove compiler warning */
     245                 :            :     if( handle ) {}
     246                 :       8696 :     return !strcmp( name, (const char*)mydata );
     247                 :            : }
     248                 :            : 
     249                 :       3882 : int mhdf_find_attribute( hid_t object, const char* attrib_name, unsigned int* index_out, mhdf_Status* status )
     250                 :            : {
     251                 :            :     herr_t rval;
     252                 :            : #if defined( H5Aiterate_vers ) && H5Aiterate_vers > 1
     253                 :       3882 :     hsize_t idx = 0;
     254                 :       3882 :     rval = H5Aiterate2( object, H5_INDEX_CRT_ORDER, H5_ITER_NATIVE, &idx, &find_attr_by_name, (void*)attrib_name );
     255                 :       3882 :     *index_out = (unsigned int)idx;
     256                 :            : #else
     257                 :            :     *index_out = 0;
     258                 :            :     rval = H5Aiterate( object, index_out, &find_attr_by_name, (void*)attrib_name );
     259                 :            : #endif
     260         [ -  + ]:       3882 :     if( rval < 0 ) mhdf_setFail( status, "Internal error calling H5Aiterate." );
     261                 :       3882 :     return (int)rval;
     262                 :            : }
     263                 :            : 
     264                 :      21416 : static herr_t find_link_by_name( hid_t handle, const char* name, void* mydata )
     265                 :            : {
     266                 :            :     /* empty statement to remove compiler warning */
     267                 :            :     if( handle ) {}
     268                 :      10708 :     return !strcmp( name, (const char*)mydata );
     269                 :            : }
     270                 :            : 
     271                 :       6085 : int mhdf_is_in_group( hid_t group, const char* name, mhdf_Status* status )
     272                 :            : {
     273                 :            :     int rval;
     274                 :       6085 :     rval = H5Giterate( group, ".", NULL, &find_link_by_name, (void*)name );
     275         [ -  + ]:       6085 :     if( rval < 0 ) mhdf_setFail( status, "Internal error in H5Giterate." );
     276                 :       6085 :     return rval;
     277                 :            : }
     278                 :            : 
     279                 :        545 : static int mhdf_readwrite( hid_t data_id, int read, long offset, long count, hid_t type, void* array, hid_t io_prop,
     280                 :            :                            mhdf_Status* status )
     281                 :            : {
     282                 :            :     hid_t   slab_id, mem_id;
     283                 :        545 :     hsize_t offsets[ 2 ], counts[ 2 ] = { 1, 1 };
     284                 :            :     herr_t  rval;
     285                 :            :     int     dims;
     286                 :            :     /*#if (1000 * H5_VERS_MAJOR + H5_VERS_MINOR) < 1008*/
     287                 :        545 :     const hsize_t one = 1;
     288                 :            :     /*#endif*/
     289                 :            : 
     290 [ +  - ][ -  + ]:        545 :     if( offset < 0 || count < 0 )
     291                 :            :     {
     292         [ #  # ]:          0 :         mhdf_setFail( status,
     293                 :            :                       "Invalid input for %s: "
     294                 :            :                       "offset = %ld, count = %ld\n",
     295                 :            :                       read ? "read" : "write", offset, count );
     296                 :          0 :         return 0;
     297                 :            :     }
     298                 :            : 
     299                 :        545 :     slab_id = H5Dget_space( data_id );
     300         [ -  + ]:        545 :     if( slab_id < 0 )
     301                 :            :     {
     302                 :          0 :         mhdf_setFail( status, "Internal error calling H5Dget_space." );
     303                 :          0 :         return 0;
     304                 :            :     }
     305                 :            : 
     306                 :        545 :     dims = H5Sget_simple_extent_ndims( slab_id );
     307 [ +  - ][ -  + ]:        545 :     if( dims < 1 || dims > 2 )
     308                 :            :     {
     309                 :          0 :         H5Sclose( slab_id );
     310                 :          0 :         mhdf_setFail( status, "Internal error: unexpected dataset rank: %d.", dims );
     311                 :          0 :         return 0;
     312                 :            :     }
     313                 :            : 
     314                 :        545 :     dims = H5Sget_simple_extent_dims( slab_id, counts, NULL );
     315         [ -  + ]:        545 :     if( dims < 0 )
     316                 :            :     {
     317                 :          0 :         H5Sclose( slab_id );
     318                 :          0 :         mhdf_setFail( status, "Internal error calling H5Sget_simple_extend_dims." );
     319                 :          0 :         return 0;
     320                 :            :     }
     321                 :            : 
     322         [ -  + ]:        545 :     if( (unsigned long)( offset + count ) > counts[ 0 ] )
     323                 :            :     {
     324                 :          0 :         H5Sclose( slab_id );
     325         [ #  # ]:          0 :         mhdf_setFail( status, "Requested %s of rows %ld to %ld of a %ld row table.\n", read ? "read" : "write", offset,
     326                 :          0 :                       offset + count - 1, (long)counts[ dims - 1 ] );
     327                 :          0 :         return 0;
     328                 :            :     }
     329                 :            : 
     330                 :        545 :     counts[ 0 ] = (hsize_t)count;
     331                 :        545 :     offsets[ 0 ] = (hsize_t)offset;
     332                 :        545 :     offsets[ 1 ] = 0;
     333         [ +  - ]:        545 :     if( count )
     334                 :        545 :         rval = H5Sselect_hyperslab( slab_id, H5S_SELECT_SET, offsets, NULL, counts, NULL );
     335                 :            :     else
     336                 :          0 :         rval = H5Sselect_none( slab_id );
     337         [ -  + ]:        545 :     if( rval < 0 )
     338                 :            :     {
     339                 :          0 :         H5Sclose( slab_id );
     340                 :          0 :         mhdf_setFail( status, "Internal error calling H5Sselect_hyperslab." );
     341                 :          0 :         return 0;
     342                 :            :     }
     343                 :            : 
     344         [ +  - ]:        545 :     if( count )
     345                 :        545 :         mem_id = H5Screate_simple( dims, counts, NULL );
     346                 :            :     else
     347                 :            :     {
     348                 :            :         /*#if H5_VERS_MAJOR > 1 || H5_VERS_MINOR >= 8
     349                 :            :             mem_id = H5Screate(H5S_NULL);
     350                 :            :         #else*/
     351                 :          0 :         mem_id = H5Screate_simple( 1, &one, NULL );
     352 [ #  # ][ #  # ]:          0 :         if( mem_id && 0 > H5Sselect_none( mem_id ) )
     353                 :            :         {
     354                 :          0 :             H5Sclose( mem_id );
     355                 :          0 :             mem_id = -1;
     356                 :            :         }
     357                 :            :         /*#endif*/
     358                 :            :     }
     359                 :            : 
     360         [ -  + ]:        545 :     if( mem_id < 0 )
     361                 :            :     {
     362                 :          0 :         H5Sclose( slab_id );
     363                 :          0 :         mhdf_setFail( status, "Internal error calling H5Screate_simple." );
     364                 :          0 :         return 0;
     365                 :            :     }
     366                 :            : 
     367         [ +  + ]:        545 :     if( read )
     368                 :         19 :         rval = H5Dread( data_id, type, mem_id, slab_id, io_prop, array );
     369                 :            :     else
     370                 :            :     {
     371                 :            :         VALGRIND_CHECK_MEM_IS_DEFINED( array, counts[ 0 ] * counts[ 1 ] * H5Tget_size( type ) );
     372                 :        526 :         rval = H5Dwrite( data_id, type, mem_id, slab_id, io_prop, array );
     373                 :            :     }
     374                 :        545 :     H5Sclose( slab_id );
     375                 :        545 :     H5Sclose( mem_id );
     376         [ -  + ]:        545 :     if( rval < 0 )
     377                 :            :     {
     378         [ #  # ]:          0 :         mhdf_setFail( status, "Internal error calling H5D%s.", read ? "read" : "write" );
     379                 :          0 :         return 0;
     380                 :            :     }
     381                 :            : 
     382                 :        545 :     mhdf_setOkay( status );
     383                 :        545 :     return 1;
     384                 :            : }
     385                 :            : 
     386                 :          0 : static int mhdf_readwrite_column( hid_t data_id, int read, int column, long offset, long count, hid_t type, void* array,
     387                 :            :                                   hid_t io_prop, mhdf_Status* status )
     388                 :            : {
     389                 :            :     hid_t   slab_id, mem_id;
     390                 :            :     hsize_t offsets[ 2 ], counts[ 2 ];
     391                 :            :     herr_t  rval;
     392                 :            :     int     dims;
     393                 :            :     /*#if (1000 * H5_VERS_MAJOR + H5_VERS_MINOR) < 1008*/
     394                 :          0 :     const hsize_t one = 1;
     395                 :            :     /*#endif*/
     396                 :            : 
     397 [ #  # ][ #  # ]:          0 :     if( column < 0 || offset < 0 || count < 0 )
                 [ #  # ]
     398                 :            :     {
     399         [ #  # ]:          0 :         mhdf_setFail( status,
     400                 :            :                       "Invalid input for %s: "
     401                 :            :                       "column = %d, offset = %ld, count = %ld\n",
     402                 :            :                       read ? "read" : "write", column, offset, count );
     403                 :          0 :         return 0;
     404                 :            :     }
     405                 :            : 
     406                 :          0 :     slab_id = H5Dget_space( data_id );
     407         [ #  # ]:          0 :     if( slab_id < 0 )
     408                 :            :     {
     409                 :          0 :         mhdf_setFail( status, "Internal error calling H5Dget_space." );
     410                 :          0 :         return 0;
     411                 :            :     }
     412                 :            : 
     413                 :          0 :     dims = H5Sget_simple_extent_ndims( slab_id );
     414 [ #  # ][ #  # ]:          0 :     if( dims < 1 || dims > 2 )
     415                 :            :     {
     416                 :          0 :         H5Sclose( slab_id );
     417                 :          0 :         mhdf_setFail( status, "Internal error: unexpected dataset rank: %d.", dims );
     418                 :          0 :         return 0;
     419                 :            :     }
     420                 :            : 
     421                 :          0 :     dims = H5Sget_simple_extent_dims( slab_id, counts, NULL );
     422         [ #  # ]:          0 :     if( dims < 0 )
     423                 :            :     {
     424                 :          0 :         H5Sclose( slab_id );
     425                 :          0 :         mhdf_setFail( status, "Internal error calling H5Sget_simple_extend_dims." );
     426                 :          0 :         return 0;
     427                 :            :     }
     428                 :            : 
     429 [ #  # ][ #  # ]:          0 :     if( (unsigned long)( offset + count ) > counts[ 0 ] || (unsigned long)column > counts[ 1 ] )
     430                 :            :     {
     431                 :          0 :         H5Sclose( slab_id );
     432         [ #  # ]:          0 :         mhdf_setFail( status, "Requested %s of (%ld,%d)->(%ld,%ld) of (%ld, %ld) table.\n", read ? "read" : "write",
     433                 :          0 :                       offset, column, offset + count - 1, column, (long)counts[ 0 ], (long)counts[ 1 ] );
     434                 :          0 :         return 0;
     435                 :            :     }
     436                 :            : 
     437                 :          0 :     counts[ 0 ] = (hsize_t)count;
     438                 :          0 :     offsets[ 0 ] = (hsize_t)offset;
     439                 :          0 :     counts[ 1 ] = 1;
     440                 :          0 :     offsets[ 1 ] = column;
     441         [ #  # ]:          0 :     if( count )
     442                 :          0 :         rval = H5Sselect_hyperslab( slab_id, H5S_SELECT_SET, offsets, NULL, counts, NULL );
     443                 :            :     else
     444                 :          0 :         rval = H5Sselect_none( slab_id );
     445         [ #  # ]:          0 :     if( rval < 0 )
     446                 :            :     {
     447                 :          0 :         H5Sclose( slab_id );
     448                 :          0 :         mhdf_setFail( status, "Internal error calling H5Sselect_hyperslab." );
     449                 :          0 :         return 0;
     450                 :            :     }
     451                 :            : 
     452         [ #  # ]:          0 :     if( count )
     453                 :          0 :         mem_id = H5Screate_simple( dims, counts, NULL );
     454                 :            :     else
     455                 :            :     {
     456                 :            :         /*#if H5_VERS_MAJOR > 1 || H5_VERS_MINOR >= 8
     457                 :            :             mem_id = H5Screate(H5S_NULL);
     458                 :            :         #else*/
     459                 :          0 :         mem_id = H5Screate_simple( 1, &one, NULL );
     460 [ #  # ][ #  # ]:          0 :         if( mem_id && 0 > H5Sselect_none( mem_id ) )
     461                 :            :         {
     462                 :          0 :             H5Sclose( mem_id );
     463                 :          0 :             mem_id = -1;
     464                 :            :         }
     465                 :            :         /*#endif*/
     466                 :            :     }
     467                 :            : 
     468         [ #  # ]:          0 :     if( mem_id < 0 )
     469                 :            :     {
     470                 :          0 :         H5Sclose( slab_id );
     471                 :          0 :         mhdf_setFail( status, "Internal error calling H5Screate_simple." );
     472                 :          0 :         return 0;
     473                 :            :     }
     474                 :            : 
     475         [ #  # ]:          0 :     if( read )
     476                 :          0 :         rval = H5Dread( data_id, type, mem_id, slab_id, io_prop, array );
     477                 :            :     else
     478                 :            :     {
     479                 :            :         VALGRIND_CHECK_MEM_IS_DEFINED( array, count * H5Tget_size( type ) );
     480                 :          0 :         rval = H5Dwrite( data_id, type, mem_id, slab_id, io_prop, array );
     481                 :            :         VALGRIND_MAKE_MEM_UNDEFINED( array, count * H5Tget_size( type ) );
     482                 :            :     }
     483                 :          0 :     H5Sclose( slab_id );
     484                 :          0 :     H5Sclose( mem_id );
     485         [ #  # ]:          0 :     if( rval < 0 )
     486                 :            :     {
     487         [ #  # ]:          0 :         mhdf_setFail( status, "Internal error calling H5D%s.", read ? "read" : "write" );
     488                 :          0 :         return 0;
     489                 :            :     }
     490                 :            : 
     491                 :          0 :     mhdf_setOkay( status );
     492                 :          0 :     return 1;
     493                 :            : }
     494                 :            : 
     495                 :        526 : int mhdf_write_data( hid_t data_id, long offset, long count, hid_t type_id, const void* array, hid_t prop,
     496                 :            :                      mhdf_Status* status )
     497                 :            : {
     498                 :        526 :     return mhdf_readwrite( data_id, 0, offset, count, type_id, (void*)array, prop, status );
     499                 :            : }
     500                 :            : 
     501                 :         19 : int mhdf_read_data( hid_t data_id, long offset, long count, hid_t type_id, void* array, hid_t prop,
     502                 :            :                     mhdf_Status* status )
     503                 :            : {
     504                 :         19 :     return mhdf_readwrite( data_id, 1, offset, count, type_id, array, prop, status );
     505                 :            : }
     506                 :            : 
     507                 :          0 : int mhdf_read_column( hid_t data_id, int column, long offset, long count, hid_t type, void* array, hid_t prop,
     508                 :            :                       mhdf_Status* status )
     509                 :            : {
     510                 :          0 :     return mhdf_readwrite_column( data_id, 1, column, offset, count, type, array, prop, status );
     511                 :            : }
     512                 :            : 
     513                 :          0 : int mhdf_write_column( hid_t data_id, int column, long offset, long count, hid_t type, const void* array, hid_t prop,
     514                 :            :                        mhdf_Status* status )
     515                 :            : {
     516                 :          0 :     return mhdf_readwrite_column( data_id, 0, column, offset, count, type, (void*)array, prop, status );
     517                 :            : }
     518                 :            : 
     519                 :        565 : hid_t mhdf_create_table( hid_t group_id, const char* path, hid_t type, int rank, hsize_t* dims, mhdf_Status* status )
     520                 :            : {
     521                 :        565 :     return mhdf_create_table_with_prop( group_id, path, type, rank, dims, H5P_DEFAULT, status );
     522                 :            : }
     523                 :            : 
     524                 :        565 : hid_t mhdf_create_table_with_prop( hid_t group_id, const char* path, hid_t type, int rank, hsize_t* dims,
     525                 :            :                                    hid_t create_prop, mhdf_Status* status )
     526                 :            : {
     527                 :            :     hid_t space_id, table_id;
     528                 :            : 
     529                 :        565 :     space_id = H5Screate_simple( rank, dims, NULL );
     530         [ -  + ]:        565 :     if( space_id < 0 )
     531                 :            :     {
     532                 :          0 :         mhdf_setFail( status, "Internal error calling H5Screate_simple." );
     533                 :          0 :         return -1;
     534                 :            :     }
     535                 :            : 
     536                 :            : #if defined( H5Dcreate_vers ) && H5Dcreate_vers > 1
     537                 :        565 :     table_id = H5Dcreate2( group_id, path, type, space_id, H5P_DEFAULT, create_prop, H5P_DEFAULT );
     538                 :            : #else
     539                 :            :     table_id = H5Dcreate( group_id, path, type, space_id, create_prop );
     540                 :            : #endif
     541                 :        565 :     H5Sclose( space_id );
     542         [ -  + ]:        565 :     if( table_id < 0 )
     543                 :            :     {
     544                 :          0 :         mhdf_setFail( status, "HDF5 DataSet creation failed." );
     545                 :          0 :         return -1;
     546                 :            :     }
     547                 :            : 
     548                 :        565 :     mhdf_setOkay( status );
     549                 :        565 :     return table_id;
     550                 :            : }
     551                 :            : 
     552                 :       1322 : hid_t mhdf_open_table( hid_t group_id, const char* path, int columns, hsize_t* rows_out, mhdf_Status* status )
     553                 :            : {
     554                 :            :     hid_t   table_id, space_id;
     555                 :            :     hsize_t dims[ 2 ];
     556                 :            :     int     rank;
     557                 :            : 
     558                 :            : #if defined( H5Dopen_vers ) && H5Dopen_vers > 1
     559                 :       1322 :     table_id = H5Dopen2( group_id, path, H5P_DEFAULT );
     560                 :            : #else
     561                 :            :     table_id = H5Dopen( group_id, path );
     562                 :            : #endif
     563         [ -  + ]:       1322 :     if( table_id < 0 )
     564                 :            :     {
     565                 :          0 :         mhdf_setFail( status, "HDF5 DataSet creation failed." );
     566                 :          0 :         return -1;
     567                 :            :     }
     568                 :            : 
     569                 :       1322 :     space_id = H5Dget_space( table_id );
     570         [ -  + ]:       1322 :     if( space_id < 0 )
     571                 :            :     {
     572                 :          0 :         mhdf_setFail( status, "Internal error in H5Dget_space." );
     573                 :          0 :         H5Dclose( table_id );
     574                 :          0 :         return -1;
     575                 :            :     }
     576                 :            : 
     577                 :       1322 :     rank = H5Sget_simple_extent_ndims( space_id );
     578 [ +  - ][ -  + ]:       1322 :     if( rank != ( columns ? 1 : 2 ) )
     579                 :            :     {
     580                 :          0 :         mhdf_setFail( status, "Incorrect DataSpace for DataSet." );
     581                 :          0 :         H5Sclose( space_id );
     582                 :          0 :         H5Dclose( table_id );
     583                 :          0 :         return -1;
     584                 :            :     }
     585                 :            : 
     586                 :       1322 :     rank = H5Sget_simple_extent_dims( space_id, dims, NULL );
     587                 :       1322 :     H5Sclose( space_id );
     588         [ -  + ]:       1322 :     if( rank < 0 )
     589                 :            :     {
     590                 :          0 :         mhdf_setFail( status, "Internal error calling H5Sget_simple_extent_dims." );
     591                 :          0 :         H5Dclose( table_id );
     592                 :          0 :         return -1;
     593                 :            :     }
     594                 :            : 
     595                 :       1322 :     *rows_out = dims[ 0 ];
     596                 :       1322 :     mhdf_setOkay( status );
     597                 :       1322 :     return table_id;
     598                 :            : }
     599                 :            : 
     600                 :        373 : hid_t mhdf_open_table2( hid_t group_id, const char* path, int rank, hsize_t* dims_out, long* start_id_out,
     601                 :            :                         mhdf_Status* status )
     602                 :            : {
     603                 :            :     hid_t table_id, space_id;
     604                 :            : 
     605                 :            : #if defined( H5Dopen_vers ) && H5Dopen_vers > 1
     606                 :        373 :     table_id = H5Dopen2( group_id, path, H5P_DEFAULT );
     607                 :            : #else
     608                 :            :     table_id = H5Dopen( group_id, path );
     609                 :            : #endif
     610         [ -  + ]:        373 :     if( table_id < 0 )
     611                 :            :     {
     612                 :          0 :         mhdf_setFail( status, "HDF5 DataSet creation failed." );
     613                 :          0 :         return -1;
     614                 :            :     }
     615                 :            : 
     616                 :        373 :     space_id = H5Dget_space( table_id );
     617         [ -  + ]:        373 :     if( space_id < 0 )
     618                 :            :     {
     619                 :          0 :         mhdf_setFail( status, "Internal error in H5Dget_space." );
     620                 :          0 :         H5Dclose( table_id );
     621                 :          0 :         return -1;
     622                 :            :     }
     623                 :            : 
     624         [ -  + ]:        373 :     if( H5Sget_simple_extent_ndims( space_id ) != rank )
     625                 :            :     {
     626                 :          0 :         mhdf_setFail( status, "Incorrect DataSpace for DataSet." );
     627                 :          0 :         H5Sclose( space_id );
     628                 :          0 :         H5Dclose( table_id );
     629                 :          0 :         return -1;
     630                 :            :     }
     631                 :            : 
     632                 :        373 :     rank = H5Sget_simple_extent_dims( space_id, dims_out, NULL );
     633                 :        373 :     H5Sclose( space_id );
     634         [ -  + ]:        373 :     if( rank < 0 )
     635                 :            :     {
     636                 :          0 :         mhdf_setFail( status, "Internal error calling H5Sget_simple_extent_dims." );
     637                 :          0 :         H5Dclose( table_id );
     638                 :          0 :         return -1;
     639                 :            :     }
     640                 :            : 
     641         [ -  + ]:        373 :     if( !mhdf_read_scalar_attrib( table_id, START_ID_ATTRIB, H5T_NATIVE_LONG, start_id_out, status ) )
     642                 :            :     {
     643                 :          0 :         mhdf_setFail( status, "File format error.  Failed to retreive ID offset." );
     644                 :          0 :         H5Dclose( table_id );
     645                 :          0 :         return -1;
     646                 :            :     }
     647                 :            : 
     648                 :        373 :     mhdf_setOkay( status );
     649                 :        373 :     return table_id;
     650                 :            : }
     651                 :            : 
     652                 :        236 : hid_t mhdf_open_table_simple( hid_t group_id, const char* path, mhdf_Status* status )
     653                 :            : {
     654                 :            :     hid_t table_id;
     655                 :            : 
     656                 :            : #if defined( H5Dopen_vers ) && H5Dopen_vers > 1
     657                 :        236 :     table_id = H5Dopen2( group_id, path, H5P_DEFAULT );
     658                 :            : #else
     659                 :            :     table_id = H5Dopen( group_id, path );
     660                 :            : #endif
     661         [ -  + ]:        236 :     if( table_id < 0 ) { mhdf_setFail( status, "HDF5 DataSet creation failed." ); }
     662                 :            :     else
     663                 :            :     {
     664                 :        236 :         mhdf_setOkay( status );
     665                 :            :     }
     666                 :            : 
     667                 :        236 :     return table_id;
     668                 :            : }
     669                 :            : 
     670                 :          0 : static int qs_comp_int( const void* ptr1, const void* ptr2 )
     671                 :            : {
     672                 :          0 :     const int* left = (const int*)ptr1;
     673                 :          0 :     const int* right = (const int*)ptr2;
     674         [ #  # ]:          0 :     return *left < *right ? -1 : *left > *right ? 1 : 0;
     675                 :            : }
     676                 :            : 
     677                 :          0 : int mhdf_compact_to_ranges( int* length, int* ids, int ordered )
     678                 :            : {
     679                 :          0 :     int    new_length = 0;
     680                 :            :     int *  iter, *end;
     681                 :            :     int    prev, count;
     682                 :          0 :     int    need_copy = 0;
     683                 :          0 :     int *  copy_ptr = 0, *w_iter;
     684                 :            :     size_t blen;
     685                 :            : 
     686         [ #  # ]:          0 :     if( !ordered ) qsort( ids, *length, sizeof( int ), &qs_comp_int );
     687                 :            : 
     688                 :          0 :     iter = ids;
     689                 :          0 :     end = ids + *length;
     690         [ #  # ]:          0 :     while( iter != end )
     691                 :            :     {
     692                 :          0 :         prev = *( iter++ );
     693 [ #  # ][ #  # ]:          0 :         while( iter < end && *( iter++ ) == ++prev )
     694                 :            :             ;
     695                 :          0 :         new_length += 2;
     696         [ #  # ]:          0 :         if( new_length > ( iter - ids ) ) need_copy = 1;
     697                 :            :     }
     698                 :            : 
     699         [ #  # ]:          0 :     if( new_length > *length ) return 0;
     700                 :            : 
     701         [ #  # ]:          0 :     if( need_copy )
     702                 :            :     {
     703                 :          0 :         blen = sizeof( int ) * *length;
     704                 :          0 :         copy_ptr = (int*)malloc( blen );
     705                 :          0 :         memcpy( copy_ptr, ids, blen );
     706                 :          0 :         iter = copy_ptr;
     707                 :            :     }
     708                 :            :     else
     709                 :            :     {
     710                 :          0 :         iter = ids;
     711                 :            :     }
     712                 :            : 
     713                 :          0 :     end = iter + *length;
     714                 :          0 :     w_iter = ids;
     715         [ #  # ]:          0 :     while( iter != end )
     716                 :            :     {
     717                 :          0 :         prev = *( iter++ );
     718                 :          0 :         count = 1;
     719 [ #  # ][ #  # ]:          0 :         while( iter < end && *( iter++ ) == ++prev )
     720                 :            :             ;
     721                 :          0 :         *( w_iter++ ) = prev - count;
     722                 :          0 :         *( w_iter++ ) = count;
     723                 :            :     }
     724                 :            : 
     725                 :          0 :     *length = new_length;
     726         [ #  # ]:          0 :     if( need_copy ) free( copy_ptr );
     727                 :          0 :     return 1;
     728                 :            : }
     729                 :            : 
     730                 :         52 : hid_t get_elem_type_enum( FileHandle* file_ptr, mhdf_Status* status )
     731                 :            : {
     732                 :            :     hid_t result;
     733                 :            : #if defined( H5Topen_vers ) && H5Topen_vers > 1
     734                 :         52 :     result = H5Topen2( file_ptr->hdf_handle, TYPE_ENUM_PATH, H5P_DEFAULT );
     735                 :            : #else
     736                 :            :     result = H5Topen( file_ptr->hdf_handle, TYPE_ENUM_PATH );
     737                 :            : #endif
     738         [ -  + ]:         52 :     if( result < 0 ) mhdf_setFail( status, "Element type enum does not exist in file.  Invalid file." );
     739                 :         52 :     return result;
     740                 :            : }
     741                 :            : 
     742                 :        129 : int mhdf_write_max_id( FileHandle* file_ptr, mhdf_Status* status )
     743                 :            : {
     744                 :            :     hid_t  group_id, attr_id, space_id;
     745                 :            :     herr_t rval;
     746                 :            : 
     747                 :            : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
     748                 :        129 :     group_id = H5Gopen2( file_ptr->hdf_handle, ROOT_GROUP, H5P_DEFAULT );
     749                 :            : #else
     750                 :            :     group_id = H5Gopen( file_ptr->hdf_handle, ROOT_GROUP );
     751                 :            : #endif
     752         [ -  + ]:        129 :     if( group_id < 0 )
     753                 :            :     {
     754                 :          0 :         mhdf_setFail( status, "Internal error -- file invalid." );
     755                 :          0 :         return 0;
     756                 :            :     }
     757                 :            : 
     758                 :        129 :     attr_id = H5Aopen_name( group_id, MAX_ID_ATTRIB );
     759         [ -  + ]:        129 :     if( attr_id < 0 )
     760                 :            :     {
     761                 :          0 :         space_id = H5Screate( H5S_SCALAR );
     762                 :            : #if defined( H5Acreate_vers ) && H5Acreate_vers > 1
     763                 :          0 :         attr_id = H5Acreate2( group_id, MAX_ID_ATTRIB, H5T_NATIVE_ULONG, space_id, H5P_DEFAULT, H5P_DEFAULT );
     764                 :            : #else
     765                 :            :         attr_id = H5Acreate( group_id, MAX_ID_ATTRIB, H5T_NATIVE_ULONG, space_id, H5P_DEFAULT );
     766                 :            : #endif
     767                 :          0 :         H5Sclose( space_id );
     768                 :            :     }
     769                 :        129 :     H5Gclose( group_id );
     770         [ -  + ]:        129 :     if( attr_id < 0 )
     771                 :            :     {
     772                 :          0 :         mhdf_setFail( status, "Failed to create attribute \"%s\" on \"%s\"", MAX_ID_ATTRIB, ROOT_GROUP );
     773                 :          0 :         return 0;
     774                 :            :     }
     775                 :            : 
     776                 :        129 :     rval = H5Awrite( attr_id, H5T_NATIVE_ULONG, &file_ptr->max_id );
     777                 :        129 :     H5Aclose( attr_id );
     778         [ -  + ]:        129 :     if( rval < 0 )
     779                 :            :     {
     780                 :          0 :         mhdf_setFail( status, "Failed to write \"%s\" attrib.", MAX_ID_ATTRIB );
     781                 :          0 :         return 0;
     782                 :            :     }
     783                 :            : 
     784                 :        129 :     return 1;
     785                 :            : }
     786                 :            : 
     787                 :            : static int mhdf_api_handle_count = 0;
     788                 :            : 
     789                 :          0 : static int num_open( )
     790                 :            : {
     791                 :            :     hid_t list[ 64 ];
     792                 :          0 :     int   nf, rval, i, count = 0;
     793                 :            : 
     794                 :          0 :     nf = H5Fget_obj_ids( H5F_OBJ_ALL, H5F_OBJ_FILE, sizeof( list ) / sizeof( hid_t ), list );
     795 [ #  # ][ #  # ]:          0 :     if( nf <= 0 || nf > 64 ) return 0;
     796                 :            : 
     797         [ #  # ]:          0 :     for( i = 0; i < nf; i++ )
     798                 :            :     {
     799                 :          0 :         rval = H5Fget_obj_count( list[ i ], H5F_OBJ_ALL );
     800         [ #  # ]:          0 :         if( rval > 0 ) count += rval;
     801                 :            :     }
     802                 :            : 
     803                 :          0 :     return count;
     804                 :            : }
     805                 :            : 
     806                 :          0 : void mhdf_api_begin_internal( )
     807                 :            : {
     808                 :            :     /* HDF5 docs are incorrect.  Passing H5F_OBJ_ALL as the first
     809                 :            :        arg to H5Fget_obj_count returns the total number of open
     810                 :            :        handles, not just those in files (i.e. temporary types and such.)
     811                 :            :     mhdf_api_handle_count = H5Fget_obj_count( H5F_OBJ_ALL, H5F_OBJ_ALL );
     812                 :            :        Need to loop to get actual file handles:
     813                 :            :     */
     814                 :          0 :     mhdf_api_handle_count = num_open( );
     815                 :          0 : }
     816                 :            : 
     817                 :          0 : void mhdf_api_end_internal( int expected_diff, const char* filename, int linenumber )
     818                 :            : {
     819         [ #  # ]:          0 :     if( mhdf_api_handle_count + expected_diff != num_open( ) )
     820                 :            :     {
     821                 :          0 :         fprintf( stderr, "Unclosed handles at end of mhdf API call.\n" );
     822                 :          0 :         fprintf( stderr, "Entered with %d, expected %d change, got %d.\n", mhdf_api_handle_count, expected_diff,
     823                 :            :                  num_open( ) );
     824                 :          0 :         fprintf( stderr, "%s:%d\n", filename, linenumber );
     825                 :          0 :         abort( );
     826                 :            :     }
     827                 :            : 
     828                 :          0 :     mhdf_api_handle_count = 0;
     829                 :          0 : }

Generated by: LCOV version 1.11