LCOV - code coverage report
Current view: top level - frmts/hdf5 - hdf5dataset.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 27 29 93.1 %
Date: 2024-05-03 15:49:35 Functions: 10 10 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  * $Id$
       3             :  *
       4             :  * Project:  Hierarchical Data Format Release 5 (HDF5)
       5             :  * Purpose:  Header file for HDF5 datasets reader.
       6             :  * Author:   Denis Nadeau (denis.nadeau@gmail.com)
       7             :  *
       8             :  ******************************************************************************
       9             :  * Copyright (c) 2005, Frank Warmerdam <warmerdam@pobox.com>
      10             :  * Copyright (c) 2013, Even Rouault <even dot rouault at spatialys.com>
      11             :  *
      12             :  * Permission is hereby granted, free of charge, to any person obtaining a
      13             :  * copy of this software and associated documentation files (the "Software"),
      14             :  * to deal in the Software without restriction, including without limitation
      15             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      16             :  * and/or sell copies of the Software, and to permit persons to whom the
      17             :  * Software is furnished to do so, subject to the following conditions:
      18             :  *
      19             :  * The above copyright notice and this permission notice shall be included
      20             :  * in all copies or substantial portions of the Software.
      21             :  *
      22             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      23             :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      24             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      25             :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      26             :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      27             :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      28             :  * DEALINGS IN THE SOFTWARE.
      29             :  ****************************************************************************/
      30             : 
      31             : #ifndef HDF5DATASET_H_INCLUDED_
      32             : #define HDF5DATASET_H_INCLUDED_
      33             : 
      34             : #include "hdf5_api.h"
      35             : #include "hdf5eosparser.h"
      36             : 
      37             : #include "cpl_list.h"
      38             : #include "gdal_pam.h"
      39             : 
      40             : #include <map>
      41             : 
      42             : #ifdef ENABLE_HDF5_GLOBAL_LOCK
      43             : #include <mutex>
      44             : std::recursive_mutex &GetHDF5GlobalMutex();
      45             : #define HDF5_GLOBAL_LOCK()                                                     \
      46             :     std::lock_guard<std::recursive_mutex> oLock(GetHDF5GlobalMutex())
      47             : #else
      48             : #define HDF5_GLOBAL_LOCK()                                                     \
      49             :     do                                                                         \
      50             :     {                                                                          \
      51             :     } while (0)
      52             : #endif
      53             : 
      54             : typedef struct HDF5GroupObjects
      55             : {
      56             :     char *pszName;
      57             :     char *pszPath;
      58             :     char *pszUnderscorePath;
      59             :     char *pszTemp;
      60             :     int nType;
      61             :     int nIndex;
      62             :     hsize_t nbObjs;
      63             :     int nbAttrs;
      64             :     int nRank;
      65             :     hsize_t *paDims;
      66             :     hid_t native;
      67             :     hid_t HDatatype;
      68             :     unsigned long objno[2];
      69             :     struct HDF5GroupObjects *poHparent;
      70             :     struct HDF5GroupObjects *poHchild;
      71             : } HDF5GroupObjects;
      72             : 
      73             : herr_t HDF5CreateGroupObjs(hid_t, const char *, void *);
      74             : 
      75             : hid_t HDF5GetFileDriver();
      76             : void HDF5UnloadFileDriver();
      77             : 
      78             : hid_t GDAL_HDF5Open(const std::string &osFilename);
      79             : 
      80             : #if defined(H5_VERSION_GE)  // added in 1.8.7
      81             : #if !H5_VERSION_GE(1, 8, 13)
      82             : #ifndef _WIN32
      83             : #define H5free_memory(x) free(x)
      84             : #else
      85             : #define H5free_memory(x) CPL_IGNORE_RET_VAL(x)
      86             : #endif
      87             : #endif
      88             : #else
      89             : #ifndef _WIN32
      90             : #define H5free_memory(x) free(x)
      91             : #else
      92             : #define H5free_memory(x) CPL_IGNORE_RET_VAL(x)
      93             : #endif
      94             : #endif
      95             : 
      96             : // Release 1.6.3 or 1.6.4 changed the type of count in some API functions.
      97             : 
      98             : #if H5_VERS_MAJOR == 1 && H5_VERS_MINOR <= 6 &&                                \
      99             :     (H5_VERS_MINOR < 6 || H5_VERS_RELEASE < 3)
     100             : #define H5OFFSET_TYPE hssize_t
     101             : #else
     102             : #define H5OFFSET_TYPE hsize_t
     103             : #endif
     104             : 
     105             : class HDF5Dataset;
     106             : class HDF5EOSParser;
     107             : class BAGDataset;
     108             : class S100BaseDataset;
     109             : 
     110             : namespace GDAL
     111             : {
     112             : class HDF5Group;
     113             : 
     114             : /************************************************************************/
     115             : /*                         HDF5SharedResources                          */
     116             : /************************************************************************/
     117             : 
     118             : class HDF5SharedResources
     119             : {
     120             :     friend class ::HDF5Dataset;
     121             :     friend class ::BAGDataset;
     122             :     friend class ::S100BaseDataset;
     123             : 
     124             :     std::weak_ptr<HDF5SharedResources> m_poSelf{};
     125             :     bool m_bReadOnly = true;
     126             :     hid_t m_hHDF5 = 0;
     127             :     CPLString m_osFilename{};
     128             :     std::shared_ptr<GDALPamMultiDim> m_poPAM{};
     129             :     std::unique_ptr<HDF5EOSParser> m_poHDF5EOSParser{};
     130             :     std::map<std::string, std::vector<std::shared_ptr<GDALDimension>>>
     131             :         m_oMapEOSGridNameToDimensions{};
     132             :     std::map<std::string, std::vector<std::shared_ptr<GDALDimension>>>
     133             :         m_oMapEOSSwathNameToDimensions{};
     134             :     std::map<std::string, std::shared_ptr<GDALMDArray>> m_oRefKeeper;
     135             : 
     136             :     explicit HDF5SharedResources(const std::string &osFilename);
     137             : 
     138             :   public:
     139             :     static std::shared_ptr<HDF5SharedResources>
     140             :     Create(const std::string &osFilename);
     141             :     ~HDF5SharedResources();
     142             : 
     143             :     std::shared_ptr<HDF5Group> GetRootGroup();
     144             : 
     145         254 :     const std::string &GetFilename() const
     146             :     {
     147         254 :         return m_osFilename;
     148             :     }
     149             : 
     150         936 :     inline hid_t GetHDF5() const
     151             :     {
     152         936 :         return m_hHDF5;
     153             :     }
     154             : 
     155          24 :     inline bool IsReadOnly() const
     156             :     {
     157          24 :         return m_bReadOnly;
     158             :     }
     159             : 
     160             :     const std::shared_ptr<GDALPamMultiDim> &GetPAM()
     161             :     {
     162             :         return m_poPAM;
     163             :     }
     164             : 
     165         175 :     const HDF5EOSParser *GetHDF5EOSParser() const
     166             :     {
     167         175 :         return m_poHDF5EOSParser.get();
     168             :     }
     169             : 
     170           2 :     void RegisterEOSGridDimensions(
     171             :         const std::string &osGridName,
     172             :         const std::vector<std::shared_ptr<GDALDimension>> &apoDims)
     173             :     {
     174           2 :         m_oMapEOSGridNameToDimensions[osGridName] = apoDims;
     175           2 :     }
     176             : 
     177             :     std::vector<std::shared_ptr<GDALDimension>>
     178           2 :     GetEOSGridDimensions(const std::string &osGridName) const
     179             :     {
     180           2 :         auto oIter = m_oMapEOSGridNameToDimensions.find(osGridName);
     181           2 :         if (oIter == m_oMapEOSGridNameToDimensions.end())
     182           0 :             return {};
     183           2 :         return oIter->second;
     184             :     }
     185             : 
     186           3 :     void RegisterEOSSwathDimensions(
     187             :         const std::string &osSwathName,
     188             :         const std::vector<std::shared_ptr<GDALDimension>> &apoDims)
     189             :     {
     190           3 :         m_oMapEOSSwathNameToDimensions[osSwathName] = apoDims;
     191           3 :     }
     192             : 
     193             :     std::vector<std::shared_ptr<GDALDimension>>
     194           3 :     GetEOSSwathDimensions(const std::string &osSwathName) const
     195             :     {
     196           3 :         auto oIter = m_oMapEOSSwathNameToDimensions.find(osSwathName);
     197           3 :         if (oIter == m_oMapEOSSwathNameToDimensions.end())
     198           0 :             return {};
     199           3 :         return oIter->second;
     200             :     }
     201             : 
     202          40 :     void KeepRef(const std::shared_ptr<GDALMDArray> &poArray)
     203             :     {
     204          40 :         m_oRefKeeper[poArray->GetFullName()] = poArray;
     205          40 :     }
     206             : };
     207             : 
     208             : }  // namespace GDAL
     209             : 
     210             : /************************************************************************/
     211             : /* ==================================================================== */
     212             : /*                              HDF5Dataset                             */
     213             : /* ==================================================================== */
     214             : /************************************************************************/
     215             : class HDF5Dataset CPL_NON_FINAL : public GDALPamDataset
     216             : {
     217             :   protected:
     218             :     hid_t m_hHDF5 = -1;
     219             :     hid_t hGroupID;  // H handler interface.
     220             :     char **papszSubDatasets;
     221             :     int nDatasetType;
     222             :     int nSubDataCount;
     223             : 
     224             :     HDF5GroupObjects *poH5RootGroup; /* Contain hdf5 Groups information */
     225             :     std::shared_ptr<GDALGroup> m_poRootGroup{};
     226             : 
     227             :     CPLStringList m_aosMetadata{};
     228             : 
     229             :     HDF5EOSParser m_oHDFEOSParser{};
     230             : 
     231             :     CPLErr ReadGlobalAttributes(int);
     232             :     CPLErr HDF5ListGroupObjects(HDF5GroupObjects *, int);
     233             :     static CPLErr CreateMetadata(hid_t hHDF5, HDF5GroupObjects *, int,
     234             :                                  bool bPrefixWithDatasetName,
     235             :                                  CPLStringList &aosMetadata);
     236             : 
     237             :     HDF5GroupObjects *HDF5FindDatasetObjects(HDF5GroupObjects *, const char *);
     238             :     HDF5GroupObjects *HDF5FindDatasetObjectsbyPath(HDF5GroupObjects *,
     239             :                                                    const char *);
     240             :     char *CreatePath(HDF5GroupObjects *);
     241             :     static void DestroyH5Objects(HDF5GroupObjects *);
     242             : 
     243             :     static const char *GetDataTypeName(hid_t);
     244             : 
     245             :     /**
     246             :      * Reads an array of double attributes from the HDF5 metadata.
     247             :      * It reads the attributes directly on its binary form directly,
     248             :      * thus avoiding string conversions.
     249             :      *
     250             :      * Important: It allocates the memory for the attributes internally,
     251             :      * so the caller must free the returned array after using it.
     252             :      * @param pszAttrName Name of the attribute to be read.
     253             :      *                    the attribute name must be the form:
     254             :      *                                    root attribute name
     255             :      *                                    SUBDATASET/subdataset attribute name
     256             :      * @param pdfValues pointer which will store the array of doubles read.
     257             :      * @param nLen it stores the length of the array read. If NULL it doesn't
     258             :      * inform the length of the array.
     259             :      * @return CPLErr CE_None in case of success, CE_Failure in case of failure
     260             :      */
     261             :     CPLErr HDF5ReadDoubleAttr(const char *pszAttrName, double **pdfValues,
     262             :                               int *nLen = nullptr);
     263             : 
     264             :   public:
     265             :     HDF5Dataset();
     266             :     ~HDF5Dataset();
     267             : 
     268          26 :     std::shared_ptr<GDALGroup> GetRootGroup() const override
     269             :     {
     270          26 :         return m_poRootGroup;
     271             :     }
     272             : 
     273             :     static GDALDataset *Open(GDALOpenInfo *);
     274             :     static GDALDataset *OpenMultiDim(GDALOpenInfo *);
     275             :     static std::shared_ptr<GDALGroup> OpenGroup(
     276             :         const std::shared_ptr<GDAL::HDF5SharedResources> &poSharedResources);
     277             : 
     278             :     static GDALDataType GetDataType(hid_t);
     279             : };
     280             : 
     281             : #endif /* HDF5DATASET_H_INCLUDED_ */

Generated by: LCOV version 1.14