LCOV - code coverage report
Current view: top level - src/io/mhdf/src - tags.c (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 365 728 50.1 %
Date: 2020-12-16 07:07:30 Functions: 19 33 57.6 %
Branches: 181 398 45.5 %

           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 <H5Tpublic.h>
      19                 :            : #include <H5Gpublic.h>
      20                 :            : #include <H5Dpublic.h>
      21                 :            : #include <H5Spublic.h> /* for H5S_MAX_RANK */
      22                 :            : #include <H5Apublic.h>
      23                 :            : #include <H5Ppublic.h>
      24                 :            : #include "status.h"
      25                 :            : #include "file-handle.h"
      26                 :            : #include "mhdf.h"
      27                 :            : #include "util.h"
      28                 :            : #include "names-and-paths.h"
      29                 :            : 
      30                 :          0 : hid_t mhdf_getNativeType( hid_t input_type, int size, mhdf_Status* status )
      31                 :            : {
      32                 :            :     H5T_sign_t  sgn;
      33                 :            :     H5T_class_t cls;
      34                 :            :     hid_t       tmp_id, type_id;
      35                 :            : 
      36                 :          0 :     mhdf_setOkay( status );
      37                 :            : 
      38                 :          0 :     cls = H5Tget_class( input_type );
      39   [ #  #  #  #  :          0 :     switch( cls )
                   #  # ]
      40                 :            :     {
      41                 :            :         case H5T_FLOAT:
      42   [ #  #  #  # ]:          0 :             switch( size )
      43                 :            :             {
      44                 :            :                 case 4:
      45                 :          0 :                     return H5T_NATIVE_FLOAT;
      46                 :            :                 case 8:
      47                 :          0 :                     return H5T_NATIVE_DOUBLE;
      48                 :            :                 case 16:
      49                 :          0 :                     return H5T_NATIVE_LDOUBLE;
      50                 :            :                 default:
      51                 :          0 :                     mhdf_setFail( status, "Invalid size for floating point type: %d", size );
      52                 :          0 :                     return -1;
      53                 :            :             }
      54                 :            : 
      55                 :            :         case H5T_INTEGER:
      56                 :          0 :             sgn = H5Tget_sign( input_type );
      57         [ #  # ]:          0 :             if( H5T_SGN_ERROR == sgn )
      58                 :            :             {
      59                 :          0 :                 mhdf_setFail( status, "Internall errror calling H5Tget_sign." );
      60                 :          0 :                 return -1;
      61                 :            :             }
      62         [ #  # ]:          0 :             if( sizeof( char ) == size )
      63         [ #  # ]:          0 :                 return sgn == H5T_SGN_NONE ? H5T_NATIVE_UCHAR : H5T_NATIVE_SCHAR;
      64         [ #  # ]:          0 :             else if( sizeof( short ) == size )
      65         [ #  # ]:          0 :                 return sgn == H5T_SGN_NONE ? H5T_NATIVE_USHORT : H5T_NATIVE_SHORT;
      66         [ #  # ]:          0 :             else if( sizeof( int ) == size )
      67         [ #  # ]:          0 :                 return sgn == H5T_SGN_NONE ? H5T_NATIVE_UINT : H5T_NATIVE_INT;
      68         [ #  # ]:          0 :             else if( sizeof( long ) == size )
      69         [ #  # ]:          0 :                 return sgn == H5T_SGN_NONE ? H5T_NATIVE_ULONG : H5T_NATIVE_LONG;
      70         [ #  # ]:          0 :             else if( (int)H5Tget_size( H5T_NATIVE_LLONG ) == size )
      71         [ #  # ]:          0 :                 return sgn == H5T_SGN_NONE ? H5T_NATIVE_ULLONG : H5T_NATIVE_LLONG;
      72                 :            : 
      73                 :          0 :             mhdf_setFail( status, "Invalid size for integer type: %d", size );
      74                 :          0 :             return -1;
      75                 :            : 
      76                 :            :         case H5T_ENUM:
      77                 :          0 :             tmp_id = H5Tget_super( input_type );
      78         [ #  # ]:          0 :             if( tmp_id < 0 )
      79                 :            :             {
      80                 :          0 :                 mhdf_setFail( status, "Internal error calling H5Tget_super." );
      81                 :          0 :                 return -1;
      82                 :            :             }
      83                 :          0 :             type_id = mhdf_getNativeType( tmp_id, size, status );
      84                 :          0 :             H5Tclose( tmp_id );
      85                 :          0 :             return type_id;
      86                 :            : 
      87                 :            :         case H5T_TIME:
      88                 :            :         case H5T_OPAQUE:
      89                 :            :         case H5T_REFERENCE:
      90                 :          0 :             mhdf_setFail( status, "Unsupported type class." );
      91                 :          0 :             return -1;
      92                 :            : 
      93                 :            :         case H5T_COMPOUND:
      94                 :            :         case H5T_VLEN:
      95                 :            :         case H5T_ARRAY:
      96                 :            :         case H5T_STRING:
      97                 :          0 :             mhdf_setFail( status, "Only atomic types are supported." );
      98                 :          0 :             return -1;
      99                 :            : 
     100                 :            :         default:
     101                 :          0 :             mhdf_setFail( status, "Internal error calling H5Tget_class.  Bad handle?" );
     102                 :          0 :             return -1;
     103                 :            :     }
     104                 :            : }
     105                 :            : 
     106                 :       1440 : static hid_t get_tag( mhdf_FileHandle file_handle, const char* tag_name, hid_t* id_type, mhdf_Status* status )
     107                 :            : {
     108                 :            :     hid_t       group_id, tag_id;
     109                 :            :     char*       path;
     110                 :            :     FileHandle* file_ptr;
     111                 :            : 
     112                 :       1440 :     file_ptr = (FileHandle*)file_handle;
     113         [ -  + ]:       1440 :     if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
     114                 :            : 
     115         [ +  + ]:       1440 :     if( NULL != id_type ) *id_type = file_ptr->id_type;
     116                 :            : 
     117                 :       1440 :     path = mhdf_name_to_path_copy( tag_name, status );
     118         [ -  + ]:       1440 :     if( NULL == path ) return -1;
     119                 :            : 
     120                 :            : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
     121                 :       1440 :     group_id = H5Gopen2( file_ptr->hdf_handle, TAG_GROUP, H5P_DEFAULT );
     122                 :            : #else
     123                 :            :     group_id = H5Gopen( file_ptr->hdf_handle, TAG_GROUP );
     124                 :            : #endif
     125         [ -  + ]:       1440 :     if( group_id < 0 )
     126                 :            :     {
     127                 :          0 :         mhdf_setFail( status, "Failed to open tag group." );
     128                 :          0 :         free( path );
     129                 :          0 :         return -1;
     130                 :            :     }
     131                 :            : 
     132                 :            : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
     133                 :       1440 :     tag_id = H5Gopen2( group_id, path, H5P_DEFAULT );
     134                 :            : #else
     135                 :            :     tag_id = H5Gopen( group_id, path );
     136                 :            : #endif
     137                 :       1440 :     H5Gclose( group_id );
     138                 :       1440 :     free( path );
     139         [ -  + ]:       1440 :     if( tag_id < 0 )
     140                 :            :     {
     141                 :          0 :         mhdf_setFail( status, "Failed to open tag data for tag \"%s\".", tag_name );
     142                 :          0 :         return -1;
     143                 :            :     }
     144                 :            : 
     145                 :       1440 :     mhdf_setOkay( status );
     146                 :       1440 :     return tag_id;
     147                 :            : }
     148                 :            : 
     149                 :        106 : static hid_t get_tag_type( FileHandle* file_ptr, const char* tag_path, mhdf_Status* status )
     150                 :            : {
     151                 :            :     hid_t group_id, tag_id, type_id;
     152                 :            : 
     153                 :            : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
     154                 :        106 :     group_id = H5Gopen2( file_ptr->hdf_handle, TAG_GROUP, H5P_DEFAULT );
     155                 :            : #else
     156                 :            :     group_id = H5Gopen( file_ptr->hdf_handle, TAG_GROUP );
     157                 :            : #endif
     158         [ -  + ]:        106 :     if( group_id < 0 )
     159                 :            :     {
     160                 :          0 :         mhdf_setFail( status, "Failed to open tag group." );
     161                 :          0 :         return -1;
     162                 :            :     }
     163                 :            : 
     164                 :            : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
     165                 :        106 :     tag_id = H5Gopen2( group_id, tag_path, H5P_DEFAULT );
     166                 :            : #else
     167                 :            :     tag_id = H5Gopen( group_id, tag_path );
     168                 :            : #endif
     169                 :        106 :     H5Gclose( group_id );
     170         [ -  + ]:        106 :     if( tag_id < 0 )
     171                 :            :     {
     172                 :          0 :         mhdf_setFail( status, "Failed to open group for tag \"%s\".", tag_path );
     173                 :          0 :         return -1;
     174                 :            :     }
     175                 :            : 
     176                 :            : #if defined( H5Topen_vers ) && H5Topen_vers > 1
     177                 :        106 :     type_id = H5Topen2( tag_id, TAG_TYPE_NAME, H5P_DEFAULT );
     178                 :            : #else
     179                 :            :     type_id = H5Topen( tag_id, TAG_TYPE_NAME );
     180                 :            : #endif
     181                 :        106 :     H5Gclose( tag_id );
     182         [ -  + ]:        106 :     if( type_id < 0 )
     183                 :            :     {
     184                 :          0 :         mhdf_setFail( status, "Failed to open type data for tag \"%s\".", tag_path );
     185                 :          0 :         return -1;
     186                 :            :     }
     187                 :            : 
     188                 :        106 :     return type_id;
     189                 :            : }
     190                 :            : 
     191                 :            : /** Helper function to write default and mesh values for tag
     192                 :            :  *\param tag_id       The file object upon which to attach the attribute
     193                 :            :  *\param attrib_name  The name of the attribute object
     194                 :            :  *\param type_id      The data type of the attribute data
     195                 :            :  *\param value        Pointer to attribute data
     196                 :            :  *\param value_size   Size of attribute data, as multiple of type indicated
     197                 :            :  *                    by type_id.  Should be 1 except for variable-length tag data.
     198                 :            :  */
     199                 :        448 : static int store_tag_val_in_attrib( hid_t tag_id, const char* attrib_name, hid_t type_id, const void* value,
     200                 :            :                                     hsize_t value_size, mhdf_Status* status )
     201                 :            : {
     202                 :            :     hid_t write_type;
     203                 :            :     int   rval;
     204         [ +  - ]:        448 :     if( value_size == 1 )
     205                 :        448 :         write_type = type_id;
     206         [ #  # ]:          0 :     else if( H5Tget_class( type_id ) == H5T_OPAQUE )
     207                 :            :     {
     208                 :          0 :         write_type = H5Tcreate( H5T_OPAQUE, value_size );
     209                 :            :     }
     210                 :            :     else
     211                 :            :     {
     212                 :            : #if defined( H5Tarray_create_vers ) && H5Tarray_create_vers > 1
     213                 :          0 :         write_type = H5Tarray_create2( type_id, 1, &value_size );
     214                 :            : #else
     215                 :            :         write_type = H5Tarray_create( type_id, 1, &value_size, 0 );
     216                 :            : #endif
     217                 :            :     }
     218                 :            : 
     219         [ -  + ]:        448 :     if( write_type < 0 )
     220                 :            :     {
     221                 :          0 :         mhdf_setFail( status, "Error constructing type object for tag mesh/default value" );
     222                 :          0 :         return -1;
     223                 :            :     }
     224                 :            : 
     225                 :        448 :     rval = mhdf_create_scalar_attrib( tag_id, attrib_name, write_type, value, status );
     226         [ -  + ]:        448 :     if( write_type != type_id ) H5Tclose( write_type );
     227                 :            : 
     228                 :        448 :     return rval;
     229                 :            : }
     230                 :            : 
     231                 :        347 : static hid_t create_tag_common( mhdf_FileHandle file_handle, const char* tag_name, enum mhdf_TagDataType tag_type,
     232                 :            :                                 int size, int storage, const void* default_value, int default_value_size_in,
     233                 :            :                                 const void* global_value, int global_value_size_in, hid_t hdf_type, hid_t hdf_base_type,
     234                 :            :                                 mhdf_Status* status )
     235                 :            : {
     236                 :            :     hid_t       temp_id, group_id, tag_id;
     237                 :            :     char*       path;
     238                 :            :     FileHandle* file_ptr;
     239                 :            :     herr_t      rval;
     240                 :            :     hsize_t     arr_len;
     241                 :        347 :     int         one = 1, var_len = 0;
     242                 :        347 :     hsize_t     default_value_size = default_value_size_in;
     243                 :        347 :     hsize_t     global_value_size = global_value_size_in;
     244                 :        347 :     int         close_base_type = 0;
     245                 :            : 
     246                 :            :     /* Force standard data types over user-specified types */
     247                 :            : 
     248         [ +  + ]:        347 :     if( tag_type != mhdf_OPAQUE ) hdf_type = 0;
     249         [ +  + ]:        347 :     if( tag_type != mhdf_ENTITY_ID ) hdf_base_type = 0;
     250                 :            : 
     251                 :            :     /* Validate input */
     252                 :            : 
     253                 :        347 :     file_ptr = (FileHandle*)file_handle;
     254         [ -  + ]:        347 :     if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
     255                 :            : 
     256 [ +  - ][ -  + ]:        347 :     if( !tag_name || !*tag_name )
     257                 :            :     {
     258                 :          0 :         mhdf_setFail( status, "Invalid tag name" );
     259                 :          0 :         return -1;
     260                 :            :     }
     261                 :            : 
     262                 :            :     /* Open the tag group */
     263                 :            : 
     264                 :            : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
     265                 :        347 :     group_id = H5Gopen2( file_ptr->hdf_handle, TAG_GROUP, H5P_DEFAULT );
     266                 :            : #else
     267                 :            :     group_id = H5Gopen( file_ptr->hdf_handle, TAG_GROUP );
     268                 :            : #endif
     269         [ -  + ]:        347 :     if( group_id < 0 )
     270                 :            :     {
     271                 :          0 :         mhdf_setFail( status, "H5Gopen(\"%s\") failed.", TAG_GROUP );
     272                 :          0 :         return -1;
     273                 :            :     }
     274                 :            : 
     275                 :            :     /* Create path string for tag object */
     276                 :            : 
     277                 :        347 :     path = mhdf_name_to_path_copy( tag_name, status );
     278         [ -  + ]:        347 :     if( !path )
     279                 :            :     {
     280                 :          0 :         H5Gclose( group_id );
     281                 :          0 :         return -1;
     282                 :            :     }
     283                 :            : 
     284                 :            :     /* Create group for this tag */
     285                 :            : 
     286                 :            : #if defined( H5Gcreate_vers ) && H5Gcreate_vers > 1
     287                 :        347 :     tag_id = H5Gcreate2( group_id, path, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
     288                 :            : #else
     289                 :            :     tag_id = H5Gcreate( group_id, path, 3 );
     290                 :            : #endif
     291         [ -  + ]:        347 :     if( tag_id < 0 )
     292                 :            :     {
     293                 :          0 :         mhdf_setFail( status, "H5Gcreate( \"%s\" ) failed.", path );
     294                 :          0 :         free( path );
     295                 :          0 :         H5Gclose( group_id );
     296                 :          0 :         return -1;
     297                 :            :     }
     298                 :            : 
     299                 :            :     /* Store the tag name as the comment on the group entry */
     300                 :            : 
     301                 :        347 :     rval = H5Gset_comment( group_id, path, tag_name );
     302                 :        347 :     H5Gclose( group_id );
     303                 :        347 :     free( path );
     304         [ -  + ]:        347 :     if( rval < 0 )
     305                 :            :     {
     306                 :          0 :         mhdf_setFail( status, "H5Gset_comment failed for tag \"%s\"", tag_name );
     307                 :          0 :         H5Gclose( tag_id );
     308                 :          0 :         return -1;
     309                 :            :     }
     310                 :            : 
     311                 :            :     /* Store TSTT tag type as attribute */
     312                 :            : 
     313                 :        347 :     rval = mhdf_create_scalar_attrib( tag_id, TAG_TYPE_ATTRIB, H5T_NATIVE_INT, &storage, status );
     314         [ -  + ]:        347 :     if( !rval )
     315                 :            :     {
     316                 :          0 :         H5Gclose( tag_id );
     317                 :          0 :         return -1;
     318                 :            :     }
     319                 :            : 
     320         [ +  + ]:        347 :     if( hdf_type )
     321                 :            :     {
     322                 :         17 :         hdf_type = H5Tcopy( hdf_type );
     323                 :         17 :         arr_len = 1;
     324                 :            :     }
     325                 :            :     else
     326                 :            :     {
     327   [ -  -  +  -  :        330 :         switch( tag_type )
                   +  + ]
     328                 :            :         {
     329                 :            :             default:
     330                 :            :             case mhdf_OPAQUE:
     331                 :          0 :                 arr_len = 1;
     332                 :          0 :                 hdf_type = H5Tcreate( H5T_OPAQUE, abs( size ) );
     333                 :          0 :                 H5Tset_tag( hdf_type, "tag_data" );
     334                 :          0 :                 break;
     335                 :            : 
     336                 :            :             case mhdf_BITFIELD:
     337                 :          0 :                 arr_len = 1;
     338         [ #  # ]:          0 :                 if( size <= 0 )
     339                 :            :                 {
     340                 :          0 :                     mhdf_setFail( status, "Invalid size (%d) for bit tag.", (int)size );
     341                 :          0 :                     return -1;
     342                 :            :                 }
     343         [ #  # ]:          0 :                 else if( size <= 8 )
     344                 :          0 :                     hdf_type = H5Tcopy( H5T_NATIVE_B8 );
     345         [ #  # ]:          0 :                 else if( size <= 16 )
     346                 :          0 :                     hdf_type = H5Tcopy( H5T_NATIVE_B16 );
     347         [ #  # ]:          0 :                 else if( size <= 32 )
     348                 :          0 :                     hdf_type = H5Tcopy( H5T_NATIVE_B32 );
     349         [ #  # ]:          0 :                 else if( size <= 64 )
     350                 :          0 :                     hdf_type = H5Tcopy( H5T_NATIVE_B64 );
     351                 :            :                 else
     352                 :            :                 {
     353                 :          0 :                     mhdf_setFail( status, "Cannot create a bit tag larger than 64-bits.  %d bits requested.\n",
     354                 :            :                                   (int)size );
     355                 :          0 :                     return -1;
     356                 :            :                 }
     357                 :            : 
     358         [ #  # ]:          0 :                 if( 0 > H5Tset_precision( hdf_type, size ) )
     359                 :            :                 {
     360                 :          0 :                     mhdf_setFail( status, "H5Tset_precision failed." );
     361                 :          0 :                     return -1;
     362                 :            :                 }
     363                 :          0 :                 break;
     364                 :            : 
     365                 :            :             case mhdf_ENTITY_ID:
     366                 :         47 :                 arr_len = abs( size );
     367                 :         47 :                 hdf_type = H5Tcopy( H5T_NATIVE_ULONG );
     368                 :         47 :                 break;
     369                 :            : 
     370                 :            :             case mhdf_BOOLEAN:
     371                 :          0 :                 arr_len = abs( size );
     372                 :          0 :                 hdf_type = H5Tcopy( H5T_NATIVE_UCHAR );
     373                 :          0 :                 break;
     374                 :            : 
     375                 :            :             case mhdf_INTEGER:
     376                 :        252 :                 arr_len = abs( size );
     377                 :        252 :                 hdf_type = H5Tcopy( H5T_NATIVE_INT );
     378                 :        252 :                 break;
     379                 :            : 
     380                 :            :             case mhdf_FLOAT:
     381                 :         31 :                 arr_len = abs( size );
     382                 :         31 :                 hdf_type = H5Tcopy( H5T_NATIVE_DOUBLE );
     383                 :         31 :                 break;
     384                 :            :         }
     385                 :            :     }
     386                 :            : 
     387         [ -  + ]:        347 :     if( hdf_type <= 0 )
     388                 :            :     {
     389                 :          0 :         mhdf_setFail( status, "Failed to create tag type object." );
     390                 :          0 :         H5Gclose( tag_id );
     391                 :          0 :         return -1;
     392                 :            :     }
     393                 :            : 
     394 [ +  + ][ -  + ]:        347 :     if( hdf_base_type && H5Tget_class( hdf_type ) != H5Tget_class( hdf_base_type ) )
     395                 :            :     {
     396                 :          0 :         mhdf_setFail( status, "Invalid base type for tag default/global data" );
     397                 :          0 :         H5Gclose( tag_id );
     398                 :          0 :         return -1;
     399                 :            :     }
     400                 :            : 
     401 [ +  - ][ -  + ]:        347 :     if( size < -1 || !arr_len )
     402                 :            :     {
     403                 :          0 :         mhdf_setFail( status, "Invalid 'size' parameter passed to mhdf_createTag (%d)", (int)size );
     404                 :          0 :         H5Gclose( tag_id );
     405                 :          0 :         return -1;
     406                 :            :     }
     407         [ +  + ]:        347 :     else if( size == -1 )
     408                 :            :     {
     409                 :            :         /* Note: we don't do anything with this here.  We rely on
     410                 :            :          *       the app to ask us to create the index table later.
     411                 :            :          */
     412                 :         24 :         arr_len = 1;
     413                 :            :         /* need to know this later, when storing default/global values */
     414                 :         24 :         var_len = 1;
     415                 :            :     }
     416         [ +  + ]:        323 :     else if( arr_len > 1 )
     417                 :            :     {
     418                 :            : #if defined( H5Tarray_create_vers ) && H5Tarray_create_vers > 1
     419                 :         33 :         temp_id = H5Tarray_create2( hdf_type, 1, &arr_len );
     420                 :            : #else
     421                 :            :         temp_id = H5Tarray_create( hdf_type, 1, &arr_len, NULL );
     422                 :            : #endif
     423                 :         33 :         H5Tclose( hdf_type );
     424         [ -  + ]:         33 :         if( temp_id < 0 )
     425                 :            :         {
     426                 :          0 :             mhdf_setFail( status, "Failed to create tag type object." );
     427                 :          0 :             H5Gclose( tag_id );
     428                 :          0 :             return -1;
     429                 :            :         }
     430                 :         33 :         hdf_type = temp_id;
     431                 :            : 
     432         [ +  + ]:         33 :         if( hdf_base_type )
     433                 :            :         {
     434         [ -  + ]:         12 :             if( H5Tequal( hdf_base_type, hdf_type ) > 0 ) { hdf_base_type = hdf_type; }
     435                 :            :             else
     436                 :            :             {
     437                 :            : #if defined( H5Tarray_create_vers ) && H5Tarray_create_vers > 1
     438                 :         12 :                 temp_id = H5Tarray_create2( hdf_base_type, 1, &arr_len );
     439                 :            : #else
     440                 :            :                 temp_id = H5Tarray_create( hdf_base_type, 1, &arr_len, NULL );
     441                 :            : #endif
     442         [ -  + ]:         12 :                 if( temp_id < 0 )
     443                 :            :                 {
     444                 :          0 :                     mhdf_setFail( status, "Failed to create tag type object." );
     445                 :          0 :                     H5Gclose( tag_id );
     446                 :          0 :                     H5Tclose( hdf_type );
     447                 :          0 :                     return -1;
     448                 :            :                 }
     449                 :         12 :                 hdf_base_type = temp_id;
     450                 :         12 :                 close_base_type = 1;
     451                 :            :             }
     452                 :            :         }
     453                 :            :     }
     454                 :            : 
     455         [ +  + ]:        347 :     if( !hdf_base_type ) hdf_base_type = hdf_type;
     456                 :            : 
     457                 :            :         /* Create tag type object, or write attribute if opaque */
     458                 :            : 
     459                 :            : #if defined( H5Tcommit_vers ) && H5Tcommit_vers > 1
     460                 :        347 :     rval = H5Tcommit2( tag_id, TAG_TYPE_NAME, hdf_type, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT );
     461                 :            : #else
     462                 :            :     rval = H5Tcommit( tag_id, TAG_TYPE_NAME, hdf_type );
     463                 :            : #endif
     464         [ -  + ]:        347 :     if( rval < 0 )
     465                 :            :     {
     466                 :          0 :         mhdf_setFail( status, "H5Tcommit failed for tag \"%s\"", tag_name );
     467         [ #  # ]:          0 :         if( close_base_type ) H5Tclose( hdf_base_type );
     468                 :          0 :         H5Tclose( hdf_type );
     469                 :          0 :         H5Gclose( tag_id );
     470                 :          0 :         return -1;
     471                 :            :     }
     472                 :            : 
     473                 :            :     /* If tag is entity handle, make note of it */
     474         [ +  + ]:        347 :     if( tag_type == mhdf_ENTITY_ID )
     475                 :            :     {
     476                 :         47 :         rval = mhdf_create_scalar_attrib( tag_id, TAG_HANDLE_TYPE_ATTRIB, H5T_NATIVE_INT, &one, status );
     477         [ -  + ]:         47 :         if( !rval )
     478                 :            :         {
     479         [ #  # ]:          0 :             if( close_base_type ) H5Tclose( hdf_base_type );
     480                 :          0 :             H5Gclose( tag_id );
     481                 :          0 :             H5Tclose( hdf_type );
     482                 :          0 :             return -1;
     483                 :            :         }
     484                 :            :     }
     485                 :            : 
     486                 :            :     /* Store the default value as a attribute of the tag group */
     487                 :            : 
     488         [ +  + ]:        347 :     if( default_value )
     489                 :            :     {
     490         [ -  + ]:        228 :         rval = store_tag_val_in_attrib( tag_id, TAG_DEFAULT_ATTRIB, hdf_base_type, default_value,
     491                 :            :                                         var_len ? default_value_size : 1, status );
     492         [ -  + ]:        228 :         if( !rval )
     493                 :            :         {
     494         [ #  # ]:          0 :             if( close_base_type ) H5Tclose( hdf_base_type );
     495                 :          0 :             H5Gclose( tag_id );
     496                 :          0 :             H5Tclose( hdf_type );
     497                 :          0 :             return -1;
     498                 :            :         }
     499                 :            :     }
     500                 :            : 
     501                 :            :     /* Store global tag value as attribute */
     502                 :            : 
     503         [ +  + ]:        347 :     if( global_value )
     504                 :            :     {
     505         [ -  + ]:        220 :         rval = store_tag_val_in_attrib( tag_id, TAG_GLOBAL_ATTRIB, hdf_base_type, global_value,
     506                 :            :                                         var_len ? global_value_size : 1, status );
     507         [ -  + ]:        220 :         if( !rval )
     508                 :            :         {
     509         [ #  # ]:          0 :             if( close_base_type ) H5Tclose( hdf_base_type );
     510                 :          0 :             H5Gclose( tag_id );
     511                 :          0 :             H5Tclose( hdf_type );
     512                 :          0 :             return -1;
     513                 :            :         }
     514                 :            :     }
     515                 :            : 
     516         [ +  + ]:        347 :     if( close_base_type ) H5Tclose( hdf_base_type );
     517                 :        347 :     H5Tclose( hdf_type );
     518                 :        347 :     mhdf_setOkay( status );
     519                 :        347 :     return tag_id;
     520                 :            : }
     521                 :            : 
     522                 :          0 : hid_t mhdf_getTagDataType( mhdf_FileHandle file_handle, const char* tag_name, mhdf_Status* status )
     523                 :            : {
     524                 :            :     FileHandle* file_ptr;
     525                 :            :     hid_t       result;
     526                 :            :     char*       path;
     527                 :            :     API_BEGIN;
     528                 :            : 
     529                 :            :     /* Validate input */
     530                 :            : 
     531                 :          0 :     file_ptr = (FileHandle*)file_handle;
     532         [ #  # ]:          0 :     if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
     533                 :            : 
     534 [ #  # ][ #  # ]:          0 :     if( !tag_name || !*tag_name )
     535                 :            :     {
     536                 :          0 :         mhdf_setFail( status, "Invalid tag name" );
     537                 :          0 :         return -1;
     538                 :            :     }
     539                 :            : 
     540                 :            :     /* Create path string for tag object */
     541                 :            : 
     542                 :          0 :     path = mhdf_name_to_path_copy( tag_name, status );
     543         [ #  # ]:          0 :     if( !path ) { return -1; }
     544                 :            : 
     545                 :          0 :     result = get_tag_type( file_ptr, path, status );
     546                 :            : 
     547                 :          0 :     free( path );
     548                 :            :     API_END;
     549                 :          0 :     return result;
     550                 :            : }
     551                 :            : 
     552                 :        323 : void mhdf_createTag( mhdf_FileHandle file_handle, const char* tag_name, enum mhdf_TagDataType tag_type, int size,
     553                 :            :                      int storage, const void* default_value, const void* global_value, hid_t hdf_type,
     554                 :            :                      hid_t hdf_base_type, mhdf_Status* status )
     555                 :            : {
     556                 :            :     hid_t tag_id;
     557                 :            :     API_BEGIN;
     558                 :        323 :     tag_id = create_tag_common( file_handle, tag_name, tag_type, size, storage, default_value, 1, global_value, 1,
     559                 :            :                                 hdf_type, hdf_base_type, status );
     560         [ +  - ]:        323 :     if( tag_id >= 0 ) H5Gclose( tag_id );
     561                 :            :     API_END;
     562                 :        323 : }
     563                 :            : 
     564                 :         24 : void mhdf_createVarLenTag( mhdf_FileHandle file_handle, const char* tag_name, enum mhdf_TagDataType tag_type,
     565                 :            :                            int storage, const void* default_value, int default_value_length, const void* global_value,
     566                 :            :                            int global_value_length, hid_t hdf_type, hid_t hdf_base_type, mhdf_Status* status )
     567                 :            : {
     568                 :            :     hid_t tag_id;
     569                 :         24 :     int   one = 1;
     570                 :            : 
     571                 :            :     API_BEGIN;
     572                 :         24 :     tag_id = create_tag_common( file_handle, tag_name, tag_type, -1, storage, default_value, default_value_length,
     573                 :            :                                 global_value, global_value_length, hdf_type, hdf_base_type, status );
     574         [ +  - ]:         24 :     if( tag_id >= 0 )
     575                 :            :     {
     576                 :         24 :         mhdf_create_scalar_attrib( tag_id, TAG_VARLEN_ATTRIB, H5T_NATIVE_INT, &one, status );
     577                 :         24 :         H5Gclose( tag_id );
     578                 :            :     }
     579                 :            :     API_END;
     580                 :         24 : }
     581                 :            : 
     582                 :          0 : int mhdf_getNumberTags( mhdf_FileHandle file_handle, mhdf_Status* status )
     583                 :            : {
     584                 :            :     hid_t       group_id;
     585                 :            :     hsize_t     result;
     586                 :            :     FileHandle* file_ptr;
     587                 :            :     API_BEGIN;
     588                 :            : 
     589                 :            :     /* Validate input */
     590                 :            : 
     591                 :          0 :     file_ptr = (FileHandle*)file_handle;
     592         [ #  # ]:          0 :     if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
     593                 :            : 
     594                 :            :         /* Open the tags group */
     595                 :            : 
     596                 :            : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
     597                 :          0 :     group_id = H5Gopen2( file_ptr->hdf_handle, TAG_GROUP, H5P_DEFAULT );
     598                 :            : #else
     599                 :            :     group_id = H5Gopen( file_ptr->hdf_handle, TAG_GROUP );
     600                 :            : #endif
     601         [ #  # ]:          0 :     if( group_id < 0 )
     602                 :            :     {
     603                 :          0 :         mhdf_setFail( status, "H5Gopen(\"%s\") failed", TAG_GROUP );
     604                 :          0 :         return -1;
     605                 :            :     }
     606                 :            : 
     607                 :            :     /* Get number of objects in tags group */
     608                 :            : 
     609         [ #  # ]:          0 :     if( H5Gget_num_objs( group_id, &result ) < 0 )
     610                 :            :     {
     611                 :          0 :         mhdf_setFail( status, "Internal failure calling H5Gget_num_objs." );
     612                 :          0 :         H5Gclose( group_id );
     613                 :          0 :         return -1;
     614                 :            :     }
     615                 :            : 
     616                 :          0 :     H5Gclose( group_id );
     617                 :          0 :     mhdf_setOkay( status );
     618                 :            :     API_END;
     619                 :          0 :     return (int)result;
     620                 :            : }
     621                 :            : 
     622                 :         68 : char** mhdf_getTagNames( mhdf_FileHandle file_handle, int* num_names_out, mhdf_Status* status )
     623                 :            : {
     624                 :            :     hid_t       group_id;
     625                 :            :     FileHandle* file_ptr;
     626                 :            :     hsize_t     count, idx;
     627                 :            :     char*       name;
     628                 :            :     char**      result;
     629                 :            :     ssize_t     size;
     630                 :            :     API_BEGIN;
     631                 :            : 
     632                 :            :     /* Validate input */
     633                 :            : 
     634                 :         68 :     file_ptr = (FileHandle*)file_handle;
     635         [ -  + ]:         68 :     if( !mhdf_check_valid_file( file_ptr, status ) ) return NULL;
     636                 :            : 
     637                 :            :         /* Open the tags group */
     638                 :            : 
     639                 :            : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
     640                 :         68 :     group_id = H5Gopen2( file_ptr->hdf_handle, TAG_GROUP, H5P_DEFAULT );
     641                 :            : #else
     642                 :            :     group_id = H5Gopen( file_ptr->hdf_handle, TAG_GROUP );
     643                 :            : #endif
     644         [ -  + ]:         68 :     if( group_id < 0 )
     645                 :            :     {
     646                 :          0 :         mhdf_setFail( status, "H5Gopen(\"%s\") failed", TAG_GROUP );
     647                 :          0 :         return NULL;
     648                 :            :     }
     649                 :            : 
     650                 :            :     /* Get number of objects in tags group */
     651                 :            : 
     652         [ -  + ]:         68 :     if( H5Gget_num_objs( group_id, &count ) < 0 )
     653                 :            :     {
     654                 :          0 :         mhdf_setFail( status, "Internal failure calling H5Gget_num_objs." );
     655                 :          0 :         H5Gclose( group_id );
     656                 :          0 :         return NULL;
     657                 :            :     }
     658                 :            : 
     659                 :            :     /* No tags? */
     660                 :            : 
     661                 :         68 :     *num_names_out = (int)count;
     662         [ -  + ]:         68 :     if( count == 0 )
     663                 :            :     {
     664                 :          0 :         H5Gclose( group_id );
     665                 :          0 :         mhdf_setOkay( status );
     666                 :          0 :         return NULL;
     667                 :            :     }
     668                 :            : 
     669                 :            :     /* Allocate string array */
     670                 :            : 
     671                 :         68 :     result = (char**)mhdf_malloc( sizeof( char* ) * count, status );
     672         [ -  + ]:         68 :     if( NULL == result )
     673                 :            :     {
     674                 :          0 :         H5Gclose( group_id );
     675                 :          0 :         return NULL;
     676                 :            :     }
     677                 :            : 
     678                 :            :     /* Get names */
     679                 :            : 
     680         [ +  + ]:        706 :     for( idx = 0; idx < count; ++idx )
     681                 :            :     {
     682                 :        638 :         size = H5Gget_objname_by_idx( group_id, idx, NULL, 0 );
     683 [ +  - ][ -  + ]:        638 :         if( size < 1 || NULL == ( name = (char*)mhdf_malloc( size + 1, status ) ) )
     684                 :            :         {
     685         [ #  # ]:          0 :             while( ( --idx ) > 0 )
     686                 :          0 :                 free( result[ idx ] );
     687                 :          0 :             free( result );
     688                 :          0 :             H5Gclose( group_id );
     689                 :          0 :             mhdf_setFail( status, "Internal failure calling H5Gget_objname_by_idx." );
     690                 :          0 :             return NULL;
     691                 :            :         }
     692                 :            : 
     693                 :        638 :         H5Gget_objname_by_idx( group_id, idx, name, size + 1 );
     694         [ -  + ]:        638 :         if( !mhdf_path_to_name( name, name ) )
     695                 :            :         {
     696                 :          0 :             mhdf_setFail( status, "Invalid character string in internal file path: \"%s\"\n", name );
     697                 :          0 :             return NULL;
     698                 :            :         }
     699                 :        638 :         result[ idx ] = name;
     700                 :            :     }
     701                 :            : 
     702                 :         68 :     H5Gclose( group_id );
     703                 :         68 :     mhdf_setOkay( status );
     704                 :            :     API_END;
     705                 :         68 :     return result;
     706                 :            : }
     707                 :            : 
     708                 :          0 : static int get_attrib_array_length_handle( hid_t attrib_id )
     709                 :            : {
     710                 :            :     hid_t   type_id;
     711                 :            :     int     rank;
     712                 :            :     hsize_t dims[ H5S_MAX_RANK ];
     713                 :            :     int     perm[ H5S_MAX_RANK ];
     714                 :            : 
     715                 :          0 :     type_id = H5Aget_type( attrib_id );
     716   [ #  #  #  # ]:          0 :     switch( H5Tget_class( type_id ) )
     717                 :            :     {
     718                 :            :         case H5T_NO_CLASS:
     719                 :          0 :             dims[ 0 ] = -1;
     720                 :          0 :             break;
     721                 :            :         case H5T_OPAQUE:
     722                 :          0 :             dims[ 0 ] = H5Tget_size( type_id );
     723                 :          0 :             break;
     724                 :            :         case H5T_ARRAY:
     725                 :            : #if defined( H5Tget_array_dims_vers ) && H5Tget_array_dims_vers > 1
     726                 :            :             (void)perm; /* suppress warning */
     727                 :          0 :             rank = H5Tget_array_dims2( type_id, dims );
     728                 :            : #else
     729                 :            :             rank = H5Tget_array_dims( type_id, dims, perm );
     730                 :            : #endif
     731         [ #  # ]:          0 :             if( rank == 1 )
     732                 :          0 :                 break;
     733                 :            :             else
     734                 :          0 :                 return -1;
     735                 :            :         default:
     736                 :          0 :             dims[ 0 ] = 1;
     737                 :          0 :             break;
     738                 :            :     }
     739                 :            : 
     740                 :          0 :     H5Tclose( type_id );
     741                 :          0 :     return dims[ 0 ];
     742                 :            : }
     743                 :            : 
     744                 :            : /*
     745                 :            : static int get_attrib_array_length_index( hid_t object_id, unsigned int index )
     746                 :            : {
     747                 :            :   hid_t attrib_id;
     748                 :            :   int result;
     749                 :            : 
     750                 :            :   attrib_id = H5Aopen_idx( object_id, index );
     751                 :            :   if (attrib_id < 0)
     752                 :            :     return -1;
     753                 :            : 
     754                 :            :   result = get_attrib_array_length_handle( attrib_id );
     755                 :            :   H5Aclose( attrib_id );
     756                 :            :   return result;
     757                 :            : }
     758                 :            : */
     759                 :            : 
     760                 :          0 : static int get_attrib_array_length_name( hid_t file, const char* path )
     761                 :            : {
     762                 :            :     hid_t attrib_id;
     763                 :            :     int   result;
     764                 :            : 
     765                 :          0 :     attrib_id = H5Aopen_name( file, path );
     766         [ #  # ]:          0 :     if( attrib_id < 0 ) return -1;
     767                 :            : 
     768                 :          0 :     result = get_attrib_array_length_handle( attrib_id );
     769                 :          0 :     H5Aclose( attrib_id );
     770                 :          0 :     return result;
     771                 :            : }
     772                 :            : 
     773                 :        638 : void mhdf_getTagInfo( mhdf_FileHandle file_handle, const char* tag_name, enum mhdf_TagDataType* class_out,
     774                 :            :                       int* size_out, int* tstt_storage_out, int* have_default_out, int* have_global_out,
     775                 :            :                       int* have_sparse_out, mhdf_Status* status )
     776                 :            : {
     777                 :            :     hid_t        tag_id, type_id, super_id;
     778                 :            :     int          i, rval, is_handle;
     779                 :            :     hsize_t      size, sup_size;
     780                 :            :     unsigned int idx;
     781                 :            :     int          rank, var_data;
     782                 :            :     hsize_t      dims[ H5S_MAX_RANK ];
     783                 :            :     int          perm[ H5S_MAX_RANK ];
     784                 :            :     H5T_class_t  class_tmp;
     785                 :            : 
     786                 :            :     API_BEGIN;
     787                 :            : 
     788                 :            :     /* Validate input */
     789 [ +  - ][ +  - ]:        638 :     if( NULL == tag_name || NULL == class_out || NULL == size_out || NULL == tstt_storage_out ||
         [ +  - ][ +  - ]
                 [ +  - ]
     790 [ +  - ][ -  + ]:        638 :         NULL == have_default_out || NULL == have_global_out || NULL == have_sparse_out )
     791                 :            :     {
     792                 :          0 :         mhdf_setFail( status, "Invalid input." );
     793                 :          0 :         return;
     794                 :            :     }
     795                 :            : 
     796                 :            :     /* Get group for tag */
     797                 :        638 :     tag_id = get_tag( file_handle, tag_name, NULL, status );
     798         [ -  + ]:        638 :     if( tag_id < 0 ) return;
     799                 :            : 
     800                 :            :     /* Check for sparse data */
     801                 :        638 :     rval = mhdf_is_in_group( tag_id, SPARSE_ENTITY_NAME, status );
     802         [ -  + ]:        638 :     if( rval < 0 )
     803                 :            :     {
     804                 :          0 :         H5Gclose( tag_id );
     805                 :          0 :         return;
     806                 :            :     }
     807                 :        638 :     *have_sparse_out = rval ? 1 : 0;
     808                 :            : 
     809                 :            :     /* Check for variable-length tag data */
     810                 :        638 :     rval = mhdf_find_attribute( tag_id, TAG_VARLEN_ATTRIB, &idx, status );
     811         [ -  + ]:        638 :     if( rval < 0 )
     812                 :            :     {
     813                 :          0 :         H5Gclose( tag_id );
     814                 :          0 :         return;
     815                 :            :     }
     816                 :        638 :     var_data = rval ? 1 : 0;
     817                 :            : 
     818                 :            :     /* Check if have default value for tag */
     819                 :        638 :     rval = mhdf_find_attribute( tag_id, TAG_DEFAULT_ATTRIB, &idx, status );
     820         [ -  + ]:        638 :     if( rval < 0 )
     821                 :            :     {
     822                 :          0 :         H5Gclose( tag_id );
     823                 :          0 :         return;
     824                 :            :     }
     825         [ +  + ]:        638 :     if( !rval )
     826                 :        315 :         *have_default_out = 0;
     827         [ +  - ]:        323 :     else if( !var_data )
     828                 :        323 :         *have_default_out = 1;
     829                 :            :     else
     830                 :            :     {
     831                 :            :         /* *have_default_out = get_attrib_array_length_index( tag_id, index ); */
     832                 :          0 :         *have_default_out = get_attrib_array_length_name( tag_id, TAG_DEFAULT_ATTRIB );
     833         [ #  # ]:          0 :         if( *have_default_out < 0 )
     834                 :            :         {
     835                 :          0 :             mhdf_setFail( status, "Error checking length of default value for tag: %s\n", tag_name );
     836                 :          0 :             H5Gclose( tag_id );
     837                 :          0 :             return;
     838                 :            :         }
     839                 :            :     }
     840                 :            : 
     841                 :            :     /* Check if have global value for tag */
     842                 :        638 :     rval = mhdf_find_attribute( tag_id, TAG_GLOBAL_ATTRIB, &idx, status );
     843         [ -  + ]:        638 :     if( rval < 0 )
     844                 :            :     {
     845                 :          0 :         H5Gclose( tag_id );
     846                 :          0 :         return;
     847                 :            :     }
     848         [ +  + ]:        638 :     if( !rval )
     849                 :        336 :         *have_global_out = 0;
     850         [ +  - ]:        302 :     else if( !var_data )
     851                 :        302 :         *have_global_out = 1;
     852                 :            :     else
     853                 :            :     {
     854                 :            :         /* *have_global_out = get_attrib_array_length_index( tag_id, index ); */
     855                 :          0 :         *have_global_out = get_attrib_array_length_name( tag_id, TAG_GLOBAL_ATTRIB );
     856         [ #  # ]:          0 :         if( *have_global_out < 0 )
     857                 :            :         {
     858                 :          0 :             mhdf_setFail( status, "Error checking length of global value for tag: %s\n", tag_name );
     859                 :          0 :             H5Gclose( tag_id );
     860                 :          0 :             return;
     861                 :            :         }
     862                 :            :     }
     863                 :            : 
     864                 :            :     /* Get TSTT tag class */
     865                 :        638 :     rval = mhdf_read_scalar_attrib( tag_id, TAG_TYPE_ATTRIB, H5T_NATIVE_INT, tstt_storage_out, status );
     866         [ -  + ]:        638 :     if( rval < 1 )
     867                 :            :     {
     868                 :          0 :         H5Gclose( tag_id );
     869                 :          0 :         return;
     870                 :            :     }
     871                 :            : 
     872                 :            :     /* Check if tag is storing entity handles */
     873                 :        638 :     rval = mhdf_find_attribute( tag_id, TAG_HANDLE_TYPE_ATTRIB, &idx, status );
     874         [ -  + ]:        638 :     if( rval < 0 )
     875                 :            :     {
     876                 :          0 :         H5Gclose( tag_id );
     877                 :          0 :         return;
     878                 :            :     }
     879                 :        638 :     is_handle = rval;
     880                 :            : 
     881                 :            :     /* Get tag type */
     882                 :            : #if defined( H5Topen_vers ) && H5Topen_vers > 1
     883                 :        638 :     type_id = H5Topen2( tag_id, TAG_TYPE_NAME, H5P_DEFAULT );
     884                 :            : #else
     885                 :            :     type_id = H5Topen( tag_id, TAG_TYPE_NAME );
     886                 :            : #endif
     887         [ -  + ]:        638 :     if( type_id < 0 )
     888                 :            :     {
     889                 :          0 :         H5Gclose( tag_id );
     890                 :          0 :         mhdf_setFail( status, "Failed to get type object for tag \"%s\".", tag_name );
     891                 :          0 :         return;
     892                 :            :     }
     893                 :            : 
     894                 :        638 :     class_tmp = H5Tget_class( type_id );
     895         [ -  + ]:        638 :     if( class_tmp < 0 )
     896                 :            :     {
     897                 :          0 :         mhdf_setFail( status, "H5Tget_class failed." );
     898                 :          0 :         H5Gclose( tag_id );
     899                 :          0 :         H5Tclose( type_id );
     900                 :          0 :         return;
     901                 :            :     }
     902                 :            : 
     903                 :        638 :     size = H5Tget_size( type_id );
     904         [ -  + ]:        638 :     if( size <= 0 )
     905                 :            :     {
     906                 :          0 :         mhdf_setFail( status, "H5Tget_size failed." );
     907                 :          0 :         H5Gclose( tag_id );
     908                 :          0 :         H5Tclose( type_id );
     909                 :          0 :         return;
     910                 :            :     }
     911                 :            : 
     912   [ +  +  -  +  :        638 :     switch( class_tmp )
                      + ]
     913                 :            :     {
     914                 :            :         case H5T_INTEGER:
     915         [ -  + ]:        477 :             *class_out = ( size == 1 ) ? mhdf_BOOLEAN : mhdf_INTEGER;
     916                 :        477 :             *size_out = 1;
     917                 :        477 :             break;
     918                 :            : 
     919                 :            :         case H5T_FLOAT:
     920                 :         43 :             *class_out = mhdf_FLOAT;
     921                 :         43 :             *size_out = 1;
     922                 :         43 :             break;
     923                 :            : 
     924                 :            :         case H5T_BITFIELD:
     925                 :          0 :             *class_out = mhdf_BITFIELD;
     926                 :          0 :             *size_out = H5Tget_precision( type_id );
     927         [ #  # ]:          0 :             if( *size_out <= 0 )
     928                 :            :             {
     929                 :          0 :                 mhdf_setFail( status, "H5Tget_precision failed." );
     930                 :          0 :                 H5Gclose( tag_id );
     931                 :          0 :                 H5Tclose( type_id );
     932                 :          0 :                 return;
     933                 :            :             }
     934                 :          0 :             break;
     935                 :            : 
     936                 :            :         default:
     937                 :            :         case H5T_OPAQUE:
     938                 :         46 :             *class_out = mhdf_OPAQUE;
     939                 :         46 :             *size_out = size;
     940                 :         46 :             break;
     941                 :            : 
     942                 :            :         case H5T_ARRAY:
     943                 :            : 
     944                 :            : #if defined( H5Tget_array_dims_vers ) && H5Tget_array_dims_vers > 1
     945                 :            :             (void)perm; /* suppress warning */
     946                 :         72 :             rank = H5Tget_array_dims2( type_id, dims );
     947                 :            : #else
     948                 :            :             rank = H5Tget_array_dims( type_id, dims, perm );
     949                 :            : #endif
     950         [ -  + ]:         72 :             if( rank <= 0 )
     951                 :            :             {
     952                 :          0 :                 mhdf_setFail( status, "H5Tget_size failed." );
     953                 :          0 :                 H5Gclose( tag_id );
     954                 :          0 :                 H5Tclose( type_id );
     955                 :          0 :                 return;
     956                 :            :             }
     957         [ -  + ]:         72 :             for( i = 1; i < rank; ++i )
     958                 :          0 :                 dims[ 0 ] *= dims[ i ];
     959                 :            : 
     960                 :         72 :             super_id = H5Tget_super( type_id );
     961         [ -  + ]:         72 :             if( super_id < 0 )
     962                 :            :             {
     963                 :          0 :                 mhdf_setFail( status, "H5Tget_super failed" );
     964                 :          0 :                 H5Gclose( tag_id );
     965                 :          0 :                 H5Tclose( type_id );
     966                 :          0 :                 return;
     967                 :            :             }
     968                 :            : 
     969                 :         72 :             class_tmp = H5Tget_class( super_id );
     970         [ -  + ]:         72 :             if( class_tmp < 0 )
     971                 :            :             {
     972                 :          0 :                 mhdf_setFail( status, "H5Tget_class failed." );
     973                 :          0 :                 H5Gclose( tag_id );
     974                 :          0 :                 H5Tclose( type_id );
     975                 :          0 :                 H5Tclose( super_id );
     976                 :          0 :                 return;
     977                 :            :             }
     978                 :            : 
     979                 :         72 :             sup_size = H5Tget_size( super_id );
     980                 :         72 :             H5Tclose( super_id );
     981         [ -  + ]:         72 :             if( sup_size <= 0 )
     982                 :            :             {
     983                 :          0 :                 mhdf_setFail( status, "H5Tget_size failed." );
     984                 :          0 :                 H5Gclose( tag_id );
     985                 :          0 :                 H5Tclose( type_id );
     986                 :          0 :                 return;
     987                 :            :             }
     988                 :            : 
     989      [ +  +  - ]:         72 :             switch( class_tmp )
     990                 :            :             {
     991                 :            :                 case H5T_INTEGER:
     992         [ -  + ]:         30 :                     *class_out = ( sup_size == 1 ) ? mhdf_BOOLEAN : mhdf_INTEGER;
     993                 :         30 :                     *size_out = dims[ 0 ];
     994                 :         30 :                     break;
     995                 :            : 
     996                 :            :                 case H5T_FLOAT:
     997                 :         42 :                     *class_out = mhdf_FLOAT;
     998                 :         42 :                     *size_out = dims[ 0 ];
     999                 :         42 :                     break;
    1000                 :            : 
    1001                 :            :                 default:
    1002                 :          0 :                     *class_out = mhdf_OPAQUE;
    1003                 :          0 :                     *size_out = size;
    1004                 :          0 :                     break;
    1005                 :            :             }
    1006                 :            : 
    1007                 :         72 :             break;
    1008                 :            :     }
    1009                 :        638 :     H5Tclose( type_id );
    1010                 :        638 :     H5Gclose( tag_id );
    1011                 :            : 
    1012         [ +  + ]:        638 :     if( is_handle )
    1013                 :            :     {
    1014         [ -  + ]:         79 :         if( *class_out != mhdf_INTEGER )
    1015                 :            :         {
    1016                 :          0 :             mhdf_setFail( status, "Non-integer tag marked as handle type." );
    1017                 :          0 :             return;
    1018                 :            :         }
    1019                 :         79 :         *class_out = mhdf_ENTITY_ID;
    1020                 :            :     }
    1021                 :            : 
    1022         [ +  + ]:        638 :     if( var_data )
    1023                 :            :     {
    1024 [ +  - ][ -  + ]:         82 :         if( *size_out != 1 || *class_out == mhdf_BITFIELD )
    1025                 :            :         {
    1026                 :          0 :             mhdf_setFail( status, "Invalid or unexpected variable-length tag data" );
    1027                 :          0 :             return;
    1028                 :            :         }
    1029                 :         82 :         *size_out = -1;
    1030                 :            :     }
    1031                 :            : 
    1032                 :        638 :     mhdf_setOkay( status );
    1033                 :            :     API_END;
    1034                 :            : }
    1035                 :            : 
    1036                 :        646 : static int read_tag_attrib_data( hid_t tag_id, const char* attrib_name, hid_t type_id, void* data, int is_var_len,
    1037                 :            :                                  mhdf_Status* status )
    1038                 :            : {
    1039                 :            :     int      rval, ilen;
    1040                 :            :     unsigned idx;
    1041                 :        646 :     hid_t    read_type = type_id;
    1042                 :            :     hsize_t  len;
    1043                 :            : 
    1044                 :            :     /* Check if tag has attribute */
    1045                 :        646 :     rval = mhdf_find_attribute( tag_id, attrib_name, &idx, status );
    1046         [ -  + ]:        646 :     if( rval < 0 )
    1047                 :          0 :         return 0;
    1048         [ +  + ]:        646 :     else if( 0 == rval )
    1049                 :         21 :         return 1;
    1050                 :            : 
    1051         [ -  + ]:        625 :     if( NULL == data )
    1052                 :            :     {
    1053                 :          0 :         mhdf_setFail( status, "Invalid input." );
    1054                 :          0 :         return 0;
    1055                 :            :     }
    1056                 :            : 
    1057         [ -  + ]:        625 :     if( is_var_len )
    1058                 :            :     {
    1059                 :            :         /* len = get_attrib_array_length_index(tag_id, index); */
    1060                 :          0 :         ilen = get_attrib_array_length_name( tag_id, attrib_name );
    1061         [ #  # ]:          0 :         if( ilen < 0 )
    1062                 :            :         {
    1063                 :          0 :             mhdf_setFail( status, "Failed to read length of default/mesh value for tag" );
    1064                 :          0 :             return 0;
    1065                 :            :         }
    1066                 :          0 :         len = ilen;
    1067                 :            : 
    1068                 :            :         /* caller passes type_id == 0 for OPAQUE */
    1069         [ #  # ]:          0 :         if( 0 == type_id )
    1070                 :          0 :             read_type = H5Tcreate( H5T_OPAQUE, len );
    1071                 :            :         else
    1072                 :            :         {
    1073                 :            : #if defined( H5Tarray_create_vers ) && H5Tarray_create_vers > 1
    1074                 :          0 :             read_type = H5Tarray_create2( type_id, 1, &len );
    1075                 :            : #else
    1076                 :            :             read_type = H5Tarray_create( type_id, 1, &len, 0 );
    1077                 :            : #endif
    1078                 :            :         }
    1079         [ #  # ]:          0 :         if( read_type < 0 )
    1080                 :            :         {
    1081                 :          0 :             mhdf_setFail( status, "Failed to read mesh/default value for tag" );
    1082                 :          0 :             return 0;
    1083                 :            :         }
    1084                 :            :     }
    1085                 :            : 
    1086                 :        625 :     rval = mhdf_read_scalar_attrib( tag_id, attrib_name, read_type, data, status );
    1087         [ -  + ]:        625 :     if( is_var_len ) H5Tclose( read_type );
    1088                 :            : 
    1089                 :        646 :     return rval;
    1090                 :            : }
    1091                 :            : 
    1092                 :        323 : void mhdf_getTagValues( mhdf_FileHandle file_handle, const char* tag_name, hid_t output_data_type, void* default_value,
    1093                 :            :                         void* global_value, mhdf_Status* status )
    1094                 :            : {
    1095                 :            :     hid_t        tag_id;
    1096                 :            :     int          rval, var_data;
    1097                 :            :     unsigned int idx;
    1098                 :            :     API_BEGIN;
    1099                 :            : 
    1100                 :            :     /* check args */
    1101 [ +  - ][ -  + ]:        323 :     if( NULL == tag_name || !*tag_name )
    1102                 :            :     {
    1103                 :          0 :         mhdf_setFail( status, "Invalid input." );
    1104                 :          0 :         return;
    1105                 :            :     }
    1106                 :            : 
    1107                 :            :     /* Get the tag group */
    1108                 :        323 :     tag_id = get_tag( file_handle, tag_name, NULL, status );
    1109         [ -  + ]:        323 :     if( tag_id < 0 ) return;
    1110                 :            : 
    1111                 :            :     /* Check for variable-length tag data */
    1112                 :        323 :     rval = mhdf_find_attribute( tag_id, TAG_VARLEN_ATTRIB, &idx, status );
    1113         [ -  + ]:        323 :     if( rval < 0 )
    1114                 :            :     {
    1115                 :          0 :         H5Gclose( tag_id );
    1116                 :          0 :         return;
    1117                 :            :     }
    1118                 :        323 :     var_data = rval ? 1 : 0;
    1119                 :            : 
    1120                 :            :     /* Read default value if present */
    1121                 :        323 :     rval = read_tag_attrib_data( tag_id, TAG_DEFAULT_ATTRIB, output_data_type, default_value, var_data, status );
    1122         [ -  + ]:        323 :     if( !rval )
    1123                 :            :     {
    1124                 :          0 :         H5Gclose( tag_id );
    1125                 :          0 :         return;
    1126                 :            :     }
    1127                 :            : 
    1128                 :            :     /* Read mesh value if present */
    1129                 :        323 :     rval = read_tag_attrib_data( tag_id, TAG_GLOBAL_ATTRIB, output_data_type, global_value, var_data, status );
    1130         [ -  + ]:        323 :     if( !rval )
    1131                 :            :     {
    1132                 :          0 :         H5Gclose( tag_id );
    1133                 :          0 :         return;
    1134                 :            :     }
    1135                 :            : 
    1136                 :        323 :     H5Gclose( tag_id );
    1137                 :        323 :     mhdf_setOkay( status );
    1138                 :            :     API_END;
    1139                 :            : }
    1140                 :            : 
    1141                 :       2366 : int mhdf_haveDenseTag( mhdf_FileHandle file_handle, const char* tag_name, const char* type_handle, mhdf_Status* status )
    1142                 :            : {
    1143                 :            :     char*       path;
    1144                 :            :     hid_t       elem_id, group_id;
    1145                 :            :     FileHandle* file_ptr;
    1146                 :       2366 :     int         rval = 0;
    1147                 :            :     API_BEGIN;
    1148                 :            : 
    1149                 :       2366 :     file_ptr = (FileHandle*)file_handle;
    1150         [ -  + ]:       2366 :     if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
    1151                 :            : 
    1152         [ +  + ]:       2366 :     if( type_handle == mhdf_node_type_handle( ) )
    1153                 :            :     {
    1154                 :            : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
    1155                 :        638 :         elem_id = H5Gopen2( file_ptr->hdf_handle, NODE_GROUP, H5P_DEFAULT );
    1156                 :            : #else
    1157                 :            :         elem_id = H5Gopen( file_ptr->hdf_handle, NODE_GROUP );
    1158                 :            : #endif
    1159         [ -  + ]:        638 :         if( elem_id < 0 ) mhdf_setFail( status, "Could not open node group." );
    1160                 :            :     }
    1161         [ +  + ]:       1728 :     else if( type_handle == mhdf_set_type_handle( ) )
    1162                 :            :     {
    1163                 :            : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
    1164                 :        638 :         elem_id = H5Gopen2( file_ptr->hdf_handle, SET_GROUP, H5P_DEFAULT );
    1165                 :            : #else
    1166                 :            :         elem_id = H5Gopen( file_ptr->hdf_handle, SET_GROUP );
    1167                 :            : #endif
    1168         [ -  + ]:        638 :         if( elem_id < 0 ) mhdf_setFail( status, "Could not open set group." );
    1169                 :            :     }
    1170                 :            :     else
    1171                 :            :     {
    1172                 :       1090 :         elem_id = mhdf_elem_group_from_handle( file_ptr, type_handle, status );
    1173                 :            :     }
    1174         [ -  + ]:       2366 :     if( elem_id < 0 ) return -1;
    1175                 :            : 
    1176                 :       2366 :     rval = mhdf_is_in_group( elem_id, TAG_GROUP_NAME, status );
    1177         [ -  + ]:       2366 :     if( rval < 0 )
    1178                 :            :     {
    1179                 :          0 :         H5Gclose( elem_id );
    1180                 :          0 :         return -1;
    1181                 :            :     }
    1182         [ -  + ]:       2366 :     else if( rval == 0 )
    1183                 :            :     {
    1184                 :          0 :         H5Gclose( elem_id );
    1185                 :          0 :         mhdf_setOkay( status );
    1186                 :          0 :         return 0;
    1187                 :            :     }
    1188                 :            : 
    1189                 :            : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
    1190                 :       2366 :     group_id = H5Gopen2( elem_id, DENSE_TAG_SUBGROUP, H5P_DEFAULT );
    1191                 :            : #else
    1192                 :            :     group_id = H5Gopen( elem_id, DENSE_TAG_SUBGROUP );
    1193                 :            : #endif
    1194                 :       2366 :     H5Gclose( elem_id );
    1195         [ -  + ]:       2366 :     if( group_id < 0 )
    1196                 :            :     {
    1197                 :          0 :         mhdf_setFail( status, "Could not open tag subgroup." );
    1198                 :          0 :         return -1;
    1199                 :            :     }
    1200                 :            : 
    1201                 :       2366 :     path = mhdf_name_to_path_copy( tag_name, status );
    1202         [ -  + ]:       2366 :     if( NULL == path )
    1203                 :            :     {
    1204                 :          0 :         H5Gclose( group_id );
    1205                 :          0 :         return -1;
    1206                 :            :     }
    1207                 :            : 
    1208                 :       2366 :     rval = mhdf_is_in_group( group_id, path, status );
    1209                 :       2366 :     H5Gclose( group_id );
    1210                 :       2366 :     free( path );
    1211                 :            : 
    1212         [ +  - ]:       2366 :     if( rval >= 0 ) { mhdf_setOkay( status ); }
    1213                 :            : 
    1214                 :            :     API_END;
    1215                 :       2366 :     return rval;
    1216                 :            : }
    1217                 :            : 
    1218                 :        106 : hid_t mhdf_createDenseTagData( mhdf_FileHandle file_handle, const char* tag_name, const char* type_handle,
    1219                 :            :                                long num_values, mhdf_Status* status )
    1220                 :            : {
    1221                 :            :     char*       path;
    1222                 :            :     hid_t       elem_id, data_id, type_id;
    1223                 :            :     FileHandle* file_ptr;
    1224                 :            :     size_t      name_len, path_len, dir_len;
    1225                 :            :     hsize_t     size;
    1226                 :            :     API_BEGIN;
    1227                 :            : 
    1228                 :        106 :     file_ptr = (FileHandle*)file_handle;
    1229         [ -  + ]:        106 :     if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
    1230                 :            : 
    1231         [ +  + ]:        106 :     if( type_handle == mhdf_node_type_handle( ) )
    1232                 :            :     {
    1233                 :            : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
    1234                 :         36 :         elem_id = H5Gopen2( file_ptr->hdf_handle, NODE_GROUP, H5P_DEFAULT );
    1235                 :            : #else
    1236                 :            :         elem_id = H5Gopen( file_ptr->hdf_handle, NODE_GROUP );
    1237                 :            : #endif
    1238         [ -  + ]:         36 :         if( elem_id < 0 ) mhdf_setFail( status, "Could not open node group." );
    1239                 :            :     }
    1240         [ +  + ]:         70 :     else if( type_handle == mhdf_set_type_handle( ) )
    1241                 :            :     {
    1242                 :            : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
    1243                 :         32 :         elem_id = H5Gopen2( file_ptr->hdf_handle, SET_GROUP, H5P_DEFAULT );
    1244                 :            : #else
    1245                 :            :         elem_id = H5Gopen( file_ptr->hdf_handle, SET_GROUP );
    1246                 :            : #endif
    1247         [ -  + ]:         32 :         if( elem_id < 0 ) mhdf_setFail( status, "Could not open set group." );
    1248                 :            :     }
    1249                 :            :     else
    1250                 :            :     {
    1251                 :         38 :         elem_id = mhdf_elem_group_from_handle( file_ptr, type_handle, status );
    1252                 :            :     }
    1253         [ -  + ]:        106 :     if( elem_id < 0 ) return -1;
    1254                 :            : 
    1255                 :        106 :     dir_len = strlen( DENSE_TAG_SUBGROUP );
    1256                 :        106 :     name_len = mhdf_name_to_path( tag_name, NULL, 0 );
    1257                 :        106 :     path_len = dir_len + name_len + 1;
    1258                 :        106 :     path = (char*)mhdf_malloc( path_len, status );
    1259         [ -  + ]:        106 :     if( NULL == path )
    1260                 :            :     {
    1261                 :          0 :         H5Gclose( elem_id );
    1262                 :          0 :         return -1;
    1263                 :            :     }
    1264                 :        106 :     strcpy( path, DENSE_TAG_SUBGROUP );
    1265                 :        106 :     mhdf_name_to_path( tag_name, path + dir_len, name_len + 1 );
    1266                 :            : 
    1267                 :        106 :     type_id = get_tag_type( file_ptr, path + dir_len, status );
    1268         [ -  + ]:        106 :     if( type_id < 0 )
    1269                 :            :     {
    1270                 :          0 :         H5Gclose( elem_id );
    1271                 :          0 :         return -1;
    1272                 :            :     }
    1273                 :            : 
    1274                 :        106 :     size = (hsize_t)num_values;
    1275                 :        106 :     data_id = mhdf_create_table( elem_id, path, type_id, 1, &size, status );
    1276                 :        106 :     free( path );
    1277                 :        106 :     H5Gclose( elem_id );
    1278                 :        106 :     H5Tclose( type_id );
    1279                 :            : 
    1280         [ +  - ]:        106 :     if( data_id > 0 ) mhdf_setOkay( status );
    1281                 :            : 
    1282                 :            :     API_END_H( 1 );
    1283                 :        106 :     return data_id;
    1284                 :            : }
    1285                 :            : 
    1286                 :        284 : hid_t mhdf_openDenseTagData( mhdf_FileHandle file_handle, const char* tag_name, const char* type_handle,
    1287                 :            :                              long* num_values_out, mhdf_Status* status )
    1288                 :            : {
    1289                 :            :     char*       path;
    1290                 :            :     hid_t       elem_id, data_id;
    1291                 :            :     FileHandle* file_ptr;
    1292                 :            :     size_t      name_len, path_len, dir_len;
    1293                 :            :     hsize_t     size;
    1294                 :            :     API_BEGIN;
    1295                 :            : 
    1296                 :        284 :     file_ptr = (FileHandle*)file_handle;
    1297         [ -  + ]:        284 :     if( !mhdf_check_valid_file( file_ptr, status ) ) return -1;
    1298                 :            : 
    1299         [ +  + ]:        284 :     if( type_handle == mhdf_node_type_handle( ) )
    1300                 :            :     {
    1301                 :            : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
    1302                 :         86 :         elem_id = H5Gopen2( file_ptr->hdf_handle, NODE_GROUP, H5P_DEFAULT );
    1303                 :            : #else
    1304                 :            :         elem_id = H5Gopen( file_ptr->hdf_handle, NODE_GROUP );
    1305                 :            : #endif
    1306         [ -  + ]:         86 :         if( elem_id < 0 ) mhdf_setFail( status, "Could not open node group." );
    1307                 :            :     }
    1308         [ +  + ]:        198 :     else if( type_handle == mhdf_set_type_handle( ) )
    1309                 :            :     {
    1310                 :            : #if defined( H5Gopen_vers ) && H5Gopen_vers > 1
    1311                 :        106 :         elem_id = H5Gopen2( file_ptr->hdf_handle, SET_GROUP, H5P_DEFAULT );
    1312                 :            : #else
    1313                 :            :         elem_id = H5Gopen( file_ptr->hdf_handle, SET_GROUP );
    1314                 :            : #endif
    1315         [ -  + ]:        106 :         if( elem_id < 0 ) mhdf_setFail( status, "Could not open set group." );
    1316                 :            :     }
    1317                 :            :     else
    1318                 :            :     {
    1319                 :         92 :         elem_id = mhdf_elem_group_from_handle( file_ptr, type_handle, status );
    1320                 :            :     }
    1321         [ -  + ]:        284 :     if( elem_id < 0 ) return -1;
    1322                 :            : 
    1323                 :        284 :     dir_len = strlen( DENSE_TAG_SUBGROUP );
    1324                 :        284 :     name_len = mhdf_name_to_path( tag_name, NULL, 0 );
    1325                 :        284 :     path_len = dir_len + name_len + 1;
    1326                 :        284 :     path = (char*)mhdf_malloc( path_len, status );
    1327         [ -  + ]:        284 :     if( NULL == path )
    1328                 :            :     {
    1329                 :          0 :         H5Gclose( elem_id );
    1330                 :          0 :         return -1;
    1331                 :            :     }
    1332                 :        284 :     strcpy( path, DENSE_TAG_SUBGROUP );
    1333                 :        284 :     mhdf_name_to_path( tag_name, path + dir_len, name_len + 1 );
    1334                 :            : 
    1335                 :        284 :     data_id = mhdf_open_table( elem_id, path, 1, &size, status );
    1336                 :        284 :     free( path );
    1337                 :        284 :     H5Gclose( elem_id );
    1338                 :        284 :     *num_values_out = (long)size;
    1339                 :            : 
    1340         [ +  - ]:        284 :     if( data_id >= 0 ) mhdf_setOkay( status );
    1341                 :            : 
    1342                 :            :     API_END_H( 1 );
    1343                 :        284 :     return data_id;
    1344                 :            : }
    1345                 :            : 
    1346                 :         95 : void mhdf_createSparseTagData( mhdf_FileHandle file_handle, const char* tag_name, long num_values,
    1347                 :            :                                hid_t handles_out[ 2 ], mhdf_Status* status )
    1348                 :            : {
    1349                 :            :     hid_t   tag_id, index_id, data_id, type_id, id_type;
    1350                 :         95 :     hsize_t count = (hsize_t)num_values;
    1351                 :            :     API_BEGIN;
    1352                 :            : 
    1353                 :         95 :     tag_id = get_tag( file_handle, tag_name, &id_type, status );
    1354         [ -  + ]:         95 :     if( tag_id < 0 ) return;
    1355                 :            : 
    1356                 :            : #if defined( H5Topen_vers ) && H5Topen_vers > 1
    1357                 :         95 :     type_id = H5Topen2( tag_id, TAG_TYPE_NAME, H5P_DEFAULT );
    1358                 :            : #else
    1359                 :            :     type_id = H5Topen( tag_id, TAG_TYPE_NAME );
    1360                 :            : #endif
    1361         [ -  + ]:         95 :     if( type_id < 0 )
    1362                 :            :     {
    1363                 :          0 :         H5Gclose( tag_id );
    1364                 :          0 :         mhdf_setFail( status, "Failed to get type object for tag \"%s\".", tag_name );
    1365                 :          0 :         return;
    1366                 :            :     }
    1367                 :            : 
    1368                 :         95 :     index_id = mhdf_create_table( tag_id, SPARSE_ENTITY_NAME, id_type, 1, &count, status );
    1369         [ -  + ]:         95 :     if( index_id < 0 )
    1370                 :            :     {
    1371                 :          0 :         H5Gclose( tag_id );
    1372                 :          0 :         H5Tclose( type_id );
    1373                 :          0 :         return;
    1374                 :            :     }
    1375                 :            : 
    1376                 :         95 :     data_id = mhdf_create_table( tag_id, SPARSE_VALUES_NAME, type_id, 1, &count, status );
    1377                 :         95 :     H5Tclose( type_id );
    1378                 :         95 :     H5Gclose( tag_id );
    1379         [ -  + ]:         95 :     if( data_id < 0 )
    1380                 :            :     {
    1381                 :          0 :         H5Dclose( index_id );
    1382                 :          0 :         return;
    1383                 :            :     }
    1384                 :            : 
    1385                 :         95 :     handles_out[ 0 ] = index_id;
    1386                 :         95 :     handles_out[ 1 ] = data_id;
    1387                 :         95 :     mhdf_setOkay( status );
    1388                 :            :     API_END_H( 2 );
    1389                 :            : }
    1390                 :            : 
    1391                 :         23 : void mhdf_createVarLenTagData( mhdf_FileHandle file_handle, const char* tag_name, long num_entities, long num_values,
    1392                 :            :                                hid_t handles_out[ 3 ], mhdf_Status* status )
    1393                 :            : {
    1394                 :            :     hid_t   tag_id, index_id, data_id, type_id, offset_id, id_type;
    1395                 :         23 :     hsize_t count = (hsize_t)num_entities;
    1396                 :            :     API_BEGIN;
    1397                 :            : 
    1398                 :         23 :     tag_id = get_tag( file_handle, tag_name, &id_type, status );
    1399         [ -  + ]:         23 :     if( tag_id < 0 ) return;
    1400                 :            : 
    1401                 :            : #if defined( H5Topen_vers ) && H5Topen_vers > 1
    1402                 :         23 :     type_id = H5Topen2( tag_id, TAG_TYPE_NAME, H5P_DEFAULT );
    1403                 :            : #else
    1404                 :            :     type_id = H5Topen( tag_id, TAG_TYPE_NAME );
    1405                 :            : #endif
    1406         [ -  + ]:         23 :     if( type_id < 0 )
    1407                 :            :     {
    1408                 :          0 :         H5Gclose( tag_id );
    1409                 :          0 :         mhdf_setFail( status, "Failed to get type object for tag \"%s\".", tag_name );
    1410                 :          0 :         return;
    1411                 :            :     }
    1412                 :            : 
    1413                 :         23 :     index_id = mhdf_create_table( tag_id, SPARSE_ENTITY_NAME, id_type, 1, &count, status );
    1414         [ -  + ]:         23 :     if( index_id < 0 )
    1415                 :            :     {
    1416                 :          0 :         H5Gclose( tag_id );
    1417                 :          0 :         H5Tclose( type_id );
    1418                 :          0 :         return;
    1419                 :            :     }
    1420                 :            : 
    1421                 :         23 :     offset_id = mhdf_create_table( tag_id, TAG_VAR_INDICES, MHDF_INDEX_TYPE, 1, &count, status );
    1422         [ -  + ]:         23 :     if( index_id < 0 )
    1423                 :            :     {
    1424                 :          0 :         H5Dclose( offset_id );
    1425                 :          0 :         H5Gclose( tag_id );
    1426                 :          0 :         H5Tclose( type_id );
    1427                 :          0 :         return;
    1428                 :            :     }
    1429                 :            : 
    1430                 :         23 :     count = (hsize_t)num_values;
    1431                 :         23 :     data_id = mhdf_create_table( tag_id, SPARSE_VALUES_NAME, type_id, 1, &count, status );
    1432                 :         23 :     H5Tclose( type_id );
    1433                 :         23 :     H5Gclose( tag_id );
    1434         [ -  + ]:         23 :     if( data_id < 0 )
    1435                 :            :     {
    1436                 :          0 :         H5Dclose( offset_id );
    1437                 :          0 :         H5Dclose( index_id );
    1438                 :          0 :         return;
    1439                 :            :     }
    1440                 :            : 
    1441                 :         23 :     handles_out[ 0 ] = index_id;
    1442                 :         23 :     handles_out[ 1 ] = data_id;
    1443                 :         23 :     handles_out[ 2 ] = offset_id;
    1444                 :         23 :     mhdf_setOkay( status );
    1445                 :            :     API_END_H( 3 );
    1446                 :            : }
    1447                 :            : 
    1448                 :        361 : void mhdf_openSparseTagData( mhdf_FileHandle file_handle, const char* tag_name, long* num_entity_out,
    1449                 :            :                              long* num_values_out, hid_t handles_out[ 3 ], mhdf_Status* status )
    1450                 :            : {
    1451                 :        361 :     hid_t    tag_id, index_id, data_id, offset_id = -1;
    1452                 :            :     hsize_t  num_ent, data_size, num_data;
    1453                 :            :     int      rval;
    1454                 :            :     unsigned idx;
    1455                 :            :     API_BEGIN;
    1456                 :            : 
    1457                 :        361 :     tag_id = get_tag( file_handle, tag_name, NULL, status );
    1458         [ -  + ]:        361 :     if( tag_id < 0 ) return;
    1459                 :            : 
    1460                 :        361 :     index_id = mhdf_open_table( tag_id, SPARSE_ENTITY_NAME, 1, &num_ent, status );
    1461         [ -  + ]:        361 :     if( index_id < 0 )
    1462                 :            :     {
    1463                 :          0 :         H5Gclose( tag_id );
    1464                 :          0 :         return;
    1465                 :            :     }
    1466                 :            : 
    1467                 :        361 :     data_id = mhdf_open_table( tag_id, SPARSE_VALUES_NAME, 1, &data_size, status );
    1468         [ -  + ]:        361 :     if( data_id < 0 )
    1469                 :            :     {
    1470                 :          0 :         H5Gclose( tag_id );
    1471                 :          0 :         H5Dclose( index_id );
    1472                 :          0 :         return;
    1473                 :            :     }
    1474                 :            : 
    1475                 :            :     /* check if tag is variable-lentgth */
    1476                 :        361 :     rval = mhdf_find_attribute( tag_id, TAG_VARLEN_ATTRIB, &idx, status );
    1477         [ -  + ]:        361 :     if( rval < 0 )
    1478                 :            :     {
    1479                 :          0 :         H5Gclose( tag_id );
    1480                 :          0 :         H5Dclose( index_id );
    1481                 :          0 :         H5Dclose( data_id );
    1482                 :          0 :         return;
    1483                 :            :     }
    1484                 :            : 
    1485                 :            :     /* If variable length... */
    1486         [ +  + ]:        361 :     if( rval )
    1487                 :            :     {
    1488                 :         96 :         offset_id = mhdf_open_table( tag_id, TAG_VAR_INDICES, 1, &num_data, status );
    1489         [ -  + ]:         96 :         if( offset_id < 0 )
    1490                 :            :         {
    1491                 :          0 :             H5Gclose( tag_id );
    1492                 :          0 :             H5Dclose( index_id );
    1493                 :          0 :             H5Dclose( data_id );
    1494                 :          0 :             return;
    1495                 :            :         }
    1496                 :            :     }
    1497                 :            :     /* Otherwise the number of values is the same as the size of the data table */
    1498                 :            :     else
    1499                 :            :     {
    1500                 :        265 :         num_data = data_size;
    1501                 :            :     }
    1502                 :            : 
    1503                 :        361 :     H5Gclose( tag_id );
    1504         [ -  + ]:        361 :     if( num_ent != num_data )
    1505                 :            :     {
    1506                 :          0 :         mhdf_setFail( status, "Data length mismatch for sparse tag data -- invalid file." );
    1507         [ #  # ]:          0 :         if( offset_id >= 0 ) H5Dclose( offset_id );
    1508                 :          0 :         H5Dclose( index_id );
    1509                 :          0 :         H5Dclose( data_id );
    1510                 :          0 :         return;
    1511                 :            :     }
    1512                 :        361 :     *num_entity_out = (long)num_ent;
    1513         [ +  - ]:        361 :     if( num_values_out ) *num_values_out = (long)data_size;
    1514                 :            : 
    1515                 :        361 :     handles_out[ 0 ] = index_id;
    1516                 :        361 :     handles_out[ 1 ] = data_id;
    1517         [ +  + ]:        361 :     if( offset_id >= 0 ) handles_out[ 2 ] = offset_id;
    1518                 :        361 :     mhdf_setOkay( status );
    1519                 :            :     API_END_H( 2 );
    1520                 :            : }
    1521                 :            : 
    1522                 :          0 : void mhdf_writeSparseTagEntities( hid_t table_id, long offset, long count, hid_t int_type, const void* id_list,
    1523                 :            :                                   mhdf_Status* status )
    1524                 :            : {
    1525                 :            :     API_BEGIN;
    1526                 :          0 :     mhdf_write_data( table_id, offset, count, int_type, id_list, H5P_DEFAULT, status );
    1527                 :            :     API_END;
    1528                 :          0 : }
    1529                 :        118 : void mhdf_writeSparseTagEntitiesWithOpt( hid_t table_id, long offset, long count, hid_t int_type, const void* id_list,
    1530                 :            :                                          hid_t io_prop, mhdf_Status* status )
    1531                 :            : {
    1532                 :            :     API_BEGIN;
    1533                 :        118 :     mhdf_write_data( table_id, offset, count, int_type, id_list, io_prop, status );
    1534                 :            :     API_END;
    1535                 :        118 : }
    1536                 :            : 
    1537                 :          0 : void mhdf_writeTagValues( hid_t table_id, long offset, long count, hid_t tag_type, const void* tag_data,
    1538                 :            :                           mhdf_Status* status )
    1539                 :            : {
    1540                 :          0 :     mhdf_writeTagValuesWithOpt( table_id, offset, count, tag_type, tag_data, H5P_DEFAULT, status );
    1541                 :          0 : }
    1542                 :            : 
    1543                 :        224 : void mhdf_writeTagValuesWithOpt( hid_t table_id, long offset, long count, hid_t tag_type, const void* tag_data,
    1544                 :            :                                  hid_t io_prop, mhdf_Status* status )
    1545                 :            : {
    1546                 :            :     API_BEGIN;
    1547                 :        224 :     mhdf_write_data( table_id, offset, count, tag_type, tag_data, io_prop, status );
    1548                 :            :     API_END;
    1549                 :        224 : }
    1550                 :            : 
    1551                 :          0 : void mhdf_writeSparseTagIndices( hid_t table_id, long offset, long count, hid_t int_type, const void* indices,
    1552                 :            :                                  mhdf_Status* status )
    1553                 :            : {
    1554                 :            :     API_BEGIN;
    1555                 :          0 :     mhdf_write_data( table_id, offset, count, int_type, indices, H5P_DEFAULT, status );
    1556                 :            :     API_END;
    1557                 :          0 : }
    1558                 :         23 : void mhdf_writeSparseTagIndicesWithOpt( hid_t table_id, long offset, long count, hid_t int_type, const void* indices,
    1559                 :            :                                         hid_t io_prop, mhdf_Status* status )
    1560                 :            : {
    1561                 :            :     API_BEGIN;
    1562                 :         23 :     mhdf_write_data( table_id, offset, count, int_type, indices, io_prop, status );
    1563                 :            :     API_END;
    1564                 :         23 : }
    1565                 :            : 
    1566                 :          0 : void mhdf_readSparseTagEntities( hid_t table_id, long offset, long count, hid_t int_type, void* id_list,
    1567                 :            :                                  mhdf_Status* status )
    1568                 :            : {
    1569                 :            :     API_BEGIN;
    1570                 :          0 :     mhdf_read_data( table_id, offset, count, int_type, id_list, H5P_DEFAULT, status );
    1571                 :            :     API_END;
    1572                 :          0 : }
    1573                 :          0 : void mhdf_readSparseTagEntitiesWithOpt( hid_t table_id, long offset, long count, hid_t int_type, void* id_list,
    1574                 :            :                                         hid_t io_prop, mhdf_Status* status )
    1575                 :            : {
    1576                 :            :     API_BEGIN;
    1577                 :          0 :     mhdf_read_data( table_id, offset, count, int_type, id_list, io_prop, status );
    1578                 :            :     API_END;
    1579                 :          0 : }
    1580                 :            : 
    1581                 :          0 : void mhdf_readTagValues( hid_t table_id, long offset, long count, hid_t tag_type, void* tag_data, mhdf_Status* status )
    1582                 :            : {
    1583                 :          0 :     mhdf_readTagValuesWithOpt( table_id, offset, count, tag_type, tag_data, H5P_DEFAULT, status );
    1584                 :          0 : }
    1585                 :          0 : void mhdf_readTagValuesWithOpt( hid_t table_id, long offset, long count, hid_t tag_type, void* tag_data, hid_t io_prop,
    1586                 :            :                                 mhdf_Status* status )
    1587                 :            : {
    1588                 :            :     API_BEGIN;
    1589                 :          0 :     mhdf_read_data( table_id, offset, count, tag_type, tag_data, io_prop, status );
    1590                 :            :     API_END;
    1591                 :          0 : }
    1592                 :            : 
    1593                 :          0 : void mhdf_readSparseTagIndices( hid_t table_id, long offset, long count, hid_t int_type, void* indices,
    1594                 :            :                                 mhdf_Status* status )
    1595                 :            : {
    1596                 :            :     API_BEGIN;
    1597                 :          0 :     mhdf_read_data( table_id, offset, count, int_type, indices, H5P_DEFAULT, status );
    1598                 :            :     API_END;
    1599                 :          0 : }
    1600                 :          0 : void mhdf_readSparseTagIndicesWithOpt( hid_t table_id, long offset, long count, hid_t int_type, void* indices,
    1601                 :            :                                        hid_t io_prop, mhdf_Status* status )
    1602                 :            : {
    1603                 :            :     API_BEGIN;
    1604                 :          0 :     mhdf_read_data( table_id, offset, count, int_type, indices, io_prop, status );
    1605                 :            :     API_END;
    1606                 :          0 : }

Generated by: LCOV version 1.11