LCOV - code coverage report
Current view: top level - frmts/hdf5 - gh5_convenience.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 187 268 69.8 %
Date: 2025-12-17 16:19:51 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  Hierarchical Data Format Release 5 (HDF5)
       4             :  * Purpose:  HDF5 convenience functions.
       5             :  * Author:   Frank Warmerdam <warmerdam@pobox.com>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2009, Frank Warmerdam <warmerdam@pobox.com>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include "cpl_float.h"
      14             : #include "gh5_convenience.h"
      15             : 
      16             : #include <limits>
      17             : 
      18             : /************************************************************************/
      19             : /*                    GH5_FetchAttribute(CPLString)                     */
      20             : /************************************************************************/
      21             : 
      22          85 : bool GH5_FetchAttribute(hid_t loc_id, const char *pszAttrName,
      23             :                         CPLString &osResult, bool bReportError)
      24             : 
      25             : {
      26          85 :     if (!bReportError && H5Aexists(loc_id, pszAttrName) <= 0)
      27             :     {
      28           0 :         return false;
      29             :     }
      30             : 
      31          85 :     hid_t hAttr = H5Aopen_name(loc_id, pszAttrName);
      32             : 
      33          85 :     osResult.clear();
      34             : 
      35          85 :     if (hAttr < 0)
      36             :     {
      37           0 :         if (bReportError)
      38           0 :             CPLError(CE_Failure, CPLE_AppDefined,
      39             :                      "Attempt to read attribute %s failed, not found.",
      40             :                      pszAttrName);
      41           0 :         return false;
      42             :     }
      43             : 
      44          85 :     const hid_t hAttrSpace = H5Aget_space(hAttr);
      45          85 :     hsize_t anSize[H5S_MAX_RANK] = {};
      46             :     const unsigned int nAttrDims =
      47          85 :         H5Sget_simple_extent_dims(hAttrSpace, anSize, nullptr);
      48          85 :     if (nAttrDims != 0 && !(nAttrDims == 1 && anSize[0] == 1))
      49             :     {
      50           0 :         H5Sclose(hAttrSpace);
      51           0 :         H5Aclose(hAttr);
      52           0 :         return false;
      53             :     }
      54             : 
      55          85 :     hid_t hAttrTypeID = H5Aget_type(hAttr);
      56          85 :     hid_t hAttrNativeType = H5Tget_native_type(hAttrTypeID, H5T_DIR_DEFAULT);
      57             : 
      58          85 :     bool retVal = false;
      59          85 :     if (H5Tget_class(hAttrNativeType) == H5T_STRING)
      60             :     {
      61          85 :         if (H5Tis_variable_str(hAttrNativeType))
      62             :         {
      63          14 :             char *aszBuffer[1] = {nullptr};
      64          14 :             H5Aread(hAttr, hAttrNativeType, aszBuffer);
      65             : 
      66          14 :             if (aszBuffer[0])
      67          14 :                 osResult = aszBuffer[0];
      68             : 
      69          14 :             H5Dvlen_reclaim(hAttrNativeType, hAttrSpace, H5P_DEFAULT,
      70             :                             aszBuffer);
      71             :         }
      72             :         else
      73             :         {
      74          71 :             const size_t nAttrSize = H5Tget_size(hAttrTypeID);
      75          71 :             char *pachBuffer = static_cast<char *>(CPLCalloc(nAttrSize + 1, 1));
      76          71 :             H5Aread(hAttr, hAttrNativeType, pachBuffer);
      77             : 
      78          71 :             osResult = pachBuffer;
      79          71 :             CPLFree(pachBuffer);
      80             :         }
      81             : 
      82          85 :         retVal = true;
      83             :     }
      84             :     else
      85             :     {
      86           0 :         if (bReportError)
      87           0 :             CPLError(
      88             :                 CE_Failure, CPLE_AppDefined,
      89             :                 "Attribute %s of unsupported type for conversion to string.",
      90             :                 pszAttrName);
      91             : 
      92           0 :         retVal = false;
      93             :     }
      94             : 
      95          85 :     H5Sclose(hAttrSpace);
      96          85 :     H5Tclose(hAttrNativeType);
      97          85 :     H5Tclose(hAttrTypeID);
      98          85 :     H5Aclose(hAttr);
      99          85 :     return retVal;
     100             : }
     101             : 
     102             : /************************************************************************/
     103             : /*                      GH5_FetchAttribute(double)                      */
     104             : /************************************************************************/
     105             : 
     106        1061 : bool GH5_FetchAttribute(hid_t loc_id, const char *pszAttrName, double &dfResult,
     107             :                         bool bReportError)
     108             : 
     109             : {
     110        1061 :     if (!bReportError && H5Aexists(loc_id, pszAttrName) <= 0)
     111             :     {
     112         444 :         return false;
     113             :     }
     114             : 
     115         617 :     const hid_t hAttr = H5Aopen_name(loc_id, pszAttrName);
     116             : 
     117         617 :     dfResult = 0.0;
     118         617 :     if (hAttr < 0)
     119             :     {
     120           0 :         if (bReportError)
     121           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     122             :                      "Attempt to read attribute %s failed, not found.",
     123             :                      pszAttrName);
     124           0 :         return false;
     125             :     }
     126             : 
     127         617 :     hid_t hAttrTypeID = H5Aget_type(hAttr);
     128         617 :     hid_t hAttrNativeType = H5Tget_native_type(hAttrTypeID, H5T_DIR_DEFAULT);
     129             : 
     130             :     // Confirm that we have a single element value.
     131         617 :     hid_t hAttrSpace = H5Aget_space(hAttr);
     132         617 :     hsize_t anSize[H5S_MAX_RANK] = {};
     133         617 :     int nAttrDims = H5Sget_simple_extent_dims(hAttrSpace, anSize, nullptr);
     134             : 
     135         617 :     int i, nAttrElements = 1;
     136             : 
     137         628 :     for (i = 0; i < nAttrDims; i++)
     138             :     {
     139          11 :         nAttrElements *= static_cast<int>(anSize[i]);
     140             :     }
     141             : 
     142         617 :     if (nAttrElements != 1)
     143             :     {
     144           0 :         if (bReportError)
     145           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     146             :                      "Attempt to read attribute %s failed, count=%d, not 1.",
     147             :                      pszAttrName, nAttrElements);
     148             : 
     149           0 :         H5Sclose(hAttrSpace);
     150           0 :         H5Tclose(hAttrNativeType);
     151           0 :         H5Tclose(hAttrTypeID);
     152           0 :         H5Aclose(hAttr);
     153           0 :         return false;
     154             :     }
     155             : 
     156             :     // Read the value.
     157         617 :     void *buf = CPLMalloc(H5Tget_size(hAttrNativeType));
     158         617 :     H5Aread(hAttr, hAttrNativeType, buf);
     159             : 
     160             :     // Translate to double.
     161         617 :     if (H5Tequal(H5T_NATIVE_CHAR, hAttrNativeType))
     162           0 :         dfResult = *(static_cast<char *>(buf));
     163         617 :     else if (H5Tequal(H5T_NATIVE_SCHAR, hAttrNativeType))
     164           0 :         dfResult = *(static_cast<signed char *>(buf));
     165         617 :     else if (H5Tequal(H5T_NATIVE_UCHAR, hAttrNativeType))
     166           1 :         dfResult = *(static_cast<unsigned char *>(buf));
     167         616 :     else if (H5Tequal(H5T_NATIVE_SHORT, hAttrNativeType))
     168           0 :         dfResult = *(static_cast<short *>(buf));
     169         616 :     else if (H5Tequal(H5T_NATIVE_USHORT, hAttrNativeType))
     170           2 :         dfResult = *(static_cast<unsigned short *>(buf));
     171         614 :     else if (H5Tequal(H5T_NATIVE_INT, hAttrNativeType))
     172           2 :         dfResult = *(static_cast<int *>(buf));
     173         612 :     else if (H5Tequal(H5T_NATIVE_UINT, hAttrNativeType))
     174           5 :         dfResult = *(static_cast<unsigned int *>(buf));
     175         607 :     else if (H5Tequal(H5T_NATIVE_INT64, hAttrNativeType))
     176             :     {
     177           1 :         const auto nVal = *static_cast<int64_t *>(buf);
     178           1 :         dfResult = static_cast<double>(nVal);
     179           1 :         if (nVal != static_cast<int64_t>(dfResult))
     180             :         {
     181           0 :             CPLDebug("HDF5",
     182             :                      "Loss of accuracy when reading attribute %s. "
     183             :                      "Value " CPL_FRMT_GIB " will be read as %.17g",
     184             :                      pszAttrName, static_cast<GIntBig>(nVal), dfResult);
     185             :         }
     186             :     }
     187         606 :     else if (H5Tequal(H5T_NATIVE_UINT64, hAttrNativeType))
     188             :     {
     189           1 :         const auto nVal = *static_cast<uint64_t *>(buf);
     190           1 :         dfResult = static_cast<double>(nVal);
     191           1 :         if (nVal != static_cast<uint64_t>(dfResult))
     192             :         {
     193           0 :             CPLDebug("HDF5",
     194             :                      "Loss of accuracy when reading attribute %s. "
     195             :                      "Value " CPL_FRMT_GUIB " will be read as %.17g",
     196             :                      pszAttrName, static_cast<GUIntBig>(nVal), dfResult);
     197             :         }
     198             :     }
     199             : #ifdef HDF5_HAVE_FLOAT16
     200             :     else if (H5Tequal(H5T_NATIVE_FLOAT16, hAttrNativeType))
     201             :     {
     202             :         const uint16_t nVal16 = *(static_cast<uint16_t *>(buf));
     203             :         const uint32_t nVal32 = CPLHalfToFloat(nVal16);
     204             :         float fVal;
     205             :         memcpy(&fVal, &nVal32, sizeof(fVal));
     206             :         dfResult = fVal;
     207             :     }
     208             : #endif
     209         605 :     else if (H5Tequal(H5T_NATIVE_FLOAT, hAttrNativeType))
     210         551 :         dfResult = *(static_cast<float *>(buf));
     211          54 :     else if (H5Tequal(H5T_NATIVE_DOUBLE, hAttrNativeType))
     212          54 :         dfResult = *(static_cast<double *>(buf));
     213             :     else
     214             :     {
     215           0 :         if (bReportError)
     216           0 :             CPLError(
     217             :                 CE_Failure, CPLE_AppDefined,
     218             :                 "Attribute %s of unsupported type for conversion to double.",
     219             :                 pszAttrName);
     220           0 :         CPLFree(buf);
     221             : 
     222           0 :         H5Sclose(hAttrSpace);
     223           0 :         H5Tclose(hAttrNativeType);
     224           0 :         H5Tclose(hAttrTypeID);
     225           0 :         H5Aclose(hAttr);
     226             : 
     227           0 :         return false;
     228             :     }
     229             : 
     230         617 :     CPLFree(buf);
     231             : 
     232         617 :     H5Sclose(hAttrSpace);
     233         617 :     H5Tclose(hAttrNativeType);
     234         617 :     H5Tclose(hAttrTypeID);
     235         617 :     H5Aclose(hAttr);
     236         617 :     return true;
     237             : }
     238             : 
     239             : /************************************************************************/
     240             : /*                          GH5_GetDataType()                           */
     241             : /*                                                                      */
     242             : /*      Transform HDF5 datatype to GDAL datatype                        */
     243             : /************************************************************************/
     244         145 : GDALDataType GH5_GetDataType(hid_t TypeID)
     245             : {
     246         145 :     if (H5Tequal(H5T_NATIVE_CHAR, TypeID))
     247           0 :         return GDT_UInt8;
     248         145 :     else if (H5Tequal(H5T_NATIVE_SCHAR, TypeID))
     249           0 :         return GDT_Int8;
     250         145 :     else if (H5Tequal(H5T_NATIVE_UCHAR, TypeID))
     251           0 :         return GDT_UInt8;
     252         145 :     else if (H5Tequal(H5T_NATIVE_SHORT, TypeID))
     253           0 :         return GDT_Int16;
     254         145 :     else if (H5Tequal(H5T_NATIVE_USHORT, TypeID))
     255           0 :         return GDT_UInt16;
     256         145 :     else if (H5Tequal(H5T_NATIVE_INT, TypeID))
     257           0 :         return GDT_Int32;
     258         145 :     else if (H5Tequal(H5T_NATIVE_UINT, TypeID))
     259           0 :         return GDT_UInt32;
     260         145 :     else if (H5Tequal(H5T_NATIVE_LONG, TypeID))
     261             :     {
     262             : #if SIZEOF_UNSIGNED_LONG == 4
     263             :         return GDT_Int32;
     264             : #else
     265           0 :         return GDT_Unknown;
     266             : #endif
     267             :     }
     268         145 :     else if (H5Tequal(H5T_NATIVE_ULONG, TypeID))
     269             :     {
     270             : #if SIZEOF_UNSIGNED_LONG == 4
     271             :         return GDT_UInt32;
     272             : #else
     273           0 :         return GDT_Unknown;
     274             : #endif
     275             :     }
     276         145 :     else if (H5Tequal(H5T_NATIVE_FLOAT, TypeID))
     277         145 :         return GDT_Float32;
     278           0 :     else if (H5Tequal(H5T_NATIVE_DOUBLE, TypeID))
     279           0 :         return GDT_Float64;
     280             : #ifdef notdef
     281             :     else if (H5Tequal(H5T_NATIVE_LLONG, TypeID))
     282             :         return GDT_Unknown;
     283             :     else if (H5Tequal(H5T_NATIVE_ULLONG, TypeID))
     284             :         return GDT_Unknown;
     285             : #endif
     286             : 
     287           0 :     return GDT_Unknown;
     288             : }
     289             : 
     290             : /************************************************************************/
     291             : /*                        GH5_CreateAttribute()                         */
     292             : /************************************************************************/
     293             : 
     294        3733 : bool GH5_CreateAttribute(hid_t loc_id, const char *pszAttrName, hid_t TypeID,
     295             :                          unsigned nMaxLen)
     296             : {
     297        3733 :     hid_t hDataSpace = H5Screate(H5S_SCALAR);
     298        3733 :     if (hDataSpace < 0)
     299           0 :         return false;
     300             : 
     301        3733 :     hid_t hDataType = H5Tcopy(TypeID);
     302        3733 :     if (hDataType < 0)
     303             :     {
     304           0 :         H5Sclose(hDataSpace);
     305           0 :         return false;
     306             :     }
     307             : 
     308        3733 :     if (TypeID == H5T_C_S1)
     309             :     {
     310         683 :         if (nMaxLen == VARIABLE_LENGTH)
     311             :         {
     312         663 :             H5Tset_size(hDataType, H5T_VARIABLE);
     313         663 :             H5Tset_strpad(hDataType, H5T_STR_NULLTERM);
     314             :         }
     315          20 :         else if (H5Tset_size(hDataType, nMaxLen) < 0)
     316             :         {
     317           0 :             H5Tclose(hDataType);
     318           0 :             H5Sclose(hDataSpace);
     319           0 :             return false;
     320             :         }
     321             :     }
     322             : 
     323             :     hid_t hAttr =
     324        3733 :         H5Acreate(loc_id, pszAttrName, hDataType, hDataSpace, H5P_DEFAULT);
     325        3733 :     if (hAttr < 0)
     326             :     {
     327           0 :         H5Sclose(hDataSpace);
     328           0 :         H5Tclose(hDataType);
     329           0 :         return false;
     330             :     }
     331             : 
     332        3733 :     H5Aclose(hAttr);
     333        3733 :     H5Sclose(hDataSpace);
     334        3733 :     H5Tclose(hDataType);
     335             : 
     336        3733 :     return true;
     337             : }
     338             : 
     339             : /************************************************************************/
     340             : /*                        GH5_WriteAttribute()                          */
     341             : /************************************************************************/
     342             : 
     343         683 : bool GH5_WriteAttribute(hid_t loc_id, const char *pszAttrName,
     344             :                         const char *pszValue)
     345             : {
     346             : 
     347         683 :     hid_t hAttr = H5Aopen_name(loc_id, pszAttrName);
     348         683 :     if (hAttr < 0)
     349           0 :         return false;
     350             : 
     351         683 :     hid_t hDataType = H5Aget_type(hAttr);
     352         683 :     if (hDataType < 0)
     353             :     {
     354           0 :         H5Aclose(hAttr);
     355           0 :         return false;
     356             :     }
     357             : 
     358         683 :     hid_t hAttrNativeType = H5Tget_native_type(hDataType, H5T_DIR_DEFAULT);
     359         683 :     bool bSuccess = false;
     360         683 :     if (H5Tget_class(hAttrNativeType) == H5T_STRING)
     361             :     {
     362         683 :         if (H5Tis_variable_str(hAttrNativeType) > 0)
     363         663 :             bSuccess = H5Awrite(hAttr, hDataType, &pszValue) >= 0;
     364             :         else
     365          20 :             bSuccess = H5Awrite(hAttr, hDataType, pszValue) >= 0;
     366             :     }
     367             :     else
     368             :     {
     369           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     370             :                  "Attribute %s is not of type string", pszAttrName);
     371             :     }
     372             : 
     373         683 :     H5Tclose(hAttrNativeType);
     374         683 :     H5Tclose(hDataType);
     375         683 :     H5Aclose(hAttr);
     376             : 
     377         683 :     return bSuccess;
     378             : }
     379             : 
     380             : /************************************************************************/
     381             : /*                        GH5_WriteAttribute()                          */
     382             : /************************************************************************/
     383             : 
     384        1623 : bool GH5_WriteAttribute(hid_t loc_id, const char *pszAttrName, double dfValue)
     385             : {
     386             : 
     387        1623 :     hid_t hAttr = H5Aopen_name(loc_id, pszAttrName);
     388        1623 :     if (hAttr < 0)
     389           0 :         return false;
     390             : 
     391        1623 :     hid_t hDataType = H5Aget_type(hAttr);
     392        1623 :     if (hDataType < 0)
     393             :     {
     394           0 :         H5Aclose(hAttr);
     395           0 :         return false;
     396             :     }
     397             : 
     398        1623 :     hid_t hAttrNativeType = H5Tget_native_type(hDataType, H5T_DIR_DEFAULT);
     399        1623 :     bool bSuccess = false;
     400        1623 :     if (H5Tequal(hAttrNativeType, H5T_NATIVE_FLOAT))
     401             :     {
     402        1087 :         float fVal = static_cast<float>(dfValue);
     403        1087 :         bSuccess = H5Awrite(hAttr, hAttrNativeType, &fVal) >= 0;
     404             :     }
     405         536 :     else if (H5Tequal(hAttrNativeType, H5T_NATIVE_DOUBLE))
     406             :     {
     407         536 :         bSuccess = H5Awrite(hAttr, hAttrNativeType, &dfValue) >= 0;
     408             :     }
     409             :     else
     410             :     {
     411           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     412             :                  "Attribute %s is not of type float or double", pszAttrName);
     413             :     }
     414             : 
     415        1623 :     H5Tclose(hAttrNativeType);
     416        1623 :     H5Aclose(hAttr);
     417        1623 :     H5Tclose(hDataType);
     418             : 
     419        1623 :     return bSuccess;
     420             : }
     421             : 
     422             : /************************************************************************/
     423             : /*                        GH5_WriteAttribute()                          */
     424             : /************************************************************************/
     425             : 
     426        1213 : bool GH5_WriteAttribute(hid_t loc_id, const char *pszAttrName, int nValue)
     427             : {
     428             : 
     429        1213 :     hid_t hAttr = H5Aopen_name(loc_id, pszAttrName);
     430        1213 :     if (hAttr < 0)
     431           0 :         return false;
     432             : 
     433        1213 :     hid_t hDataType = H5Aget_type(hAttr);
     434        1213 :     if (hDataType < 0)
     435             :     {
     436           0 :         H5Aclose(hAttr);
     437           0 :         return false;
     438             :     }
     439             : 
     440        1213 :     hid_t hEnumType = -1;
     441        1213 :     if (H5Tget_class(hDataType) == H5T_ENUM)
     442             :     {
     443         654 :         hEnumType = hDataType;
     444         654 :         hDataType = H5Tget_super(hDataType);
     445             :     }
     446             : 
     447        1213 :     hid_t hAttrNativeType = H5Tget_native_type(hDataType, H5T_DIR_DEFAULT);
     448        1213 :     bool bSuccess = false;
     449        1213 :     if (hEnumType < 0 && H5Tequal(hAttrNativeType, H5T_NATIVE_INT))
     450             :     {
     451         297 :         bSuccess = H5Awrite(hAttr, hAttrNativeType, &nValue) >= 0;
     452             :     }
     453         916 :     else if (hEnumType < 0 && H5Tequal(hAttrNativeType, H5T_NATIVE_UINT))
     454             :     {
     455         126 :         if (nValue < 0)
     456             :         {
     457           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     458             :                      "Attribute %s has value %d which is negative but the type "
     459             :                      "is uint",
     460             :                      pszAttrName, nValue);
     461             :         }
     462             :         else
     463             :         {
     464         126 :             bSuccess = H5Awrite(hAttr, hAttrNativeType, &nValue) >= 0;
     465             :         }
     466             :     }
     467         790 :     else if (hEnumType < 0 && H5Tequal(hAttrNativeType, H5T_NATIVE_UINT8))
     468             :     {
     469         232 :         if (nValue < 0 ||
     470         116 :             nValue > static_cast<int>(std::numeric_limits<uint8_t>::max()))
     471             :         {
     472           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     473             :                      "Attribute %s has value %d which is not in the range of a "
     474             :                      "uint8",
     475             :                      pszAttrName, nValue);
     476             :         }
     477             :         else
     478             :         {
     479         116 :             uint8_t nUint8 = static_cast<uint8_t>(nValue);
     480         116 :             bSuccess = H5Awrite(hAttr, hAttrNativeType, &nUint8) >= 0;
     481             :         }
     482             :     }
     483         674 :     else if (hEnumType < 0 && H5Tequal(hAttrNativeType, H5T_NATIVE_UINT16))
     484             :     {
     485          40 :         if (nValue < 0 ||
     486          20 :             nValue >= static_cast<int>(std::numeric_limits<uint16_t>::max()))
     487             :         {
     488           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     489             :                      "Attribute %s has value %d which is not in the range of a "
     490             :                      "uint16",
     491             :                      pszAttrName, nValue);
     492             :         }
     493             :         else
     494             :         {
     495          20 :             uint16_t nUint16 = static_cast<uint16_t>(nValue);
     496          20 :             bSuccess = H5Awrite(hAttr, hAttrNativeType, &nUint16) >= 0;
     497             :         }
     498             :     }
     499         654 :     else if (hEnumType >= 0 && H5Tequal(hAttrNativeType, H5T_NATIVE_UINT8))
     500             :     {
     501         654 :         if (nValue < 0 || nValue > 255)
     502             :         {
     503           0 :             CPLError(CE_Failure, CPLE_AppDefined,
     504             :                      "Attribute %s has value %d which is not in the range of a "
     505             :                      "uint8",
     506             :                      pszAttrName, nValue);
     507             :         }
     508             :         else
     509             :         {
     510         654 :             uint8_t nUint8 = static_cast<uint8_t>(nValue);
     511         654 :             bSuccess = H5Awrite(hAttr, hEnumType, &nUint8) >= 0;
     512             :         }
     513             :     }
     514             :     else
     515             :     {
     516           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     517             :                  "Attribute %s is not of type int/uint", pszAttrName);
     518             :     }
     519             : 
     520        1213 :     H5Tclose(hAttrNativeType);
     521        1213 :     H5Aclose(hAttr);
     522        1213 :     H5Tclose(hDataType);
     523        1213 :     if (hEnumType >= 0)
     524         654 :         H5Tclose(hEnumType);
     525             : 
     526        1213 :     return bSuccess;
     527             : }
     528             : 
     529             : /************************************************************************/
     530             : /*                        GH5_WriteAttribute()                          */
     531             : /************************************************************************/
     532             : 
     533         247 : bool GH5_WriteAttribute(hid_t loc_id, const char *pszAttrName, unsigned nValue)
     534             : {
     535             : 
     536         247 :     hid_t hAttr = H5Aopen_name(loc_id, pszAttrName);
     537         247 :     if (hAttr < 0)
     538           0 :         return false;
     539             : 
     540         247 :     hid_t hDataType = H5Aget_type(hAttr);
     541         247 :     if (hDataType < 0)
     542             :     {
     543           0 :         H5Aclose(hAttr);
     544           0 :         return false;
     545             :     }
     546             : 
     547         247 :     hid_t hEnumType = -1;
     548         247 :     if (H5Tget_class(hDataType) == H5T_ENUM)
     549             :     {
     550           0 :         hEnumType = hDataType;
     551           0 :         hDataType = H5Tget_super(hDataType);
     552             :     }
     553             : 
     554         247 :     hid_t hAttrNativeType = H5Tget_native_type(hDataType, H5T_DIR_DEFAULT);
     555         247 :     bool bSuccess = false;
     556         247 :     if (H5Tequal(hAttrNativeType, H5T_NATIVE_UINT))
     557             :     {
     558         247 :         bSuccess = H5Awrite(hAttr, hAttrNativeType, &nValue) >= 0;
     559             :     }
     560           0 :     else if (H5Tequal(hAttrNativeType, H5T_NATIVE_INT))
     561             :     {
     562           0 :         if (nValue > static_cast<unsigned>(INT_MAX))
     563             :         {
     564           0 :             CPLError(
     565             :                 CE_Failure, CPLE_AppDefined,
     566             :                 "Attribute %s has value %u which does not fit on a signed int",
     567             :                 pszAttrName, nValue);
     568             :         }
     569             :         else
     570             :         {
     571           0 :             bSuccess = H5Awrite(hAttr, hAttrNativeType, &nValue) >= 0;
     572             :         }
     573             :     }
     574             :     else
     575             :     {
     576           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     577             :                  "Attribute %s is not of type int/uint", pszAttrName);
     578             :     }
     579             : 
     580         247 :     H5Tclose(hAttrNativeType);
     581         247 :     H5Aclose(hAttr);
     582         247 :     H5Tclose(hDataType);
     583         247 :     if (hEnumType >= 0)
     584           0 :         H5Tclose(hEnumType);
     585             : 
     586         247 :     return bSuccess;
     587             : }

Generated by: LCOV version 1.14