summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
12 files changed, 425 insertions, 43 deletions
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