diff options
author | Quincey Koziol <koziol@hdfgroup.org> | 2012-09-25 15:47:25 (GMT) |
---|---|---|
committer | Quincey Koziol <koziol@hdfgroup.org> | 2012-09-25 15:47:25 (GMT) |
commit | 6a89177036b5808ed0ce06ce0aab3af056b56984 (patch) | |
tree | 43367eb16716e1a2f074e2af07121e2723eae8d8 /src/H5Pencdec.c | |
parent | 50e3990f2a9e3bba421460d8d5cb21bb6f6e98fe (diff) | |
download | hdf5-6a89177036b5808ed0ce06ce0aab3af056b56984.zip hdf5-6a89177036b5808ed0ce06ce0aab3af056b56984.tar.gz hdf5-6a89177036b5808ed0ce06ce0aab3af056b56984.tar.bz2 |
[svn-r22807] Description:
Add encode/decode API routines for property lists: H5Pencode/H5Pdecode.
Tested on:
FreeBSD/32 8.2 (loyalty) w/gcc4.6, w/C++ & FORTRAN, in debug mode
FreeBSD/64 8.2 (freedom) w/gcc4.6, w/C++ & FORTRAN, in debug mode
Linux/32 2.6 (jam) w/PGI compilers, w/default API=1.8.x,
w/C++ & FORTRAN, w/threadsafe, in debug mode
Linux/64-amd64 2.6 (koala) w/Intel compilers, w/default API=1.6.x,
w/C++ & FORTRAN, in production mode
Solaris/32 2.10 (linew) w/deprecated symbols disabled, w/C++ & FORTRAN,
w/szip filter, w/threadsafe, in production mode
Linux/PPC 2.6 (ostrich) w/C++ & FORTRAN, w/threadsafe, in debug mode
Linux/64-ia64 2.6 (ember) w/Intel compilers, w/parallel, C++ & FORTRAN,
in production mode
Mac OS X/32 10.7.3 (amazon) in debug mode
Mac OS X/32 10.7.3 (amazon) w/C++ & FORTRAN, w/threadsafe,
in production mode
Mac OS X/32 10.7.3 (amazon) w/parallel, in debug mode
Diffstat (limited to 'src/H5Pencdec.c')
-rw-r--r-- | src/H5Pencdec.c | 797 |
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() */ + |