* the COPYING file, which can be found at the root of the source code       *
 * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
 * If you do not have access to either file, you may request a copy from     *
 * help@hdfgroup.org.                                                        *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/*
 * Programmer:  Robb Matzke <robb@arborea.spizella.com>
 *              Thursday, October  1, 1998
 *
 * Purpose: Tests dataset fill values.
 * Purpose:    Tests dataset fill values.
 */
#include "h5test.h"
#include "H5srcdir.h"
/*
 * Define NO_FILLING if you want to compare how this test works when there is
 * no fill value (that is, when the fill value is zero).
 */
/* #define NO_FILLING */
    int    x;
    char   *a;
    char   *b;
    int    y;
} comp_vl_datatype;
/* The fill_old.h5 is generated from gen_old_fill.c in HDF5 'test' directory
 * for version 1.4(after 1.4.3).  To get this data file, simply compile
 * gen_old_fill.c with HDF5 library (before v1.5) and run it. */
#define FILE_COMPATIBLE "fill_old.h5"
#define FILE_NAME_RAW   "fillval.raw"
#define FILE_NAME_RAW    "fillval.raw"
/*-------------------------------------------------------------------------
 * Function:    create_compound_type
 *
 * Purpose:     create a compound datatype
 *
 * Return:      Success:        datatype ID
 *
 *              Failure:        -1
 *
 * Programmer:  Raymond Lu
    if((ret_value = H5Tcreate(H5T_COMPOUND, sizeof(comp_datatype))) < 0)
        goto error;
    if(H5Tinsert(ret_value, "a", HOFFSET(comp_datatype, a), H5T_NATIVE_FLOAT) < 0)
        goto error;
    if(H5Tinsert(ret_value, "x", HOFFSET(comp_datatype, x), H5T_NATIVE_INT) < 0)
        goto error;
    if(H5Tinsert(ret_value, "y", HOFFSET(comp_datatype, y), H5T_NATIVE_DOUBLE) < 0)
        goto error;
    if(H5Tinsert(ret_value, "z", HOFFSET(comp_datatype, z), H5T_NATIVE_CHAR) < 0)
    goto error;
    goto error;
    return ret_value;
error:
    H5E_BEGIN_TRY {
        H5Tclose(ret_value);
    } H5E_END_TRY;
    return -1;
}
/*-------------------------------------------------------------------------
 * Function:    create_compound_vl_type
 *
 * Purpose:     create a compound+vl datatype
 *
 * Return:      Success:        datatype ID
 *
 *              Failure:        -1
 *
 * Programmer:  Quincey Koziol
    return ret_value;
error:
    H5E_BEGIN_TRY {
        H5Tclose(str_id);
        H5Tclose(ret_value);
    } H5E_END_TRY;
    return -1;
} /* end create_compound_vl_type() */
/*-------------------------------------------------------------------------
 * Function:    test_getset
 * Function:    test_getset
 *
 * Purpose: Tests the H5Pget_fill_value() and H5Pset_fill_value()
 *      functions.
 * Purpose:    Tests the H5Pget_fill_value() and H5Pset_fill_value()
 *        functions.
 *
 * Return:  Success:    0
 * Return:    Success:    0
 *
 *      Failure:    number of errors
 *        Failure:    number of errors
 *
 * Programmer:  Robb Matzke
 * Programmer:    Robb Matzke
 *              Thursday, October  1, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_getset(void)
{
    hid_t   dcpl=-1;
    int     fill_i;
    hid_t   type_ss=-1, type_si=-1;
    hid_t    dcpl=-1;
    int        fill_i;
    hid_t    type_ss=-1, type_si=-1;
    struct fill_si {
    int     v1, v2;
    }       fill_si;
    int     v1, v2;
    }        fill_si;
    struct fill_ss {
    short   v1, v2;
    }       fill_ss, fill_ss_rd;
    short    v1, v2;
    }        fill_ss, fill_ss_rd;
    TESTING("property lists");
    /*
     * Create the dataset creation property list and the data types that will
     * be used during this test.
     */
    if((dcpl=H5Pcreate(H5P_DATASET_CREATE)) < 0) goto error;
    if((type_ss=H5Tcreate(H5T_COMPOUND, sizeof fill_ss)) < 0 ||
    H5Tinsert(type_ss, "v1", HOFFSET(struct fill_ss, v1),
          H5T_NATIVE_SHORT) < 0 ||
    H5Tinsert(type_ss, "v2", HOFFSET(struct fill_ss, v2),
          H5T_NATIVE_SHORT) < 0) {
    goto error;
    H5Tinsert(type_ss, "v1", HOFFSET(struct fill_ss, v1),
        H5T_NATIVE_SHORT) < 0 ||
    H5Tinsert(type_ss, "v2", HOFFSET(struct fill_ss, v2),
        H5T_NATIVE_SHORT) < 0) {
    goto error;
    }
    if((type_si=H5Tcreate(H5T_COMPOUND, sizeof fill_si)) < 0 ||
    H5Tinsert(type_si, "v1", HOFFSET(struct fill_si, v1),
          H5T_NATIVE_INT) < 0 ||
    H5Tinsert(type_si, "v2", HOFFSET(struct fill_si, v2),
          H5T_NATIVE_INT) < 0) {
    goto error;
    H5Tinsert(type_si, "v1", HOFFSET(struct fill_si, v1),
        H5T_NATIVE_INT) < 0 ||
    H5Tinsert(type_si, "v2", HOFFSET(struct fill_si, v2),
        H5T_NATIVE_INT) < 0) {
    goto error;
    }
    /*
     * Reading the fill value from a dataset creation property list that has
     * no fill value should result in a failure.
     */
    H5E_BEGIN_TRY {
    H5Pget_fill_value(dcpl, H5T_NATIVE_INT, &fill_i);
    H5Pget_fill_value(dcpl, H5T_NATIVE_INT, &fill_i);
    } H5E_END_TRY;
    if(fill_i != 0) {
    H5_FAILED();
    puts("    H5Pget_fill_value() should return default 0");
    goto error;
    H5_FAILED();
    puts("    H5Pget_fill_value() should return default 0");
    goto error;
    }
    /*
     * Set the fill value using a struct as the data type.
     */
    fill_ss.v1 = 1111;
    fill_ss.v2 = 2222;
    if(H5Pset_fill_value(dcpl, type_ss, &fill_ss) < 0) goto error;
    /*
     * Get the fill value using the same data type that was used to set it.
     */
    if(H5Pget_fill_value(dcpl, type_ss, &fill_ss_rd) < 0) goto error;
    if(fill_ss.v1!=fill_ss_rd.v1 || fill_ss.v2!=fill_ss_rd.v2) {
    H5_FAILED();
    puts("    Failed to get fill value using same data type that was ");
    puts("    used to set the fill value.");
    goto error;
    H5_FAILED();
    puts("    Failed to get fill value using same data type that was ");
    puts("    used to set the fill value.");
    goto error;
    }
    /*
     * Get the fill value using some other data type.
     */
    if(H5Pget_fill_value(dcpl, type_si, &fill_si) < 0) goto error;
    if(fill_ss.v1!=fill_si.v1 || fill_ss.v2!=fill_si.v2) {
    H5_FAILED();
    puts("    Failed to get fill value using a data type other than what");
    puts("    was used to set the fill value.");
    goto error;
    H5_FAILED();
    puts("    Failed to get fill value using a data type other than what");
    puts("    was used to set the fill value.");
    goto error;
    }
    /*
     * Reset the fill value
     */
    if(H5Pset_fill_value(dcpl, type_si, &fill_si) < 0) goto error;
    if(H5Pget_fill_value(dcpl, type_ss, &fill_ss) < 0) goto error;
    if(fill_si.v1!=fill_ss.v1 || fill_si.v2!=fill_ss.v2) {
    H5_FAILED();
    puts("    Resetting the fill value was unsuccessful.");
    goto error;
    H5_FAILED();
    puts("    Resetting the fill value was unsuccessful.");
    goto error;
    }
    /* Success */
    if(H5Pclose(dcpl) < 0) goto error;
    if(H5Tclose(type_si) < 0) goto error;
    if(H5Tclose(type_ss) < 0) goto error;
    PASSED();
    return 0;
 error:
    H5E_BEGIN_TRY {
    H5Pclose(dcpl);
    H5Tclose(type_si);
    H5Tclose(type_ss);
    H5Pclose(dcpl);
    H5Tclose(type_si);
    H5Tclose(type_ss);
    } H5E_END_TRY;
    return 1;
}
/*-------------------------------------------------------------------------
 * Function:    test_getset_vl
 * Function:    test_getset_vl
 *
 * Purpose: Tests the H5Pget_fill_value() and H5Pset_fill_value()
 *      functions, using variable-length datatype.
 * Purpose:    Tests the H5Pget_fill_value() and H5Pset_fill_value()
 *        functions, using variable-length datatype.
 *
 * Return:  Success:    0
 *      Failure:    number of errors
 * Return:    Success:    0
 *        Failure:    number of errors
 *
 * Programmer:  Quincey Koziol
 * Programmer:    Quincey Koziol
 *              Thursday, May 31, 2007
 *
 *-------------------------------------------------------------------------
 */
static int
test_getset_vl(hid_t fapl)
{
    hsize_t dims[1] = {2};
    hid_t fileid = (-1), spaceid = (-1), dtypeid = (-1), datasetid = (-1), plistid = (-1);
    char fill_value[] = "aaaa";
    PASSED();
    return 0;
 error:
    H5E_BEGIN_TRY {
    } H5E_END_TRY;
    return 1;
} /* end test_getset_vl() */
/*-------------------------------------------------------------------------
 * Function:    test_create
 * Function:    test_create
 *
 * Purpose: Tests creating datasets that have fill values.
 * Purpose:    Tests creating datasets that have fill values.
 *
 * Return:  Success:    0
 * Return:    Success:    0
 *
 *      Failure:    number of errors
 *        Failure:    number of errors
 *
 * Programmer:  Robb Matzke
 * Programmer:    Robb Matzke
 *              Thursday, October  1, 1998
 *
 * Modifications:
 *      Many new cases have been added to this test since
 *      the fill value design has been modified.
 *        Many new cases have been added to this test since
 *        the fill value design has been modified.
 *
 *-------------------------------------------------------------------------
 */
