/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 * Copyright by The HDF Group.                                               *
 * All rights reserved.                                                      *
 *                                                                           *
 * This file is part of HDF5.  The full HDF5 copyright notice, including     *
 * terms governing use, modification, and redistribution, is contained in    *
 * the COPYING file, which can be found at the root of the source code       *
 * distribution tree, or in https://www.hdfgroup.org/licenses.               *
 * If you do not have access to either file, you may request a copy from     *
 * help@hdfgroup.org.                                                        *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

#include <iostream>
#include <string>

#include "H5Include.h"
#include "H5Exception.h"
#include "H5IdComponent.h"
#include "H5PropList.h"

namespace H5 {
using std::cerr;
using std::endl;

#ifndef DOXYGEN_SHOULD_SKIP_THIS
// This DOXYGEN_SHOULD_SKIP_THIS block is a work-around approach to control
// the order of creation and deletion of the global constants.  See Design Notes
// in "H5PredType.cpp" for information.

// Initialize a pointer for the constant
PropList *PropList::DEFAULT_ = 0;

//--------------------------------------------------------------------------
// Function:    PropList::getConstant
// Purpose      Creates a PropList object representing the HDF5 constant
//              H5P_DEFAULT, pointed to by PropList::DEFAULT_.
// Exception    H5::PropListIException
// Description
//              If PropList::DEFAULT_ already points to an allocated object,
//              throw a PropListIException.  This scenario should not happen.
//--------------------------------------------------------------------------
PropList *
PropList::getConstant()
{
    // Tell the C library not to clean up, H5Library::termH5cpp will call
    // H5close - more dependency if use H5Library::dontAtExit()
    if (!IdComponent::H5dontAtexit_called) {
        (void)H5dont_atexit();
        IdComponent::H5dontAtexit_called = true;
    }

    // If the constant pointer is not allocated, allocate it. Otherwise,
    // throw because it shouldn't be.
    if (DEFAULT_ == 0)
        DEFAULT_ = new PropList(H5P_DEFAULT);
    else
        throw PropListIException("PropList::getConstant",
                                 "PropList::getConstant is being invoked on an allocated DEFAULT_");
    return (DEFAULT_);
}

//--------------------------------------------------------------------------
// Function:    PropList::deleteConstants
// Purpose      Deletes the constant object that PropList::DEFAULT_ points to.
//--------------------------------------------------------------------------
void
PropList::deleteConstants()
{
    delete DEFAULT_;
}

//--------------------------------------------------------------------------
// Purpose      Constant for default property.
//--------------------------------------------------------------------------
const PropList &PropList::DEFAULT = *getConstant();

#endif // DOXYGEN_SHOULD_SKIP_THIS

//--------------------------------------------------------------------------
// Function:    Default constructor
///\brief       Default constructor: creates a stub property list object.
//--------------------------------------------------------------------------
PropList::PropList() : IdComponent(), id(H5P_DEFAULT)
{
}

//--------------------------------------------------------------------------
// Function:    PropList copy constructor
///\brief       Copy constructor: same HDF5 object as \a original
///\param       original - IN: The original property list to copy
//--------------------------------------------------------------------------
PropList::PropList(const PropList &original) : IdComponent(), id(original.id)
{
    incRefCount(); // increment number of references to this id
}

//--------------------------------------------------------------------------
// Function:    PropList overloaded constructor
///\brief       Creates a property list using the id of an existing property.
///\param       plist_id - IN: Id of the existing property list
///\exception   H5::PropListIException
// Description
//              This function creates a new property list if a property
//              class is provided or makes a copy of a property list if one
//              is given.  If the given id is anything else, then set this
//              property's id to H5P_DEFAULT.
//--------------------------------------------------------------------------
PropList::PropList(const hid_t plist_id) : IdComponent(), id{H5P_DEFAULT}
{
    H5I_type_t id_type = H5Iget_type(plist_id);
    switch (id_type) {
        case H5I_GENPROP_CLS:
            // call C routine to create a new property from the given prop class
            id = H5Pcreate(plist_id);
            if (id < 0) {
                throw PropListIException("PropList constructor", "H5Pcreate failed");
            }
            break;
        case H5I_GENPROP_LST:
            // call C routine to make a copy of the given property list
            id = H5Pcopy(plist_id);
            if (id < 0) {
                throw PropListIException("PropList constructor", "H5Pcopy failed");
            }
            break;
        /* These should really be error cases, but changing that breaks
         * the stated behavior and causes test failures.
         * (DER, July 2017)
         */
        case H5I_BADID:
        case H5I_FILE:
        case H5I_GROUP:
        case H5I_DATATYPE:
        case H5I_DATASPACE:
        case H5I_DATASET:
        case H5I_ATTR:
        case H5I_VFL:
        case H5I_VOL:
        case H5I_ERROR_CLASS:
        case H5I_ERROR_MSG:
        case H5I_ERROR_STACK:
        case H5I_NTYPES:
        case H5I_UNINIT:
        case H5I_MAP:
        case H5I_SPACE_SEL_ITER:
        case H5I_EVENTSET:
        default:
            id = H5P_DEFAULT;
            break;
    }
}

//--------------------------------------------------------------------------
// Function:    PropList::copy
///\brief       Makes a copy of an existing property list.
///\param       like_plist - IN: Reference to the existing property list
///\exception   H5::PropListIException
// Modification
//              - Replaced resetIdComponent() with decRefCount() to use C
//              library ID reference counting mechanism - BMR, Jun 1, 2004
//              - Replaced decRefCount with close() to let the C library
//              handle the reference counting - BMR, Jun 1, 2006
//--------------------------------------------------------------------------
void
PropList::copy(const PropList &like_plist)
{
    // If this object is representing an hdf5 object, close it before
    // copying like_plist to it
    try {
        close();
    }
    catch (Exception &close_error) {
        throw PropListIException(inMemFunc("copy"), close_error.getDetailMsg());
    }

    // call C routine to copy the property list
    id = H5Pcopy(like_plist.getId());
    if (id < 0)
        throw PropListIException(inMemFunc("copy"), "H5Pcopy failed");
}

//--------------------------------------------------------------------------
// Function:    PropList::operator=
///\brief       Assignment operator.
///\param       rhs - IN: Reference to the existing property list
///\return      Reference to PropList instance
///\exception   H5::PropListIException
// Description
//              Makes a copy of the property list on the right hand side
//              and stores the new id in the left hand side object.
//--------------------------------------------------------------------------
PropList &
PropList::operator=(const PropList &rhs)
{
    if (this != &rhs)
        copy(rhs);
    return (*this);
}

//--------------------------------------------------------------------------
// Function:    PropList::copyProp
///\brief       Copies a property from this property list or class to another
///\param       dest - IN: Destination property list or class
///\param       name - IN: Name of the property to copy - \c char pointer
///\exception   H5::PropListIException
//--------------------------------------------------------------------------
void
PropList::copyProp(PropList &dest, const char *name) const
{
    hid_t  dst_id    = dest.getId();
    herr_t ret_value = H5Pcopy_prop(dst_id, id, name);
    if (ret_value < 0) {
        throw PropListIException(inMemFunc("copyProp"), "H5Pcopy_prop failed");
    }
}

//--------------------------------------------------------------------------
// Function:    PropList::copyProp
///\brief       This is an overloaded member function, provided for convenience.
///             It differs from the above function only in what arguments it
///             accepts.
///\param       dest - IN: Destination property list or class
///\param       name - IN: Name of the property to copy - \c H5std_string
//--------------------------------------------------------------------------
void
PropList::copyProp(PropList &dest, const H5std_string &name) const
{
    copyProp(dest, name.c_str());
}

//--------------------------------------------------------------------------
// Function:    PropList::copyProp
///\brief       Copies a property from one list or class to another - Obsolete
///\param       dest - IN: Destination property list or class
///\param       src  - IN: Source property list or class
///\param       name - IN: Name of the property to copy - \c char pointer
///\note        This member function will be removed in the next release
///\exception   H5::PropListIException
//--------------------------------------------------------------------------
void
PropList::copyProp(PropList &dest, PropList &src, const char *name) const
{
    hid_t  dst_id    = dest.getId();
    hid_t  src_id    = src.getId();
    herr_t ret_value = H5Pcopy_prop(dst_id, src_id, name);
    if (ret_value < 0) {
        throw PropListIException(inMemFunc("copyProp"), "H5Pcopy_prop failed");
    }
}

//--------------------------------------------------------------------------
// Function:    PropList::copyProp
///\brief       This is an overloaded member function, provided for convenience.
///             It differs from the above function only in what arguments it
///             accepts. - Obsolete
///\param       dest - IN: Destination property list or class
///\param       src  - IN: Source property list or class
///\param       name - IN: Name of the property to copy - \c H5std_string
//--------------------------------------------------------------------------
void
PropList::copyProp(PropList &dest, PropList &src, const H5std_string &name) const
{
    copyProp(dest, src, name.c_str());
}

//--------------------------------------------------------------------------
// Function:    PropList::getId
///\brief       Get the id of this property list
///\return      Property list identifier
// Description:
//              Class hierarchy is revised to address bugzilla 1068.  Class
//              AbstractDS and Attribute are moved out of H5Object.  In
//              addition, member IdComponent::id is moved into subclasses, and
//              IdComponent::getId now becomes pure virtual function.
//--------------------------------------------------------------------------
hid_t
PropList::getId() const
{
    return (id);
}

#ifndef DOXYGEN_SHOULD_SKIP_THIS
//--------------------------------------------------------------------------
// Function:    PropList::p_setId
///\brief       Sets the identifier of this object to a new value.
///
///\exception   H5::IdComponentException when the attempt to close the HDF5
///             object fails
// Description:
//              The underlying reference counting in the C library ensures
//              that the current valid id of this object is properly closed.
//              Then the object's id is reset to the new id.
//--------------------------------------------------------------------------
void
PropList::p_setId(const hid_t new_id)
{
    // handling references to this old id
    try {
        close();
    }
    catch (Exception &close_error) {
        throw PropListIException(inMemFunc("p_setId"), close_error.getDetailMsg());
    }
    // reset object's id to the given id
    id = new_id;
}

#endif // DOXYGEN_SHOULD_SKIP_THIS

//--------------------------------------------------------------------------
// Function:    PropList::close
///\brief       Closes the property list if it is not a default one.
///
///\exception   H5::PropListIException
//--------------------------------------------------------------------------
void
PropList::close()
{
    if (p_valid_id(id)) {
        herr_t ret_value = H5Pclose(id);
        if (ret_value < 0) {
            throw PropListIException(inMemFunc("close"), "H5Pclose failed");
        }
        // reset the id
        id = H5I_INVALID_HID;
    }
}

//--------------------------------------------------------------------------
// Function:    PropList::getClass
///\brief       Returns the class of this property list, i.e. \c H5P_FILE_CREATE...
///\return      The property list class if it is not equal to \c H5P_ROOT
///\exception   H5::PropListIException
//--------------------------------------------------------------------------
hid_t
PropList::getClass() const
{
    hid_t plist_class = H5Pget_class(id);
    if (plist_class == H5P_ROOT) {
        throw PropListIException(inMemFunc("getClass"), "H5Pget_class failed - returned H5P_ROOT");
    }
    return (plist_class);
}

//--------------------------------------------------------------------------
// Function:    PropList::propExist
///\brief       Queries the existence of a property in a property object.
///\param       name - IN: Name of property to check for - \c char pointer
///\return      true if the property exists in the property object, and
///             false, otherwise.
///\exception   H5::PropListIException
///\par Description
///             This routine checks if a property exists within a property
///             list or class.
//--------------------------------------------------------------------------
bool
PropList::propExist(const char *name) const
{
    // Calls C routine H5Pexist to determine whether a property exists
    // within a property list or class.  It returns a positive value, 0,
    // or a negative value
    htri_t ret_value = H5Pexist(id, name);
    if (ret_value > 0)
        return true;
    else if (ret_value == 0)
        return false;
    else // Raise exception when H5Pexist returns a negative value
    {
        throw PropListIException(inMemFunc("propExist"), "H5Pexist failed");
    }
}
//--------------------------------------------------------------------------
// Function:    PropList::propExist
///\brief       This is an overloaded member function, provided for convenience.
///             It differs from the above function only in what arguments it
///             accepts.
///\param       name - IN: Name of property to check for - \c H5std_string
//--------------------------------------------------------------------------
bool
PropList::propExist(const H5std_string &name) const
{
    return (propExist(name.c_str()));
}

//--------------------------------------------------------------------------
// Function:    PropList::closeClass
///\brief       Close a property list class.
///
///\exception   H5::PropListIException
///\par Description
///             Releases memory and detaches a class from the property
///             list class hierarchy.
//--------------------------------------------------------------------------
void
PropList::closeClass() const
{
    herr_t ret_value = H5Pclose_class(id);
    if (ret_value < 0) {
        throw PropListIException(inMemFunc("closeClass"), "H5Pclose_class failed");
    }
}

//--------------------------------------------------------------------------
// Function:    PropList::getProperty
///\brief       Query the value of a property in a property list.
///\param       name -   IN: Name of property to query - \c char pointer
///\param       value - OUT: Pointer to the buffer for the property value
///\exception   H5::PropListIException
///\par Description
///             Retrieves a copy of the value for a property in a property
///             list.  The property name must exist or this routine will
///             throw an exception.
//--------------------------------------------------------------------------
void
PropList::getProperty(const char *name, void *value) const
{
    herr_t ret_value = H5Pget(id, name, value);
    if (ret_value < 0) {
        throw PropListIException(inMemFunc("getProperty"), "H5Pget failed");
    }
}
//--------------------------------------------------------------------------
// Function:    PropList::getProperty
///\brief       This is an overloaded member function, provided for convenience.
///             It differs from the above function only in what arguments it
///             accepts.
///\param       name -  IN: Name of property to query - \c char pointer
///\return      The property that is a \c H5std_string.
///\exception   H5::PropListIException
//--------------------------------------------------------------------------
H5std_string
PropList::getProperty(const char *name) const
{
    // Get property size first
    size_t size = getPropSize(name);

    // Allocate buffer then get the property
    char *prop_strg_C = new char[size + 1]();

    herr_t ret_value = H5Pget(id, name, prop_strg_C); // call C API

    // Throw exception if H5Pget returns failure
    if (ret_value < 0) {
        delete[] prop_strg_C;
        throw PropListIException(inMemFunc("getProperty"), "H5Pget failed");
    }

    // Return property value as a string after deleting temp C-string
    H5std_string prop_strg(prop_strg_C);
    delete[] prop_strg_C;
    return (prop_strg);
}
//--------------------------------------------------------------------------
// Function:    PropList::getProperty
///\brief       This is an overloaded member function, provided for convenience.
///             It differs from the above function only in what arguments it
///             accepts.
///\param       name -   IN: Name of property to query - \c H5std_string
///\param       value - OUT: Pointer to the buffer for the property value
//--------------------------------------------------------------------------
void
PropList::getProperty(const H5std_string &name, void *value) const
{
    getProperty(name.c_str(), value);
}
//--------------------------------------------------------------------------
// Function:    PropList::getProperty
///\brief       This is an overloaded member function, provided for convenience.
///             It differs from the above function only in what arguments it
///             accepts.
///\param       name -  IN: Name of property to query - \c H5std_string
///\return      The property that is a \c H5std_string.
//--------------------------------------------------------------------------
H5std_string
PropList::getProperty(const H5std_string &name) const
{
    return (getProperty(name.c_str()));
}

//--------------------------------------------------------------------------
// Function:    PropList::getPropSize
///\brief       Query the size of a property in a property list or class.
///\param       name - IN: Name of property to query
///\return      Size of the property
///\exception   H5::PropListIException
///\par Description
///             This routine retrieves the size of a property's value
///             in bytes.  Zero-sized properties are allowed and the return
///             value will be of 0.  This function works for both property
///             lists and classes.
//--------------------------------------------------------------------------
size_t
PropList::getPropSize(const char *name) const
{
    size_t prop_size;
    herr_t ret_value = H5Pget_size(id, name, &prop_size);
    if (ret_value < 0) {
        throw PropListIException(inMemFunc("getPropSize"), "H5Pget_size failed");
    }
    return (prop_size);
}
//--------------------------------------------------------------------------
// Function:    PropList::getPropSize
///\brief       This is an overloaded member function, provided for convenience.
///             It differs from the above function only in what arguments it
///             accepts.
///\param       name - IN: Name of property to query - \c H5std_string
///
//--------------------------------------------------------------------------
size_t
PropList::getPropSize(const H5std_string &name) const
{
    return (getPropSize(name.c_str()));
}

//--------------------------------------------------------------------------
// Function:    PropList::getClassName
///\brief       Return the name of a generic property list class.
///\return      A string containing the class name, if success, otherwise,
///             an empty string.
//--------------------------------------------------------------------------
H5std_string
PropList::getClassName() const
{
    char *temp_str;
    temp_str = H5Pget_class_name(id);
    if (temp_str != NULL) {
        H5std_string class_name(temp_str);
        H5free_memory(temp_str);
        return (class_name);
    }
    else
        return "";
}

//--------------------------------------------------------------------------
// Function:    PropList::getNumProps
///\brief       Returns the number of properties in this property list or class.
///\return      Size of the property.
///\exception   H5::PropListIException
//--------------------------------------------------------------------------
size_t
PropList::getNumProps() const
{
    size_t nprops;
    herr_t ret_value = H5Pget_nprops(id, &nprops);
    if (ret_value < 0) {
        throw PropListIException(inMemFunc("getNumProps"), "H5Pget_nprops failed");
    }
    return (nprops);
}

//--------------------------------------------------------------------------
// Function:    PropList::setProperty
///\brief       Set a property's value in a property list.
///\param       name  - IN: Name of property to set - \c char pointer
///\param       value - IN: Void pointer to the value for the property
///\exception   H5::PropListIException
// Description
//              Revision svn r29815 changed 'value' to const, hence, deprecated
//              the non-const setProperty.
//--------------------------------------------------------------------------
void
PropList::setProperty(const char *name, const void *value) const
{
    herr_t ret_value = H5Pset(id, name, value);
    if (ret_value < 0) {
        throw PropListIException(inMemFunc("setProperty"), "H5Pset failed");
    }
}

//--------------------------------------------------------------------------
// Function:    PropList::setProperty
///\brief       Deprecated due to missing const in prototype. (1.10.1)
// Modification
//              Planned for removal. -BMR, 2017/03/17 1.10.1
//--------------------------------------------------------------------------
void
PropList::setProperty(const char *name, void *value) const
{
    herr_t ret_value = H5Pset(id, name, value);
    if (ret_value < 0) {
        throw PropListIException(inMemFunc("setProperty"), "H5Pset failed");
    }
}

//--------------------------------------------------------------------------
// Function:    PropList::setProperty
///\brief       This is an overloaded member function, provided for convenience.
///             It differs from the above function only in what arguments it
///             accepts.
///\param       name    - IN: Name of property to set - \c char pointer
///\param       charptr - IN: Char pointer to the value for the property
// Description
//              Revision svn r29815 changed 'value' to const, hence, deprecated
//              the non-const setProperty.
//--------------------------------------------------------------------------
void
PropList::setProperty(const char *name, const char *charptr) const
{
    herr_t ret_value = H5Pset(id, name, static_cast<const void *>(charptr));
    if (ret_value < 0) {
        throw PropListIException(inMemFunc("setProperty"), "H5Pset failed");
    }
}

//--------------------------------------------------------------------------
// Function:    PropList::setProperty
///\brief       This is an overloaded member function, provided for convenience.
///             It differs from the above function only in what arguments it
///             accepts.
///\param       name - IN: Name of property to set - \c char pointer
///\param       strg - IN: Value for the property is a \c H5std_string
//--------------------------------------------------------------------------
void
PropList::setProperty(const char *name, const H5std_string &strg) const
{
    setProperty(name, strg.c_str());
}

//--------------------------------------------------------------------------
// Function:    PropList::setProperty
///\brief       Deprecated due to missing const in prototype. (1.10.1)
// Modification
//              Planned for removal. -BMR, 2017/03/17 1.10.1
//--------------------------------------------------------------------------
void
PropList::setProperty(const char *name, H5std_string &strg) const
{
    setProperty(name, strg.c_str());
}

//--------------------------------------------------------------------------
// Function:    PropList::setProperty
///\brief       This is an overloaded member function, provided for convenience.
///             It differs from the above function only in what arguments it
///             accepts.
///\param       name  - IN: Name of property to set - \c H5std_string
///\param       value - IN: Void pointer to the value for the property
//--------------------------------------------------------------------------
void
PropList::setProperty(const H5std_string &name, const void *value) const
{
    setProperty(name.c_str(), value);
}

//--------------------------------------------------------------------------
// Function:    PropList::setProperty
///\brief       Deprecated due to missing const in prototype. (1.10.1)
// Modification
//              Planned for removal. -BMR, 2017/03/17 1.10.1
//--------------------------------------------------------------------------
void
PropList::setProperty(const H5std_string &name, void *value) const
{
    setProperty(name.c_str(), value);
}

//--------------------------------------------------------------------------
// Function:    PropList::setProperty
///\brief       This is an overloaded member function, provided for convenience.
///             It differs from the above function only in what arguments it
///             accepts.
///\param       name - IN: Name of property to set - \c H5std_string
///\param       strg - IN: Value for the property is a \c H5std_string
//--------------------------------------------------------------------------
void
PropList::setProperty(const H5std_string &name, const H5std_string &strg) const
{
    setProperty(name.c_str(), strg.c_str());
}

//--------------------------------------------------------------------------
// Function:    PropList::setProperty
///\brief       Deprecated due to missing const in prototype. (1.10.1)
// Modification
//              Planned for removal. -BMR, 2017/03/17 1.10.1
//--------------------------------------------------------------------------
void
PropList::setProperty(const H5std_string &name, H5std_string &strg) const
{
    setProperty(name.c_str(), strg.c_str());
}

//--------------------------------------------------------------------------
// Function:    PropList::isAClass
///\brief       Determines whether a property list is a certain class.
///\param       prop_class - IN: Property class to query
///\return      true if the property list is a member of the property list
///             class, and false, otherwise.
///\exception   H5::PropListIException
//--------------------------------------------------------------------------
bool
PropList::isAClass(const PropList &prop_class) const
{
    htri_t ret_value = H5Pisa_class(id, prop_class.getId());
    if (ret_value > 0)
        return true;
    else if (ret_value == 0)
        return false;
    else // Raise exception when H5Pisa_class returns a negative value
    {
        throw PropListIException(inMemFunc("isAClass"), "H5Pisa_class failed");
    }
}

//--------------------------------------------------------------------------
// Function:    PropList::removeProp
///\brief       Removes a property from a property list.
///\param       name - IN: Name of property to remove - \c char pointer
///\exception   H5::PropListIException
//--------------------------------------------------------------------------
void
PropList::removeProp(const char *name) const
{
    herr_t ret_value = H5Premove(id, name);
    if (ret_value < 0) {
        throw PropListIException(inMemFunc("removeProp"), "H5Premove failed");
    }
}

//--------------------------------------------------------------------------
// Function:    PropList::removeProp
///\brief       This is an overloaded member function, provided for convenience.
///             It differs from the above function only in what arguments it
///             accepts.
///\param       name - IN: Name of property to remove - \c H5std_string
//--------------------------------------------------------------------------
void
PropList::removeProp(const H5std_string &name) const
{
    removeProp(name.c_str());
}

//--------------------------------------------------------------------------
// Function:    PropList::operator==
///\brief       Compares this property list or class against the given list or class.
///\param       rhs - IN: Reference to the property list to compare
///\return      true if the property lists or classes are equal, and
///             false, otherwise.
///\exception   H5::PropListIException
//--------------------------------------------------------------------------
bool
PropList::operator==(const PropList &rhs) const
{
    htri_t ret_value = H5Pequal(id, rhs.getId());
    if (ret_value > 0)
        return true;
    else if (ret_value == 0)
        return false;
    else // Raise exception when H5Pequal returns a negative value
    {
        throw PropListIException(inMemFunc("operator=="), "H5Pequal failed");
    }
}

//--------------------------------------------------------------------------
// Function:    PropList::getClassParent
///\brief       Returns the parent class of a generic property class
///\return      The parent class of a property class
///\exception   H5::PropListIException
//--------------------------------------------------------------------------
PropList
PropList::getClassParent() const
{
    hid_t class_id = H5Pget_class_parent(id);
    if (class_id < 0) {
        throw PropListIException(inMemFunc("getClassParent"), "H5Pget_class_parent failed");
    }
    PropList pclass(class_id);
    return (pclass);
}

//--------------------------------------------------------------------------
// Function:    PropList destructor
///\brief       Properly terminates access to this property list.
// Modification
//              - Replaced resetIdComponent() with decRefCount() to use C
//              library ID reference counting mechanism - BMR, Jun 1, 2004
//              - Replaced decRefCount with close() to let the C library
//              handle the reference counting - BMR, Jun 1, 2006
//--------------------------------------------------------------------------
PropList::~PropList()
{
    try {
        close();
    }
    catch (Exception &close_error) {
        cerr << "PropList::~PropList - " << close_error.getDetailMsg() << endl;
    }
}

} // namespace H5
