void *
ss_prop_get(ss_prop_t *prop, /* property list to be queried */
const char *name, /* name of queried property */
hid_t type, /* optional type of data to return */
void *buffer /* optional result buffer */
)
{
SS_ENTER(ss_prop_get, voidP);
hid_t stored_type=-1; /* datatype stored in the property list */
void *convbuf=NULL; /* temporary buffer for data conversion */
void *src=NULL; /* source data from property list */
void *retval=NULL; /* return value */
if ((stored_type=ss_prop_type(prop, name))<0) SS_ERROR(FAILED);
if (NULL==(src=ss_prop_buffer(prop, name))) SS_ERROR(FAILED);
if (buffer) {
if (type<=0 || H5Tequal(type, stored_type)>0) {
/* No datatype conversion necessary */
memcpy(buffer, src, H5Tget_size(stored_type));
} else if (H5Tget_size(type)>=H5Tget_size(stored_type)) {
/* User-supplied buffer is large enough to use for conversion */
memcpy(buffer, src, H5Tget_size(stored_type));
if (H5Tconvert(stored_type, type, 1, buffer, NULL, H5P_DEFAULT)<0) SS_ERROR(HDF5);
} else {
/* User-supplied buffer is too small for conversion */
if (NULL==(convbuf=malloc(H5Tget_size(stored_type)))) SS_ERROR(RESOURCE);
memcpy(convbuf, src, H5Tget_size(stored_type));
if (H5Tconvert(stored_type, type, 1, convbuf, NULL, H5P_DEFAULT)<0) SS_ERROR(HDF5);
memcpy(buffer, convbuf, H5Tget_size(type));
convbuf = SS_FREE(convbuf);
}
retval = buffer;
} else if (type<=0 || H5Tequal(type, stored_type)>0) {
/* Allocate result buffer but no conversion necessary */
if (NULL==(retval=malloc(H5Tget_size(stored_type)))) SS_ERROR(RESOURCE);
memcpy(retval, src, H5Tget_size(stored_type));
} else {
/* Allocate result buffer and do data conversion */
size_t buf_size = MAX(H5Tget_size(type), H5Tget_size(stored_type));
if (NULL==(retval=malloc(buf_size))) SS_ERROR(RESOURCE);
memcpy(retval, src, H5Tget_size(stored_type));
if (H5Tconvert(stored_type, type, 1, retval, NULL, H5P_DEFAULT)<0) SS_ERROR(HDF5);
}
SS_CLEANUP:
if (stored_type>0) H5Tclose(stored_type);
if (!buffer) SS_FREE(retval);
SS_FREE(convbuf);
SS_LEAVE(retval);
}