static int
test_create(hid_t fapl, const char *base_name, H5D_layout_t layout)
{
    hid_t   file=-1, space=-1, dcpl=-1, comp_type_id=-1;
    hid_t   dset1=-1, dset2=-1, dset3=-1, dset4=-1, dset5=-1,
        dset6=-1, /* dset7=-1, */ dset8=-1, dset9=-1;
    hid_t    file=-1, space=-1, dcpl=-1, comp_type_id=-1;
    hid_t    dset1=-1, dset2=-1, dset3=-1, dset4=-1, dset5=-1,
        dset6=-1, /* dset7=-1, */ dset8=-1, dset9=-1;
    hsize_t     cur_size[5] = {2, 8, 8, 4, 2};
    hsize_t ch_size[5] = {1, 1, 1, 4, 1};
    short   rd_s, fill_s = 0x1234;
    long    rd_l, fill_l = 0x4321;
    char    filename[1024];
    H5D_space_status_t  allocation;
    hsize_t    ch_size[5] = {1, 1, 1, 4, 1};
    short    rd_s, fill_s = 0x1234;
    long    rd_l, fill_l = 0x4321;
    char    filename[1024];
    H5D_space_status_t    allocation;
    H5D_alloc_time_t    alloc_time;
    H5D_fill_time_t fill_time;
    H5D_fill_time_t    fill_time;
    comp_datatype       rd_c, fill_ctype;
    if(H5D_CHUNKED==layout) {
    TESTING("chunked dataset creation");
    TESTING("chunked dataset creation");
    } else if(H5D_COMPACT==layout) {
        TESTING("compact dataset creation");
    } else {
    TESTING("contiguous dataset creation");
    TESTING("contiguous dataset creation");
    }
    /*
     * Create a file.
     */
    h5_fixname(base_name, fapl, filename, sizeof filename);
    if((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
    goto error;
    goto error;
    if((space=H5Screate_simple(5, cur_size, cur_size)) < 0) goto error;
    if((dcpl=H5Pcreate(H5P_DATASET_CREATE)) < 0) goto error;
    if(H5D_CHUNKED==layout) {
    if(H5Pset_chunk(dcpl, 5, ch_size) < 0) goto error;
    if(H5Pset_chunk(dcpl, 5, ch_size) < 0) goto error;
    } else if(H5D_COMPACT==layout) {
        if(H5Pset_layout(dcpl, H5D_COMPACT) < 0) goto error;
    }
    /* Create a compound datatype */
    if((comp_type_id = create_compound_type()) < 0) goto error;
    /* I. Test cases for late space allocation except compact dataset */
    if(H5D_COMPACT!=layout) {
        /* The three datasets test three fill
         * conversion paths: small to large, large to small, and no conversion.
         * They depend on `short' being smaller than `long'.
         */
        /* 2. Small to large fill conversion */
#ifndef NO_FILLING
        if(H5Pset_fill_value(dcpl, H5T_NATIVE_SHORT, &fill_s) < 0) goto error;
#endif
        if((dset1=H5Dcreate2(file, "dset1", H5T_NATIVE_LONG, space, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
       goto error;
    goto error;
        /* 3. Large to small fill conversion */
#ifndef NO_FILLING
        if(H5Pset_fill_value(dcpl, H5T_NATIVE_LONG, &fill_l) < 0) goto error;
#endif
        if((dset2=H5Dcreate2(file, "dset2", H5T_NATIVE_SHORT, space, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
       goto error;
    goto error;
        /* 4. No conversion */
#ifndef NO_FILLING
        if(H5Pset_fill_value(dcpl, H5T_NATIVE_LONG, &fill_l) < 0) goto error;
#endif
        if((dset3=H5Dcreate2(file, "dset3", H5T_NATIVE_LONG, space, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
       goto error;
    goto error;
        /* 5. late space allocation and never write fill value */
        if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_NEVER) < 0) goto error;
        if((dset4=H5Dcreate2(file, "dset4", H5T_NATIVE_LONG, space, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
            goto error;
        /* 6. fill value is undefined while fill write time is H5D_FILL_TIME_ALLOC.
         * Supposed to fail. */
        if(H5Pset_fill_value(dcpl, (hid_t)-1, NULL) < 0) goto error;
        if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_ALLOC) < 0) goto error;
    if(H5Pset_fill_value(dcpl, H5T_NATIVE_LONG, &fill_l) < 0) goto error;
    /* 2. Never write fill value */
    if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_NEVER) < 0) goto error;
    if((dset5 = H5Dcreate2(file, "dset5", H5T_NATIVE_INT, space, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
        goto error;
    /* 3. Write fill value at space allocation time */
    if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_ALLOC) < 0) goto error;
    if((dset6 = H5Dcreate2(file, "dset6", H5T_NATIVE_LONG, space, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
    goto error;
    goto error;
    /* 4. fill value is undefined while fill write time is H5D_FILL_TIME_ALLOC.
     * Supposed to fail. */
    if(H5Pset_fill_value(dcpl, (hid_t)-1, NULL) < 0) goto error;
    H5E_BEGIN_TRY {
        if(H5Dcreate2(file, "dset7", H5T_NATIVE_LONG, space, H5P_DEFAULT, dcpl, H5P_DEFAULT)!=FAIL)
            goto error;
    } H5E_END_TRY;
    /* Close everything */
    }
    if(H5Dclose(dset5) < 0) goto error;
    if(H5Dclose(dset6) < 0) goto error;
    if(H5Dclose(dset8) < 0) goto error;
    if(H5Sclose(space) < 0) goto error;
    if(H5Pclose(dcpl) < 0)  goto error;
    if(H5Fclose(file) < 0)  goto error;
    /* Open the file and get the dataset fill value from each dataset */
    if((file = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
    goto error;
    goto error;
    /* I. Check cases for late space allocation except compact dataset */
    if(H5D_COMPACT != layout) {
        /* 1. Large to small conversion */
        if((dset1 = H5Dopen2(file, "dset1", H5P_DEFAULT)) < 0) goto error;
        if((dcpl = H5Dget_create_plist(dset1)) < 0) goto error;
#ifndef NO_FILLING
        if(H5Pget_fill_value(dcpl, H5T_NATIVE_SHORT, &rd_s) < 0) goto error;
        if(rd_s != fill_s) {
       H5_FAILED();
       HDprintf("    %d: Got a different fill value than what was set.",__LINE__);
       HDprintf("    Got %d, set %d\n", rd_s, fill_s);
       goto error;
    H5_FAILED();
    HDprintf("    %d: Got a different fill value than what was set.",__LINE__);
    HDprintf("    Got %d, set %d\n", rd_s, fill_s);
    goto error;
        }
#endif
        if(H5Dclose(dset1) < 0) goto error;
        if(H5Pclose(dcpl) < 0) goto error;
        /* 2. Small to large conversion */
        if((dset2 = H5Dopen2(file, "dset2", H5P_DEFAULT)) < 0) goto error;
        if((dcpl = H5Dget_create_plist(dset2)) < 0) goto error;
#ifndef NO_FILLING
        if(H5Pget_fill_value(dcpl, H5T_NATIVE_LONG, &rd_l) < 0) goto error;
        if(rd_l!=fill_l) {
       H5_FAILED();
       HDprintf("    %d: Got a different fill value than what was set.",__LINE__);
       HDprintf("    Got %ld, set %ld\n", rd_l, fill_l);
       goto error;
    H5_FAILED();
    HDprintf("    %d: Got a different fill value than what was set.",__LINE__);
    HDprintf("    Got %ld, set %ld\n", rd_l, fill_l);
    goto error;
        }
#endif
        if(H5Dclose(dset2) < 0) goto error;
        if(H5Pclose(dcpl) < 0) goto error;
        /* 3. No conversion */
        if((dset3 = H5Dopen2(file, "dset3", H5P_DEFAULT)) < 0) goto error;
        if((dcpl = H5Dget_create_plist(dset3)) < 0) goto error;
#ifndef NO_FILLING
        if(H5Pget_fill_value(dcpl, H5T_NATIVE_LONG, &rd_l) < 0) goto error;
        if(rd_l != fill_l) {
       H5_FAILED();
       HDprintf("    %d: Got a different fill value than what was set.",__LINE__);
       HDprintf("    Got %ld, set %ld\n", rd_l, fill_l);
       goto error;
    H5_FAILED();
    HDprintf("    %d: Got a different fill value than what was set.",__LINE__);
    HDprintf("    Got %ld, set %ld\n", rd_l, fill_l);
    goto error;
        }
#endif
        if(H5Pget_alloc_time(dcpl, &alloc_time) < 0) goto error;
        if(H5Pget_fill_time(dcpl, &fill_time) < 0) goto error;
        if(alloc_time != H5D_ALLOC_TIME_LATE) {
            H5_FAILED();
            puts("    Got non-H5D_ALLOC_TIME_LATE space allocation time.");
            HDprintf("    Got %d\n", alloc_time);
        }
        if(fill_time != H5D_FILL_TIME_ALLOC) {
        if(layout == H5D_CONTIGUOUS && allocation != H5D_SPACE_STATUS_NOT_ALLOCATED) {
            H5_FAILED();
            puts("    Got allocated space instead of unallocated.");
            HDprintf("    Got %d\n", allocation);
            goto error;
        }
        if((dcpl = H5Dget_create_plist(dset4)) < 0) goto error;
        if(H5Pget_alloc_time(dcpl, &alloc_time) < 0) goto error;
        if(H5Pget_fill_time(dcpl, &fill_time) < 0) goto error;
        if(alloc_time != H5D_ALLOC_TIME_LATE) {
       H5_FAILED();
       puts("    Got non-H5D_ALLOC_TIME_LATE space allocation time.");
       HDprintf("    Got %d\n", alloc_time);
    H5_FAILED();
    puts("    Got non-H5D_ALLOC_TIME_LATE space allocation time.");
    HDprintf("    Got %d\n", alloc_time);
        }
        if(fill_time != H5D_FILL_TIME_NEVER) {
       H5_FAILED();
       puts("    Got non-H5D_FILL_TIME_NEVER fill value write time.");
           HDprintf("    Got %d\n", fill_time);
    H5_FAILED();
    puts("    Got non-H5D_FILL_TIME_NEVER fill value write time.");
        HDprintf("    Got %d\n", fill_time);
        }
        if(H5Dclose(dset4) < 0) goto error;
        if(H5Pclose(dcpl) < 0) goto error;
        /* 5. Compound datatype test */
        if((dset9 = H5Dopen2(file, "dset9", H5P_DEFAULT)) < 0) goto error;
        if((dcpl = H5Dget_create_plist(dset9)) < 0) goto error;
        if(H5Pget_fill_value(dcpl, comp_type_id, &rd_c) < 0) goto error;
        if(!H5_FLT_ABS_EQUAL(rd_c.a, 0) || !H5_DBL_ABS_EQUAL(rd_c.y, fill_ctype.y) || rd_c.x != 0 || rd_c.z != '\0') {
           H5_FAILED();
    if(H5Dget_space_status(dset6, &allocation) < 0) goto error;
    if(layout == H5D_CONTIGUOUS && allocation != H5D_SPACE_STATUS_ALLOCATED) {
        H5_FAILED();
        HDprintf("    %d: Got unallocated space instead of allocated.\n",__LINE__);
        HDprintf("    Got %d\n", allocation);
        goto error;
    }
    if(H5Pget_fill_value(dcpl, H5T_NATIVE_LONG, &rd_l) < 0) goto error;
    if(rd_l != fill_l) {
        H5_FAILED();
    HDprintf("    %d: Got a different fill value than what was set.",__LINE__);
    HDprintf("    %d: Got a different fill value than what was set.",__LINE__);
        HDprintf("    Got %ld, set %ld\n", rd_l, fill_l);
        goto error;
    }
    if(H5Pget_alloc_time(dcpl, &alloc_time) < 0) goto error;
    if(alloc_time != H5D_ALLOC_TIME_EARLY) {
        H5_FAILED();
        puts("    Got non-H5D_ALLOC_TIME_EARLY space allocation time.");
        HDprintf("    Got %d\n", alloc_time);
    }
    if(H5Pget_fill_time(dcpl, &fill_time) < 0) goto error;
    if(H5Pclose(dcpl) < 0) goto error;
    /* 3. Compound datatype test */
    if((dset8 = H5Dopen2(file, "dset8", H5P_DEFAULT)) < 0) goto error;
    if((dcpl = H5Dget_create_plist(dset8)) < 0) goto error;
    if(H5Pget_fill_value(dcpl, comp_type_id, &rd_c) < 0) goto error;
    if(!H5_FLT_ABS_EQUAL(rd_c.a, 0) || !H5_DBL_ABS_EQUAL(rd_c.y, fill_ctype.y) || rd_c.x != 0 || rd_c.z != '\0') {
        H5_FAILED();
        puts("    Got wrong fill value");
        HDprintf("    Got rd_c.a=%f, rd_c.y=%f and rd_c.x=%d, rd_c.z=%c\n",
        (double)rd_c.a, rd_c.y, rd_c.x, rd_c.z);
        (double)rd_c.a, rd_c.y, rd_c.x, rd_c.z);
    }
    if(H5Dclose(dset8) < 0) goto error;
    if(H5Pclose(dcpl) < 0) goto error;
    if(H5Fclose(file) < 0) goto error;
    PASSED();
    return 0;
error:
    H5E_BEGIN_TRY {
    H5Pclose(dcpl);
    H5Sclose(space);
    H5Pclose(dcpl);
    H5Sclose(space);
        if(H5D_COMPACT != layout) {
       H5Dclose(dset1);
       H5Dclose(dset2);
       H5Dclose(dset3);
    H5Dclose(dset1);
    H5Dclose(dset2);
    H5Dclose(dset3);
           H5Dclose(dset4);
           H5Dclose(dset9);
        }
        H5Dclose(dset5);
        H5Dclose(dset6);
    H5Dclose(dset8);
    H5Fclose(file);
    H5Dclose(dset8);
    H5Fclose(file);
    } H5E_END_TRY;
    return 1;
}
/*-------------------------------------------------------------------------
 * Function:    test_rdwr_cases
 * Function:    test_rdwr_cases
 *
 * Purpose: Tests fill values read and write for datasets.
 * Purpose:    Tests fill values read and write for datasets.
 *
 * Return:  Success:    0
 * Return:    Success:    0
 *
 *      Failure:    1
 *        Failure:    1
 *
 * Programmer:  Robb Matzke
 * Programmer:    Robb Matzke
 *              Thursday, October  1, 1998
 *
 * Modifications:
 *      This function is called by test_rdwr to write and read
 *      dataset for different cases.
 *         This function is called by test_rdwr to write and read
 *        dataset for different cases.
 *
 *-------------------------------------------------------------------------
 */
static int
test_rdwr_cases(hid_t file, hid_t dcpl, const char *dname, void *_fillval,
        H5D_fill_time_t fill_time, H5D_layout_t layout,
        H5T_class_t datatype, hid_t ctype_id)
        H5D_fill_time_t fill_time, H5D_layout_t layout,
        H5T_class_t datatype, hid_t ctype_id)
{
    hid_t   fspace=-1, mspace=-1, dset1=-1, dset2=-1;
    hsize_t cur_size[5] = {2, 8, 8, 4, 2};
    hsize_t one[5] = {1, 1, 1, 1, 1};
    hsize_t hs_size[5], hs_stride[5];
    hsize_t hs_offset[5], nelmts;
    int     fillval=(-1), val_rd, should_be;
    int     i, j, *buf=NULL, odd;
    hid_t    fspace=-1, mspace=-1, dset1=-1, dset2=-1;
    hsize_t    cur_size[5] = {2, 8, 8, 4, 2};
    hsize_t    one[5] = {1, 1, 1, 1, 1};
    hsize_t    hs_size[5], hs_stride[5];
    hsize_t    hs_offset[5], nelmts;
    int        fillval=(-1), val_rd, should_be;
    int        i, j, *buf=NULL, odd;
    unsigned    u;
    comp_datatype       rd_c, fill_c, should_be_c;
    comp_datatype   *buf_c=NULL;
    comp_datatype    *buf_c=NULL;
    H5D_space_status_t  allocation;
    if(datatype == H5T_INTEGER) {
        fillval = *(int*)_fillval;
    }
    else if(datatype == H5T_COMPOUND) {
        fill_c.a=((comp_datatype*)_fillval)->a;
        fill_c.x=((comp_datatype*)_fillval)->x;
        fill_c.y=((comp_datatype*)_fillval)->y;
        fill_c.z=((comp_datatype*)_fillval)->z;
        goto error;
    if(datatype == H5T_INTEGER && (dset1 = H5Dcreate2(file, dname, H5T_NATIVE_INT, fspace, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
        goto error;
    if(datatype == H5T_COMPOUND && (dset2 = H5Dcreate2(file, dname, ctype_id, fspace, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
        goto error;
    /* Read some data and make sure it's the fill value */
    if((mspace = H5Screate_simple(5, one, NULL)) < 0)
        goto error;
    for (i=0; i<1000; i++) {
    for (j=0; j<5; j++)
        hs_offset[j] = (hsize_t)HDrand() % cur_size[j];
    if(H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_offset, NULL,
                one, NULL) < 0) goto error;
    for (j=0; j<5; j++)
        hs_offset[j] = (hsize_t)HDrand() % cur_size[j];
    if(H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_offset, NULL,
                one, NULL) < 0) goto error;
    /* case for atomic datatype */
    if(datatype==H5T_INTEGER) {
    /* case for atomic datatype */
    if(datatype==H5T_INTEGER) {
            if(H5Dread(dset1, H5T_NATIVE_INT, mspace, fspace, H5P_DEFAULT,
        &val_rd) < 0) goto error;
        if(fill_time!=H5D_FILL_TIME_NEVER && val_rd!=fillval) {
            H5_FAILED();
        &val_rd) < 0) goto error;
        if(fill_time!=H5D_FILL_TIME_NEVER && val_rd!=fillval) {
            H5_FAILED();
                HDfprintf(stdout, "%u: Value read was not a fill value.\n", (unsigned)__LINE__);
            HDfprintf(stdout,"    Elmt={%Hu,%Hu,%Hu,%Hu,%Hu}, read: %u, "
               "Fill value: %u\n",
               hs_offset[0], hs_offset[1],
               hs_offset[2], hs_offset[3],
               hs_offset[4], val_rd, fillval);
            goto error;
        }
    /* case for compound datatype */
    }
            HDfprintf(stdout,"    Elmt={%Hu,%Hu,%Hu,%Hu,%Hu}, read: %u, "
            "Fill value: %u\n",
            hs_offset[0], hs_offset[1],
            hs_offset[2], hs_offset[3],
            hs_offset[4], val_rd, fillval);
            goto error;
        }
    /* case for compound datatype */
    }
    else if(datatype==H5T_COMPOUND) {
            if(H5Dread(dset2, ctype_id, mspace, fspace, H5P_DEFAULT,
                &rd_c) < 0) goto error;
            if(fill_time != H5D_FILL_TIME_NEVER && (!H5_FLT_ABS_EQUAL(rd_c.a, fill_c.a) ||
                    rd_c.x != fill_c.x || !H5_DBL_ABS_EQUAL(rd_c.y, fill_c.y) ||
                    rd_c.z != fill_c.z)) {
                H5_FAILED();
                HDfprintf(stdout, "%u: Value read was not a fill value.\n", (unsigned)__LINE__);
                HDfprintf(stdout,"    Elmt={%Hu,%Hu,%Hu,%Hu,%Hu}, read: %f, %d, %f, %c"
                       "Fill value: %f, %d, %f, %c\n",
                       hs_offset[0], hs_offset[1],
                       hs_offset[2], hs_offset[3],
                       hs_offset[4], (double)rd_c.a, rd_c.x, rd_c.y, rd_c.z,
            (double)fill_c.a, fill_c.x, fill_c.y, fill_c.z);
            (double)fill_c.a, fill_c.x, fill_c.y, fill_c.z);
                goto error;
            }
        }
    }
    if(H5Sclose(mspace) < 0) goto error;
    /* Select all odd data locations in the file dataset */
    for (i=0, nelmts=1; i<5; i++) {
        hs_size[i] = cur_size[i]/2;
        hs_offset[i] = 0;
                           hs_offset[4], buf[u], fillval);
                    goto error;
                } /* end if */
            } /* end for */
        } /* end if */
    }
    /* case for compound datatype */
    else if(datatype == H5T_COMPOUND) {
        /*check for overflow*/
        HDassert((nelmts * sizeof(comp_datatype)) ==
        (hsize_t)((size_t)(nelmts * sizeof(comp_datatype))));
    buf_c = (comp_datatype *)HDmalloc((size_t)nelmts * sizeof(comp_datatype));
        (hsize_t)((size_t)(nelmts * sizeof(comp_datatype))));
    buf_c = (comp_datatype *)HDmalloc((size_t)nelmts * sizeof(comp_datatype));
        if(H5Dread(dset2, ctype_id, mspace, fspace, H5P_DEFAULT, buf_c) < 0)
            goto error;
        /* Verify values, except if no fill value written */
        if(fill_time != H5D_FILL_TIME_NEVER) {
            for(u = 0; u < nelmts; u++) {
                if(!H5_FLT_ABS_EQUAL(buf_c[u].a, fill_c.a) || buf_c[u].x != fill_c.x ||
                        !H5_DBL_ABS_EQUAL(buf_c[u].y, fill_c.y) || buf_c[u].z != fill_c.z) {
                    H5_FAILED();
    if(datatype == H5T_INTEGER) {
        for(u = 0; u < nelmts; u++)
            buf[u] = 9999;
        if(H5Dwrite(dset1, H5T_NATIVE_INT, mspace, fspace, H5P_DEFAULT, buf) < 0)
            goto error;
    }
    /* case for compound datatype */
    else if(datatype == H5T_COMPOUND) {
        HDmemset(buf_c, 0, ((size_t)nelmts * sizeof(comp_datatype)));
        for(u = 0; u < nelmts; u++) {
        buf_c[u].a = 1111.11F;
        buf_c[u].x = 2222;
        buf_c[u].y = 3333.3333F;
        buf_c[u].z = 'd';
    }
        buf_c[u].a = 1111.11F;
        buf_c[u].x = 2222;
        buf_c[u].y = 3333.3333F;
        buf_c[u].z = 'd';
    }
        if(H5Dwrite(dset2, ctype_id, mspace, fspace, H5P_DEFAULT, buf_c) < 0)
            goto error;
    }
    /* Check if space is allocated */
    if(datatype==H5T_INTEGER && H5Dget_space_status(dset1, &allocation) < 0)
    goto error;
    goto error;
    if(datatype==H5T_COMPOUND && H5Dget_space_status(dset2, &allocation) < 0)
        goto error;
    if(layout == H5D_CONTIGUOUS && allocation != H5D_SPACE_STATUS_ALLOCATED) {
        H5_FAILED();
        HDprintf("    %d: Got unallocated space instead of allocated.\n",__LINE__);
        HDprintf("    Got %d\n", allocation);
        goto error;
    }
    HDfree(buf);
    buf = NULL;
    H5Sclose(mspace);
    /* Read some data and make sure it's the right value */
    if((mspace = H5Screate_simple(5, one, NULL)) < 0)
        goto error;
    for(i = 0; i < 1000; i++) {
    for(j = 0, odd = 0; j < 5; j++) {
        hs_offset[j] = (hsize_t)HDrand() % cur_size[j];
        odd += (int)(hs_offset[j]%2);
    } /* end for */
    if(H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_offset, NULL, one, NULL) < 0)
    for(j = 0, odd = 0; j < 5; j++) {
        hs_offset[j] = (hsize_t)HDrand() % cur_size[j];
        odd += (int)(hs_offset[j]%2);
    } /* end for */
    if(H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_offset, NULL, one, NULL) < 0)
            goto error;
    /* case for atomic datatype */
    /* case for atomic datatype */
        if(datatype==H5T_INTEGER) {
        if(H5Dread(dset1, H5T_NATIVE_INT, mspace, fspace, H5P_DEFAULT, &val_rd) < 0)
        if(H5Dread(dset1, H5T_NATIVE_INT, mspace, fspace, H5P_DEFAULT, &val_rd) < 0)
                goto error;
            if(fill_time == H5D_FILL_TIME_ALLOC) {
                should_be = odd ? fillval : 9999;
                if(val_rd!=should_be) {
                    H5_FAILED();
                    HDfprintf(stdout, "%u: Value read was not correct.\n", (unsigned)__LINE__);
                    HDprintf("    Elmt={%ld,%ld,%ld,%ld,%ld}, read: %u, "
                           "should be: %u\n",
                           (long)hs_offset[0], (long)hs_offset[1],
                           (long)hs_offset[2], (long)hs_offset[3],
                           (long)hs_offset[4], val_rd, should_be);
                    goto error;
                }
        }
        else if(fill_time == H5D_FILL_TIME_NEVER && !odd) {
            should_be = 9999;
            if(val_rd!=should_be) {
                H5_FAILED();
        }
        else if(fill_time == H5D_FILL_TIME_NEVER && !odd) {
            should_be = 9999;
            if(val_rd!=should_be) {
                H5_FAILED();
                    HDfprintf(stdout, "%u: Value read was not correct.\n", (unsigned)__LINE__);
                HDprintf("    Elmt={%ld,%ld,%ld,%ld,%ld}, read: %u, "
                   "should be: %u\n",
                   (long)hs_offset[0], (long)hs_offset[1],
                   (long)hs_offset[2], (long)hs_offset[3],
                   (long)hs_offset[4], val_rd, should_be);
                goto error;
            }
        } else if(fill_time == H5D_FILL_TIME_NEVER && odd) {
            /*Trash data. Don't compare*/
        }
    } /* end for datatype==H5T_INTEGER */
    /* case for compound datatype */
    else if(datatype==H5T_COMPOUND) {
                HDprintf("    Elmt={%ld,%ld,%ld,%ld,%ld}, read: %u, "
                "should be: %u\n",
                (long)hs_offset[0], (long)hs_offset[1],
                (long)hs_offset[2], (long)hs_offset[3],
                (long)hs_offset[4], val_rd, should_be);
                goto error;
            }
        } else if(fill_time == H5D_FILL_TIME_NEVER && odd) {
            /*Trash data. Don't compare*/
        }
    } /* end for datatype==H5T_INTEGER */
    /* case for compound datatype */
    else if(datatype==H5T_COMPOUND) {
            if(H5Dread(dset2, ctype_id, mspace, fspace, H5P_DEFAULT, &rd_c) < 0)
                goto error;
            if(fill_time == H5D_FILL_TIME_ALLOC) {
        if(odd) {
            should_be_c.a=fill_c.a;
            should_be_c.x=fill_c.x;
            should_be_c.y=fill_c.y;
            should_be_c.z=fill_c.z;
        } else {
            should_be_c.a=buf_c[0].a;
            should_be_c.x=buf_c[0].x;
            should_be_c.y=buf_c[0].y;
            should_be_c.z=buf_c[0].z;
        }
        if(!H5_FLT_ABS_EQUAL(rd_c.a, should_be_c.a) || rd_c.x != should_be_c.x ||
            !H5_DBL_ABS_EQUAL(rd_c.y, should_be_c.y) || rd_c.z != should_be_c.z)  {
        if(odd) {
            should_be_c.a=fill_c.a;
            should_be_c.x=fill_c.x;
            should_be_c.y=fill_c.y;
            should_be_c.z=fill_c.z;
        } else {
            should_be_c.a=buf_c[0].a;
            should_be_c.x=buf_c[0].x;
            should_be_c.y=buf_c[0].y;
            should_be_c.z=buf_c[0].z;
        }
        if(!H5_FLT_ABS_EQUAL(rd_c.a, should_be_c.a) || rd_c.x != should_be_c.x ||
            !H5_DBL_ABS_EQUAL(rd_c.y, should_be_c.y) || rd_c.z != should_be_c.z)  {
                    H5_FAILED();
                    HDfprintf(stdout, "%u: Value read was not correct.\n", (unsigned)__LINE__);
                    HDprintf("    Elmt={%ld,%ld,%ld,%ld,%ld}, read: %f,%d,%f,%c "
                           "should be: %f,%d,%f,%c\n",
                           (long)hs_offset[0], (long)hs_offset[1],
                           (long)hs_offset[2], (long)hs_offset[3],
                           (long)hs_offset[4],
               (double)rd_c.a, rd_c.x, rd_c.y, rd_c.z, (double)should_be_c.a,
                   should_be_c.x,should_be_c.y,should_be_c.z);
            (double)rd_c.a, rd_c.x, rd_c.y, rd_c.z, (double)should_be_c.a,
                should_be_c.x,should_be_c.y,should_be_c.z);
                    goto error;
        }
        } /* end for fill_time == H5D_FILL_TIME_ALLOC */
        else if(fill_time == H5D_FILL_TIME_NEVER && !odd) {
        }
        } /* end for fill_time == H5D_FILL_TIME_ALLOC */
        else if(fill_time == H5D_FILL_TIME_NEVER && !odd) {
                should_be_c.a=buf_c[0].a;
                should_be_c.x=buf_c[0].x;
                should_be_c.y=buf_c[0].y;
                should_be_c.z=buf_c[0].z;
        if(!H5_FLT_ABS_EQUAL(rd_c.a, should_be_c.a) || rd_c.x != should_be_c.x ||
            !H5_DBL_ABS_EQUAL(rd_c.y, should_be_c.y) || rd_c.z != should_be_c.z)  {
        if(!H5_FLT_ABS_EQUAL(rd_c.a, should_be_c.a) || rd_c.x != should_be_c.x ||
            !H5_DBL_ABS_EQUAL(rd_c.y, should_be_c.y) || rd_c.z != should_be_c.z)  {
                    H5_FAILED();
                    HDfprintf(stdout, "%u: Value read was not correct.\n", (unsigned)__LINE__);
                    HDprintf("    Elmt={%ld,%ld,%ld,%ld,%ld}, read: %f,%d,%f,%c "
                           "should be: %f,%d,%f,%c\n",
                           (long)hs_offset[0], (long)hs_offset[1],
                           (long)hs_offset[2], (long)hs_offset[3],
                           (long)hs_offset[4],
                           (double)rd_c.a, rd_c.x, rd_c.y, rd_c.z, (double)should_be_c.a,
                           should_be_c.x,should_be_c.y,should_be_c.z);
                    goto error;
                }
        } /* end for fill_time == H5D_FILL_TIME_NEVER */
        } /* end for fill_time == H5D_FILL_TIME_NEVER */
            else if(fill_time == H5D_FILL_TIME_NEVER && odd) {
                /*Trash data. Don't compare*/
            }
    } /* end for datatype==H5T_COMPOUND */
    } /* end for datatype==H5T_COMPOUND */
    }
    if(datatype == H5T_COMPOUND) {
        HDfree(buf_c);
        buf_c = NULL;
    } /* end if */
    if(H5Sclose(mspace) < 0) goto error;
    if(datatype==H5T_INTEGER && H5Dclose(dset1) < 0) goto error;
    if(datatype==H5T_COMPOUND && H5Dclose(dset2) < 0) goto error;
    if(H5Sclose(fspace) < 0) goto error;
    return 0;
 error:
    H5E_BEGIN_TRY {
    if(datatype==H5T_INTEGER) H5Dclose(dset1);
    if(datatype==H5T_COMPOUND) H5Dclose(dset2);
    H5Sclose(fspace);
    H5Sclose(mspace);
    if(datatype==H5T_INTEGER) H5Dclose(dset1);
    if(datatype==H5T_COMPOUND) H5Dclose(dset2);
    H5Sclose(fspace);
    H5Sclose(mspace);
    } H5E_END_TRY;
    return 1;
}
/*-------------------------------------------------------------------------
 * Function:    test_rdwr
 *
 * Purpose:     Tests fill values for datasets.
 *
 * Return:      Success:        0
 *
 *              Failure:        number of errors
 *
 * Programmer:  Robb Matzke
 *              Thursday, October  1, 1998
 *
 * Modifications:
 *      Many new cases have been added to this test since the
 *      fill value design is modified.
 *        Many new cases have been added to this test since the
 *        fill value design is modified.
 *
 *-------------------------------------------------------------------------
 */
static int
test_rdwr(hid_t fapl, const char *base_name, H5D_layout_t layout)
{
    char        filename[1024];
    hid_t   file=-1, dcpl=-1, ctype_id=-1;
    hid_t     file=-1, dcpl=-1, ctype_id=-1;
    hsize_t     ch_size[5] = {2, 8, 8, 4, 2};
    int     nerrors=0;
    int        nerrors=0;
    int         fillval = 0x4c70f1cd;
    comp_datatype       fill_ctype={0,0,0,0};
    if(H5D_CHUNKED==layout) {
        TESTING("chunked dataset I/O");
    } else if(H5D_COMPACT==layout) {
        TESTING("compact dataset I/O");
    } else {
        TESTING("contiguous dataset I/O");
    }
        nerrors += test_rdwr_cases(file, dcpl, "dset5", &fillval, H5D_FILL_TIME_NEVER,
                                   layout, H5T_INTEGER, (hid_t)-1);
        /* case for H5D_FILL_TIME_ALLOC as fill write time and fill value is user-defined
         * as compound type */
        if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_ALLOC) < 0) goto error;
        HDmemset(&fill_ctype, 0, sizeof(fill_ctype));
        fill_ctype.y = 4444.4444F;
        if(H5Pset_fill_value(dcpl, ctype_id, &fill_ctype) < 0) goto error;
        nerrors += test_rdwr_cases(file, dcpl, "dset11", &fill_ctype, H5D_FILL_TIME_ALLOC,
                layout, H5T_COMPOUND, ctype_id);
                layout, H5T_COMPOUND, ctype_id);
        if(H5Pclose(dcpl) < 0) goto error;
        if((dcpl=H5Pcreate(H5P_DATASET_CREATE)) < 0) goto error;
        if(H5D_CHUNKED==layout) {
            if(H5Pset_chunk(dcpl, 5, ch_size) < 0) goto error;
        }
    }
    /* II.  Test H5D_ALLOC_TIME_EARLY space allocation cases */
     * as compound type */
    if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_ALLOC) < 0) goto error;
    HDmemset(&fill_ctype, 0, sizeof(fill_ctype));
    fill_ctype.y = 4444.4444F;
    if(H5Pset_fill_value(dcpl, ctype_id, &fill_ctype) < 0) goto error;
    nerrors += test_rdwr_cases(file, dcpl, "dset12", &fill_ctype, H5D_FILL_TIME_ALLOC,
                                layout, H5T_COMPOUND, ctype_id);
    if(nerrors)
    goto error;
    goto error;
    if(H5Pclose(dcpl) < 0) goto error;
    if(H5Tclose(ctype_id) < 0) goto error;
    if(H5Fclose(file) < 0) goto error;
    PASSED();
    return 0;
 error:
    H5E_BEGIN_TRY {
        H5Pclose(dcpl);
    H5Tclose(ctype_id);
    H5Tclose(ctype_id);
        H5Fclose(file);
    } H5E_END_TRY;
    return nerrors;
}
/*-------------------------------------------------------------------------
 * Function:    test_extend_init_integer
 * Function:    test_extend_init_integer
 *
 * Purpose: Initializes integer values
 * Purpose:    Initializes integer values
 *
 * Return:  Success:    0
 *      Failure:    < 0
 * Return:    Success:    0
 *        Failure:    < 0
 *
 * Programmer:  Quincey Koziol
 * Programmer:    Quincey Koziol
 *              Tuesday, July  3, 2007
 *
 *-------------------------------------------------------------------------
 */
static int
test_extend_init_integer(void *_buf, size_t nelmts, const void *_val)
{
    int *buf = (int *)_buf;                     /* Buffer to initialize */
    const int   *val = (const int *)_val;       /* Value to use */
    while(nelmts) {
        *buf++ = *val;
        nelmts--;
    } /* end while */
    return 0;
} /* end test_extend_init_integer() */
/*-------------------------------------------------------------------------
 * Function:    test_extend_verify_integer
 * Function:    test_extend_verify_integer
 *
 * Purpose: Verifies integer values
 * Purpose:    Verifies integer values
 *
 * Return:  Success:    0
 *      Failure:    < 0
 * Return:    Success:    0
 *        Failure:    < 0
 *
 * Programmer:  Quincey Koziol
 * Programmer:    Quincey Koziol
 *              Tuesday, July  3, 2007
 *
 *-------------------------------------------------------------------------
 */
static int
test_extend_verify_integer(unsigned lineno, const hsize_t *offset,
    const void *_test_val, const void *_compare_val)
{
    const int   *test_val = (const int *)_test_val;             /* Value to test */
    const int   *compare_val = (const int *)_compare_val;       /* Value to compare against */
                offset[4], *test_val, *compare_val);
        goto error;
    } /* end if */
    return 0;
error:
    return -1;
} /* end test_extend_verify_integer() */
/*-------------------------------------------------------------------------
 * Function:    test_extend_release_integer
 * Function:    test_extend_release_integer
 *
 * Purpose: Release element of integer value
 * Purpose:    Release element of integer value
 *
 * Return:  Success:    0
 *      Failure:    < 0
 * Return:    Success:    0
 *        Failure:    < 0
 *
 * Programmer:  Quincey Koziol
 * Programmer:    Quincey Koziol
 *              Tuesday, July  3, 2007
 *
 *-------------------------------------------------------------------------
 */
static int
test_extend_release_integer(void H5_ATTR_UNUSED *_elmt)
{
    return 0;
} /* end test_extend_release_integer() */
/*-------------------------------------------------------------------------
 * Function:    test_extend_init_cmpd_vl
 * Function:    test_extend_init_cmpd_vl
 *
 * Purpose: Initializes compound+vl values
 * Purpose:    Initializes compound+vl values
 *
 * Return:  Success:    0
 *      Failure:    < 0
 * Return:    Success:    0
 *        Failure:    < 0
 *
 * Programmer:  Quincey Koziol
 * Programmer:    Quincey Koziol
 *              Tuesday, July  3, 2007
 *
 *-------------------------------------------------------------------------
 */
static int
test_extend_init_cmpd_vl(void *_buf, size_t nelmts, const void *_val)
{
    comp_vl_datatype *buf = (comp_vl_datatype *)_buf;                     /* Buffer to initialize */
    const comp_vl_datatype   *val = (const comp_vl_datatype *)_val;       /* Value to use */
        buf->a = HDstrdup(val->a);
        buf->b = HDstrdup(val->b);
        buf++;
        nelmts--;
    } /* end while */
    return 0;
} /* end test_extend_init_cmpd_vl() */
/*-------------------------------------------------------------------------
 * Function:    test_extend_verify_cmpd_vl
 * Function:    test_extend_verify_cmpd_vl
 *
 * Purpose: Verifies compound+vl values
 * Purpose:    Verifies compound+vl values
 *
 * Return:  Success:    0
 *      Failure:    < 0
 * Return:    Success:    0
 *        Failure:    < 0
 *
 * Programmer:  Quincey Koziol
 * Programmer:    Quincey Koziol
 *              Tuesday, July  3, 2007
 *
 *-------------------------------------------------------------------------
 */
static int
test_extend_verify_cmpd_vl(unsigned lineno, const hsize_t *offset,
    const void *_test_val, const void *_compare_val)
{
    const comp_vl_datatype   *test_val = (const comp_vl_datatype *)_test_val;             /* Value to test */
    const comp_vl_datatype   *compare_val = (const comp_vl_datatype *)_compare_val;       /* Value to compare against */
                compare_val->x, compare_val->a, compare_val->b, compare_val->y);
        goto error;
    } /* end if */
    return 0;
