*
 * Programmer:  Quincey Koziol
 *              Wednesday, August 11, 1999
 *
 *-------------------------------------------------------------------------
 */
herr_t
H5Dvlen_get_buf_size(hid_t dataset_id, hid_t type_id, hid_t space_id,
        hsize_t *size)
{
    H5D_vlen_bufsize_t vlen_bufsize = {0, 0, 0, 0, 0, 0};
    H5D_vlen_bufsize_t vlen_bufsize = {NULL, H5I_INVALID_HID, H5I_INVALID_HID, NULL, NULL, 0, H5P_DATASET_XFER_DEFAULT};
    H5VL_object_t  *vol_obj;       /* Dataset for this operation */
    H5S_t *mspace = NULL;       /* Memory dataspace */
    char bogus;                 /* bogus value to pass to H5Diterate() */
    H5S_t *space;               /* Dataspace for iteration */
    H5T_t *type;                /* Datatype */
    H5S_sel_iter_op_t dset_op;  /* Operator for iteration */
    herr_t ret_value;           /* Return value */
    FUNC_ENTER_API(FAIL)
    H5TRACE4("e", "iii*h", dataset_id, type_id, space_id, size);
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataset identifier")
    if(NULL == (type = (H5T_t *)H5I_object_verify(type_id, H5I_DATATYPE)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an valid base datatype")
    if(NULL == (space = (H5S_t *)H5I_object_verify(space_id, H5I_DATASPACE)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "invalid dataspace")
    if(!(H5S_has_extent(space)))
        HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "dataspace does not have extent set")
    /* Save the dataset */
    vlen_bufsize.dset_vol_obj = vol_obj;
    vlen_bufsize.fspace_id = H5I_INVALID_HID;
    vlen_bufsize.mspace_id = H5I_INVALID_HID;
    /* Get a copy of the dataset's dataspace */
    if(H5VL_dataset_get(vol_obj, H5VL_DATASET_GET_SPACE, H5P_DATASET_XFER_DEFAULT, H5_REQUEST_NULL, &vlen_bufsize.fspace_id) < 0)
        HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, FAIL, "can't copy dataspace")
    /* Create a scalar for the memory dataspace */
    if(NULL == (mspace = H5S_create(H5S_SCALAR)))
        HGOTO_ERROR(H5E_DATASPACE, H5E_CANTCREATE, FAIL, "can't create dataspace")
    if((vlen_bufsize.mspace_id = H5I_register(H5I_DATASPACE, mspace, TRUE)) < 0)
        HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register dataspace atom")
    /* Grab the temporary buffers required */
    if(NULL == (vlen_bufsize.fl_tbuf = H5FL_BLK_MALLOC(vlen_fl_buf, (size_t)1)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "no temporary buffers available")
    if(NULL == (vlen_bufsize.vl_tbuf = H5FL_BLK_MALLOC(vlen_vl_buf, (size_t)1)))
        HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL, "no temporary buffers available")
    /* Set the memory manager to the special allocation routine */
    if(H5CX_set_vlen_alloc_info(H5D__vlen_get_buf_size_alloc, &vlen_bufsize, NULL, NULL) < 0)
        HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set VL data allocation routine")
    /* If we are not using the native VOL connector we must also set this
     * property on the DXPL since the context is not visible to the connector
     * and will be ignored if the connector re-enters the library */
    if(vol_obj->connector->cls->value != H5VL_NATIVE_VALUE) {
        H5P_genplist_t *dxpl;
        if(NULL == (dxpl = (H5P_genplist_t *)H5I_object(H5P_DATASET_XFER_DEFAULT)))
            HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get default DXPL")
        if((vlen_bufsize.dxpl_id = H5P_copy_plist(dxpl, TRUE)) < 0)
            HGOTO_ERROR(H5E_DATASET, H5E_CANTCOPY, H5I_INVALID_HID, "can't copy property list");
        if(NULL == (dxpl = (H5P_genplist_t *)H5I_object(vlen_bufsize.dxpl_id)))
            HGOTO_ERROR(H5E_DATASET, H5E_CANTGET, FAIL, "can't get copied DXPL")
        if(H5P_set_vlen_mem_manager(dxpl, H5D__vlen_get_buf_size_alloc, &vlen_bufsize, NULL, NULL) < 0)
            HGOTO_ERROR(H5E_DATASET, H5E_CANTSET, FAIL, "can't set VL data allocation routine on DXPL")
    } /* end if */
    /* Set the initial number of bytes required */
    vlen_bufsize.size = 0;
    /* Call H5S_select_iterate with args, etc. */
    dset_op.op_type             = H5S_SEL_ITER_OP_APP;
    dset_op.u.app_op.op         = H5D__vlen_get_buf_size;
    dset_op.u.app_op.type_id    = type_id;
    ret_value = H5S_select_iterate(&bogus, type, space, &dset_op, &vlen_bufsize);
    /* Get the size if we succeeded */
    if(ret_value >= 0)
        *size = vlen_bufsize.size;
done:
    if(ret_value < 0)
        if(mspace && H5S_close(mspace) < 0)
            HDONE_ERROR(H5E_DATASPACE, H5E_CANTRELEASE, FAIL, "unable to release dataspace")
    if(vlen_bufsize.fspace_id && H5I_dec_app_ref(vlen_bufsize.fspace_id) < 0)
        HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "problem freeing id")
    if(vlen_bufsize.mspace_id && H5I_dec_app_ref(vlen_bufsize.mspace_id) < 0)
        HGOTO_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "problem freeing id")
    if(vlen_bufsize.fspace_id >= 0 && H5I_dec_app_ref(vlen_bufsize.fspace_id) < 0)
        HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "problem freeing id")
    if(vlen_bufsize.mspace_id >= 0 && H5I_dec_app_ref(vlen_bufsize.mspace_id) < 0)
        HDONE_ERROR(H5E_DATASPACE, H5E_CANTDEC, FAIL, "problem freeing id")
    if(vlen_bufsize.fl_tbuf != NULL)
        vlen_bufsize.fl_tbuf = H5FL_BLK_FREE(vlen_fl_buf, vlen_bufsize.fl_tbuf);
    if(vlen_bufsize.vl_tbuf != NULL)
        vlen_bufsize.vl_tbuf = H5FL_BLK_FREE(vlen_vl_buf, vlen_bufsize.vl_tbuf);
    if(vlen_bufsize.dxpl_id != H5P_DATASET_XFER_DEFAULT)
        if(H5I_dec_app_ref(vlen_bufsize.dxpl_id) < 0)
            HDONE_ERROR(H5E_DATASET, H5E_CANTDEC, FAIL, "can't close property list")
    FUNC_LEAVE_API(ret_value)
}   /* end H5Dvlen_get_buf_size() */
/*-------------------------------------------------------------------------
 * Function:    H5Dset_extent
 *
 * Purpose:     Modifies the dimensions of a dataset.
 *              Can change to a smaller dimension.