Exemple #1
0
/*
 * Create datasets in the location (in "/" or "/group") with 
 *   message id: (a) H5O_BOGUS_VALID_ID or (b)H5O_BOGUS_INVALID_ID
 *   and various unknown message flags
 */
static int
generate_datasets(hid_t loc_id, unsigned bogus_id) 
{
    hid_t sid = -1;             /* Dataspace ID */
    hid_t dcpl = -1;            /* Dataset creation property list ID */
    hid_t did = -1;             /* Dataset ID */
    uint8_t bogus_flags = 0;    /* Flags for bogus message */

    /* Create dataspace for datasets */
    if((sid = H5Screate(H5S_SCALAR)) < 0) goto error;

    /* Create dataset creation property list */
    if((dcpl = H5Pcreate(H5P_DATASET_CREATE)) < 0) goto error;

    /* Add property for bogus message flags */
    if(H5Pinsert2(dcpl, H5O_BOGUS_MSG_FLAGS_NAME, H5O_BOGUS_MSG_FLAGS_SIZE, &bogus_flags, NULL, NULL, NULL, NULL, NULL, NULL) < 0) goto error;

    /* Add property for bogus message ID */
    if(H5Pinsert2(dcpl, H5O_BOGUS_MSG_ID_NAME, H5O_BOGUS_MSG_ID_SIZE, &bogus_id, NULL, NULL, NULL, NULL, NULL, NULL) < 0) goto error;

    /* Create dataset with "bogus" message, but no message flags */
    if((did = H5Dcreate2(loc_id, "Dataset1", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) goto error;
    if(H5Dclose(did) < 0) goto error;

    /* Set "fail if unknown and open for write" message flag for bogus message */
    bogus_flags = H5O_MSG_FLAG_FAIL_IF_UNKNOWN_AND_OPEN_FOR_WRITE;
    if(H5Pset(dcpl, H5O_BOGUS_MSG_FLAGS_NAME, &bogus_flags) < 0) goto error;

    /* Create second dataset, with "fail if unknown" message flag */
    if((did = H5Dcreate2(loc_id, "Dataset2", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) goto error;
    if(H5Dclose(did) < 0) goto error;

    /* Set "fail if unknown always" message flag for bogus message */
    bogus_flags = H5O_MSG_FLAG_FAIL_IF_UNKNOWN_ALWAYS;
    if(H5Pset(dcpl, H5O_BOGUS_MSG_FLAGS_NAME, &bogus_flags) < 0) goto error;

    /* Create third dataset, with "fail if unknown always" message flag */
    if((did = H5Dcreate2(loc_id, "Dataset3", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) goto error;
    if(H5Dclose(did) < 0) goto error;

    /* Set "mark if unknown" message flag for bogus message */
    bogus_flags = H5O_MSG_FLAG_MARK_IF_UNKNOWN;
    if(H5Pset(dcpl, H5O_BOGUS_MSG_FLAGS_NAME, &bogus_flags) < 0) goto error;

    /* Create fourth dataset, with "mark if unknown" message flag */
    if((did = H5Dcreate2(loc_id, "Dataset4", H5T_NATIVE_INT, sid, H5P_DEFAULT, dcpl, H5P_DEFAULT)) < 0) goto error;
    if(H5Dclose(did) < 0) goto error;

    /* Close dataset creation property list */
    if(H5Pclose(dcpl) < 0) goto error;

    /* Close dataspace */
    if(H5Sclose(sid) < 0) goto error;

    return 0;

error:
    H5E_BEGIN_TRY {
        H5Dclose(did);
        H5Sclose(sid);
        H5Pclose(dcpl);
    } H5E_END_TRY;

    return -1;
} /* generate_datasets() */
Exemple #2
0
static void plist_link_example(void)
{
    hid_t file_id;
    hid_t group_id, group2_id;
    hid_t gapl_id;
    char *path = NULL;

    /* Define the link class that we'll use to register "plist
     * links" using the callback we defined above.
     * A link class can have NULL for any callback except its traverse
     * callback.
     */
    const H5L_class_t UD_plist_class[1] = {{
        H5L_LINK_CLASS_T_VERS,      /* Version number for this struct.
                                     * This field is always H5L_LINK_CLASS_T_VERS */
        (H5L_type_t)UD_PLIST_CLASS, /* Link class id number. This can be any
                                     * value between H5L_TYPE_UD_MIN (64) and
                                     * H5L_TYPE_MAX (255). It should be a
                                     * value that isn't already being used by
                                     * another kind of link. We'll use 67. */
        "UD_plist_link",            /* Link class name for debugging  */
        NULL,                       /* Creation callback              */
        NULL,                       /* Move callback                  */
        NULL,                       /* Copy callback                  */
        UD_plist_traverse,          /* The actual traversal function  */
        NULL,                       /* Deletion callback              */
        NULL                        /* Query callback                 */
    }};


    /* First, create a file and two objects within the file for the link to
     * point to.
     */
    file_id = H5Fcreate(HARD_LINK_FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    group_id = H5Gcreate2(file_id, "group_1", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    H5Gclose(group_id);
    group_id = H5Gcreate2(file_id, "group_1/group_2", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
    H5Gclose(group_id);

    /* Register "plist links" and create one.  It has no udata at all. */
    H5Lregister(UD_plist_class);
    H5Lcreate_ud(file_id, "plist_link", (H5L_type_t)UD_PLIST_CLASS, NULL, 0,
                 H5P_DEFAULT, H5P_DEFAULT);

    /* Create a group access property list to pass in the target for the
     * plist link.
     */
    gapl_id = H5Pcreate(H5P_GROUP_ACCESS);

    /* There is no HDF5 API for setting the property that controls these
     * links, so we have to add the property manually
     */
    H5Pinsert2(gapl_id, PLIST_LINK_PROP, sizeof(const char *), &(path), NULL, NULL, NULL, NULL, NULL, NULL);

    /* Set the property to point to the first group. */
    path = "group_1";
    H5Pset(gapl_id, PLIST_LINK_PROP, &path);

    /* Open the first group through the plist link using the GAPL we just
     * created */
    group_id = H5Gopen2(file_id, "plist_link", gapl_id);

    /* If we change the value set on the property list, it will change where
     * the plist link points.
     */
    path = "group_1/group_2";
    H5Pset(gapl_id, PLIST_LINK_PROP, &path);
    group2_id = H5Gopen2(file_id, "plist_link", gapl_id);

    /* group_id points to group_1 and group2_id points to group_2, both opened
     * through the same link.
     * Using more than one of this type of link could quickly become confusing,
     * since they will all use the same property list; however, there is
     * nothing to prevent the links from changing the property list in their
     * traverse callbacks.
     */

    /* Clean up */
    H5Pclose(gapl_id);
    H5Gclose(group_id);
    H5Gclose(group2_id);
    H5Fclose(file_id);
}
Exemple #3
0
/*-------------------------------------------------------------------------
 * Function:	main
 *
 * Purpose:	Split an hdf5 file
 *
 * Return:	Success:
 *
 *		Failure:
 *
 * Programmer:	Robb Matzke
 *              Wednesday, May 13, 1998
 *
 * Modifications:
 *
 *-------------------------------------------------------------------------
 */
int
main (int argc, char *argv[])
{
    const char	*prog_name;		/*program name			*/
    size_t	blk_size=1024;		/*size of each I/O block	*/
    char	*buf=NULL;		/*I/O block buffer		*/
    size_t	n, i;			/*counters			*/
    ssize_t	nio;			/*I/O return value		*/
    int		argno=1;		/*program argument number	*/
    int		src, dst=-1;		/*source & destination files	*/
    int		need_seek=FALSE;	/*destination needs to seek?	*/
    int		need_write;		/*data needs to be written?	*/
    h5_stat_t sb;                       /*temporary file stat buffer	*/

    int		verbose=FALSE;		/*display file names?		*/

    const char	*src_gen_name;  /*general source name		*/
    char	*src_name=NULL;	    /*source member name		*/

    int		src_is_family;		/*is source name a family name?	*/
    int		src_membno=0;		/*source member number		*/

    const char	*dst_gen_name;	/*general destination name	*/
    char	*dst_name=NULL;	    /*destination member name	*/
    int		dst_is_family;		/*is dst name a family name?	*/
    int		dst_membno=0;		/*destination member number	*/

    off_t	left_overs=0;		/*amount of zeros left over	*/
    off_t	src_offset=0;		/*offset in source member	*/
    off_t	dst_offset=0;		/*offset in destination member	*/
    off_t	src_size;           /*source logical member size	*/
    off_t	src_act_size;		/*source actual member size	*/
    off_t	dst_size=1 GB;		/*destination logical memb size	*/
    hid_t       fapl;                   /*file access property list     */
    hid_t       file;
    hsize_t     hdsize;                 /*destination logical memb size */
    hbool_t     family_to_sec2=FALSE;   /*change family to sec2 driver? */

    /*
     * Get the program name from argv[0]. Use only the last component.
     */
    if ((prog_name=strrchr (argv[0], '/'))) prog_name++;
    else prog_name = argv[0];

    /*
     * Parse switches.
     */
    while (argno<argc && '-'==argv[argno][0]) {
        if (!strcmp (argv[argno], "-v")) {
            verbose = TRUE;
            argno++;
        } else if (!strcmp(argv[argno], "-V")) {
            printf("This is %s version %u.%u release %u\n",
                prog_name, H5_VERS_MAJOR, H5_VERS_MINOR, H5_VERS_RELEASE);
            exit(EXIT_SUCCESS);
        } else if (!strcmp (argv[argno], "-family_to_sec2")) {
            family_to_sec2 = TRUE;
            argno++;
        } else if ('b'==argv[argno][1]) {
            blk_size = (size_t)get_size (prog_name, &argno, argc, argv);
        } else if ('m'==argv[argno][1]) {
            dst_size = get_size (prog_name, &argno, argc, argv);
        } else {
            usage (prog_name);
        } /* end if */
    } /* end while */

    /* allocate names */
    if(NULL == (src_name = (char *)HDcalloc((size_t)NAMELEN, sizeof(char))))
        exit(EXIT_FAILURE);
    if(NULL == (dst_name = (char *)HDcalloc((size_t)NAMELEN, sizeof(char))))
        exit(EXIT_FAILURE);

    /*
     * Get the name for the source file and open the first member.  The size
     * of the first member determines the logical size of all the members.
     */
    if (argno>=argc) usage (prog_name);
    src_gen_name = argv[argno++];
    sprintf (src_name, src_gen_name, src_membno);
    src_is_family = strcmp (src_name, src_gen_name);

    if ((src = HDopen(src_name, O_RDONLY)) < 0) {
        HDperror(src_name);
        HDexit(EXIT_FAILURE);
    }

    if (HDfstat(src, &sb)<0) {
        perror ("fstat");
        exit (EXIT_FAILURE);
    }
    src_size = src_act_size = sb.st_size;
    if (verbose) fprintf (stderr, "< %s\n", src_name);

    /*
     * Get the name for the destination file and open the first member.
     */
    if (argno>=argc) usage (prog_name);
    dst_gen_name = argv[argno++];
    sprintf (dst_name, dst_gen_name, dst_membno);
    dst_is_family = strcmp (dst_name, dst_gen_name);

    if ((dst = HDopen(dst_name, O_RDWR|O_CREAT|O_TRUNC, H5_POSIX_CREATE_MODE_RW)) < 0) {
        HDperror(dst_name);
        HDexit(EXIT_FAILURE);
    }
    if (verbose) fprintf (stderr, "> %s\n", dst_name);

    /* No more arguments */
    if (argno<argc) usage (prog_name);

    /* Now the real work, split the file */
    buf = (char *)HDmalloc(blk_size);
    while (src_offset<src_size) {

	/* Read a block.  The amount to read is the minimum of:
	 *    1. The I/O block size
	 *    2. What's left to write in the destination member
	 *    3. Left over zeros or what's left in the source member.
	 */
	n = blk_size;
	if (dst_is_family) n = (size_t)MIN((off_t)n, dst_size-dst_offset);
	if (left_overs) {
	    n = (size_t)MIN ((off_t)n, left_overs);
	    left_overs = left_overs - (off_t)n;
	    need_write = FALSE;
	} else if (src_offset<src_act_size) {
	    n = (size_t)MIN ((off_t)n, src_act_size-src_offset);
	    if ((nio=HDread (src, buf, n))<0) {
		perror ("read");
		exit (EXIT_FAILURE);
	    } else if ((size_t)nio!=n) {
		fprintf (stderr, "%s: short read\n", src_name);
		exit (EXIT_FAILURE);
	    }
	    for (i=0; i<n; i++) {
		if (buf[i]) break;
	    }
	    need_write = (i<n);
	} else {
	    n = 0;
	    left_overs = src_size - src_act_size;
	    need_write = FALSE;
	}

	/*
	 * If the block contains non-zero data then write it to the
	 * destination, otherwise just remember that we'll have to do a seek
	 * later in the destination when we finally get non-zero data.
	 */
	if (need_write) {
	    if (need_seek && HDlseek (dst, dst_offset, SEEK_SET)<0) {
		perror ("HDlseek");
		exit (EXIT_FAILURE);
	    }
	    if ((nio=HDwrite (dst, buf, n))<0) {
		perror ("write");
		exit (EXIT_FAILURE);
	    } else if ((size_t)nio!=n) {
		fprintf (stderr, "%s: short write\n", dst_name);
		exit (EXIT_FAILURE);
	    }
	    need_seek = FALSE;
	} else {
	    need_seek = TRUE;
	}

	/*
	 * Update the source offset and open the next source family member if
	 * necessary.  The source stream ends at the first member which
	 * cannot be opened because it doesn't exist.  At the end of the
	 * source stream, update the destination offset and break out of the
	 * loop.   The destination offset must be updated so we can fix
	 * trailing holes.
	 */
	src_offset = src_offset + (off_t)n;
	if (src_offset==src_act_size) {
	    HDclose (src);
	    if (!src_is_family) {
                dst_offset = dst_offset + (off_t)n;
		break;
	    }
	    sprintf (src_name, src_gen_name, ++src_membno);
	    if ((src = HDopen(src_name, O_RDONLY)) < 0 && ENOENT == errno) {
            dst_offset = dst_offset + (off_t)n;
            break;
	    } else if (src<0) {
		perror (src_name);
		exit (EXIT_FAILURE);
	    }
	    if (HDfstat (src, &sb)<0) {
		perror ("fstat");
		exit (EXIT_FAILURE);
	    }
	    src_act_size = sb.st_size;
	    if (src_act_size>src_size) {
		fprintf (stderr, "%s: member truncated to %lu bytes\n",
			 src_name, (unsigned long)src_size);
	    }
	    src_offset = 0;
	    if (verbose) fprintf (stderr, "< %s\n", src_name);
	}

	/*
	 * Update the destination offset, opening a new member if one will be
	 * needed. The first member is extended to the logical member size
	 * but other members might be smaller if they end with a hole.
	 */
        dst_offset = dst_offset + (off_t)n;
	if (dst_is_family && dst_offset==dst_size) {
	    if (0==dst_membno) {
		if (HDlseek (dst, dst_size-1, SEEK_SET)<0) {
		    perror ("HDHDlseek");
		    exit (EXIT_FAILURE);
		}
		if (HDread (dst, buf, 1)<0) {
		    perror ("read");
		    exit (EXIT_FAILURE);
		}
		if (HDlseek (dst, dst_size-1, SEEK_SET)<0) {
		    perror ("HDlseek");
		    exit (EXIT_FAILURE);
		}
		if (HDwrite (dst, buf, 1)<0) {
		    perror ("write");
		    exit (EXIT_FAILURE);
		}
	    }
	    HDclose (dst);
	    sprintf (dst_name, dst_gen_name, ++dst_membno);
	    if ((dst = HDopen(dst_name, O_RDWR|O_CREAT|O_TRUNC, H5_POSIX_CREATE_MODE_RW)) < 0) {
            HDperror(dst_name);
            HDexit(EXIT_FAILURE);
	    }
	    dst_offset = 0;
	    need_seek = FALSE;
	    if (verbose) fprintf (stderr, "> %s\n", dst_name);
	}
    }

    /*
     * Make sure the last family member is the right size and then close it.
     * The last member can't end with a hole or hdf5 will think that the
     * family has been truncated.
     */
    if (need_seek) {
	if (HDlseek (dst, dst_offset-1, SEEK_SET)<0) {
	    perror ("HDlseek");
	    exit (EXIT_FAILURE);
	}
	if (HDread (dst, buf, 1)<0) {
	    perror ("read");
	    exit (EXIT_FAILURE);
	}
	if (HDlseek (dst, dst_offset-1, SEEK_SET)<0) {
	    perror ("HDlseek");
	    exit (EXIT_FAILURE);
	}
	if (HDwrite (dst, buf, 1)<0) {
	    perror ("write");
	    exit (EXIT_FAILURE);
	}
    }
    HDclose (dst);

    /* Modify family driver information saved in superblock through private property.
     * These private properties are for this tool only. */
    if ((fapl=H5Pcreate(H5P_FILE_ACCESS))<0) {
        perror ("H5Pcreate");
        exit (EXIT_FAILURE);
    }

    if(family_to_sec2) {
        /* The user wants to change file driver from family to sec2. Open the file
         * with sec2 driver.  This property signals the library to ignore the family
         * driver information saved in the superblock. */
        if(H5Pset(fapl, H5F_ACS_FAMILY_TO_SEC2_NAME, &family_to_sec2) < 0) {
            perror ("H5Pset");
            exit (EXIT_FAILURE);
        }
    } else {
        /* Modify family size saved in superblock through private property. It signals
         * library to save the new member size(specified in command line) in superblock.
         * This private property is for this tool only. */
        if(H5Pset_fapl_family(fapl, H5F_FAMILY_DEFAULT, H5P_DEFAULT) < 0) {
            perror ("H5Pset_fapl_family");
            exit (EXIT_FAILURE);
        }

        /* Set the property of the new member size as hsize_t */
        hdsize = (hsize_t)dst_size;
        if(H5Pset(fapl, H5F_ACS_FAMILY_NEWSIZE_NAME, &hdsize) < 0) {
            perror ("H5Pset");
            exit (EXIT_FAILURE);
        }
    }

    /* If the new file is a family file, try to open file for "read and write" to
     * flush metadata. Flushing metadata will update the superblock to the new
     * member size.  If the original file is a family file and the new file is a sec2
     * file, the property FAMILY_TO_SEC2 will signal the library to switch to sec2
     * driver when the new file is opened.  If the original file is a sec2 file and the
     * new file can only be a sec2 file, reopen the new file should fail.  There's
     * nothing to do in this case. */
    H5E_BEGIN_TRY {
        file=H5Fopen(dst_gen_name, H5F_ACC_RDWR, fapl);
    } H5E_END_TRY;

    if(file>=0) {
        if(H5Fclose(file)<0) {
            perror ("H5Fclose");
            exit (EXIT_FAILURE);
        } /* end if */
    } /* end if */

    if(H5Pclose(fapl)<0) {
        perror ("H5Pclose");
        exit (EXIT_FAILURE);
    } /* end if */

    /* Free resources and return */
    HDfree(src_name);
    HDfree(dst_name);
    HDfree(buf);
    return EXIT_SUCCESS;
} /* end main */