error:
    return -1;
} /* end test_extend_verify_cmpd_vl() */
/*-------------------------------------------------------------------------
 * Function:    test_extend_release_cmpd_vl
 * Function:    test_extend_release_cmpd_vl
 *
 * Purpose: Release element of compound+vl value
 * Purpose:    Release element of compound+vl value
 *
 * Return:  Success:    0
 *      Failure:    < 0
 * Return:    Success:    0
 *        Failure:    < 0
 *
 * Programmer:  Quincey Koziol
 * Programmer:    Quincey Koziol
 *              Tuesday, July  3, 2007
 *
 *-------------------------------------------------------------------------
 */
static int
test_extend_release_cmpd_vl(void *_elmt)
{
    comp_vl_datatype   *elmt = (comp_vl_datatype *)_elmt;             /* Element to free */
    /* Free memory for string fields */
    HDfree(elmt->a);
    HDfree(elmt->b);
    return 0;
} /* end test_extend_release_integer() */
/*-------------------------------------------------------------------------
 * Function:    test_extend_cases
 * Function:    test_extend_cases
 *
 * Purpose: Called to test fill values with various different values
 * Purpose:    Called to test fill values with various different values
 *
 * Return:  Success:    0
 *      Failure:    number of errors
 * Return:    Success:    0
 *        Failure:    number of errors
 *
 * Programmer:  Quincey Koziol
 * Programmer:    Quincey Koziol
 *              Tuesday, July  3, 2007
 *
 *-------------------------------------------------------------------------
 */
