summaryrefslogtreecommitdiffstats
path: root/examples/h5_elink_unix2win.c
diff options
context:
space:
mode:
authorJames Laird <jlaird@hdfgroup.org>2006-08-22 16:22:43 (GMT)
committerJames Laird <jlaird@hdfgroup.org>2006-08-22 16:22:43 (GMT)
commit9d4229713ebb1ed899c5c5fa72dbaeb5611e923e (patch)
tree381374eb5ffa7cf95f6794a0910e1cdd12cf0175 /examples/h5_elink_unix2win.c
parentc17ea4461717a8065cc421980f897fa30a07f8d0 (diff)
downloadhdf5-9d4229713ebb1ed899c5c5fa72dbaeb5611e923e.zip
hdf5-9d4229713ebb1ed899c5c5fa72dbaeb5611e923e.tar.gz
hdf5-9d4229713ebb1ed899c5c5fa72dbaeb5611e923e.tar.bz2
[svn-r12608] Checked in External Link C examples.
Since these examples need to follow filesystem paths, the Makefiles need to create directories in the examples directory; added this to the Makefile.am. Tested on Windows, mir, juniper
Diffstat (limited to 'examples/h5_elink_unix2win.c')
-rw-r--r--examples/h5_elink_unix2win.c209
1 files changed, 209 insertions, 0 deletions
diff --git a/examples/h5_elink_unix2win.c b/examples/h5_elink_unix2win.c
new file mode 100644
index 0000000..35ab271
--- /dev/null
+++ b/examples/h5_elink_unix2win.c
@@ -0,0 +1,209 @@
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Copyright by the Board of Trustees of the University of Illinois. *
+ * All rights reserved. *
+ * *
+ * This file is part of HDF5. The full HDF5 copyright notice, including *
+ * terms governing use, modification, and redistribution, is contained in *
+ * the files COPYING and Copyright.html. COPYING can be found at the root *
+ * of the source code distribution tree; Copyright.html can be found at the *
+ * root level of an installed copy of the electronic HDF5 document set and *
+ * is linked from the top-level documents page. It can also be found at *
+ * http://hdf.ncsa.uiuc.edu/HDF5/doc/Copyright.html. If you do not have *
+ * access to either file, you may request a copy from hdfhelp@ncsa.uiuc.edu. *
+ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+/* This program demonstrates how to translate an external link created on
+ * a Windows machine into a format that a *nix machine can read.
+ * This is done by registering a new traversal function for external links.
+ *
+ * This example is designed to be run on Unix and will create an external
+ * link with a Windows-style path. Using the traversal function below,
+ * the example then successfully follows the external link.
+ *
+ * The external link will create a file called "u2w/u2w_target.h5".
+ * The example will fail if the directory u2w does not exist.
+ */
+
+#include "hdf5.h"
+#include <stdlib.h>
+#include <string.h>
+
+
+/* "Windows to Unix" traversal function for external links
+ *
+ * Translates a filename stored in Unix format to Windows format by replacing
+ * forward slashes with backslashes.
+ * Makes no attempt to handle Windows drive names (e.g., "C:\"), spaces within
+ * file names, quotes, etc. These are left as an exercise for the user. :)
+ * Note that this may not be necessary on your system; many Windows systems can
+ * understand Unix paths.
+ */
+static hid_t elink_unix2win_trav(const char *link_name, hid_t cur_group, void * udata, size_t udata_size, hid_t lapl_id)
+{
+ hid_t fid;
+ char *file_name;
+ hbool_t fname_alloc = 0; /* Whether file_name has been allocated */
+ char *obj_name;
+ char *new_fname = NULL; /* Buffer allocated to hold Unix file path */
+ size_t fname_len;
+ htri_t result;
+ size_t buf_size; /* Size prefix buffer */
+ size_t start_pos; /* Initial position in new_fname buffer */
+ size_t x; /* Counter variable */
+ hid_t ret_value = -1;
+
+ printf("Converting Unix path to Windows path.\n");
+
+ if(H5Lunpack_elink_val(udata, &file_name, &obj_name) < 0)
+ goto error;
+ fname_len = strlen(file_name);
+
+ /* See if the external link prefix property is set */
+ if((result = H5Pexist(lapl_id, H5L_ELINK_PREFIX_PROP)) < 0)
+ goto error;
+
+ /* If so, prepend it to the filename. We assume that the prefix
+ * is in the correct format for the current file system.
+ */
+ if(result > 0)
+ {
+ if(H5Pget_size(lapl_id, H5L_ELINK_PREFIX_PROP, &buf_size) < 0)
+ goto error;
+
+ /* Allocate a buffer to hold the filename plus prefix */
+ new_fname = malloc(buf_size + fname_len + 1);
+
+ /* Copy the prefix into the buffer */
+ if(H5Pget(lapl_id, H5L_ELINK_PREFIX_PROP, new_fname) < 0)
+ goto error;
+
+ start_pos = buf_size - 1;
+ }
+ else
+ {
+ /* Allocate a buffer to hold just the filename */
+ new_fname = malloc(fname_len + 1);
+ start_pos = 0;
+ }
+
+ /* We should now copy file_name into new_fname starting at position pos.
+ * We'll convert '/' characters into '\' characters as we go.
+ */
+ for(x=0; file_name[x] != '\0'; x++)
+ {
+ if(file_name[x] == '/')
+ new_fname[x + start_pos] = '\\';
+ else
+ new_fname[x + start_pos] = file_name[x];
+ }
+ new_fname[x + start_pos] = '\0';
+
+ /* Now open the file and object within it */
+ if((fid = H5Fopen(new_fname, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
+ goto error;
+ ret_value = H5Oopen(fid, obj_name, lapl_id); /* If this fails, our return value will be negative. */
+ if(H5Fclose(fid) < 0)
+ goto error;
+
+ /* Free file_name if it's been allocated */
+ if(fname_alloc)
+ free(file_name);
+
+ return ret_value;
+
+error:
+ /* Free file_name if it's been allocated */
+ if(new_fname)
+ free(new_fname);
+ return -1;
+}
+
+const H5L_link_class_t elink_unix2win_class[1] = {{
+ H5L_LINK_CLASS_T_VERS, /* H5L_link_class_t version */
+ H5L_LINK_EXTERNAL, /* Link type id number */
+ "unix2win external link", /* Link class name for debugging */
+ NULL, /* Creation callback */
+ NULL, /* Move callback */
+ NULL, /* Copy callback */
+ elink_unix2win_trav, /* The actual traversal function */
+ NULL, /* Deletion callback */
+ NULL /* Query callback */
+}};
+
+
+/* The example function.
+ * Creates a file named "unix2win.h5" with an external link pointing to
+ * the file "u2w/u2w_target.h5".
+ *
+ * Registers a new traversal function for external links and then
+ * follows the external link to open the target file.
+ */
+static int
+unix2win_example()
+{
+ hid_t fid = (-1); /* File ID */
+ hid_t gid = (-1); /* Group ID */
+
+ /* Create the target file. */
+#ifdef WIN32
+ if((fid=H5Fcreate("u2w\u2w_target.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT))<0) goto error;
+#else
+ if((fid=H5Fcreate("u2w/u2w_target.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT))<0) goto error;
+#endif
+ if(H5Fclose(fid) < 0) goto error;
+
+ /* Create the source file with an external link in Windows format */
+ if((fid=H5Fcreate("unix2win.h5", H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT))<0) goto error;
+
+ /* Create the external link */
+ if(H5Lcreate_external("u2w/../u2w/u2w_target.h5", "/", fid, "ext_link", H5P_DEFAULT, H5P_DEFAULT) < 0) goto error;
+
+ /* If we are not on Windows, assume we are on a Unix-y filesystem and
+ * follow the external link normally.
+ * If we are on Windows, register the unix2win traversal function so
+ * that external links can be traversed.
+ */
+
+#ifdef WIN32
+ /* Register the elink_unix2win class defined above to replace default
+ * external links
+ */
+ if(H5Lregister(elink_unix2win_class) < 0) goto error;
+#endif
+
+ /* Now follow the link */
+ if((gid = H5Gopen(fid, "ext_link")) < 0) goto error;
+ printf("Successfully followed external link.\n");
+
+ /* Close the group and the file */
+ if(H5Gclose(gid) <0) goto error;
+ if(H5Fclose(fid) <0) goto error;
+
+ return 0;
+
+ error:
+ printf("Error!\n");
+ H5E_BEGIN_TRY {
+ H5Gclose (gid);
+ H5Fclose (fid);
+ } H5E_END_TRY;
+ return -1;
+}
+
+
+/* Main function
+ *
+ * Invokes the example function.
+ */
+int
+main(void)
+{
+ int ret;
+
+ printf("Testing unix2win external links.\n");
+ ret = unix2win_example();
+
+ return ret;
+}
+
+