Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-16 09:13:55

0001 /*
0002  *  Copyright (c), 2017, Adrien Devresse <adrien.devresse@epfl.ch>
0003  *
0004  *  Distributed under the Boost Software License, Version 1.0.
0005  *    (See accompanying file LICENSE_1_0.txt or copy at
0006  *          http://www.boost.org/LICENSE_1_0.txt)
0007  *
0008  */
0009 #pragma once
0010 
0011 #include <string>
0012 
0013 #include <H5Fpublic.h>
0014 
0015 #include "../H5Utility.hpp"
0016 #include "H5Utils.hpp"
0017 #include "h5f_wrapper.hpp"
0018 
0019 namespace HighFive {
0020 
0021 namespace {  // unnamed
0022 
0023 // libhdf5 uses a preprocessor trick on their oflags
0024 // we can not declare them constant without a mapper
0025 inline unsigned convert_open_flag(File::AccessMode openFlags) {
0026     unsigned res_open = 0;
0027     if (any(openFlags & File::ReadOnly))
0028         res_open |= H5F_ACC_RDONLY;
0029     if (any(openFlags & File::ReadWrite))
0030         res_open |= H5F_ACC_RDWR;
0031     if (any(openFlags & File::Create))
0032         res_open |= H5F_ACC_CREAT;
0033     if (any(openFlags & File::Truncate))
0034         res_open |= H5F_ACC_TRUNC;
0035     if (any(openFlags & File::Excl))
0036         res_open |= H5F_ACC_EXCL;
0037 #if H5_VERSION_GE(1, 10, 0)
0038     if (any(openFlags & File::ReadSWMR))
0039         res_open |= H5F_ACC_SWMR_READ | H5F_ACC_RDONLY;
0040     if (any(openFlags & File::WriteSWMR))
0041         res_open |= H5F_ACC_SWMR_WRITE | H5F_ACC_RDWR;
0042 #else
0043     if (any(openFlags & (File::ReadSWMR | File::WriteSWMR)))
0044         throw FileException("Your HDF5 library is too old for SWMR mode, you need at least 1.10");
0045 #endif
0046     return res_open;
0047 }
0048 }  // namespace
0049 
0050 inline File::File(const std::string& filename,
0051                   AccessMode openFlags,
0052                   const FileAccessProps& fileAccessProps)
0053     : File(filename, openFlags, FileCreateProps::Default(), fileAccessProps) {}
0054 
0055 
0056 inline File::File(const std::string& filename,
0057                   AccessMode access_mode,
0058                   const FileCreateProps& fileCreateProps,
0059                   const FileAccessProps& fileAccessProps) {
0060     unsigned openFlags = convert_open_flag(access_mode);
0061 
0062     unsigned createMode = openFlags & (H5F_ACC_TRUNC | H5F_ACC_EXCL);
0063     unsigned openMode = openFlags & (H5F_ACC_RDWR | H5F_ACC_RDONLY);
0064 #if H5_VERSION_GE(1, 10, 0)
0065     openMode |= openFlags & (H5F_ACC_SWMR_READ | H5F_ACC_SWMR_WRITE);
0066 #endif
0067     bool mustCreate = createMode > 0;
0068     bool openOrCreate = (openFlags & H5F_ACC_CREAT) > 0;
0069 
0070     // open is default. It's skipped only if flags require creation
0071     // If open fails it will try create() if H5F_ACC_CREAT is set
0072     if (!mustCreate) {
0073         // Silence open errors if create is allowed
0074         std::unique_ptr<SilenceHDF5> silencer;
0075         if (openOrCreate) {
0076             silencer = std::make_unique<SilenceHDF5>();
0077         }
0078 
0079         _hid = detail::nothrow::h5f_open(filename.c_str(), openMode, fileAccessProps.getId());
0080 
0081         if (isValid()) {
0082             return;  // Done
0083         }
0084 
0085         if (openOrCreate) {
0086             // Will attempt to create ensuring wont clobber any file
0087             createMode = H5F_ACC_EXCL;
0088         } else {
0089             HDF5ErrMapper::ToException<FileException>(
0090                 std::string("Unable to open file " + filename));
0091         }
0092     }
0093 
0094     auto fcpl = fileCreateProps.getId();
0095     auto fapl = fileAccessProps.getId();
0096     _hid = detail::h5f_create(filename.c_str(), createMode, fcpl, fapl);
0097 }
0098 
0099 inline const std::string& File::getName() const {
0100     if (_filename.empty()) {
0101         _filename = details::get_name([this](char* buffer, size_t length) {
0102             return detail::h5f_get_name(getId(), buffer, length);
0103         });
0104     }
0105     return _filename;
0106 }
0107 
0108 inline hsize_t File::getMetadataBlockSize() const {
0109     auto fapl = getAccessPropertyList();
0110     return MetadataBlockSize(fapl).getSize();
0111 }
0112 
0113 inline std::pair<H5F_libver_t, H5F_libver_t> File::getVersionBounds() const {
0114     auto fapl = getAccessPropertyList();
0115     auto fileVer = FileVersionBounds(fapl);
0116     return fileVer.getVersion();
0117 }
0118 
0119 #if H5_VERSION_GE(1, 10, 1)
0120 inline H5F_fspace_strategy_t File::getFileSpaceStrategy() const {
0121     auto fcpl = getCreatePropertyList();
0122     FileSpaceStrategy spaceStrategy(fcpl);
0123     return spaceStrategy.getStrategy();
0124 }
0125 
0126 inline hsize_t File::getFileSpacePageSize() const {
0127     auto fcpl = getCreatePropertyList();
0128 
0129     if (getFileSpaceStrategy() != H5F_FSPACE_STRATEGY_PAGE) {
0130         HDF5ErrMapper::ToException<FileException>(
0131             std::string("Cannot obtain page size as paged allocation is not used."));
0132     }
0133 
0134     return FileSpacePageSize(fcpl).getPageSize();
0135 }
0136 #endif
0137 
0138 inline void File::flush() {
0139     detail::h5f_flush(_hid, H5F_SCOPE_GLOBAL);
0140 }
0141 
0142 #if H5_VERSION_GE(1, 10, 0)
0143 inline void File::startSWMRWrite() {
0144     detail::h5f_start_swmr_write(_hid);
0145 }
0146 #endif
0147 
0148 inline size_t File::getFileSize() const {
0149     hsize_t sizeValue = 0;
0150     detail::h5f_get_filesize(_hid, &sizeValue);
0151     return static_cast<size_t>(sizeValue);
0152 }
0153 
0154 inline size_t File::getFreeSpace() const {
0155     return static_cast<size_t>(detail::h5f_get_freespace(_hid));
0156 }
0157 
0158 }  // namespace HighFive