static int
test_extend_cases(hid_t file, hid_t _dcpl, const char *dset_name,
    hsize_t *ch_size, hsize_t *start_size, hsize_t *max_size, hid_t dtype, void *fillval)
{
    hid_t   fspace = -1, mspace = -1;       /* File & memory dataspaces */
    hid_t   dset = -1;                      /* Dataset ID */
    hid_t    fspace = -1, mspace = -1;       /* File & memory dataspaces */
    hid_t    dset = -1;                      /* Dataset ID */
    hid_t       dcpl = -1;                      /* Dataset creation property list */
    hsize_t extend_size[5];                 /* Dimensions to extend to */
    hsize_t one[5] = {1, 1, 1, 1, 1};       /* Dimensions of single element dataspace */
    hsize_t hs_size[5], hs_stride[5], hs_offset[5];
    size_t  nelmts;
    hsize_t    extend_size[5];                 /* Dimensions to extend to */
    hsize_t    one[5] = {1, 1, 1, 1, 1};       /* Dimensions of single element dataspace */
    hsize_t    hs_size[5], hs_stride[5], hs_offset[5];
    size_t    nelmts;
    H5T_class_t dtype_class;            /* Class of datatype */
    int         (*init_rtn)(void *, size_t, const void *);
    int         (*verify_rtn)(unsigned, const hsize_t *, const void *, const void *);
    int         (*release_rtn)(void *);
    size_t      val_size;               /* Size of element */
    void        *val_rd, *odd_val;
    const void  *init_val, *should_be, *even_val;
    int     val_rd_i, init_val_i = 9999;
    int        val_rd_i, init_val_i = 9999;
    comp_vl_datatype init_val_c = {87, "baz", "mumble", 129};
    comp_vl_datatype val_rd_c;
    void    *buf = NULL;
    unsigned    odd;                    /* Whether an odd or even coord. was read */
    unsigned    i, j;                   /* Local index variables */
    void    *buf = NULL;
    unsigned    odd;                    /* Whether an odd or even coord. was read */
    unsigned    i, j;                   /* Local index variables */
    /* Make copy of dataset creation property list */
    if((dcpl = H5Pcopy(_dcpl)) < 0) TEST_ERROR
#ifndef NO_FILLING
    if(H5Pset_fill_value(dcpl, dtype, fillval) < 0) TEST_ERROR
#endif
    /* Get class of datatype */
    if((dtype_class = H5Tget_class(dtype)) < 0) TEST_ERROR
        val_rd = &val_rd_c;
        odd_val = fillval;
        even_val = &init_val_c;
    } /* end else */
    /* Read some data and make sure it's the fill value */
    if((mspace = H5Screate_simple(5, one, NULL)) < 0) TEST_ERROR
    for(i = 0; i < 1000; i++) {
        /* Set offset for random element */
    for(j = 0; j < 5; j++)
        hs_offset[j] = (hsize_t)HDrand() % start_size[j];
    for(j = 0; j < 5; j++)
        hs_offset[j] = (hsize_t)HDrand() % start_size[j];
        /* Select the random element */
    if(H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_offset, NULL, one, NULL) < 0) TEST_ERROR
    if(H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_offset, NULL, one, NULL) < 0) TEST_ERROR
        /* Read the random element */
    if(H5Dread(dset, dtype, mspace, fspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
    if(H5Dread(dset, dtype, mspace, fspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
        /* Verify the element read in */
        if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, fillval) < 0) TEST_ERROR
        /* Release any VL components */
        if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
        /* Clear the read buffer */
        HDmemset(val_rd, 0, val_size);
    } /* end for */
    if(H5Sclose(mspace) < 0) TEST_ERROR
    /* Initialize dataspace & hyperslab info */
    for(i = 0, nelmts = 1; i < 5; i++) {
    hs_size[i] = (start_size[i] + 1) / 2;
    hs_offset[i] = 0;
    hs_stride[i] = 2;
    nelmts *= hs_size[i];
    hs_size[i] = (start_size[i] + 1) / 2;
    hs_offset[i] = 0;
    hs_stride[i] = 2;
    nelmts *= hs_size[i];
    } /* end for */
    /* Check for overflow */
    assert((nelmts * val_size) == (hsize_t)((size_t)(nelmts * val_size)));
    /* Allocate & initialize buffer */
    buf = HDmalloc((size_t)(nelmts * val_size));
    init_rtn(buf, nelmts, init_val);
    /* Create dataspace describing memory buffer */
    if(H5Dwrite(dset, dtype, mspace, fspace, H5P_DEFAULT, buf) < 0) TEST_ERROR
    /* Close memory dataspace */
    if(H5Sclose(mspace) < 0) TEST_ERROR
    /* Read some data and make sure it's the right value */
    if((mspace = H5Screate_simple(5, one, NULL)) < 0) TEST_ERROR
    for(i = 0; i < 1000; i++) {
        /* Set offset for random element */
    for(j = 0, odd = 0; j < 5; j++) {
        hs_offset[j] = (hsize_t)HDrand() % start_size[j];
        odd += (unsigned)(hs_offset[j] % 2);
    } /* end for */
    for(j = 0, odd = 0; j < 5; j++) {
        hs_offset[j] = (hsize_t)HDrand() % start_size[j];
        odd += (unsigned)(hs_offset[j] % 2);
    } /* end for */
        /* Select the random element */
    if(H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_offset, NULL, one, NULL) < 0) TEST_ERROR
    if(H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_offset, NULL, one, NULL) < 0) TEST_ERROR
        /* Read the random element */
    if(H5Dread(dset, dtype, mspace, fspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
    if(H5Dread(dset, dtype, mspace, fspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
        /* Verify the element read in */
    should_be = odd ? odd_val : even_val;
    should_be = odd ? odd_val : even_val;
        if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, should_be) < 0) TEST_ERROR
        /* Release any VL components */
        if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
        /* Clear the read buffer */
        HDmemset(val_rd, 0, val_size);
    } /* end for */
    if(H5Sclose(mspace) < 0) TEST_ERROR
    /* Re-open file dataspace */
    if(H5Sclose(fspace) < 0) TEST_ERROR
    if((fspace = H5Dget_space(dset)) < 0) TEST_ERROR
    /* Read some data and make sure it's the right value */
    if((mspace = H5Screate_simple(5, one, NULL)) < 0) TEST_ERROR
    for(i = 0; i < 1000; i++) {
        /* Set offset for random element */
    for(j = 0, odd = 0; j < 5; j++) {
        hs_offset[j] = (hsize_t)HDrand() % extend_size[j];
        if(hs_offset[j] >= start_size[j])
        odd = 1;
        else
        odd += (unsigned)(hs_offset[j] % 2);
    } /* end for */
    for(j = 0, odd = 0; j < 5; j++) {
        hs_offset[j] = (hsize_t)HDrand() % extend_size[j];
        if(hs_offset[j] >= start_size[j])
        odd = 1;
        else
        odd += (unsigned)(hs_offset[j] % 2);
    } /* end for */
        /* Select the random element */
    if(H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_offset, NULL, one, NULL) < 0) TEST_ERROR
    if(H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_offset, NULL, one, NULL) < 0) TEST_ERROR
        /* Read the random element */
    if(H5Dread(dset, dtype, mspace, fspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
    if(H5Dread(dset, dtype, mspace, fspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
        /* Verify the element read in */
    should_be = odd ? odd_val : even_val;
    should_be = odd ? odd_val : even_val;
        if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, should_be) < 0) TEST_ERROR
        /* Release any VL components */
        if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
        /* Clear the read buffer */
        HDmemset(val_rd, 0, val_size);
    } /* end for */
    if(H5Sclose(mspace) < 0) TEST_ERROR
    /* Re-open file dataspace */
    if(H5Sclose(fspace) < 0) TEST_ERROR
    if((fspace = H5Dget_space(dset)) < 0) TEST_ERROR
    /* Read some data and make sure it's the right value */
    if((mspace = H5Screate_simple(5, one, NULL)) < 0) TEST_ERROR
    for(i = 0; i < 1000; i++) {
        /* Set offset for random element */
    for(j = 0, odd = 0; j < 5; j++) {
        hs_offset[j] = (hsize_t)HDrand() % max_size[j];
        if(hs_offset[j] >= start_size[j])
        odd = 1;
        else
        odd += (unsigned)(hs_offset[j] % 2);
    } /* end for */
    for(j = 0, odd = 0; j < 5; j++) {
        hs_offset[j] = (hsize_t)HDrand() % max_size[j];
        if(hs_offset[j] >= start_size[j])
        odd = 1;
        else
        odd += (unsigned)(hs_offset[j] % 2);
    } /* end for */
        /* Select the random element */
    if(H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_offset, NULL, one, NULL) < 0) TEST_ERROR
    if(H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_offset, NULL, one, NULL) < 0) TEST_ERROR
        /* Read the random element */
    if(H5Dread(dset, dtype, mspace, fspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
    if(H5Dread(dset, dtype, mspace, fspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
        /* Verify the element read in */
    should_be = odd ? odd_val : even_val;
    should_be = odd ? odd_val : even_val;
        if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, should_be) < 0) TEST_ERROR
        /* Release any VL components */
        if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
        /* Clear the read buffer */
        HDmemset(val_rd, 0, val_size);
    } /* end for */
    if(H5Sclose(mspace) < 0) TEST_ERROR
    /* Re-open file dataspace */
    if(H5Sclose(fspace) < 0) TEST_ERROR
    if((fspace = H5Dget_space(dset)) < 0) TEST_ERROR
    /* Read some data and make sure it's the right value */
    if((mspace = H5Screate_simple(5, one, NULL)) < 0) TEST_ERROR
    for(i = 0; i < 1000; i++) {
        /* Set offset for random element */
    for(j = 0, odd = 0; j < 5; j++) {
        hs_offset[j] = (hsize_t)HDrand() % extend_size[j];
        if(hs_offset[j] >= start_size[j])
        odd = 1;
        else
        odd += (unsigned)(hs_offset[j] % 2);
    } /* end for */
    for(j = 0, odd = 0; j < 5; j++) {
        hs_offset[j] = (hsize_t)HDrand() % extend_size[j];
        if(hs_offset[j] >= start_size[j])
        odd = 1;
        else
        odd += (unsigned)(hs_offset[j] % 2);
    } /* end for */
        /* Select the random element */
    if(H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_offset, NULL, one, NULL) < 0) TEST_ERROR
    if(H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_offset, NULL, one, NULL) < 0) TEST_ERROR
        /* Read the random element */
    if(H5Dread(dset, dtype, mspace, fspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
    if(H5Dread(dset, dtype, mspace, fspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
        /* Verify the element read in */
    should_be = odd ? odd_val : even_val;
    should_be = odd ? odd_val : even_val;
        if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, should_be) < 0) TEST_ERROR
        /* Release any VL components */
        if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
        /* Clear the read buffer */
        HDmemset(val_rd, 0, val_size);
    } /* end for */
    if(H5Sclose(mspace) < 0) TEST_ERROR
    /* Release any VL components */
    if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
    /* Clear the read buffer */
    HDmemset(val_rd, 0, val_size);
    /* Read some data and make sure it's the right value */
    for(i = 0; i < 1000; i++) {
        /* Set offset for random element */
    for(j = 0, odd = 0; j < 5; j++) {
        hs_offset[j] = (hsize_t)HDrand() % extend_size[j];
        if(hs_offset[j] >= start_size[j])
        odd = 1;
        else
        odd += (unsigned)(hs_offset[j] % 2);
    } /* end for */
    for(j = 0, odd = 0; j < 5; j++) {
        hs_offset[j] = (hsize_t)HDrand() % extend_size[j];
        if(hs_offset[j] >= start_size[j])
        odd = 1;
        else
        odd += (unsigned)(hs_offset[j] % 2);
    } /* end for */
        /* Select the random element */
    if(H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_offset, NULL, one, NULL) < 0) TEST_ERROR
    if(H5Sselect_hyperslab(fspace, H5S_SELECT_SET, hs_offset, NULL, one, NULL) < 0) TEST_ERROR
        /* Read the random element */
    if(H5Dread(dset, dtype, mspace, fspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
    if(H5Dread(dset, dtype, mspace, fspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
        /* Verify the element read in */
    should_be = odd ? odd_val : even_val;
    should_be = odd ? odd_val : even_val;
        if(verify_rtn((unsigned)__LINE__, hs_offset, val_rd, should_be) < 0) TEST_ERROR
        /* Release any VL components */
        if(H5Dvlen_reclaim(dtype, mspace, H5P_DEFAULT, val_rd) < 0) TEST_ERROR
        /* Clear the read buffer */
        HDmemset(val_rd, 0, val_size);
    } /* end for */
    if(H5Sclose(mspace) < 0) TEST_ERROR
    if(H5Pclose(dcpl) < 0) TEST_ERROR
    if(H5Dclose(dset) < 0) TEST_ERROR
    if(H5Sclose(fspace) < 0) TEST_ERROR
    return 0;
error:
    if(buf)
        HDfree(buf);
    H5E_BEGIN_TRY {
    H5Pclose(dcpl);
    H5Dclose(dset);
    H5Sclose(fspace);
    H5Sclose(mspace);
    H5Pclose(dcpl);
    H5Dclose(dset);
    H5Sclose(fspace);
    H5Sclose(mspace);
    } H5E_END_TRY;
    return -1;
} /* end test_extend_cases() */
/*-------------------------------------------------------------------------
 * Function:    test_extend
 * Function:    test_extend
 *
 * Purpose: Test that filling works okay when a dataset is extended.
 * Purpose:    Test that filling works okay when a dataset is extended.
 *
 * Return:  Success:    0
 * Return:    Success:    0
 *
 *      Failure:    number of errors
 *        Failure:    number of errors
 *
 * Programmer:  Robb Matzke
 * Programmer:    Robb Matzke
 *              Monday, October  5, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
static int
test_extend(hid_t fapl, const char *base_name, H5D_layout_t layout)
{
    hid_t   file = -1;              /* File ID */
    hid_t   dcpl = -1;              /* Dataset creation property list ID */
    hid_t   cmpd_vl_tid = -1;       /* Compound+vl datatype ID */
    hsize_t start_size[5] = {8, 8, 8, 4, 2};
    hsize_t max_size[5] = {32, 32, 32, 16, 8};
    hsize_t ch_size[5] = {1, 8, 8, 4, 2};
    hid_t    file = -1;              /* File ID */
    hid_t    dcpl = -1;              /* Dataset creation property list ID */
    hid_t    cmpd_vl_tid = -1;       /* Compound+vl datatype ID */
    hsize_t    start_size[5] = {8, 8, 8, 4, 2};
    hsize_t    max_size[5] = {32, 32, 32, 16, 8};
    hsize_t    ch_size[5] = {1, 8, 8, 4, 2};
#ifdef NO_FILLING
    int     fillval_i = 0;
    int        fillval_i = 0;
#else
    int     fillval_i = 0x4c70f1cd;
    int        fillval_i = 0x4c70f1cd;
#endif
    comp_vl_datatype fillval_c = {32, "foo", "bar", 64};         /* Fill value for compound+vl datatype tests */
    char    filename[1024];
    char    filename[1024];
    /* Print testing message */
    if(H5D_CHUNKED == layout)
    TESTING("chunked dataset extend")
    TESTING("chunked dataset extend")
    else
    TESTING("contiguous dataset extend")
    TESTING("contiguous dataset extend")
    /* Create dataset creation property list */
    if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) TEST_ERROR
    if(H5D_CHUNKED == layout)
    if(H5Pset_chunk(dcpl, 5, ch_size) < 0) TEST_ERROR
    if(H5Pset_chunk(dcpl, 5, ch_size) < 0) TEST_ERROR
#if 1
    /*
     * Remove this once contiguous datasets can support extensions in other
     * than the slowest varying dimension.  The purpose of this block is to
     * make only the slowest varying dimension extendible and yet have the
     * same total number of elements as originally.
     *
     * If this is removed prematurely then you will get an error `only the
     * first dimension can be extendible' as long as the test isn't skipped
     * below.
     */
    if(H5D_CONTIGUOUS==layout) {
    max_size[0] = (max_size[0] * max_size[1] * max_size[2] *
               max_size[3] * max_size[4]) /
              (start_size[1] * start_size[2] * start_size[3] * start_size[4]);
    max_size[1] = start_size[1];
    max_size[2] = start_size[2];
    max_size[3] = start_size[3];
    max_size[4] = start_size[4];
    max_size[0] = (max_size[0] * max_size[1] * max_size[2] *
            max_size[3] * max_size[4]) /
            (start_size[1] * start_size[2] * start_size[3] * start_size[4]);
    max_size[1] = start_size[1];
    max_size[2] = start_size[2];
    max_size[3] = start_size[3];
    max_size[4] = start_size[4];
    }
#endif
#if 1
    /*
     * Remove this once internal contiguous datasets can support
     * extending. If it's removed prematurely you will get an error
     * `extendible contiguous non-external dataset' as long as the test isn't
     * skipped below.
     */
    if(H5D_CONTIGUOUS==layout) {
        int fd;
        hsize_t nelmts;
        hsize_t    nelmts;
    nelmts = max_size[0]*max_size[1]*max_size[2]*max_size[3]*max_size[4];
    if((fd = HDopen(FILE_NAME_RAW, O_RDWR|O_CREAT|O_TRUNC, H5_POSIX_CREATE_MODE_RW)) < 0 ||
        HDclose(fd) < 0) goto error;
    if(H5Pset_external(dcpl, FILE_NAME_RAW, (off_t)0, (hsize_t)nelmts*sizeof(int)) < 0)
        goto error;
    nelmts = max_size[0]*max_size[1]*max_size[2]*max_size[3]*max_size[4];
    if((fd = HDopen(FILE_NAME_RAW, O_RDWR|O_CREAT|O_TRUNC, H5_POSIX_CREATE_MODE_RW)) < 0 ||
        HDclose(fd) < 0) goto error;
    if(H5Pset_external(dcpl, FILE_NAME_RAW, (off_t)0, (hsize_t)nelmts*sizeof(int)) < 0)
        goto error;
    }
#endif
#if 1
    /*
     * Remove this when contiguous datasets can be exended to some
     * predetermined fininte size, even if it's just in the slowest varying
     * dimension.  If it's removed prematurely then you'll get one of the
     * errors described above or `unable to select fill value region'.
     */
    if(H5D_CONTIGUOUS==layout) {
    SKIPPED();
    puts("    Not implemented yet -- needs H5S_SELECT_DIFF operator");
    goto skip;
    SKIPPED();
    puts("    Not implemented yet -- needs H5S_SELECT_DIFF operator");
    goto skip;
    }
#endif
    /* Create a file and dataset */
    h5_fixname(base_name, fapl, filename, sizeof filename);
    if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
    /* Get the compound+vl datatype */
    if((cmpd_vl_tid = create_compound_vl_type()) < 0) TEST_ERROR
    if(H5Pclose(dcpl) < 0) TEST_ERROR
    if(H5Fclose(file) < 0) TEST_ERROR
    PASSED();
    return 0;
error:
    H5E_BEGIN_TRY {
        H5Tclose(cmpd_vl_tid);
    H5Pclose(dcpl);
    H5Fclose(file);
    H5Pclose(dcpl);
    H5Fclose(file);
    } H5E_END_TRY;
    return 1;
skip:
    H5E_BEGIN_TRY {
    H5Pclose(dcpl);
    H5Fclose(file);
    H5Pclose(dcpl);
    H5Fclose(file);
    } H5E_END_TRY;
    return 0;
} /* end test_extend() */
/*-------------------------------------------------------------------------
 * Function:    test_compatible
 *
 * Purpose:     Tests fill value and dataspace for datasets created by v1.4
 *              library.
 *
 * Return:      Success:        0
 *
 *              Failure:        number of errors
 *
        H5Dclose(dset1);
        H5Pclose(dcpl2);
        H5Sclose(fspace);
        H5Dclose(dset2);
        H5Fclose(file);
    } H5E_END_TRY;
    return 1;
}
/*-------------------------------------------------------------------------
 * Function:    test_partalloc_cases
 * Function:    test_partalloc_cases
 *
 * Purpose: Tests fill values read and write for datasets.
 * Purpose:    Tests fill values read and write for datasets.
 *
 * Return:  Success:    0
 * Return:    Success:    0
 *
 *      Failure:    1
 *        Failure:    1
 *
 * Programmer:  Joel Plutchak
 * Programmer:    Joel Plutchak
 *              April 15, 2013
 *
 * Modifications:
 *      This function is called by test_rdwr to write and read
 *      dataset for different cases of chunked datasets with 
 *         This function is called by test_rdwr to write and read
 *        dataset for different cases of chunked datasets with
 *              unallocated chunks.
 *
 *-------------------------------------------------------------------------
 */
static int
test_partalloc_cases(hid_t file, hid_t dcpl, const char *dname, H5D_fill_time_t fill_time)
{
    hid_t   fspace=-1, dset1=-1, rspace = -1;
    herr_t  ret;
    hsize_t ds_size[2] = {4, 4};
    hsize_t max_size[2] = {H5S_UNLIMITED,4};
    hid_t    fspace=-1, dset1=-1, rspace = -1;
    herr_t    ret;
    hsize_t    ds_size[2] = {4, 4};
    hsize_t    max_size[2] = {H5S_UNLIMITED,4};
    hsize_t     chunk_size[2] = {1, 4};
    int     fillval=(-1);
    int        fillval=(-1);
    int     w_values[] = {42};            /* New value to be written */
    int     f_values[4] = {88,88,88,88};  /* pre-seed read buffer with known values */
    int     r_values[4] = {88,88,88,88};  /* pre-seed read buffer with known values */
    hsize_t coord[1][2];                  /* coordinate(s) of point to write */
    hsize_t start[2], count[2];
    fillval = 0;   /* default fill value is zero */
    /* Create dataset with 4x4 integer dataset */
    if((fspace = H5Screate_simple(2, ds_size, max_size)) < 0)
        goto error;
    if((dset1 = H5Dcreate2(file, dname, H5T_NATIVE_INT, fspace, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0)
        goto error;
    /*
     * Select a point in the file dataspace.
     */
    coord[0][0]=0; coord[0][1]=0; 
    coord[0][0]=0; coord[0][1]=0;
    if (H5Sselect_elements( fspace, H5S_SELECT_SET, (size_t)1, (const hsize_t *)coord))
        goto error;
    
    /*
     * Write single data point to the dataset.
     */
    if ((ret = H5Dwrite(dset1, H5T_NATIVE_INT, H5S_ALL, fspace, H5P_DEFAULT, w_values))< 0) {
        goto error;
    }
    
    /* Read a line/chunk and make sure values are right */
    rspace = H5Screate_simple(2, chunk_size, NULL);
    /* Read the first row of elements: one known plus three fill */
    start[0] = 0;
    start[1] = 0;
    count[0] = 1;
    count[1] = 4;
    if ((ret = H5Sselect_hyperslab(fspace, H5S_SELECT_SET, start, NULL, count, NULL)) < 0)
        goto error;
    if ((ret = H5Sselect_all(rspace)) < 0)
    goto error;
    goto error;
    if(H5Dread(dset1, H5T_NATIVE_INT, rspace, fspace, H5P_DEFAULT, &r_values) < 0)
        goto error;
    /* Read the third row of elements: all fill */
    start[0] = 2;
    start[1] = 0;
    count[0] = 1;
    count[1] = 4;
    if ((ret = H5Sselect_hyperslab(fspace, H5S_SELECT_SET, start, NULL, count, NULL)) < 0)
        goto error;
    else if(fill_time == H5D_FILL_TIME_NEVER) {
    }
    if(H5Sclose(rspace) < 0) goto error;
    if(H5Dclose(dset1) < 0) goto error;
    if(H5Sclose(fspace) < 0) goto error;
    return 0;
 error:
    H5E_BEGIN_TRY {
    H5Dclose(dset1);
    H5Sclose(fspace);
    H5Sclose(rspace);
    H5Dclose(dset1);
    H5Sclose(fspace);
    H5Sclose(rspace);
    } H5E_END_TRY;
    return 1;
}
/*-------------------------------------------------------------------------
 * Function:    test_partalloc
 *
 * Purpose:     Tests fill values for chunked, partially-allocated datasets.
 *              Regression test for HDFFV-8247.
 *
 * Return:      Success:        0
 *
 *              Failure:        number of errors
 *
 * Programmer:  Joel Plutchak
 *              April 15, 2013
 *
 *-------------------------------------------------------------------------
 */
static int
test_partalloc(hid_t fapl, const char *base_name)
{
    char        filename[1024];
    hid_t   file=-1, dcpl=-1;
    hid_t     file=-1, dcpl=-1;
    hsize_t     ch_size[2] = {1, 4};
    int     nerrors=0;
    int        nerrors=0;
    TESTING("chunked dataset partially allocated I/O");
    h5_fixname(base_name, fapl, filename, sizeof filename);
    if((file=H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
        goto error;
    if((dcpl=H5Pcreate(H5P_DATASET_CREATE)) < 0) goto error;
    if(H5Pset_chunk(dcpl, 2, ch_size) < 0) goto error;
#ifdef DEBUG
    HDfprintf( stdout, "\nALLOC_TIME_LATE\n" );
#endif
    /* case for H5D_FILL_TIME_ALLOC as fill write time and fill value to be default */
    if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_ALLOC) < 0) goto error;
#ifdef DEBUG
    HDfprintf( stdout, "   FILL_TIME_ALLOC\n" );
#endif
    nerrors += test_partalloc_cases(file, dcpl, "dset1", H5D_FILL_TIME_ALLOC);
            
    /* case for H5D_FILL_TIME_NEVER as fill write time and fill value to be default */
    if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_NEVER) < 0) goto error;
#ifdef DEBUG
    HDfprintf( stdout, "   FILL_TIME_NEVER\n" );
#endif
    nerrors += test_partalloc_cases(file, dcpl, "dset2", H5D_FILL_TIME_NEVER );
    /* case for H5D_FILL_TIME_IFSET as fill write time and fill value to be default */
    if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_IFSET) < 0) goto error;
