summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xbin/snapshot2
-rw-r--r--configure.in2
-rw-r--r--src/H5D.c61
-rw-r--r--src/H5Dprivate.h1
-rw-r--r--src/H5G.c220
-rw-r--r--src/H5Gprivate.h15
-rw-r--r--src/H5Gpublic.h18
-rw-r--r--src/H5O.c49
-rw-r--r--src/H5Oprivate.h1
-rw-r--r--src/H5RA.c61
-rw-r--r--src/H5RAprivate.h1
-rw-r--r--src/H5T.c35
-rw-r--r--src/H5Tprivate.h1
-rw-r--r--src/H5config.h.in5
-rw-r--r--tools/h5ls.c66
-rw-r--r--tools/h5tools.c15
-rw-r--r--tools/h5tools.h8
17 files changed, 498 insertions, 63 deletions
diff --git a/bin/snapshot b/bin/snapshot
index d87dd3a..ef49c29 100755
--- a/bin/snapshot
+++ b/bin/snapshot
@@ -42,7 +42,7 @@ snapshot=yes
if [ -d ${COMPARE}/previous ]; then
if (diff -c ${COMPARE}/previous/MANIFEST ${COMPARE}/current/MANIFEST); then
snapshot=no
- for src in `grep '^\.' ${COMPARE}/current/MANIFEST|expand|cut -f1`; do
+ for src in `grep '^\.' ${COMPARE}/current/MANIFEST|expand|cut -f1 -d' '`; do
if (diff -I H5_VERS_RELEASE -I " released on " \
${COMPARE}/previous/$src ${COMPARE}/current/$src); then
else
diff --git a/configure.in b/configure.in
index c26a3c3..0999e01 100644
--- a/configure.in
+++ b/configure.in
@@ -1,4 +1,4 @@
-dnl Process this file with autoconf to produce configure. -*-indented-text-*-
+dnl Process this file with autoconf to produce configure.
dnl
dnl Copyright (C) 1997 National Center for Supercomputing Applications.
dnl All rights reserved.
diff --git a/src/H5D.c b/src/H5D.c
index 62e6b74..65dca31 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -1101,7 +1101,57 @@ H5D_create(H5G_entry_t *loc, const char *name, const H5T_t *type,
FUNC_LEAVE(ret_value);
}
+
/*-------------------------------------------------------------------------
+ * Function: H5D_isa
+ *
+ * Purpose: Determines if an object has the requisite messages for being
+ * a dataset.
+ *
+ * Return: Success: TRUE if the required dataset messages are
+ * present; FALSE otherwise.
+ *
+ * Failure: FAIL if the existence of certain messages
+ * cannot be determined.
+ *
+ * Programmer: Robb Matzke
+ * Monday, November 2, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5D_isa(H5G_entry_t *ent)
+{
+ htri_t exists;
+
+ FUNC_ENTER(H5D_isa, FAIL);
+ assert(ent);
+
+ /* Data type */
+ if ((exists=H5O_exists(ent, H5O_DTYPE, 0))<0) {
+ HRETURN_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to read object header");
+ } else if (!exists) {
+ HRETURN(FALSE);
+ }
+
+ /* Layout */
+ if ((exists=H5O_exists(ent, H5O_LAYOUT, 0))<0) {
+ HRETURN_ERROR(H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to read object header");
+ } else if (!exists) {
+ HRETURN(FALSE);
+ }
+
+
+
+ FUNC_LEAVE(TRUE);
+}
+
+/*
+ *-------------------------------------------------------------------------
* Function: H5D_open
*
* Purpose: Finds a dataset named NAME in file F and builds a descriptor
@@ -1130,7 +1180,7 @@ H5D_open(H5G_entry_t *loc, const char *name)
{
H5D_t *dataset = NULL; /*the dataset which was found */
H5D_t *ret_value = NULL; /*return value */
- H5G_entry_t ent; /* Dataset symbol table entry */
+ H5G_entry_t ent; /*dataset symbol table entry */
FUNC_ENTER(H5D_open, NULL);
@@ -1173,10 +1223,10 @@ done:
H5D_t *
H5D_open_oid(H5G_entry_t *ent)
{
- H5D_t *dataset = NULL; /* New dataset struct */
- H5D_t *ret_value = NULL; /*return value */
+ H5D_t *dataset = NULL; /*new dataset struct */
+ H5D_t *ret_value = NULL; /*return value */
+ H5S_t *space = NULL; /*data space */
intn i;
- H5S_t *space = NULL;
FUNC_ENTER(H5D_open_oid, NULL);
@@ -1290,8 +1340,7 @@ H5D_open_oid(H5G_entry_t *ent)
ret_value = dataset;
done:
- if (space)
- H5S_close (space);
+ if (space) H5S_close (space);
if (ret_value==NULL && dataset) {
if (H5F_addr_defined(&(dataset->ent.header))) {
H5O_close(&(dataset->ent));
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index bdf66f7..3a30731 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -71,6 +71,7 @@ H5D_t *H5D_create (H5G_entry_t *loc, const char *name, const H5T_t *type,
const H5S_t *space, const H5D_create_t *create_parms);
H5D_t *H5D_open (H5G_entry_t *loc, const char *name);
herr_t H5D_close (H5D_t *dataset);
+htri_t H5D_isa(H5G_entry_t *ent);
herr_t H5D_read (H5D_t *dataset, const H5T_t *mem_type,
const H5S_t *mem_space, const H5S_t *file_space,
const H5D_xfer_t *xfer_parms, void *buf/*out*/);
diff --git a/src/H5G.c b/src/H5G.c
index bf15f3d..992de26 100644
--- a/src/H5G.c
+++ b/src/H5G.c
@@ -95,6 +95,9 @@ static hbool_t interface_initialize_g = FALSE;
#define INTERFACE_INIT H5G_init_interface
static herr_t H5G_init_interface(void);
static void H5G_term_interface(void);
+static H5G_typeinfo_t *H5G_type_g = NULL; /*object typing info */
+static size_t H5G_ntypes_g = 0; /*entries in type table */
+static size_t H5G_atypes_g = 0; /*entries allocated */
/*-------------------------------------------------------------------------
@@ -523,8 +526,9 @@ H5Gget_objinfo(hid_t loc_id, const char *name, hbool_t follow_link,
* most SIZE characters (counting the null terminator) are
* copied to the BUF result buffer.
*
- * Return: Non-negative on success (the link value is in BUF.) /Negative on
- * failure
+ * Return: Success: Non-negative with the link value in BUF.
+ *
+ * Failure: Negative
*
* Programmer: Robb Matzke
* Monday, April 13, 1998
@@ -684,6 +688,17 @@ H5G_init_interface(void)
HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL,
"unable to initialize interface");
}
+
+ /*
+ * Initialize the type info table. Begin with the most general types and
+ * end with the most specific. For instance, any object that has a data
+ * type message is a data type but only some of them are datasets.
+ */
+ H5G_register_type(H5G_TYPE, H5T_isa, "data type");
+ H5G_register_type(H5G_GROUP, H5G_isa, "group");
+ H5G_register_type(H5G_DATASET, H5D_isa, "dataset");
+ H5G_register_type(H5G_RAGGED, H5RA_isa, "ragged array");
+
FUNC_LEAVE(SUCCEED);
}
@@ -710,6 +725,85 @@ H5G_term_interface(void)
/*-------------------------------------------------------------------------
+ * Function: H5G_register_type
+ *
+ * Purpose: Register a new object type so H5G_get_type() can detect it.
+ * One should always register a general type before a more
+ * specific type. For instance, any object that has a data type
+ * message is a data type, but only some of those objects are
+ * datasets.
+ *
+ * Return: Success: Non-negative
+ *
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, November 4, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5G_register_type(intn type, htri_t(*isa)(H5G_entry_t*), const char *_desc)
+{
+ char *desc = NULL;
+ size_t i;
+ herr_t ret_value = FAIL;
+
+ FUNC_ENTER(H5G_register_type, FAIL);
+ assert(type>=0);
+ assert(isa);
+ assert(_desc);
+
+ /* Copy the description */
+ if (NULL==(desc=H5MM_strdup(_desc))) {
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed for object type description");
+ }
+
+ /*
+ * If the type is already registered then just update its entry without
+ * moving it to the end
+ */
+ for (i=0; i<H5G_ntypes_g; i++) {
+ if (H5G_type_g[i].type==type) {
+ H5G_type_g[i].isa = isa;
+ H5MM_xfree(H5G_type_g[i].desc);
+ H5G_type_g[i].desc = desc;
+ ret_value = SUCCEED;
+ goto done;
+ }
+ }
+
+ /* Increase table size */
+ if (H5G_ntypes_g>=H5G_atypes_g) {
+ size_t n = MAX(32, 2*H5G_atypes_g);
+ H5G_typeinfo_t *x = H5MM_realloc(H5G_type_g,
+ n*sizeof(H5G_typeinfo_t));
+ if (!x) {
+ HGOTO_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
+ "memory allocation failed for objec type table");
+ }
+ H5G_atypes_g = n;
+ H5G_type_g = x;
+ }
+
+ /* Add a new entry */
+ H5G_type_g[H5G_ntypes_g].type = type;
+ H5G_type_g[H5G_ntypes_g].isa = isa;
+ H5G_type_g[H5G_ntypes_g].desc = desc; /*already copied*/
+ H5G_ntypes_g++;
+
+ ret_value = SUCCEED;
+
+ done:
+ if (ret_value<0) H5MM_xfree(desc);
+ FUNC_LEAVE(ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5G_component
*
* Purpose: Returns the pointer to the first component of the
@@ -842,14 +936,14 @@ H5G_basename(const char *name, size_t *size_p)
*
* Errors:
*
- * Return: Success: Non-negative if name can be fully resolved. See
- * above for values of REST, GRP_ENT, and
+ * Return: Success: Non-negative if name can be fully resolved.
+ * See above for values of REST, GRP_ENT, and
* OBJ_ENT. NLINKS has been decremented for
* each symbolic link that was followed.
*
- * Failure: Negative if the name could not be fully resolved.
- * See above for values of REST, GRP_ENT, and
- * OBJ_ENT.
+ * Failure: Negative if the name could not be fully
+ * resolved. See above for values of REST,
+ * GRP_ENT, and OBJ_ENT.
*
* Programmer: Robb Matzke
* matzke@llnl.gov
@@ -1191,6 +1285,42 @@ H5G_create(H5G_entry_t *loc, const char *name, size_t size_hint)
grp->nref = 1;
FUNC_LEAVE(grp);
}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5G_isa
+ *
+ * Purpose: Determines if an object has the requisite messages for being
+ * a group.
+ *
+ * Return: Success: TRUE if the required group messages are
+ * present; FALSE otherwise.
+ *
+ * Failure: FAIL if the existence of certain messages
+ * cannot be determined.
+ *
+ * Programmer: Robb Matzke
+ * Monday, November 2, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5G_isa(H5G_entry_t *ent)
+{
+ htri_t exists;
+
+ FUNC_ENTER(H5G_isa, FAIL);
+ assert(ent);
+
+ if ((exists=H5O_exists(ent, H5O_STAB, 0))<0) {
+ HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL,
+ "unable to read object header");
+ }
+ FUNC_LEAVE(exists);
+}
+
/*-------------------------------------------------------------------------
* Function: H5G_open
@@ -1431,8 +1561,8 @@ H5G_insert(H5G_entry_t *loc, const char *name, H5G_entry_t *ent)
*
* Errors:
*
- * Return: Success: Non-negative, see above for values of GRP_ENT and
- * OBJ_ENT.
+ * Return: Success: Non-negative, see above for values of GRP_ENT
+ * and OBJ_ENT.
*
* Failure: Negative
*
@@ -1761,12 +1891,54 @@ H5G_link (H5G_entry_t *loc, H5G_link_t type, const char *cur_name,
/*-------------------------------------------------------------------------
+ * Function: H5G_get_type
+ *
+ * Purpose: Returns the type of object pointed to by `ent'.
+ *
+ * Return: Success: An object type defined in H5Gpublic.h
+ *
+ * Failure: H5G_UNKNOWN
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, November 4, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+intn
+H5G_get_type(H5G_entry_t *ent)
+{
+ htri_t isa;
+ size_t i;
+
+ FUNC_ENTER(H5G_get_type, H5G_UNKNOWN);
+
+ for (i=H5G_ntypes_g; i>0; --i) {
+ if ((isa=(H5G_type_g[i-1].isa)(ent))<0) {
+ HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL,
+ "unable to determine object type");
+ } else if (isa) {
+ HRETURN(H5G_type_g[i-1].type);
+ }
+ }
+
+ if (0==i) {
+ HRETURN_ERROR(H5E_SYM, H5E_CANTINIT, FAIL,
+ "unable to determine object type");
+ }
+ FUNC_LEAVE(H5G_UNKNOWN);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5G_get_objinfo
*
* Purpose: Returns information about an object.
*
- * Return: Success: Non-negative with info about the object returned
- * through STATBUF if it isn't the null pointer.
+ * Return: Success: Non-negative with info about the object
+ * returned through STATBUF if it isn't the null
+ * pointer.
*
* Failure: Negative
*
@@ -1784,9 +1956,6 @@ H5G_get_objinfo (H5G_entry_t *loc, const char *name, hbool_t follow_link,
H5O_stab_t stab_mesg;
H5G_entry_t grp_ent, obj_ent;
const char *s = NULL;
- H5D_t *temp_dset = NULL;
- H5G_t *temp_grp = NULL;
- H5T_t *temp_type = NULL;
FUNC_ENTER (H5G_get_objinfo, FAIL);
@@ -1833,24 +2002,7 @@ H5G_get_objinfo (H5G_entry_t *loc, const char *name, hbool_t follow_link,
H5E_clear();
statbuf->mtime = 0;
}
-
- /*
- * Determining the type of an object is a rather expensive
- * operation compared to the other stuff here. It's also not
- * very flexible.
- */
- if (NULL!=(temp_dset=H5D_open (loc, name))) {
- statbuf->type = H5G_DATASET;
- H5D_close (temp_dset);
- } else if (NULL!=(temp_grp=H5G_open (loc, name))) {
- statbuf->type = H5G_GROUP;
- H5G_close (temp_grp);
- } else if (NULL!=(temp_type=H5T_open(loc, name))) {
- statbuf->type = H5G_TYPE;
- H5T_close(temp_type);
- } else {
- statbuf->type = H5G_UNKNOWN;
- }
+ statbuf->type = H5G_get_type(&obj_ent);
H5E_clear(); /*clear errors resulting from checking type*/
}
}
@@ -1864,8 +2016,8 @@ H5G_get_objinfo (H5G_entry_t *loc, const char *name, hbool_t follow_link,
*
* Purpose: Returns the value of a symbolic link.
*
- * Return: Success: Non-negative, with at most SIZE bytes of the link
- * value copied into the BUF buffer. If the
+ * Return: Success: Non-negative, with at most SIZE bytes of the
+ * link value copied into the BUF buffer. If the
* link value is larger than SIZE characters
* counting the null terminator then the BUF
* result will not be null terminated.
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index 1cf448f..ac430c1 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -96,9 +96,22 @@ typedef struct H5G_entry_t {
typedef struct H5G_t H5G_t;
/*
+ * This table contains a list of object types, descriptions, and the
+ * functions that determine if some object is a particular type. The table
+ * is allocated dynamically.
+ */
+typedef struct H5G_typeinfo_t {
+ intn type; /*one of the public H5G_* types */
+ htri_t (*isa)(H5G_entry_t*); /*function to determine type */
+ char *desc; /*description of object type */
+} H5G_typeinfo_t;
+
+/*
* Library prototypes... These are the ones that other packages routinely
* call.
*/
+herr_t H5G_register_type(intn type, htri_t(*isa)(H5G_entry_t*),
+ const char *desc);
H5G_entry_t *H5G_loc (hid_t loc_id);
herr_t H5G_mkroot (H5F_t *f, H5G_entry_t *root_entry);
H5G_entry_t *H5G_entof (H5G_t *grp);
@@ -108,8 +121,10 @@ H5G_t *H5G_open (H5G_entry_t *loc, const char *name);
H5G_t *H5G_reopen (H5G_t *grp);
herr_t H5G_close (H5G_t *grp);
H5G_t *H5G_rootof(H5F_t *f);
+htri_t H5G_isa(H5G_entry_t *ent);
herr_t H5G_link (H5G_entry_t *loc, H5G_link_t type, const char *cur_name,
const char *new_name, uintn namei_flags);
+intn H5G_get_type(H5G_entry_t *ent);
herr_t H5G_get_objinfo (H5G_entry_t *loc, const char *name,
hbool_t follow_link, H5G_stat_t *statbuf/*out*/);
herr_t H5G_linkval (H5G_entry_t *loc, const char *name, size_t size,
diff --git a/src/H5Gpublic.h b/src/H5Gpublic.h
index cc3cc7d..32fc1d4 100644
--- a/src/H5Gpublic.h
+++ b/src/H5Gpublic.h
@@ -34,13 +34,27 @@ typedef enum H5G_link_t {
H5G_LINK_SOFT = 1
} H5G_link_t;
-/* An object has a certain type */
+/*
+ * An object has a certain type. The first few numbers are reserved for use
+ * internally by HDF5. Users may add their own types with higher values. The
+ * values are never stored in the file -- they only exist while an
+ * application is running. An object may satisfy the `isa' function for more
+ * than one type.
+ */
#define H5G_UNKNOWN (-1) /* Unknown object type */
#define H5G_LINK 0 /* Object is a symbolic link */
#define H5G_GROUP 1 /* Object is a group */
#define H5G_DATASET 2 /* Object is a dataset */
#define H5G_TYPE 3 /* Object is a named data type */
-#define H5G_NTYPES 4 /* THIS MUST BE LAST */
+#define H5G_RAGGED 4 /* Object is a ragged array */
+#define H5G_RESERVED_5 5 /* Reserved for future use */
+#define H5G_RESERVED_6 6 /* Reserved for future use */
+#define H5G_RESERVED_7 7 /* Reserved for future use */
+
+#define H5G_NTYPES 256 /* Max possible number of types */
+#define H5G_NLIBTYPES 8 /* Number of internal types */
+#define H5G_NUSERTYPES (H5G_NTYPES-H5G_NLIBTYPES)
+#define H5G_USERTYPE(X) (8+(X)) /* User defined types */
/* Information about an object */
typedef struct H5G_stat_t {
diff --git a/src/H5O.c b/src/H5O.c
index 8d7ee63..d1e1d07 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -878,6 +878,55 @@ H5O_count (H5G_entry_t *ent, const H5O_class_t *type)
/*-------------------------------------------------------------------------
+ * Function: H5O_exists
+ *
+ * Purpose: Determines if a particular message exists in an object
+ * header without trying to decode the message.
+ *
+ * Return: Success: FALSE if the message does not exist; TRUE if
+ * th message exists.
+ *
+ * Failure: FAIL if the existence of the message could
+ * not be determined due to some error such as
+ * not being able to read the object header.
+ *
+ * Programmer: Robb Matzke
+ * Monday, November 2, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5O_exists(H5G_entry_t *ent, const H5O_class_t *type, intn sequence)
+{
+ H5O_t *oh=NULL;
+ intn i;
+
+ FUNC_ENTER(H5O_exists, FAIL);
+ assert(ent);
+ assert(ent->file);
+ assert(type);
+ assert(sequence>=0);
+
+ /* Load the object header */
+ if (NULL==(oh=H5AC_find(ent->file, H5AC_OHDR, &(ent->header),
+ NULL, NULL))) {
+ HRETURN_ERROR(H5E_OHDR, H5E_CANTLOAD, FAIL,
+ "unable to load object header");
+ }
+
+ /* Scan through the messages looking for the right one */
+ for (i=0; i<oh->nmesgs; i++) {
+ if (type->id!=oh->mesg[i].type->id) continue;
+ if (--sequence<0) break;
+ }
+
+ FUNC_LEAVE(sequence<0);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5O_read
*
* Purpose: Reads a message from an object header and returns a pointer
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 7dff3c9..16fbded 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -273,6 +273,7 @@ herr_t H5O_open (H5G_entry_t *ent);
herr_t H5O_close (H5G_entry_t *ent);
intn H5O_link (H5G_entry_t *ent, intn adjust);
intn H5O_count (H5G_entry_t *ent, const H5O_class_t *type);
+htri_t H5O_exists(H5G_entry_t *ent, const H5O_class_t *type, intn sequence);
void *H5O_read (H5G_entry_t *ent, const H5O_class_t *type, intn sequence,
void *mesg);
intn H5O_modify (H5G_entry_t *ent, const H5O_class_t *type, intn overwrite,
diff --git a/src/H5RA.c b/src/H5RA.c
index c0ed491..11d02e9 100644
--- a/src/H5RA.c
+++ b/src/H5RA.c
@@ -398,6 +398,67 @@ H5RAopen(hid_t loc_id, const char *name)
/*-------------------------------------------------------------------------
+ * Function: H5RA_isa
+ *
+ * Purpose: Determines if an object is a ragged array.
+ *
+ * Return: Success: TRUE if the object is a ragged array; FALSE
+ * otherwise.
+ *
+ * Failure: Negative
+ *
+ * Programmer: Robb Matzke
+ * Wednesday, November 4, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5RA_isa(H5G_entry_t *ent)
+{
+ htri_t exists;
+ H5G_entry_t d_ent;
+
+ FUNC_ENTER(H5RA_isa, FAIL);
+
+ /* Open the container group */
+ if ((exists=H5G_isa(ent))<0) {
+ HRETURN_ERROR(H5E_RAGGED, H5E_CANTINIT, FAIL,
+ "unable to read object header");
+ } else if (!exists) {
+ HRETURN(FALSE);
+ }
+
+ /* Is `raw' a dataset? */
+ if (H5G_find(ent, "raw", NULL, &d_ent)<0 ||
+ (exists=H5D_isa(&d_ent))<0) {
+ HRETURN_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found");
+ } else if (!exists) {
+ HRETURN(FALSE);
+ }
+
+ /* Is `over' a dataset? */
+ if (H5G_find(ent, "over", NULL, &d_ent)<0 ||
+ (exists=H5D_isa(&d_ent))<0) {
+ HRETURN_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found");
+ } else if (!exists) {
+ HRETURN(FALSE);
+ }
+
+ /* Is `meta' a dataset? */
+ if (H5G_find(ent, "meta", NULL, &d_ent)<0 ||
+ (exists=H5D_isa(&d_ent))<0) {
+ HRETURN_ERROR(H5E_DATASET, H5E_NOTFOUND, FAIL, "not found");
+ } else if (!exists) {
+ HRETURN(FALSE);
+ }
+
+ FUNC_LEAVE(TRUE);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5RA_open
*
* Purpose: Open a ragged array. The name of the array is the same as
diff --git a/src/H5RAprivate.h b/src/H5RAprivate.h
index 19e11d7..89e83db 100644
--- a/src/H5RAprivate.h
+++ b/src/H5RAprivate.h
@@ -19,6 +19,7 @@ herr_t H5RA_close(H5RA_t *ra);
H5RA_t *H5RA_create(H5G_entry_t *loc, const char *name, H5T_t *type,
const H5D_create_t *dcpl);
H5RA_t *H5RA_open(H5G_entry_t *loc, const char *name);
+htri_t H5RA_isa(H5G_entry_t *ent);
herr_t H5RA_write(H5RA_t *ra, hssize_t start_row, hsize_t nrows, H5T_t *type,
hsize_t size[], void *buf[]);
herr_t H5RA_read(H5RA_t *ra, hssize_t start_row, hsize_t nrows, H5T_t *type,
diff --git a/src/H5T.c b/src/H5T.c
index 916bc87..517e6a3 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -3466,6 +3466,41 @@ H5T_create(H5T_class_t type, size_t size)
/*-------------------------------------------------------------------------
+ * Function: H5T_isa
+ *
+ * Purpose: Determines if an object has the requisite messages for being
+ * a data type.
+ *
+ * Return: Success: TRUE if the required data type messages are
+ * present; FALSE otherwise.
+ *
+ * Failure: FAIL if the existence of certain messages
+ * cannot be determined.
+ *
+ * Programmer: Robb Matzke
+ * Monday, November 2, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+htri_t
+H5T_isa(H5G_entry_t *ent)
+{
+ htri_t exists;
+
+ FUNC_ENTER(H5T_isa, FAIL);
+ assert(ent);
+
+ if ((exists=H5O_exists(ent, H5O_DTYPE, 0))<0) {
+ HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to read object header");
+ }
+ FUNC_LEAVE(exists);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5T_open
*
* Purpose: Open a named data type.
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index 25d4f6d..3b602a1 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -44,6 +44,7 @@ typedef enum H5T_copy_t {
/* Private functions */
herr_t H5T_init (void);
herr_t H5T_init_interface (void);
+htri_t H5T_isa(H5G_entry_t *ent);
H5T_t *H5T_open (H5G_entry_t *loc, const char *name);
H5T_t *H5T_create (H5T_class_t type, size_t size);
H5T_t *H5T_copy (const H5T_t *old_dt, H5T_copy_t method);
diff --git a/src/H5config.h.in b/src/H5config.h.in
index 755ec7e..a08c7e2 100644
--- a/src/H5config.h.in
+++ b/src/H5config.h.in
@@ -44,7 +44,7 @@
/* Define if it's safe to use `long long' for hsize_t and hssize_t */
#undef HAVE_LARGE_HSIZET
-/* The width parameter for printf formats for type `long long', us. `ll' */
+/* Width for printf() for type `long long' or `__int64', us. `ll' */
#undef PRINTF_LL_WIDTH
/* Define if `tm_gmtoff' is a member of `struct tm' */
@@ -56,6 +56,9 @@
/* Define if `struct timezone' is defined */
#undef HAVE_STRUCT_TIMEZONE
+/* Define if `struct stat' has the `st_blocks' field */
+#undef HAVE_STAT_ST_BLOCKS
+
/* The number of bytes in a __int64. */
#undef SIZEOF___INT64
diff --git a/tools/h5ls.c b/tools/h5ls.c
index 39124b8..3d7b845 100644
--- a/tools/h5ls.c
+++ b/tools/h5ls.c
@@ -5,14 +5,15 @@
* Programmer: Robb Matzke <matzke@llnl.gov>
* Monday, March 23, 1998
*/
-#include <ctype.h>
-#include <h5tools.h>
-#include <hdf5.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+
+/*
+ * We include the private header file so we can get to the uniform
+ * programming environment it declares.
+ */
#include <H5private.h>
+#include <h5tools.h>
+
#ifndef HAVE_ATTRIBUTE
# undef __attribute__
# define __attribute__(X) /*void*/
@@ -25,6 +26,7 @@
static int verbose_g = 0;
static int dump_g = 0;
static int width_g = 80;
+static int string_g = FALSE;
/* Information about how to display each type of object */
static struct dispatch_t {
@@ -68,6 +70,7 @@ usage: %s [OPTIONS] FILE [OBJECTS...]\n\
OPTIONS\n\
-h, -?, --help Print a usage message and exit\n\
-d, --dump Print the values of datasets\n\
+ -s, --string Print 1-byte integer datasets as ASCII\n\
-wN, --width=N Set the number of columns of output\n\
-v, --verbose Generate more verbose output\n\
-V, --version Print version number and exit\n\
@@ -112,9 +115,11 @@ dump_dataset_values(hid_t dset)
/*
* If the dataset is a 1-byte integer type then format it as an ASCI
- * character string instead of integers.
+ * character string instead of integers if the `-s' or `--string'
+ * command-line option was given.
*/
- if (1==size && H5T_INTEGER==H5Tget_class(f_type)) {
+ if (string_g && 1==size && H5T_INTEGER==H5Tget_class(f_type)) {
+ info.ascii = TRUE;
info.elmt_suf1 = "";
info.elmt_suf2 = "";
info.idx_fmt = " (%s) \"";
@@ -286,6 +291,34 @@ dataset_list2(hid_t dset)
/*-------------------------------------------------------------------------
+ * Function: ragged_list2
+ *
+ * Purpose: List information about a ragged array which should appear
+ * after information which is general to all objects.
+ *
+ * Return: Success: 0
+ *
+ * Failure: -1
+ *
+ * Programmer: Robb Matzke
+ * Thursday, November 5, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+ragged_list2(hid_t __unused__ ra)
+{
+ if (dump_g) {
+ puts(" Data: Not implemented yet (see values of member");
+ puts(" datasets `raw', `over', and `meta')");
+ }
+ return -1;
+}
+
+
+/*-------------------------------------------------------------------------
* Function: link_open
*
* Purpose: This gets called to open a symbolic link. Since symbolic
@@ -399,7 +432,6 @@ list (hid_t group, const char *name, void __unused__ *cd)
return 0;
}
-
/*-------------------------------------------------------------------------
* Function: main
@@ -426,6 +458,7 @@ main (int argc, char *argv[])
const char *s;
char *rest;
int argno;
+ H5G_stat_t sb;
DISPATCH(H5G_DATASET, "Dataset", H5Dopen, H5Dclose,
dataset_list1, dataset_list2);
@@ -435,6 +468,8 @@ main (int argc, char *argv[])
NULL, NULL);
DISPATCH(H5G_LINK, "-> ", link_open, NULL,
NULL, NULL);
+ DISPATCH(H5G_RAGGED, "Ragged Array", H5Gopen, H5Gclose,
+ NULL, ragged_list2);
/* Name of this program without the path */
if ((progname=strrchr (argv[0], '/'))) progname++;
@@ -451,6 +486,8 @@ main (int argc, char *argv[])
exit(0);
} else if (!strcmp(argv[argno], "--dump")) {
dump_g++;
+ } else if (!strcmp(argv[argno], "--string")) {
+ string_g = TRUE;
} else if (!strncmp(argv[argno], "--width=", 8)) {
width_g = strtol(argv[argno]+8, &rest, 0);
if (width_g<=0 || *rest) {
@@ -488,6 +525,9 @@ main (int argc, char *argv[])
case 'd': /* --dump */
dump_g++;
break;
+ case 's':
+ string_g = TRUE;
+ break;
case 'v': /* --verbose */
verbose_g++;
break;
@@ -531,17 +571,15 @@ main (int argc, char *argv[])
H5Giterate(file, "/", NULL, list, NULL);
} else {
for (/*void*/; argno<argc; argno++) {
- H5E_BEGIN_TRY {
- root = H5Gopen (file, argv[argno]);
- } H5E_END_TRY;
- if (root>=0) {
+ if (H5Gget_objinfo(file, argv[argno], TRUE, &sb)>=0 &&
+ H5G_GROUP==sb.type) {
H5Giterate(file, argv[argno], NULL, list, NULL);
} else if ((root=H5Gopen(file, "/"))<0) {
exit(1);
} else {
list(root, argv[argno], NULL);
+ if (H5Gclose(root)<0) exit(1);
}
- if (H5Gclose(root)<0) exit(1);
}
}
diff --git a/tools/h5tools.c b/tools/h5tools.c
index d3c9615..83915b3 100644
--- a/tools/h5tools.c
+++ b/tools/h5tools.c
@@ -22,7 +22,7 @@
* size of that temporary buffer in bytes. For efficiency's sake, choose the
* largest value suitable for your machine (for testing use a small value).
*/
-#if 0
+#if 1
#define H5DUMP_BUFSIZE (1024*1024)
#else
#define H5DUMP_BUFSIZE (1024)
@@ -126,8 +126,9 @@ h5dump_sprint(char *s/*out*/, const h5dump_t *info, hid_t type, void *vp)
} else if (H5Tequal(type, H5T_NATIVE_FLOAT)) {
sprintf(temp, "%g", *((float*)vp));
- } else if (H5Tequal(type, H5T_NATIVE_CHAR) ||
- H5Tequal(type, H5T_NATIVE_UCHAR)) {
+ } else if (info->ascii &&
+ (H5Tequal(type, H5T_NATIVE_CHAR) ||
+ H5Tequal(type, H5T_NATIVE_UCHAR))) {
switch (*((char*)vp)) {
case '"':
strcpy(temp, "\\\"");
@@ -223,7 +224,13 @@ h5dump_sprint(char *s/*out*/, const h5dump_t *info, hid_t type, void *vp)
}
}
if (quote) sprintf(temp+strlen(temp), "%c", quote);
-
+
+ } else if (H5Tequal(type, H5T_NATIVE_CHAR)) {
+ sprintf(temp, "%d", *((signed char*)vp));
+
+ } else if (H5Tequal(type, H5T_NATIVE_UCHAR)) {
+ sprintf(temp, "%u", *((unsigned char*)vp));
+
} else if (H5Tequal(type, H5T_NATIVE_SHORT)) {
sprintf(temp, "%d", *((short*)vp));
diff --git a/tools/h5tools.h b/tools/h5tools.h
index 374bb71..54017aa 100644
--- a/tools/h5tools.h
+++ b/tools/h5tools.h
@@ -58,6 +58,13 @@ typedef struct h5dump_t {
/*
* Fields associated with the individual elements.
*
+ * ascii: If set then print 1-byte integer values as an ASCII
+ * character (no quotes). If the character is one of the
+ * standard C escapes then print the escaped version. If
+ * the character is unprintable then print a 3-digit octal
+ * escape. If `ascii' is zero then then 1-byte integers are
+ * printed as numeric values. The default is zero.
+ *
* fmt: A printf(3c) format to use to print the value string
* after it has been rendered. The default is "%s".
*
@@ -69,6 +76,7 @@ typedef struct h5dump_t {
* are followed on the same line by another element. The
* default is a single space.
*/
+ int ascii;
const char *elmt_fmt;
const char *elmt_suf1;
const char *elmt_suf2;