summaryrefslogtreecommitdiffstats
path: root/src/H5Pencdec.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/H5Pencdec.c')
-rw-r--r--src/H5Pencdec.c797
1 files changed, 797 insertions, 0 deletions
diff --git a/src/H5Pencdec.c b/src/H5Pencdec.c
new file mode 100644
index 0000000..11439db
--- /dev/null
+++ b/src/H5Pencdec.c
@@ -0,0 +1,797 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by The HDF Group. *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * 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 files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdfgroup.org/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from help@hdfgroup.org. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* Programmer: Quincey Koziol <koziol@hdfgroup.org>
+ *
+ * Purpose: Generic Property Functions
+ */
+
+/****************/
+/* Module Setup */
+/****************/
+
+#define H5P_PACKAGE /*suppress error about including H5Ppkg */
+
+/* Interface initialization */
+#define H5_INTERFACE_INIT_FUNC H5P_init_encdec_interface
+
+
+/***********/
+/* Headers */
+/***********/
+#include "H5private.h" /* Generic Functions */
+#include "H5Eprivate.h" /* Error handling */
+#include "H5Iprivate.h" /* IDs */
+#include "H5MMprivate.h" /* Memory management */
+#include "H5Ppkg.h" /* Property lists */
+
+
+/****************/
+/* Local Macros */
+/****************/
+
+/* Version # of encoded property lists */
+#define H5P_ENCODE_VERS 0
+
+
+/******************/
+/* Local Typedefs */
+/******************/
+
+/* Typedef for iterator when encoding a property list */
+typedef struct {
+ hbool_t encode; /* Whether the property list should be encoded */
+ size_t *enc_size_ptr; /* Pointer to size of encoded buffer */
+ uint8_t **pp; /* Pointer to encoding buffer pointer */
+} H5P_enc_iter_ud_t;
+
+
+/********************/
+/* Local Prototypes */
+/********************/
+
+
+/*********************/
+/* Package Variables */
+/*********************/
+
+
+/*****************************/
+/* Library Private Variables */
+/*****************************/
+
+
+/*******************/
+/* Local Variables */
+/*******************/
+
+
+
+/*--------------------------------------------------------------------------
+NAME
+ H5P_init_encdec_interface -- Initialize interface-specific information
+USAGE
+ herr_t H5P_init_encdec_interface()
+RETURNS
+ Non-negative on success/Negative on failure
+DESCRIPTION
+ Initializes any interface-specific data or routines. (Just calls
+ H5P_init() currently).
+
+--------------------------------------------------------------------------*/
+static herr_t
+H5P_init_encdec_interface(void)
+{
+ FUNC_ENTER_NOAPI_NOINIT_NOERR
+
+ FUNC_LEAVE_NOAPI(H5P_init())
+} /* H5P_init_encdec_interface() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__encode_size_t
+ *
+ * Purpose: Generic encoding callback routine for 'size_t' properties.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, July 29, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P__encode_size_t(const void *value, uint8_t **pp, size_t *size)
+{
+ uint64_t enc_value = (uint64_t)*(const size_t *)value; /* Property value to encode */
+ unsigned enc_size = H5V_limit_enc_size(enc_value); /* Size of encoded property */
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Sanity checks */
+ HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
+ HDassert(enc_size < 256);
+ HDassert(size);
+
+ if(NULL != *pp) {
+ /* Encode the size */
+ *(*pp)++ = (uint8_t)enc_size;
+
+ /* Encode the value */
+ UINT64ENCODE_VAR(*pp, enc_value, enc_size);
+ } /* end if */
+
+ /* Set size needed for encoding */
+ *size += (1 + enc_size);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5P__encode_size_t() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__encode_hsize_t
+ *
+ * Purpose: Generic encoding callback routine for 'hsize_t' properties.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 07, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P__encode_hsize_t(const void *value, uint8_t **pp, size_t *size)
+{
+ uint64_t enc_value = (uint64_t)*(const hsize_t *)value; /* Property value to encode */
+ unsigned enc_size = H5V_limit_enc_size(enc_value); /* Size of encoded property */
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Sanity checks */
+ HDcompile_assert(sizeof(hsize_t) <= sizeof(uint64_t));
+ HDassert(enc_size < 256);
+ HDassert(size);
+
+ if(NULL != *pp) {
+ *(*pp)++ = (uint8_t)enc_size;
+
+ /* Encode the value */
+ UINT64ENCODE_VAR(*pp, enc_value, enc_size);
+ } /* end if */
+
+ /* Set size needed for encoding */
+ *size += (1 + enc_size);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5P__encode_hsize_t() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__encode_unsigned
+ *
+ * Purpose: Generic encoding callback routine for 'unsigned' properties.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, July 29, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P__encode_unsigned(const void *value, uint8_t **pp, size_t *size)
+{
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Sanity checks */
+ HDassert(value);
+ HDassert(size);
+
+ if(NULL != *pp) {
+ /* Encode the size */
+ *(*pp)++ = (uint8_t)sizeof(unsigned);
+
+ /* Encode the value */
+ H5_ENCODE_UNSIGNED(*pp, *(const unsigned *)value)
+ } /* end if */
+
+ /* Set size needed for encoding */
+ *size += (1 + sizeof(unsigned));
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5P__encode_unsigned() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__encode_uint8_t
+ *
+ * Purpose: Generic encoding callback routine for 'uint8_t' properties.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 07, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P__encode_uint8_t(const void *value, uint8_t **pp, size_t *size)
+{
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Sanity checks */
+ HDassert(value);
+ HDassert(size);
+
+ if(NULL != *pp) {
+ /* Encode the value */
+ *(*pp)++ = *(const uint8_t *)value;
+ } /* end if */
+
+ /* Set size needed for encoding */
+ *size += 1;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5P__encode_uint8_t() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__encode_hbool_t
+ *
+ * Purpose: Generic encoding callback routine for 'hbool_t' properties.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * August 15, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P__encode_hbool_t(const void *value, uint8_t **pp, size_t *size)
+{
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Sanity checks */
+ HDassert(value);
+ HDassert(size);
+
+ if(NULL != *pp)
+ /* Encode the value */
+ *(*pp)++ = (uint8_t)*(const hbool_t *)value;
+
+ /* Set size needed for encoding */
+ *size += 1;
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5P__encode_hbool_t() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__encode_double
+ *
+ * Purpose: Generic encoding callback routine for 'double' properties.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Sunday, July 29, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P__encode_double(const void *value, uint8_t **pp, size_t *size)
+{
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Sanity checks */
+ HDassert(value);
+ HDassert(size);
+
+ if(NULL != *pp) {
+ /* Encode the size */
+ *(*pp)++ = (uint8_t)sizeof(double);
+
+ /* Encode the value */
+ H5_ENCODE_DOUBLE(*pp, *(const double *)value)
+ } /* end if */
+
+ /* Set size needed for encoding */
+ *size += (1 + sizeof(double));
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5P__encode_double() */
+
+
+/*--------------------------------------------------------------------------
+ NAME
+ H5P__encode_cb
+ PURPOSE
+ Internal callback routine when iterating over properties while encoding
+ a property list.
+ USAGE
+ int H5P__encode_cb(item, key, udata)
+ H5P_genprop_t *prop; IN: Pointer to the property
+ void *udata; IN/OUT: Pointer to iteration data from user
+ RETURNS
+ Success: H5_ITER_CONT
+ Fail: H5_ITER_ERROR
+ DESCRIPTION
+ This routine encodes a property in a property list
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+static int
+H5P__encode_cb(H5P_genprop_t *prop, void *_udata)
+{
+ H5P_enc_iter_ud_t *udata = (H5P_enc_iter_ud_t *)_udata; /* Pointer to user data */
+ int ret_value = H5_ITER_CONT; /* Return value */
+
+ FUNC_ENTER_STATIC
+
+ /* Sanity check */
+ HDassert(prop);
+ HDassert(udata);
+
+ /* Check if this property can be encoded */
+ if(prop->encode) {
+ size_t prop_name_len; /* Length of property's name */
+ size_t prop_value_len; /* Encoded size of property's value */
+
+ /* Encode (or not, if the 'encode' flag is off) the property's name */
+ prop_name_len = HDstrlen(prop->name) + 1;
+ if(udata->encode) {
+ HDstrncpy((char *)*(udata->pp), prop->name, prop_name_len);
+ *(udata->pp) += prop_name_len;
+ } /* end if */
+ *(udata->enc_size_ptr) += prop_name_len;
+
+ /* Encode (or not, if *(udata->pp) is NULL) the property value */
+ prop_value_len = 0;
+ if((prop->encode)(prop->value, udata->pp, &prop_value_len) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, H5_ITER_ERROR, "property encoding routine failed")
+ *(udata->enc_size_ptr) += prop_value_len;
+ } /* end if */
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__encode_cb() */
+
+
+/*-------------------------------------------------------------------------
+ NAME
+ H5P__encode
+ PURPOSE
+ Internal routine to encode a property list into a binary buffer.
+ USAGE
+ herr_t H5P__encode(plist, enc_all_prop, buf, nalloc)
+ const H5P_genplist_t *plist; IN: Property list to encode
+ hbool_t enc_all_prop; IN: Whether to encode all properties (TRUE),
+ or just non-default (i.e. changed) properties (FALSE).
+ uint8_t *buf; OUT: buffer to hold the encoded plist
+ size_t *nalloc; IN/OUT: size of buffer needed to encode plist
+ RETURNS
+ Returns non-negative on success, negative on failure.
+ DESCRIPTION
+ Encodes a property list into a binary buffer. If the buffer is NULL, then
+ the call will set the size needed to encode the plist in nalloc. Otherwise
+ the routine will encode the plist in buf.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+herr_t
+H5P__encode(const H5P_genplist_t *plist, hbool_t enc_all_prop, void *buf,
+ size_t *nalloc)
+{
+ H5P_enc_iter_ud_t udata; /* User data for property iteration callback */
+ uint8_t *p = (uint8_t *)buf; /* Temporary pointer to encoding buffer */
+ int idx; /* Index of property to start at */
+ size_t encode_size = 0; /* Size of buffer needed to encode properties */
+ hbool_t encode = TRUE; /* Whether the property list should be encoded */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity check */
+ if(NULL == nalloc)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "bad allocation size pointer")
+
+ /* If the buffer is NULL, then this call to H5P__encode will return how much
+ * space is needed to encode a property.
+ */
+ if(NULL == p)
+ encode = FALSE;
+
+ /* Encode property list description info */
+ if(encode) {
+ /* Version # of property list encoding */
+ *p++ = (uint8_t)H5P_ENCODE_VERS;
+
+ /* Type of property list */
+ *p++ = (uint8_t)plist->pclass->type;
+ } /* end if */
+ encode_size += 2;
+
+ /* Initialize user data for iteration callback */
+ udata.encode = encode;
+ udata.enc_size_ptr = &encode_size;
+ udata.pp = &p;
+
+ /* Iterate over all properties in property list, encoding them */
+ idx = 0;
+ if(H5P_iterate_plist(plist, enc_all_prop, &idx, H5P__encode_cb, &udata) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADITER, FAIL, "can't iterate over properties")
+
+ /* Encode a terminator for list of properties */
+ if(encode)
+ *p++ = 0;
+ encode_size++;
+
+ /* Set the size of the buffer needed/used to encode the property list */
+ *nalloc = encode_size;
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__encode() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__decode_size_t
+ *
+ * Purpose: Generic decoding callback routine for 'size_t' properties.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, August 2, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P__decode_size_t(const uint8_t **pp, void *_value)
+{
+ size_t *value = (size_t *)_value; /* Property value to return */
+ uint64_t enc_value; /* Decoded property value */
+ unsigned enc_size; /* Size of encoded property */
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Sanity check */
+ HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
+ HDassert(pp);
+ HDassert(*pp);
+ HDassert(value);
+
+ /* Decode the size */
+ enc_size = *(*pp)++;
+ HDassert(enc_size < 256);
+
+ /* Decode the value */
+ UINT64DECODE_VAR(*pp, enc_value, enc_size);
+ H5_ASSIGN_OVERFLOW(*value, enc_value, uint64_t, size_t);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5P__decode_size_t() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__decode_hsize_t
+ *
+ * Purpose: Generic decoding callback routine for 'hsize_t' properties.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Mohamad Chaarawi
+ * August 07, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P__decode_hsize_t(const uint8_t **pp, void *_value)
+{
+ hsize_t *value = (hsize_t *)_value; /* Property value to return */
+ uint64_t enc_value; /* Decoded property value */
+ unsigned enc_size; /* Size of encoded property */
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Sanity check */
+ HDcompile_assert(sizeof(hsize_t) <= sizeof(uint64_t));
+ HDassert(pp);
+ HDassert(*pp);
+ HDassert(value);
+
+ /* Decode the size */
+ enc_size = *(*pp)++;
+ HDassert(enc_size < 256);
+
+ /* Decode the value */
+ UINT64DECODE_VAR(*pp, enc_value, enc_size);
+ H5_ASSIGN_OVERFLOW(*value, enc_value, uint64_t, hsize_t);
+
+ FUNC_LEAVE_NOAPI(SUCCEED)
+} /* end H5P__decode_hsize_t() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__decode_unsigned
+ *
+ * Purpose: Generic decoding callback routine for 'unsigned' properties.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, August 2, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P__decode_unsigned(const uint8_t **pp, void *_value)
+{
+ unsigned *value = (unsigned *)_value; /* Property value to return */
+ unsigned enc_size; /* Size of encoded property */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity checks */
+ HDassert(pp);
+ HDassert(*pp);
+ HDassert(value);
+
+ /* Decode the size */
+ enc_size = *(*pp)++;
+ if(enc_size != sizeof(unsigned))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "unsigned value can't be decoded")
+
+ H5_DECODE_UNSIGNED(*pp, *value)
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__decode_unsigned() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__decode_uint8_t
+ *
+ * Purpose: Generic decoding callback routine for 'uint8_t' properties.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, August 2, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P__decode_uint8_t(const uint8_t **pp, void *_value)
+{
+ uint8_t *value = (uint8_t *)_value; /* Property value to return */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Sanity checks */
+ HDassert(pp);
+ HDassert(*pp);
+ HDassert(value);
+
+ /* Decode the value */
+ *value = *(*pp)++;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__decode_uint8_t() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__decode_hbool_t
+ *
+ * Purpose: Generic decoding callback routine for 'hbool_t' properties.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Wednesday, August 15, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P__decode_hbool_t(const uint8_t **pp, void *_value)
+{
+ hbool_t *value = (hbool_t *)_value; /* Property value to return */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE_NOERR
+
+ /* Sanity checks */
+ HDassert(pp);
+ HDassert(*pp);
+ HDassert(value);
+
+ /* Decode the value */
+ *value = (hbool_t)*(*pp)++;
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__decode_hbool_t() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5P__decode_double
+ *
+ * Purpose: Generic decoding callback routine for 'double' properties.
+ *
+ * Return: Success: Non-negative
+ * Failure: Negative
+ *
+ * Programmer: Quincey Koziol
+ * Thursday, August 2, 2012
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5P__decode_double(const uint8_t **pp, void *_value)
+{
+ double *value = (double *)_value; /* Property value to return */
+ unsigned enc_size; /* Size of encoded property */
+ herr_t ret_value = SUCCEED; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity checks */
+ HDassert(pp);
+ HDassert(*pp);
+ HDassert(value);
+
+ /* Decode the size */
+ enc_size = *(*pp)++;
+ if(enc_size != sizeof(double))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "double value can't be decoded")
+
+ H5_DECODE_DOUBLE(*pp, *value)
+
+done:
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__decode_double() */
+
+
+/*-------------------------------------------------------------------------
+ NAME
+ H5P__decode
+ PURPOSE
+ Internal routine to decode a property list from a binary buffer.
+ USAGE
+ H5P_genplist_t *H5P__decode(buf)
+ const void *buf; IN: buffer that holds the encoded plist
+ RETURNS
+ Returns non-negative ID of new property list object on success, negative
+ on failure.
+ DESCRIPTION
+ Decodes a property list from a binary buffer. The contents of the buffer
+ contain the values for the correponding properties of the plist. The decode
+ callback of a certain property decodes its value from the buffer and sets it
+ in the property list.
+ GLOBAL VARIABLES
+ COMMENTS, BUGS, ASSUMPTIONS
+ Properties in the property list that are not encoded in the serialized
+ form retain their default value.
+ EXAMPLES
+ REVISION LOG
+--------------------------------------------------------------------------*/
+hid_t
+H5P__decode(const void *buf)
+{
+ H5P_genplist_t *plist; /* Property list to decode into */
+ void *value_buf = NULL; /* Pointer to buffer to use when decoding values */
+ const uint8_t *p = (const uint8_t *)buf; /* Current pointer into buffer */
+ H5P_plist_type_t type; /* Type of encoded property list */
+ hid_t plist_id = -1; /* ID of new property list */
+ size_t value_buf_size = 0; /* Size of current value buffer */
+ uint8_t vers; /* Version of encoded property list */
+ hid_t ret_value; /* Return value */
+
+ FUNC_ENTER_PACKAGE
+
+ /* Sanity check */
+ if(NULL == p)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADVALUE, FAIL, "decode buffer is NULL")
+
+ /* Get the version number of the encoded property list */
+ vers = (uint8_t)*p++;
+ if((uint8_t)H5P_ENCODE_VERS != vers)
+ HGOTO_ERROR(H5E_PLIST, H5E_VERSION, FAIL, "bad version # of encoded information, expected %u, got %u", (unsigned)H5P_ENCODE_VERS, (unsigned)vers)
+
+ /* Get the type of the property list */
+ type = (H5P_plist_type_t)*p++;
+ if(type <= H5P_TYPE_USER || type > H5P_TYPE_LINK_ACCESS)
+ HGOTO_ERROR(H5E_PLIST, H5E_BADRANGE, FAIL, "bad type of encoded information: %u", (unsigned)type)
+
+ /* Create new property list of the specified type */
+ if((plist_id = H5P__new_plist_of_type(type)) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_VERSION, FAIL, "can't create property list of type: %u\n", (unsigned)type);
+
+ /* Get the property list object */
+ if(NULL == (plist = (H5P_genplist_t *)H5I_object(plist_id)))
+ HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "not a property class")
+
+ /* Loop over encoded properties, deserializing their values */
+ while(p) {
+ H5P_genprop_t *prop; /* Pointer to property with same name */
+ const char *name; /* Pointer to property list name */
+
+ /* Check for end of serialized list of properties */
+ if(0 == *p)
+ break;
+
+ /* Get property list name */
+ name = (const char *)p;
+ p += HDstrlen(name) + 1;
+
+ /* Find property with name */
+ if(NULL == (prop = H5P__find_prop_plist(plist, name)))
+ HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "property doesn't exist: '%s'", name)
+
+ /* Check if we should increase the size of the value buffer */
+ if(prop->size > value_buf_size) {
+ if(NULL == (value_buf = H5MM_realloc(value_buf, prop->size)))
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTALLOC, FAIL, "decoding buffer allocation failed")
+ value_buf_size = prop->size;
+ } /* end if */
+
+ /* Decode serialized value */
+ if(prop->decode) {
+ if((prop->decode)(&p, value_buf) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTDECODE, FAIL, "property decoding routine failed, property: '%s'", name)
+ } /* end if */
+ else
+ HGOTO_ERROR(H5E_PLIST, H5E_NOTFOUND, FAIL, "no decode callback for property: '%s', name")
+
+ /* Set the value for the property */
+ if(H5P_set(plist, name, value_buf) < 0)
+ HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "unable to set value for property: '%s'", name)
+ } /* end while */
+
+ /* Set return value */
+ ret_value = plist_id;
+
+done:
+ /* Release resources */
+ if(value_buf)
+ value_buf = H5MM_xfree(value_buf);
+
+ /* Cleanup on error */
+ if(ret_value < 0) {
+ if(plist_id > 0 && H5I_dec_ref(plist_id) < 0)
+ HDONE_ERROR(H5E_PLIST, H5E_CANTCLOSEOBJ, FAIL, "unable to close partially initialized property list")
+ } /* end if */
+
+ FUNC_LEAVE_NOAPI(ret_value)
+} /* end H5P__decode() */
+