#ifdef DEBUG
    nerrors += test_partalloc_cases(file, dcpl, "dset8", H5D_FILL_TIME_NEVER );
    /* case for H5D_FILL_TIME_IFSET as fill write time and fill value to be default */
    if(H5Pset_fill_time(dcpl, H5D_FILL_TIME_IFSET) < 0) goto error;
#ifdef DEBUG
    HDfprintf( stdout, "   FILL_TIME_IFSET\n" );
#endif
    nerrors += test_partalloc_cases(file, dcpl, "dset9", H5D_FILL_TIME_IFSET );
    if(nerrors)
    goto error;
    goto error;
    if(H5Pclose(dcpl) < 0) goto error;
    if(H5Fclose(file) < 0) goto error;
    PASSED();
    return 0;
 error:
    H5E_BEGIN_TRY {
        H5Pclose(dcpl);
        H5Fclose(file);
    } H5E_END_TRY;
    return nerrors;
}
/*-------------------------------------------------------------------------
 * Function:    main
 * Function:    main
 *
 * Purpose: Tests fill values
 * Purpose:    Tests fill values
 *
 * Return:  Success:
 * Return:    Success:
 *
 *      Failure:
 *        Failure:
 *
 * Programmer:  Robb Matzke
 * Programmer:    Robb Matzke
 *              Thursday, October  1, 1998
 *
 *-------------------------------------------------------------------------
 */
int
main(int argc, char *argv[])
{
    int nerrors=0, argno, test_contig=1, test_chunk=1, test_compact=1;
    hid_t   fapl = (-1), fapl2 = (-1);    /* File access property lists */
    unsigned    new_format;         /* Whether to use the new format or not */
    int    nerrors=0, argno, test_contig=1, test_chunk=1, test_compact=1;
    hid_t    fapl = (-1), fapl2 = (-1);    /* File access property lists */
    unsigned     new_format;         /* Whether to use the new format or not */
    if(argc >= 2) {
        test_contig = test_chunk = test_compact = 0;
        for(argno = 1; argno < argc; argno++) {
            if(!strcmp(argv[argno], "contiguous"))
                test_contig = 1;
            else if(!strcmp(argv[argno], "chunked"))
                test_chunk = 1;
            else if(!strcmp(argv[argno], "compact"))
                test_compact =1;