summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPedro Vicente Nunes <pvn@hdfgroup.org>2008-08-27 15:18:34 (GMT)
committerPedro Vicente Nunes <pvn@hdfgroup.org>2008-08-27 15:18:34 (GMT)
commitdda858faf6b607a344370df5d578159d42a28882 (patch)
tree4abe2f7a6f8352285f95501d696bc573e563fe3a
parent1e2cc2c9e3781c55eb35d54ad5f7433e14b7da64 (diff)
downloadhdf5-dda858faf6b607a344370df5d578159d42a28882.zip
hdf5-dda858faf6b607a344370df5d578159d42a28882.tar.gz
hdf5-dda858faf6b607a344370df5d578159d42a28882.tar.bz2
[svn-r15544] #1184
1) Add a userblock to an HDF5 file during the repack. The user gives give a filename and userblock size as command line parameters to h5repack and the contents of that file are stored in the userblock for the HDF5 file created by h5repack. 2) add a copy of userblock from HDF5 file New flags to handle this -u and -b tested: windows, linux
-rw-r--r--tools/h5repack/h5repack.c18
-rw-r--r--tools/h5repack/h5repack.h4
-rwxr-xr-xtools/h5repack/h5repack.sh.in5
-rw-r--r--tools/h5repack/h5repack_copy.c333
-rw-r--r--tools/h5repack/h5repack_main.c31
-rw-r--r--tools/h5repack/h5repacktst.c251
6 files changed, 623 insertions, 19 deletions
diff --git a/tools/h5repack/h5repack.c b/tools/h5repack/h5repack.c
index a934f1b..6f58516 100644
--- a/tools/h5repack/h5repack.c
+++ b/tools/h5repack/h5repack.c
@@ -377,6 +377,24 @@ static int check_options(pack_opt_t *options)
is present with other objects\n");
return -1;
}
+
+ /*--------------------------------------------------------------------------------
+ * verify new user userblock options; both file name and block size must be present
+ *---------------------------------------------------------------------------------
+ */
+ if ( options->ublock_filename != NULL && options->ublock_size == 0 )
+ {
+ error_msg(progname, "user block size missing for file %s\n",
+ options->ublock_filename);
+ return -1;
+ }
+
+ if ( options->ublock_filename == NULL && options->ublock_size != 0 )
+ {
+ error_msg(progname, "file name missing for user block\n",
+ options->ublock_filename);
+ return -1;
+ }
diff --git a/tools/h5repack/h5repack.h b/tools/h5repack/h5repack.h
index 411f23c..9e2b546 100644
--- a/tools/h5repack/h5repack.h
+++ b/tools/h5repack/h5repack.h
@@ -104,7 +104,9 @@ typedef struct {
H5D_layout_t layout_g; /*global layout information for the ALL case */
int verbose; /*verbose mode */
hsize_t threshold; /*minimum size to compress, in bytes */
- int use_native; /*use a native type in write */
+ int use_native; /*use a native type in write */
+ const char *ublock_filename; /* user block file name */
+ int ublock_size; /* user block size */
} pack_opt_t;
diff --git a/tools/h5repack/h5repack.sh.in b/tools/h5repack/h5repack.sh.in
index 305e512..d37f1ba 100755
--- a/tools/h5repack/h5repack.sh.in
+++ b/tools/h5repack/h5repack.sh.in
@@ -390,6 +390,11 @@ TOOLTEST $arg9
arg="$FILE1 -n"
TOOLTEST $arg
+# add a userblock to file
+arg="$FILE1 -u ublock.bin -b 2048"
+TOOLTEST $arg
+
+
if test $nerrors -eq 0 ; then
echo "All $H5REPACK tests passed."
diff --git a/tools/h5repack/h5repack_copy.c b/tools/h5repack/h5repack_copy.c
index 91f70c6..b0ccf4f 100644
--- a/tools/h5repack/h5repack_copy.c
+++ b/tools/h5repack/h5repack_copy.c
@@ -23,12 +23,18 @@
extern char *progname;
+#if 0
+#define H5REPACK_DEBUG
+#endif
+
/*-------------------------------------------------------------------------
* macros
*-------------------------------------------------------------------------
*/
#define FORMAT_OBJ " %-27s %s\n" /* obj type, name */
#define FORMAT_OBJ_ATTR " %-27s %s\n" /* obj type, name */
+#define USERBLOCK_XFER_SIZE 512 /* size of buffer/# of bytes to xfer at a time when copying userblock */
+
/*-------------------------------------------------------------------------
@@ -38,6 +44,9 @@ extern char *progname;
static void print_dataset_info(hid_t dcpl_id,char *objname,double per,int pr);
static int do_copy_objects(hid_t fidin,hid_t fidout,trav_table_t *travt,pack_opt_t *options);
static int copy_attr(hid_t loc_in,hid_t loc_out,pack_opt_t *options);
+static int copy_user_block(const char *infile, const char *outfile, hsize_t size);
+static void print_user_block(const char *filename, hid_t fid);
+
/*-------------------------------------------------------------------------
* Function: copy_objects
@@ -60,33 +69,160 @@ int copy_objects(const char* fnamein,
hid_t fidin;
hid_t fidout=-1;
trav_table_t *travt=NULL;
+ hsize_t ub_size = 0; /* size of user block */
+ hid_t fcpl = H5P_DEFAULT; /* file creation property list ID */
- /*-------------------------------------------------------------------------
- * open the files
- *-------------------------------------------------------------------------
+
+ /*-------------------------------------------------------------------------
+ * open input file
+ *-------------------------------------------------------------------------
*/
if ((fidin=h5tools_fopen(fnamein, NULL, NULL, 0))<0 )
{
error_msg(progname, "<%s>: %s\n", fnamein, H5FOPENERROR );
goto out;
}
- if ((fidout=H5Fcreate(fnameout,H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT))<0 )
+
+ /*-------------------------------------------------------------------------
+ * get user block size
+ *-------------------------------------------------------------------------
+ */
+
+ {
+ hid_t fcpl_in; /* file creation property list ID for input file */
+
+ if((fcpl_in = H5Fget_create_plist(fidin)) < 0)
+ {
+ error_msg(progname, "failed to retrieve file creation property list\n");
+ goto out;
+ }
+
+ if(H5Pget_userblock(fcpl_in, &ub_size) < 0)
+ {
+ error_msg(progname, "failed to retrieve userblock size\n");
+ goto out;
+ }
+
+ if(H5Pclose(fcpl_in) < 0)
+ {
+ error_msg(progname, "failed to close property list\n");
+ goto out;
+ }
+ }
+
+ /*-------------------------------------------------------------------------
+ * check if we need to create a non-default file creation property list
+ *-------------------------------------------------------------------------
+ */
+
+ if ( ub_size > 0)
+ {
+ /* Create file creation property list */
+ if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
+ {
+ error_msg(progname, "fail to create a file creation property list\n");
+ goto out;
+ } /* end if */
+
+ if(ub_size > 0)
+ {
+ if(H5Pset_userblock(fcpl, ub_size) < 0)
+ {
+ error_msg(progname, "failed to set non-default userblock size\n");
+ goto out;
+ }
+ }
+
+
+ } /* ub_size */
+
+
+
+
+#if defined (H5REPACK_DEBUG)
+ print_user_block(fnamein,fidin);
+#endif
+
+
+ /*-------------------------------------------------------------------------
+ * set the new user userblock options in the FCPL (before H5Fcreate )
+ *-------------------------------------------------------------------------
+ */
+
+ if ( options->ublock_size > 0 )
+ {
+ /* either use the FCPL already created or create a new one */
+ if(fcpl != H5P_DEFAULT)
+ {
+ /* set user block size */
+ if(H5Pset_userblock(fcpl, options->ublock_size) < 0)
+ {
+ error_msg(progname, "failed to set userblock size\n");
+ goto out;
+ }
+
+ }
+
+ else
+ {
+
+ /* create a file creation property list */
+ if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
+ {
+ error_msg(progname, "fail to create a file creation property list\n");
+ goto out;
+ }
+
+ /* set user block size */
+ if(H5Pset_userblock(fcpl, options->ublock_size) < 0)
+ {
+ error_msg(progname, "failed to set userblock size\n");
+ goto out;
+ }
+
+ }
+
+
+
+ }
+
+ /*-------------------------------------------------------------------------
+ * create the output file
+ *-------------------------------------------------------------------------
+ */
+
+
+ if ((fidout=H5Fcreate(fnameout,H5F_ACC_TRUNC, fcpl, H5P_DEFAULT))<0 )
{
error_msg(progname, "<%s>: Could not create file\n", fnameout );
goto out;
}
if (options->verbose)
+ {
printf("Making file <%s>...\n",fnameout);
+ }
+
+ /*-------------------------------------------------------------------------
+ * write a new user block if requested
+ *-------------------------------------------------------------------------
+ */
+ if ( options->ublock_size > 0 )
+ {
+ copy_user_block( options->ublock_filename, fnameout, options->ublock_size);
+ }
+
/* init table */
trav_table_init(&travt);
/* get the list of objects in the file */
if (h5trav_gettable(fidin,travt)<0)
+ {
goto out;
+ }
- /*-------------------------------------------------------------------------
+ /*-------------------------------------------------------------------------
* do the copy
*-------------------------------------------------------------------------
*/
@@ -96,7 +232,7 @@ int copy_objects(const char* fnamein,
goto out;
}
- /*-------------------------------------------------------------------------
+ /*-------------------------------------------------------------------------
* do the copy of referenced objects
* and create hard links
*-------------------------------------------------------------------------
@@ -110,22 +246,31 @@ int copy_objects(const char* fnamein,
/* free table */
trav_table_free(travt);
- /*-------------------------------------------------------------------------
+ /*-------------------------------------------------------------------------
* close
*-------------------------------------------------------------------------
*/
+ if(fcpl > 0)
+ H5Pclose(fcpl);
+
H5Fclose(fidin);
H5Fclose(fidout);
+
+ /* write only the input file user block if there is no user block file input */
+ if(ub_size > 0 && options->ublock_size == 0)
+ copy_user_block(fnamein, fnameout, ub_size);
+
return 0;
- /*-------------------------------------------------------------------------
+ /*-------------------------------------------------------------------------
* out
*-------------------------------------------------------------------------
*/
out:
H5E_BEGIN_TRY {
+ H5Pclose(fcpl);
H5Fclose(fidin);
H5Fclose(fidout);
} H5E_END_TRY;
@@ -946,3 +1091,175 @@ static void print_dataset_info(hid_t dcpl_id,
}
}
+/*-------------------------------------------------------------------------
+ * Function: copy_user_block
+ *
+ * Purpose: copy user block from one file to another
+ *
+ * Return: 0, ok, -1 no
+ *
+ * Programmer: Peter Cao
+ *
+ * Date: October, 25, 2007
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+copy_user_block(const char *infile, const char *outfile, hsize_t size)
+{
+ int infid = -1, outfid = -1; /* File descriptors */
+ int status = 0; /* Return value */
+
+ /* User block must be any power of 2 equal to 512 or greater (512, 1024, 2048, etc.) */
+ assert(size > 0);
+
+ /* Open files */
+ if((infid = HDopen(infile, O_RDONLY, 0)) < 0) {
+ status = -1;
+ goto done;
+ }
+ if((outfid = HDopen(outfile, O_WRONLY, 0644)) < 0) {
+ status = -1;
+ goto done;
+ }
+
+ /* Copy the userblock from the input file to the output file */
+ while(size > 0) {
+ ssize_t nread, nbytes; /* # of bytes transfered, etc. */
+ char rbuf[USERBLOCK_XFER_SIZE]; /* Buffer for reading */
+ const char *wbuf; /* Pointer into buffer, for writing */
+
+ /* Read buffer from source file */
+ if(size > USERBLOCK_XFER_SIZE)
+ nread = HDread(infid, rbuf, (size_t)USERBLOCK_XFER_SIZE);
+ else
+ nread = HDread(infid, rbuf, (size_t)size);
+ if(nread < 0) {
+ status = -1;
+ goto done;
+ } /* end if */
+
+ /* Write buffer to destination file */
+ /* (compensating for interrupted writes & checking for errors, etc.) */
+ nbytes = nread;
+ wbuf = rbuf;
+ while(nbytes > 0) {
+ ssize_t nwritten; /* # of bytes written */
+
+ do {
+ nwritten = HDwrite(outfid, wbuf, (size_t)nbytes);
+ } while(-1 == nwritten && EINTR == errno);
+ if(-1 == nwritten) { /* error */
+ status = -1;
+ goto done;
+ } /* end if */
+ assert(nwritten > 0);
+ assert(nwritten <= nbytes);
+
+ /* Update # of bytes left & offset in buffer */
+ nbytes -= nwritten;
+ wbuf += nwritten;
+ assert(nbytes == 0 || wbuf < (rbuf + USERBLOCK_XFER_SIZE));
+ } /* end while */
+
+ /* Update size of userblock left to transfer */
+ size -= nread;
+ } /* end while */
+
+done:
+ if(infid > 0)
+ HDclose(infid);
+ if(outfid > 0)
+ HDclose(outfid);
+
+ return status;
+}
+
+
+
+/*-------------------------------------------------------------------------
+ * Function: print_user_block
+ *
+ * Purpose: print user block
+ *
+ * Return: 0, ok, -1 no
+ *
+ * Programmer: Pedro Vicente
+ *
+ * Date: August, 20, 2008
+ *
+ *-------------------------------------------------------------------------
+ */
+static
+void print_user_block(const char *filename, hid_t fid)
+{
+ int fh; /* file handle */
+ hsize_t ub_size; /* user block size */
+ hsize_t size; /* size read */
+ hid_t fcpl; /* file creation property list ID for HDF5 file */
+ int i;
+
+ /* get user block size */
+ if(( fcpl = H5Fget_create_plist(fid)) < 0)
+ {
+ error_msg(progname, "failed to retrieve file creation property list\n");
+ goto done;
+ }
+
+ if(H5Pget_userblock(fcpl, &ub_size) < 0)
+ {
+ error_msg(progname, "failed to retrieve userblock size\n");
+ goto done;
+ }
+
+ if(H5Pclose(fcpl) < 0)
+ {
+ error_msg(progname, "failed to close property list\n");
+ goto done;
+ }
+
+ /* open file */
+ if((fh = HDopen(filename, O_RDONLY, 0)) < 0)
+ {
+ goto done;
+ }
+
+ size = ub_size;
+
+ /* read file */
+ while(size > 0)
+ {
+ ssize_t nread; /* # of bytes read */
+ char rbuf[USERBLOCK_XFER_SIZE]; /* buffer for reading */
+
+ /* read buffer */
+ if(size > USERBLOCK_XFER_SIZE)
+ nread = HDread(fh, rbuf, (size_t)USERBLOCK_XFER_SIZE);
+ else
+ nread = HDread(fh, rbuf, (size_t)size);
+
+ for(i = 0; i < nread; i++)
+ {
+
+ printf("%c ", rbuf[i]);
+
+ }
+ printf("\n");
+
+ if(nread < 0)
+ {
+ goto done;
+ }
+
+
+ /* update size of userblock left to transfer */
+ size -= nread;
+ }
+
+done:
+ if(fh > 0)
+ HDclose(fh);
+
+
+ return;
+}
diff --git a/tools/h5repack/h5repack_main.c b/tools/h5repack/h5repack_main.c
index 4d45d56..a047778 100644
--- a/tools/h5repack/h5repack_main.c
+++ b/tools/h5repack/h5repack_main.c
@@ -34,7 +34,7 @@ int d_status = EXIT_SUCCESS;
* Command-line options: The user can specify short or long-named
* parameters.
*/
-static const char *s_opts = "hVvf:l:m:e:nLc:i:s:";
+static const char *s_opts = "hVvf:l:m:e:nLc:i:s:u:b:";
static struct long_options l_opts[] = {
{ "help", no_arg, 'h' },
{ "version", no_arg, 'V' },
@@ -44,7 +44,8 @@ static struct long_options l_opts[] = {
{ "threshold", require_arg, 'm' },
{ "file", require_arg, 'e' },
{ "native", no_arg, 'n' },
-
+ { "ublock", require_arg, 'u' },
+ { "block", require_arg, 'b' },
{ NULL, 0, '\0' }
};
@@ -68,12 +69,12 @@ static struct long_options l_opts[] = {
* July 2004: Introduced the extra EC or NN option for SZIP
* October 2006: Added a new switch -n, that allows to write the dataset
* using a native type. The default to write is the file type.
- *
- * Modification:
- * PVN, November 19, 2007
+ * PVN, November 19, 2007
* adopted the syntax h5repack [OPTIONS] file1 file2
- * PVN, November 28, 2007
+ * PVN, November 28, 2007
* added support for multiple global filters
+ * PVN, August 20, 2008
+ * add a user block to repacked file (switches -u -b)
*-------------------------------------------------------------------------
*/
int main(int argc, char **argv)
@@ -146,6 +147,8 @@ static void usage(const char *prog)
printf(" -m T, --threshold=T Do not apply the filter to datasets smaller than T\n");
printf(" -e M, --file=M Name of file M with the -f and -l options\n");
+ printf(" -u U, --ublock=U Name of file U with user block data to be added\n");
+ printf(" -b D, --block=D Size of user block to be added\n");
printf(" -f FILT, --filter=FILT Filter type\n");
printf(" -l LAYT, --layout=LAYT Layout type\n");
@@ -153,6 +156,8 @@ static void usage(const char *prog)
printf(" T - is an integer greater than 1, size of dataset in bytes \n");
printf(" M - is a filename.\n");
+ printf(" U - is a filename.\n");
+ printf(" D - is the user block size (any power of 2 equal to 512 or greater)\n");
printf("\n");
@@ -281,10 +286,18 @@ static void parse_command_line(int argc, const char* argv[], pack_opt_t* options
case 'n':
options->use_native = 1;
break;
-
-
-
+ case 'u':
+
+ options->ublock_filename = opt_arg;
+ break;
+
+ case 'b':
+
+ options->ublock_size = atoi( opt_arg );
+ break;
+
+
} /* switch */
diff --git a/tools/h5repack/h5repacktst.c b/tools/h5repack/h5repacktst.c
index 002fe76..ed773fa 100644
--- a/tools/h5repack/h5repacktst.c
+++ b/tools/h5repack/h5repacktst.c
@@ -15,8 +15,8 @@
#include "h5repack.h"
#include "h5test.h"
-#include "h5tools.h"
#include "h5diff.h"
+#include "h5tools.h"
#define GOERROR {H5_FAILED(); goto error;}
@@ -64,6 +64,12 @@
#define FNAME15 "h5repack_ext.h5"
#define FNAME15OUT "h5repack_ext_out.h5"
+/* File w/userblock */
+#define FNAME16 "h5repack_ub.h5"
+#define FNAME16OUT "h5repack_ub_out.h5"
+
+#define FNAME_UB "ublock.bin"
+
const char *H5REPACK_FILENAMES[] = {
"h5repack_big_out",
@@ -82,6 +88,10 @@ int d_status = EXIT_SUCCESS;
#define CDIM2 DIM2/2
#define RANK 2
+/* Size of userblock (for userblock test) */
+#define USERBLOCK_SIZE 2048
+
+
/*-------------------------------------------------------------------------
* prototypes
*-------------------------------------------------------------------------
@@ -109,6 +119,10 @@ int make_dset(hid_t loc_id,const char *name,hid_t sid,hid_t dcpl,void *buf);
int make_attr(hid_t loc_id,int rank,hsize_t *dims,const char *attr_name,hid_t type_id,void *buf);
void make_dset_reg_ref(hid_t loc_id);
int make_external(hid_t loc_id);
+static int make_userblock(void);
+static int verify_userblock( const char* filename);
+static int make_userblock_file(void);
+
/*-------------------------------------------------------------------------
@@ -141,6 +155,10 @@ int main (void)
/* set h5diff "contents" mode */
diff_options.m_contents = 1;
+
+ /* set h5diff "contents" mode */
+ diff_options.m_contents = 1;
+
/* run tests */
puts("Testing h5repack:");
@@ -1208,6 +1226,49 @@ if (szip_can_encode) {
SKIPPED();
#endif
+ /*-------------------------------------------------------------------------
+ * test file with userblock
+ *-------------------------------------------------------------------------
+ */
+ TESTING(" file with userblock");
+ if(h5repack_init(&pack_options, 0) < 0)
+ GOERROR;
+ if(h5repack(FNAME16, FNAME16OUT, &pack_options) < 0)
+ GOERROR;
+ if(h5diff(FNAME16, FNAME16OUT, NULL, NULL, &diff_options) > 0)
+ GOERROR;
+ if(h5repack_verify(FNAME16OUT, &pack_options) <= 0)
+ GOERROR;
+ if(verify_userblock(FNAME16OUT) < 0)
+ GOERROR;
+ if(h5repack_end(&pack_options) < 0)
+ GOERROR;
+ PASSED();
+
+ /*-------------------------------------------------------------------------
+ * test file with userblock
+ *-------------------------------------------------------------------------
+ */
+ TESTING(" file with added userblock");
+ if(h5repack_init(&pack_options, 0) < 0)
+ GOERROR;
+
+ /* add the options for a user block size and user block filename */
+ pack_options.ublock_size = USERBLOCK_SIZE;
+ pack_options.ublock_filename = FNAME_UB;
+
+ if(h5repack(FNAME8, FNAME8OUT, &pack_options) < 0)
+ GOERROR;
+ if(h5diff(FNAME8, FNAME8OUT, NULL, NULL, &diff_options) > 0)
+ GOERROR;
+ if(h5repack_verify(FNAME8OUT, &pack_options) <= 0)
+ GOERROR;
+ if(verify_userblock(FNAME8OUT) < 0)
+ GOERROR;
+ if(h5repack_end(&pack_options) < 0)
+ GOERROR;
+ PASSED();
+
/*-------------------------------------------------------------------------
@@ -1388,6 +1449,20 @@ int make_testfiles(void)
if(H5Fclose(loc_id)<0)
return -1;
+ /*-------------------------------------------------------------------------
+ * create a file with userblock
+ *-------------------------------------------------------------------------
+ */
+ if(make_userblock() < 0)
+ goto out;
+
+ /*-------------------------------------------------------------------------
+ * create a userblock file
+ *-------------------------------------------------------------------------
+ */
+ if(make_userblock_file() < 0)
+ goto out;
+
return 0;
@@ -2390,6 +2465,180 @@ out:
}
/*-------------------------------------------------------------------------
+ * Function: make_userblock
+ *
+ * Purpose: create a file for the userblock copying test
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+make_userblock(void)
+{
+ hid_t fid = -1;
+ hid_t fcpl = -1;
+ int fd = -1; /* File descriptor for writing userblock */
+ char ub[USERBLOCK_SIZE]; /* User block data */
+ ssize_t nwritten; /* # of bytes written */
+ size_t u; /* Local index variable */
+
+ /* Create file creation property list with userblock set */
+ if((fcpl = H5Pcreate(H5P_FILE_CREATE)) < 0)
+ goto out;
+ if(H5Pset_userblock(fcpl, (hsize_t)USERBLOCK_SIZE) < 0)
+ goto out;
+
+ /* Create file with userblock */
+ if((fid = H5Fcreate(FNAME16, H5F_ACC_TRUNC, fcpl, H5P_DEFAULT)) < 0)
+ goto out;
+ if(H5Fclose(fid) < 0)
+ goto out;
+
+ /* Close file creation property list */
+ if(H5Pclose(fcpl) < 0)
+ goto out;
+
+
+ /* Initialize userblock data */
+ for(u = 0; u < USERBLOCK_SIZE; u++)
+ ub[u] = 'a' + (u % 26);
+
+ /* Re-open HDF5 file, as "plain" file */
+ if((fd = HDopen(FNAME16, O_WRONLY, 0644)) < 0)
+ goto out;
+
+ /* Write userblock data */
+ nwritten = HDwrite(fd, ub, (size_t)USERBLOCK_SIZE);
+ assert(nwritten == USERBLOCK_SIZE);
+
+ /* Close file */
+ HDclose(fd);
+
+ return 0;
+
+out:
+ H5E_BEGIN_TRY {
+ H5Pclose(fcpl);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ if(fd > 0)
+ HDclose(fd);
+
+ return -1;
+} /* end make_userblock() */
+
+/*-------------------------------------------------------------------------
+ * Function: verify_userblock
+ *
+ * Purpose: Verify that the userblock was copied correctly
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+verify_userblock( const char* filename)
+{
+ hid_t fid = -1;
+ hid_t fcpl = -1;
+ int fd = -1; /* File descriptor for writing userblock */
+ char ub[USERBLOCK_SIZE]; /* User block data */
+ hsize_t ub_size = 0; /* User block size */
+ ssize_t nread; /* # of bytes read */
+ size_t u; /* Local index variable */
+
+ /* Open file with userblock */
+ if((fid = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
+ goto out;
+
+ /* Retrieve file creation property list & userblock size */
+ if((fcpl = H5Fget_create_plist(fid)) < 0)
+ goto out;
+ if(H5Pget_userblock(fcpl, &ub_size) < 0)
+ goto out;
+
+ /* Verify userblock size is correct */
+ if(ub_size != USERBLOCK_SIZE)
+ goto out;
+
+ /* Close file creation property list */
+ if(H5Pclose(fcpl) < 0)
+ goto out;
+
+ if(H5Fclose(fid) < 0)
+ goto out;
+
+
+ /* Re-open HDF5 file, as "plain" file */
+ if((fd = HDopen(filename, O_RDONLY, 0)) < 0)
+ goto out;
+
+ /* Read userblock data */
+ nread = HDread(fd, ub, (size_t)USERBLOCK_SIZE);
+ assert(nread == USERBLOCK_SIZE);
+
+ /* Verify userblock data */
+ for(u = 0; u < USERBLOCK_SIZE; u++)
+ if(ub[u] != (char)('a' + (u % 26)))
+ goto out;
+
+ /* Close file */
+ HDclose(fd);
+
+ return 0;
+
+out:
+ H5E_BEGIN_TRY {
+ H5Pclose(fcpl);
+ H5Fclose(fid);
+ } H5E_END_TRY;
+ if(fd > 0)
+ HDclose(fd);
+
+ return -1;
+} /* end verify_userblock() */
+
+
+/*-------------------------------------------------------------------------
+ * Function: make_userblock_file
+ *
+ * Purpose: create a file for the userblock add test
+ *
+ *-------------------------------------------------------------------------
+ */
+static int
+make_userblock_file(void)
+{
+ hid_t fid = -1;
+ hid_t fcpl = -1;
+ int fd = -1; /* File descriptor for writing userblock */
+ char ub[USERBLOCK_SIZE]; /* User block data */
+ ssize_t nwritten; /* # of bytes written */
+ size_t u; /* Local index variable */
+
+ /* initialize userblock data */
+ for(u = 0; u < USERBLOCK_SIZE; u++)
+ ub[u] = 'a' + (u % 26);
+
+ /* open file */
+ if((fd = HDopen(FNAME_UB,O_WRONLY|O_CREAT|O_TRUNC, 0644 )) < 0)
+ goto out;
+
+ /* write userblock data */
+ nwritten = HDwrite(fd, ub, (size_t)USERBLOCK_SIZE);
+ assert(nwritten == USERBLOCK_SIZE);
+
+ /* close file */
+ HDclose(fd);
+
+ return 0;
+
+out:
+
+ if(fd > 0)
+ HDclose(fd);
+
+ return -1;
+}
+
+/*-------------------------------------------------------------------------
* Function: write_dset_in
*
* Purpose: write datasets in LOC_ID