summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/H5A.c32
-rw-r--r--src/H5D.c123
-rw-r--r--src/H5Dprivate.h1
-rw-r--r--src/H5Epublic.h8
-rw-r--r--src/H5F.c6
-rw-r--r--src/H5Gent.c6
-rw-r--r--src/H5Gpkg.h3
-rw-r--r--src/H5Gprivate.h6
-rw-r--r--src/H5O.c93
-rw-r--r--src/H5Oattr.c13
-rw-r--r--src/H5Ocomp.c8
-rw-r--r--src/H5Ocont.c27
-rw-r--r--src/H5Odtype.c97
-rw-r--r--src/H5Oefl.c27
-rw-r--r--src/H5Olayout.c27
-rw-r--r--src/H5Oname.c28
-rw-r--r--src/H5Oprivate.h14
-rw-r--r--src/H5Osdspace.c27
-rw-r--r--src/H5Oshared.c62
-rw-r--r--src/H5Ostab.c27
-rw-r--r--src/H5T.c771
-rw-r--r--src/H5Tconv.c5
-rw-r--r--src/H5Tpkg.h14
-rw-r--r--src/H5Tprivate.h14
-rw-r--r--src/H5Tpublic.h5
-rw-r--r--src/H5detect.c3
-rw-r--r--src/h5ls.c3
27 files changed, 924 insertions, 526 deletions
diff --git a/src/H5A.c b/src/H5A.c
index d9ba963..fbce35e 100644
--- a/src/H5A.c
+++ b/src/H5A.c
@@ -237,7 +237,7 @@ H5A_create(const H5G_entry_t *ent, const char *name, const H5T_t *type, const H5
HRETURN_ERROR(H5E_RESOURCE, H5E_NOSPACE, FAIL,
"unable to allocate space for attribute info");
attr->name=HDstrdup(name);
- attr->dt=H5T_copy(type);
+ attr->dt=H5T_copy(type, H5T_COPY_ALL);
attr->ds=H5S_copy(space);
attr->initialized = TRUE; /*for now, set to false later*/
@@ -638,8 +638,10 @@ H5A_write(H5A_t *attr, const H5T_t *mem_type, void *buf)
HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL,
"unable to convert between src and dest data types");
} else if (H5T_conv_noop!=tconv_func) {
- if ((src_id = H5I_register(H5_DATATYPE, H5T_copy(mem_type)))<0 ||
- (dst_id = H5I_register(H5_DATATYPE, H5T_copy(attr->dt)))<0) {
+ if ((src_id = H5I_register(H5_DATATYPE,
+ H5T_copy(mem_type, H5T_COPY_ALL)))<0 ||
+ (dst_id = H5I_register(H5_DATATYPE,
+ H5T_copy(attr->dt, H5T_COPY_ALL)))<0) {
HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL,
"unable to register types for conversion");
}
@@ -803,8 +805,10 @@ H5A_read(H5A_t *attr, const H5T_t *mem_type, void *buf)
HGOTO_ERROR(H5E_ATTR, H5E_UNSUPPORTED, FAIL,
"unable to convert between src and dest data types");
} else if (H5T_conv_noop!=tconv_func) {
- if ((src_id = H5I_register(H5_DATATYPE, H5T_copy(attr->dt)))<0 ||
- (dst_id = H5I_register(H5_DATATYPE, H5T_copy(mem_type)))<0) {
+ if ((src_id = H5I_register(H5_DATATYPE,
+ H5T_copy(attr->dt, H5T_COPY_ALL)))<0 ||
+ (dst_id = H5I_register(H5_DATATYPE,
+ H5T_copy(mem_type, H5T_COPY_ALL)))<0) {
HGOTO_ERROR(H5E_ATTR, H5E_CANTREGISTER, FAIL,
"unable to register types for conversion");
}
@@ -908,6 +912,14 @@ H5Aget_space(hid_t attr_id)
This function retrieves a copy of the datatype for an attribute.
The datatype ID returned from this function must be released with H5Tclose
or resource leaks will develop.
+ *
+ * Modifications:
+ * Robb Matzke, 4 Jun 1998
+ * The data type is reopened if it's a named type before returning it to
+ * the application. If the data type of the attribute is read-only then
+ * it is returned to the application as a read-only type. If an error
+ * occurs when atomizing the return data type then the data type is
+ * closed.
--------------------------------------------------------------------------*/
hid_t
H5Aget_type(hid_t attr_id)
@@ -924,14 +936,18 @@ H5Aget_type(hid_t attr_id)
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an attribute");
}
- /* Copy the attribute's dataspace */
- if (NULL==(dst=H5T_copy (attr->dt))) {
+ /*
+ * Copy the attribute's data type. If the type is a named type then
+ * reopen the type before returning it to the user.
+ */
+ if (NULL==(dst=H5T_copy (attr->dt, H5T_COPY_REOPEN))) {
HRETURN_ERROR (H5E_ATTR, H5E_CANTINIT, FAIL,
"unable to copy datatype");
}
/* Atomize */
if ((ret_value=H5I_register (H5_DATATYPE, dst))<0) {
+ H5T_close (dst);
HRETURN_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL,
"unable to register datatype atom");
}
@@ -1278,7 +1294,7 @@ H5A_copy(const H5A_t *old_attr)
/* Copy the guts of the attribute */
new_attr->name=HDstrdup(old_attr->name);
- new_attr->dt=H5T_copy(old_attr->dt);
+ new_attr->dt=H5T_copy(old_attr->dt, H5T_COPY_ALL);
new_attr->ds=H5S_copy(old_attr->ds);
if(old_attr->data) {
new_attr->data=H5MM_xmalloc(old_attr->data_size);
diff --git a/src/H5D.c b/src/H5D.c
index ea0eb38..7c8783d 100644
--- a/src/H5D.c
+++ b/src/H5D.c
@@ -393,6 +393,11 @@ H5Dget_space (hid_t dataset_id)
*
* Modifications:
*
+ * Robb Matzke, 1 Jun 1998
+ * If the dataset has a named data type then a handle to the opened data
+ * type is returned. Otherwise the returned data type is read-only. If
+ * atomization of the data type fails then the data type is closed.
+ *
*-------------------------------------------------------------------------
*/
hid_t
@@ -411,20 +416,27 @@ H5Dget_type (hid_t dataset_id)
HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
}
- /* Copy the data type */
- if (NULL==(copied_type=H5T_copy (dataset->type))) {
+ /* Copy the data type and mark it read-only */
+ if (NULL==(copied_type=H5T_copy (dataset->type, H5T_COPY_REOPEN))) {
HRETURN_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
"unable to copy the data type");
}
-
+ if (H5T_lock (copied_type, FALSE)<0) {
+ H5T_close (copied_type);
+ HRETURN_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to lock transient data type");
+ }
+
/* Create an atom */
if ((ret_value=H5I_register (H5_DATATYPE, copied_type))<0) {
+ H5T_close (copied_type);
HRETURN_ERROR (H5E_ATOM, H5E_CANTREGISTER, FAIL,
"unable to register data type");
}
FUNC_LEAVE (ret_value);
}
+
/*-------------------------------------------------------------------------
* Function: H5Dget_create_plist
@@ -758,7 +770,7 @@ H5D_create(H5G_t *loc, const char *name, const H5T_t *type, const H5S_t *space,
/* Initialize the dataset object */
new_dset = H5MM_xcalloc(1, sizeof(H5D_t));
H5F_addr_undef(&(new_dset->ent.header));
- new_dset->type = H5T_copy(type);
+ new_dset->type = H5T_copy(type, H5T_COPY_ALL);
new_dset->space = H5S_copy(space);
new_dset->create_parms = H5P_copy (H5P_DATASET_CREATE, create_parms);
efl = &(new_dset->create_parms->efl);
@@ -781,35 +793,37 @@ H5D_create(H5G_t *loc, const char *name, const H5T_t *type, const H5S_t *space,
"unable to initialize contiguous storage");
}
- /* Don't go through all these checks for scalar dataspaces */
- if(ndims>0) {
- for (i=1; i<ndims; i++) {
- if (max_dim[i]>new_dset->layout.dim[i]) {
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL,
- "only the first dimension can be extendible");
- }
- }
- if (efl->nused>0) {
- hsize_t max_points = H5S_get_npoints_max (space);
- hsize_t max_storage = H5O_efl_total_size (efl);
-
- if (H5S_UNLIMITED==max_points) {
- if (H5O_EFL_UNLIMITED!=max_storage) {
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL,
- "unlimited data space but finite storage");
- }
- } else if (max_points * H5T_get_size (type) < max_points) {
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL,
- "data space * type size overflowed");
- } else if (max_points * H5T_get_size (type) > max_storage) {
- HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL,
- "data space size exceeds external storage size");
- }
- } else if (max_dim[0]>new_dset->layout.dim[0]) {
- HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, NULL,
- "extendible contiguous non-external dataset");
- }
- }
+ /* Don't go through all these checks for scalar dataspaces */
+ if(ndims>0) {
+ for (i=1; i<ndims; i++) {
+ if (max_dim[i]>new_dset->layout.dim[i]) {
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL,
+ "only the first dimension can be extendible");
+ }
+ }
+ if (efl->nused>0) {
+ hsize_t max_points = H5S_get_npoints_max (space);
+ hsize_t max_storage = H5O_efl_total_size (efl);
+
+ if (H5S_UNLIMITED==max_points) {
+ if (H5O_EFL_UNLIMITED!=max_storage) {
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL,
+ "unlimited data space but finite "
+ "storage");
+ }
+ } else if (max_points * H5T_get_size (type) < max_points) {
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL,
+ "data space * type size overflowed");
+ } else if (max_points * H5T_get_size (type) > max_storage) {
+ HGOTO_ERROR (H5E_DATASET, H5E_CANTINIT, NULL,
+ "data space size exceeds external storage "
+ "size");
+ }
+ } else if (max_dim[0]>new_dset->layout.dim[0]) {
+ HGOTO_ERROR (H5E_DATASET, H5E_UNSUPPORTED, NULL,
+ "extendible contiguous non-external dataset");
+ }
+ }
break;
case H5D_CHUNKED:
@@ -842,8 +856,7 @@ H5D_create(H5G_t *loc, const char *name, const H5T_t *type, const H5S_t *space,
/* Update the type and space header messages */
if (H5O_modify(&(new_dset->ent), H5O_DTYPE, 0,
- (H5O_FLAG_CONSTANT|H5O_FLAG_SHARED),
- new_dset->type) < 0 ||
+ H5O_FLAG_CONSTANT|H5O_FLAG_SHARED, new_dset->type)<0 ||
H5S_modify(&(new_dset->ent), new_dset->space) < 0) {
HGOTO_ERROR(H5E_DATASET, H5E_CANTINIT, NULL,
"unable to update type or space header messages");
@@ -1215,8 +1228,10 @@ H5D_read(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL,
"unable to convert between src and dest data types");
} else if (H5T_conv_noop!=tconv_func) {
- if ((src_id=H5I_register(H5_DATATYPE, H5T_copy(dataset->type)))<0 ||
- (dst_id=H5I_register(H5_DATATYPE, H5T_copy(mem_type)))<0) {
+ if ((src_id=H5I_register(H5_DATATYPE,
+ H5T_copy(dataset->type, H5T_COPY_ALL)))<0 ||
+ (dst_id=H5I_register(H5_DATATYPE,
+ H5T_copy(mem_type, H5T_COPY_ALL)))<0) {
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL,
"unable to register types for conversion");
}
@@ -1520,8 +1535,10 @@ H5D_write(H5D_t *dataset, const H5T_t *mem_type, const H5S_t *mem_space,
HGOTO_ERROR(H5E_DATASET, H5E_UNSUPPORTED, FAIL,
"unable to convert between src and dest data types");
} else if (H5T_conv_noop!=tconv_func) {
- if ((src_id = H5I_register(H5_DATATYPE, H5T_copy(mem_type)))<0 ||
- (dst_id = H5I_register(H5_DATATYPE, H5T_copy(dataset->type)))<0) {
+ if ((src_id = H5I_register(H5_DATATYPE,
+ H5T_copy(mem_type, H5T_COPY_ALL)))<0 ||
+ (dst_id = H5I_register(H5_DATATYPE,
+ H5T_copy(dataset->type, H5T_COPY_ALL)))<0) {
HGOTO_ERROR(H5E_DATASET, H5E_CANTREGISTER, FAIL,
"unable to register types for conversion");
}
@@ -1793,3 +1810,31 @@ H5D_entof (H5D_t *dataset)
{
return dataset ? &(dataset->ent) : NULL;
}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5D_typeof
+ *
+ * Purpose: Returns a pointer to the dataset's data type. The data type
+ * is not copied.
+ *
+ * Return: Success: Ptr to the dataset's data type, uncopied.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, June 4, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5T_t *
+H5D_typeof (H5D_t *dset)
+{
+ FUNC_ENTER (H5D_typeof, NULL);
+ assert (dset);
+ assert (dset->type);
+ FUNC_LEAVE (dset->type);
+}
+
diff --git a/src/H5Dprivate.h b/src/H5Dprivate.h
index f144d30..3ed4e2f 100644
--- a/src/H5Dprivate.h
+++ b/src/H5Dprivate.h
@@ -78,5 +78,6 @@ herr_t H5D_write (H5D_t *dataset, const H5T_t *mem_type,
hid_t H5D_find_name (hid_t file_id, H5I_group_t UNUSED, const char *name);
herr_t H5D_extend (H5D_t *dataset, const hsize_t *size);
H5G_entry_t *H5D_entof (H5D_t *dataset);
+H5T_t *H5D_typeof (H5D_t *dset);
#endif
diff --git a/src/H5Epublic.h b/src/H5Epublic.h
index 85c7b60..96ca600 100644
--- a/src/H5Epublic.h
+++ b/src/H5Epublic.h
@@ -31,20 +31,20 @@
* like:
* H5E_BEGIN_TRY {
* ...stuff here that's likely to fail...
- * } H5E_END_TRY
+ * } H5E_END_TRY;
*
* Warning: don't break, return, or longjmp() from the body of the loop or
* the error reporting won't be properly restored!
*/
-#define H5T_BEGIN_TRY do { \
+#define H5E_BEGIN_TRY do { \
herr_t (*H5E_saved_efunc)(void*); \
void *H5E_saved_edata; \
H5Eget_auto (&H5E_saved_efunc, &H5E_saved_edata); \
H5Eset_auto (NULL, NULL);
-#define H5T_END_TRY \
+#define H5E_END_TRY \
H5Eset_auto (H5E_saved_efunc, H5E_saved_edata); \
-}
+} while(0)
/*
diff --git a/src/H5F.c b/src/H5F.c
index 78d70b3..7d2b619 100644
--- a/src/H5F.c
+++ b/src/H5F.c
@@ -1384,8 +1384,9 @@ H5F_close(H5F_t *f)
*/
if (f->nopen>0) {
#ifndef NDEBUG
- fprintf(stderr, "H5F: H5F_close: %u object header%s still "
+ fprintf(stderr, "H5F: H5F_close(%s): %u object header%s still "
"open (file close will complete when %s closed)\n",
+ f->name,
f->nopen,
1 == f->nopen ? " is" : "s are",
1 == f->nopen ? "that header is" : "those headers are");
@@ -1398,9 +1399,6 @@ H5F_close(H5F_t *f)
#endif
}
- /* Invalidate shared data types since they depend on the H5F_t pointer */
- H5I_search (H5_DATATYPE, H5T_invalidate_cb, f);
-
/*
* If this is the last reference to the shared part of the file then
* close it also.
diff --git a/src/H5Gent.c b/src/H5Gent.c
index 1bcd18f..b2120c0 100644
--- a/src/H5Gent.c
+++ b/src/H5Gent.c
@@ -240,7 +240,7 @@ H5G_ent_decode(H5F_t *f, const uint8 **pp, H5G_entry_t *ent)
*-------------------------------------------------------------------------
*/
herr_t
-H5G_ent_encode_vec(H5F_t *f, uint8 **pp, H5G_entry_t *ent, intn n)
+H5G_ent_encode_vec(H5F_t *f, uint8 **pp, const H5G_entry_t *ent, intn n)
{
intn i;
@@ -288,7 +288,7 @@ H5G_ent_encode_vec(H5F_t *f, uint8 **pp, H5G_entry_t *ent, intn n)
*-------------------------------------------------------------------------
*/
herr_t
-H5G_ent_encode(H5F_t *f, uint8 **pp, H5G_entry_t *ent)
+H5G_ent_encode(H5F_t *f, uint8 **pp, const H5G_entry_t *ent)
{
uint8 *p_ret = *pp + H5G_SIZEOF_ENTRY(f);
@@ -358,7 +358,7 @@ H5G_ent_encode(H5F_t *f, uint8 **pp, H5G_entry_t *ent)
*-------------------------------------------------------------------------
*/
herr_t
-H5G_ent_debug(H5F_t __unused__ *f, H5G_entry_t *ent, FILE * stream,
+H5G_ent_debug(H5F_t __unused__ *f, const H5G_entry_t *ent, FILE * stream,
intn indent, intn fwidth, const haddr_t *heap)
{
const char *lval = NULL;
diff --git a/src/H5Gpkg.h b/src/H5Gpkg.h
index 38e07ed..c4579be 100644
--- a/src/H5Gpkg.h
+++ b/src/H5Gpkg.h
@@ -130,5 +130,6 @@ herr_t H5G_stab_insert (H5G_entry_t *grp_ent, const char *name,
*/
herr_t H5G_ent_decode_vec (H5F_t *f, const uint8 **pp, H5G_entry_t *ent,
intn n);
-herr_t H5G_ent_encode_vec (H5F_t *f, uint8 **pp, H5G_entry_t *ent, intn n);
+herr_t H5G_ent_encode_vec (H5F_t *f, uint8 **pp, const H5G_entry_t *ent,
+ intn n);
#endif
diff --git a/src/H5Gprivate.h b/src/H5Gprivate.h
index bbb2a1c..f6a641e 100644
--- a/src/H5Gprivate.h
+++ b/src/H5Gprivate.h
@@ -122,7 +122,7 @@ herr_t H5G_find (H5G_t *cwg, const char *name, H5G_entry_t *grp_ent/*out*/,
herr_t H5G_traverse_slink (H5G_entry_t *grp_ent/*in,out*/,
H5G_entry_t *obj_ent/*in,out*/,
intn *nlinks/*in,out*/);
-herr_t H5G_ent_encode (H5F_t *f, uint8 **pp, H5G_entry_t *ent);
+herr_t H5G_ent_encode (H5F_t *f, uint8 **pp, const H5G_entry_t *ent);
herr_t H5G_ent_decode (H5F_t *f, const uint8 **pp, H5G_entry_t *ent/*out*/);
/*
@@ -139,7 +139,7 @@ herr_t H5G_node_debug (H5F_t *f, const haddr_t *addr, FILE * stream,
H5G_entry_t *H5G_ent_calloc (H5G_entry_t *init);
H5G_cache_t *H5G_ent_cache (H5G_entry_t *ent, H5G_type_t *cache_type);
herr_t H5G_ent_modified (H5G_entry_t *ent, H5G_type_t cache_type);
-herr_t H5G_ent_debug (H5F_t *f, H5G_entry_t *ent, FILE * stream, intn indent,
- intn fwidth, const haddr_t *heap);
+herr_t H5G_ent_debug (H5F_t *f, const H5G_entry_t *ent, FILE * stream,
+ intn indent, intn fwidth, const haddr_t *heap);
#endif
diff --git a/src/H5O.c b/src/H5O.c
index ce369cf..cb625c0 100644
--- a/src/H5O.c
+++ b/src/H5O.c
@@ -916,27 +916,37 @@ H5O_read(H5G_entry_t *ent, const H5O_class_t *type, intn sequence, void *mesg)
/*
* If the message is shared then then the native pointer points to an
* H5O_SHARED message. We use that information to look up the real
- * message in the global heap.
+ * message in the global heap or some other object header.
*/
H5O_shared_t *shared;
void *tmp_buf, *tmp_mesg;
shared = (H5O_shared_t *)(oh->mesg[idx].native);
- if (NULL==(tmp_buf = H5HG_read (ent->file, shared, NULL))) {
- HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL,
- "unable to read shared message from global heap");
- }
- tmp_mesg = (type->decode)(ent->file, tmp_buf, shared);
- tmp_buf = H5MM_xfree (tmp_buf);
- if (!tmp_mesg) {
- HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL,
- "unable to decode object header shared message");
- }
- if (mesg) {
- HDmemcpy (mesg, tmp_mesg, type->native_size);
- H5MM_xfree (tmp_mesg);
+ if (shared->in_gh) {
+ if (NULL==(tmp_buf = H5HG_read (ent->file, &(shared->u.gh),
+ NULL))) {
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL,
+ "unable to read shared message from global heap");
+ }
+ tmp_mesg = (type->decode)(ent->file, tmp_buf, shared);
+ tmp_buf = H5MM_xfree (tmp_buf);
+ if (!tmp_mesg) {
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTLOAD, NULL,
+ "unable to decode object header shared message");
+ }
+ if (mesg) {
+ HDmemcpy (mesg, tmp_mesg, type->native_size);
+ H5MM_xfree (tmp_mesg);
+ } else {
+ ret_value = tmp_mesg;
+ }
} else {
- ret_value = tmp_mesg;
+ ret_value = H5O_read (&(shared->u.ent), type, 0, mesg);
+ if (type->set_share &&
+ (type->set_share)(ent->file, ret_value, shared)<0) {
+ HGOTO_ERROR (H5E_OHDR, H5E_CANTINIT, NULL,
+ "unable to set sharing information");
+ }
}
} else {
/*
@@ -1124,12 +1134,12 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite,
if (overwrite < 0) {
/* Allocate space for the new message */
if (flags & H5O_FLAG_SHARED) {
- if (NULL==type->share) {
+ if (NULL==type->get_share) {
HGOTO_ERROR (H5E_OHDR, H5E_UNSUPPORTED, FAIL,
"message class is not sharable");
}
sh_mesg = H5MM_xcalloc (1, sizeof *sh_mesg);
- if ((type->share)(ent->file, mesg, sh_mesg/*out*/)<0) {
+ if ((type->get_share)(ent->file, mesg, sh_mesg/*out*/)<0) {
/*
* If the message isn't shared then turn off the shared bit
* and treat it as an unshared message.
@@ -1137,8 +1147,22 @@ H5O_modify(H5G_entry_t *ent, const H5O_class_t *type, intn overwrite,
H5E_clear ();
flags &= ~H5O_FLAG_SHARED;
H5MM_xfree (sh_mesg);
+ } else if (sh_mesg->in_gh) {
+ /*
+ * The shared message is stored in the global heap.
+ * Increment the reference count on the global heap message.
+ */
+ if (H5HG_link (ent->file, &(sh_mesg->u.gh), 1)<0) {
+ HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL,
+ "unable to adjust shared object link count");
+ }
+ size = (H5O_SHARED->raw_size)(ent->file, sh_mesg);
} else {
- if (H5HG_link (ent->file, sh_mesg, 1)<0) {
+ /*
+ * The shared message is stored in some other object header.
+ * Increment the reference count on that object header.
+ */
+ if (H5O_link (&(sh_mesg->u.ent), 1)<0) {
HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL,
"unable to adjust shared object link count");
}
@@ -1269,10 +1293,18 @@ H5O_remove(H5G_entry_t *ent, const H5O_class_t *type, intn sequence)
"unable to decode shared message info");
}
}
- if (H5HG_link (ent->file, sh_mesg, -1)<0) {
- HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL,
- "unable to decrement link count on shared "
- "message");
+ if (sh_mesg->in_gh) {
+ if (H5HG_link (ent->file, &(sh_mesg->u.gh), -1)<0) {
+ HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL,
+ "unable to decrement link count on "
+ "shared message");
+ }
+ } else {
+ if (H5O_link (&(sh_mesg->u.ent), -1)<0) {
+ HGOTO_ERROR (H5E_OHDR, H5E_LINK, FAIL,
+ "unable to decrement link count on "
+ "shared message");
+ }
}
}
@@ -1526,7 +1558,8 @@ H5O_alloc_new_chunk(H5F_t *f, H5O_t *oh, size_t size)
oh->mesg = H5MM_xrealloc(oh->mesg,
oh->alloc_nmesgs * sizeof(H5O_mesg_t));
/* Set new object header info to zeros */
- HDmemset(&oh->mesg[old_alloc],0,(oh->alloc_nmesgs-old_alloc)*sizeof(H5O_mesg_t));
+ HDmemset(&oh->mesg[old_alloc], 0,
+ (oh->alloc_nmesgs-old_alloc)*sizeof(H5O_mesg_t));
}
/*
@@ -1779,7 +1812,7 @@ H5O_debug(H5F_t *f, const haddr_t *addr, FILE * stream, intn indent,
int *sequence;
haddr_t tmp_addr;
herr_t ret_value = FAIL;
- void *(*decode)(H5F_t*, const uint8*, H5HG_t*);
+ void *(*decode)(H5F_t*, const uint8*, H5O_shared_t*);
herr_t (*debug)(H5F_t*, const void*, FILE*, intn, intn)=NULL;
FUNC_ENTER(H5O_debug, FAIL);
@@ -1912,14 +1945,20 @@ H5O_debug(H5F_t *f, const haddr_t *addr, FILE * stream, intn indent,
/* If the message is shared then also print the pointed-to message */
if (oh->mesg[i].flags & H5O_FLAG_SHARED) {
- void *p = H5HG_read (f, oh->mesg[i].native, NULL);
- void *mesg = (oh->mesg[i].type->decode)(f, p, oh->mesg[i].native);
+ H5O_shared_t *shared = (H5O_shared_t*)(oh->mesg[i].native);
+ void *mesg = NULL;
+ if (shared->in_gh) {
+ void *p = H5HG_read (f, oh->mesg[i].native, NULL);
+ mesg = (oh->mesg[i].type->decode)(f, p, oh->mesg[i].native);
+ H5MM_xfree (p);
+ } else {
+ mesg = H5O_read (&(shared->u.ent), oh->mesg[i].type, 0, NULL);
+ }
if (oh->mesg[i].type->debug) {
(oh->mesg[i].type->debug)(f, mesg, stream, indent+3,
MAX (0, fwidth-3));
}
H5O_free (oh->mesg[i].type, mesg);
- H5MM_xfree (p);
}
}
sequence = H5MM_xfree(sequence);
diff --git a/src/H5Oattr.c b/src/H5Oattr.c
index 320c713..2e56a75 100644
--- a/src/H5Oattr.c
+++ b/src/H5Oattr.c
@@ -29,24 +29,25 @@ static char RcsId[] = "@(#)$Revision$";
/* PRIVATE PROTOTYPES */
static herr_t H5O_attr_encode (H5F_t *f, uint8 *p, const void *mesg);
-static void *H5O_attr_decode (H5F_t *f, const uint8 *p, H5HG_t *hobj);
+static void *H5O_attr_decode (H5F_t *f, const uint8 *p, H5O_shared_t *sh);
static void *H5O_attr_copy (const void *_mesg, void *_dest);
static size_t H5O_attr_size (H5F_t *f, const void *_mesg);
static herr_t H5O_attr_reset (void *_mesg);
static herr_t H5O_attr_debug (H5F_t *f, const void *_mesg,
- FILE * stream, intn indent, intn fwidth);
+ FILE * stream, intn indent, intn fwidth);
/* This message derives from H5O */
const H5O_class_t H5O_ATTR[1] = {{
H5O_ATTR_ID, /* message id number */
"attribute", /* message name for debugging */
sizeof(H5A_t), /* native message size */
- H5O_attr_decode, /* decode message */
- H5O_attr_encode, /* encode message */
+ H5O_attr_decode, /* decode message */
+ H5O_attr_encode, /* encode message */
H5O_attr_copy, /* copy the native value */
H5O_attr_size, /* size of raw message */
H5O_attr_reset, /* reset method */
- NULL, /* no share method (currently) */
+ NULL, /* get share method */
+ NULL, /* set share method */
H5O_attr_debug, /* debug the message */
}};
@@ -73,7 +74,7 @@ static hbool_t interface_initialize_g = FALSE;
function using malloc() and is returned to the caller.
--------------------------------------------------------------------------*/
static void *
-H5O_attr_decode(H5F_t *f, const uint8 *p, H5HG_t __unused__ *hobj)
+H5O_attr_decode(H5F_t *f, const uint8 *p, H5O_shared_t __unused__ *sh)
{
H5A_t *attr = NULL;
H5S_simple_t *simple; /*simple dimensionality information */
diff --git a/src/H5Ocomp.c b/src/H5Ocomp.c
index 6b6c2e7..7d659ea 100644
--- a/src/H5Ocomp.c
+++ b/src/H5Ocomp.c
@@ -16,7 +16,7 @@
/* PRIVATE PROTOTYPES */
static herr_t H5O_comp_encode (H5F_t *f, uint8 *p, const void *mesg);
-static void *H5O_comp_decode (H5F_t *f, const uint8 *p, H5HG_t *hobj);
+static void *H5O_comp_decode (H5F_t *f, const uint8 *p, H5O_shared_t *sh);
static void *H5O_comp_copy (const void *_mesg, void *_dest);
static size_t H5O_comp_size (H5F_t *f, const void *_mesg);
static herr_t H5O_comp_reset (void *_mesg);
@@ -33,7 +33,8 @@ const H5O_class_t H5O_COMPRESS[1] = {{
H5O_comp_copy, /* copy the native value */
H5O_comp_size, /* size of raw message */
H5O_comp_reset, /* reset method */
- NULL, /* share method */
+ NULL, /* get share method */
+ NULL, /* set share method */
H5O_comp_debug, /* debug the message */
}};
@@ -59,7 +60,8 @@ static hbool_t interface_initialize_g = FALSE;
*-------------------------------------------------------------------------
*/
static void *
-H5O_comp_decode(H5F_t __unused__ *f, const uint8 *p, H5HG_t __unused__ *hobj)
+H5O_comp_decode(H5F_t __unused__ *f, const uint8 *p,
+ H5O_shared_t __unused__ *sh)
{
H5O_compress_t *comp = NULL;
diff --git a/src/H5Ocont.c b/src/H5Ocont.c
index e9bda3e..ff81be9 100644
--- a/src/H5Ocont.c
+++ b/src/H5Ocont.c
@@ -25,23 +25,24 @@
#define PABLO_MASK H5O_cont_mask
/* PRIVATE PROTOTYPES */
-static void *H5O_cont_decode(H5F_t *f, const uint8 *p, H5HG_t *hobj);
+static void *H5O_cont_decode(H5F_t *f, const uint8 *p, H5O_shared_t *sh);
static herr_t H5O_cont_encode(H5F_t *f, uint8 *p, const void *_mesg);
static herr_t H5O_cont_debug(H5F_t *f, const void *_mesg, FILE * stream,
intn indent, intn fwidth);
/* This message derives from H5O */
const H5O_class_t H5O_CONT[1] = {{
- H5O_CONT_ID, /*message id number */
- "hdr continuation", /*message name for debugging */
- sizeof(H5O_cont_t), /*native message size */
- H5O_cont_decode, /*decode message */
- H5O_cont_encode, /*encode message */
- NULL, /*no copy method */
- NULL, /*no size method */
- NULL, /*default reset method */
- NULL, /*no share method */
- H5O_cont_debug, /*debugging */
+ H5O_CONT_ID, /*message id number */
+ "hdr continuation", /*message name for debugging */
+ sizeof(H5O_cont_t), /*native message size */
+ H5O_cont_decode, /*decode message */
+ H5O_cont_encode, /*encode message */
+ NULL, /*no copy method */
+ NULL, /*no size method */
+ NULL, /*default reset method */
+ NULL, /*get share method */
+ NULL, /*set share method */
+ H5O_cont_debug, /*debugging */
}};
/* Interface initialization */
@@ -66,7 +67,7 @@ static intn interface_initialize_g = FALSE;
*-------------------------------------------------------------------------
*/
static void *
-H5O_cont_decode(H5F_t *f, const uint8 *p, H5HG_t __unused__ *hobj)
+H5O_cont_decode(H5F_t *f, const uint8 *p, H5O_shared_t __unused__ *sh)
{
H5O_cont_t *cont = NULL;
@@ -75,7 +76,7 @@ H5O_cont_decode(H5F_t *f, const uint8 *p, H5HG_t __unused__ *hobj)
/* check args */
assert(f);
assert(p);
- assert (!hobj || !H5HG_defined (hobj));
+ assert (!sh);
/* decode */
cont = H5MM_xcalloc(1, sizeof(H5O_cont_t));
diff --git a/src/H5Odtype.c b/src/H5Odtype.c
index bfbe5a3..9ea0713 100644
--- a/src/H5Odtype.c
+++ b/src/H5Odtype.c
@@ -29,13 +29,16 @@ static char RcsId[] = "@(#)$Revision$";
/* PRIVATE PROTOTYPES */
static herr_t H5O_dtype_encode (H5F_t *f, uint8 *p, const void *mesg);
-static void *H5O_dtype_decode (H5F_t *f, const uint8 *p, H5HG_t *hobj);
+static void *H5O_dtype_decode (H5F_t *f, const uint8 *p, H5O_shared_t *sh);
static void *H5O_dtype_copy (const void *_mesg, void *_dest);
static size_t H5O_dtype_size (H5F_t *f, const void *_mesg);
static herr_t H5O_dtype_reset (void *_mesg);
+static herr_t H5O_dtype_get_share (H5F_t *f, const void *_mesg,
+ H5O_shared_t *sh);
+static herr_t H5O_dtype_set_share (H5F_t *f, void *_mesg,
+ const H5O_shared_t *sh);
static herr_t H5O_dtype_debug (H5F_t *f, const void *_mesg,
FILE * stream, intn indent, intn fwidth);
-static herr_t H5O_dtype_share (H5F_t *f, const void *_mesg, H5HG_t *hobj);
/* This message derives from H5O */
const H5O_class_t H5O_DTYPE[1] = {{
@@ -47,7 +50,8 @@ const H5O_class_t H5O_DTYPE[1] = {{
H5O_dtype_copy, /* copy the native value */
H5O_dtype_size, /* size of raw message */
H5O_dtype_reset, /* reset method */
- H5O_dtype_share, /* share method */
+ H5O_dtype_get_share, /* get share method */
+ H5O_dtype_set_share, /* set share method */
H5O_dtype_debug, /* debug the message */
}};
@@ -174,6 +178,7 @@ H5O_dtype_decode_helper(const uint8 **pp, H5T_t *dt)
dt->u.compnd.memb[i].perm[2] = (perm_word >> 16) & 0xff;
dt->u.compnd.memb[i].perm[3] = (perm_word >> 24) & 0xff;
dt->u.compnd.memb[i].type = H5MM_xcalloc (1, sizeof(H5T_t));
+ H5F_addr_undef (&(dt->u.compnd.memb[i].type->ent.header));
if (H5O_dtype_decode_helper(pp, dt->u.compnd.memb[i].type) < 0 ||
H5T_COMPOUND == dt->u.compnd.memb[i].type->type) {
for (j = 0; j <= i; j++)
@@ -436,7 +441,7 @@ H5O_dtype_encode_helper(uint8 **pp, const H5T_t *dt)
function using malloc() and is returned to the caller.
--------------------------------------------------------------------------*/
static void *
-H5O_dtype_decode(H5F_t *f, const uint8 *p, H5HG_t *hobj)
+H5O_dtype_decode(H5F_t *f, const uint8 *p, H5O_shared_t *sh)
{
H5T_t *dt = NULL;
@@ -445,19 +450,16 @@ H5O_dtype_decode(H5F_t *f, const uint8 *p, H5HG_t *hobj)
/* check args */
assert(f);
assert(p);
+ assert (!sh);
dt = H5MM_xcalloc(1, sizeof(H5T_t));
+ H5F_addr_undef (&(dt->ent.header));
if (H5O_dtype_decode_helper(&p, dt) < 0) {
H5MM_xfree(dt);
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTDECODE, NULL,
"can't decode type");
}
- if (hobj) {
- dt->sh_heap = *hobj;
- dt->sh_file = f;
- }
-
FUNC_LEAVE(dt);
}
@@ -515,7 +517,7 @@ H5O_dtype_encode(H5F_t __unused__ *f, uint8 *p, const void *mesg)
This function copies a native (memory) simple datatype message,
allocating the destination structure if necessary.
--------------------------------------------------------------------------*/
-static void *
+static void *
H5O_dtype_copy(const void *_src, void *_dst)
{
const H5T_t *src = (const H5T_t *) _src;
@@ -527,7 +529,7 @@ H5O_dtype_copy(const void *_src, void *_dst)
assert(src);
/* copy */
- if (NULL == (dst = H5T_copy(src))) {
+ if (NULL == (dst = H5T_copy(src, H5T_COPY_ALL))) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, NULL, "can't copy type");
}
/* was result already allocated? */
@@ -627,43 +629,78 @@ H5O_dtype_reset(void *_mesg)
/*-------------------------------------------------------------------------
- * Function: H5O_dtype_share
+ * Function: H5O_dtype_get_share
*
- * Purpose: Returns, through argument HOBJ, whether a data type is shared
- * in the specified file.
+ * Purpose: Returns information about where the shared message is located
+ * by filling in the SH shared message struct.
*
- * Return: Success: SUCCEED if the data type is shared in file F,
- * and HOBJ is set to the global heap address.
+ * Return: Success: SUCCEED
*
- * Failure: FAIL if the data type is not shared, or
- * shared but not in file F. The value of HOBJ
- * is undefined.
+ * Failure: FAIL
*
* Programmer: Robb Matzke
- * Thursday, April 2, 1998
+ * Monday, June 1, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
static herr_t
-H5O_dtype_share (H5F_t *f, const void *_mesg, H5HG_t *hobj/*out*/)
+H5O_dtype_get_share (H5F_t *f, const void *_mesg, H5O_shared_t *sh/*out*/)
{
- const H5T_t *dt = (const H5T_t *)_mesg;
-
- FUNC_ENTER (H5O_dtype_share, FAIL);
+ const H5T_t *dt = (const H5T_t *)_mesg;
- if (!H5HG_defined (&(dt->sh_heap)) ||
- NULL==dt->sh_file ||
- dt->sh_file->shared != f->shared) {
+ FUNC_ENTER (H5O_dtype_get_share, FAIL);
+ assert (f);
+ assert (dt);
+ assert (sh);
+
+ if (H5F_addr_defined (&(dt->ent.header))) {
+ assert (H5T_STATE_NAMED==dt->state || H5T_STATE_OPEN==dt->state);
+ sh->in_gh = FALSE;
+ sh->u.ent = dt->ent;
+ } else {
HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
- "data type is not shared");
+ "data type is not sharable");
}
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5O_dtype_set_share
+ *
+ * Purpose: Copies sharing information from SH into the message.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, June 4, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+static herr_t
+H5O_dtype_set_share (H5F_t *f, void *_mesg/*in,out*/, const H5O_shared_t *sh)
+{
+ H5T_t *dt = (H5T_t *)_mesg;
- *hobj = dt->sh_heap;
+ FUNC_ENTER (H5O_dtype_set_share, FAIL);
+ assert (f);
+ assert (dt);
+ assert (sh);
+ assert (!sh->in_gh);
+
+ dt->ent = sh->u.ent;
+ dt->state = H5T_STATE_NAMED;
+
FUNC_LEAVE (SUCCEED);
}
-
+
/*--------------------------------------------------------------------------
NAME
H5O_dtype_debug
diff --git a/src/H5Oefl.c b/src/H5Oefl.c
index ba598b7..246aa79 100644
--- a/src/H5Oefl.c
+++ b/src/H5Oefl.c
@@ -14,7 +14,7 @@
#define PABLO_MASK H5O_efl_mask
/* PRIVATE PROTOTYPES */
-static void *H5O_efl_decode(H5F_t *f, const uint8 *p, H5HG_t *hobj);
+static void *H5O_efl_decode(H5F_t *f, const uint8 *p, H5O_shared_t *sh);
static herr_t H5O_efl_encode(H5F_t *f, uint8 *p, const void *_mesg);
static void *H5O_efl_copy(const void *_mesg, void *_dest);
static size_t H5O_efl_size(H5F_t *f, const void *_mesg);
@@ -24,16 +24,17 @@ static herr_t H5O_efl_debug(H5F_t *f, const void *_mesg, FILE * stream,
/* This message derives from H5O */
const H5O_class_t H5O_EFL[1] = {{
- H5O_EFL_ID, /*message id number */
- "external file list", /*message name for debugging */
- sizeof(H5O_efl_t), /*native message size */
- H5O_efl_decode, /*decode message */
- H5O_efl_encode, /*encode message */
- H5O_efl_copy, /*copy native value */
- H5O_efl_size, /*size of message on disk */
- H5O_efl_reset, /*reset method */
- NULL, /*no share method */
- H5O_efl_debug, /*debug the message */
+ H5O_EFL_ID, /*message id number */
+ "external file list", /*message name for debugging */
+ sizeof(H5O_efl_t), /*native message size */
+ H5O_efl_decode, /*decode message */
+ H5O_efl_encode, /*encode message */
+ H5O_efl_copy, /*copy native value */
+ H5O_efl_size, /*size of message on disk */
+ H5O_efl_reset, /*reset method */
+ NULL, /*get share method */
+ NULL, /*set share method */
+ H5O_efl_debug, /*debug the message */
}};
/* Interface initialization */
@@ -59,7 +60,7 @@ static hbool_t interface_initialize_g = FALSE;
*-------------------------------------------------------------------------
*/
static void *
-H5O_efl_decode(H5F_t *f, const uint8 *p, H5HG_t __unused__ *hobj)
+H5O_efl_decode(H5F_t *f, const uint8 *p, H5O_shared_t __unused__ *sh)
{
H5O_efl_t *mesg = NULL;
int i;
@@ -70,7 +71,7 @@ H5O_efl_decode(H5F_t *f, const uint8 *p, H5HG_t __unused__ *hobj)
/* Check args */
assert(f);
assert(p);
- assert (!hobj || !H5HG_defined (hobj));
+ assert (!sh);
/* Decode the header */
mesg = H5MM_xcalloc(1, sizeof(H5O_efl_t));
diff --git a/src/H5Olayout.c b/src/H5Olayout.c
index 42b21e5..510c0dd 100644
--- a/src/H5Olayout.c
+++ b/src/H5Olayout.c
@@ -14,7 +14,7 @@
#include <H5Oprivate.h>
/* PRIVATE PROTOTYPES */
-static void *H5O_layout_decode(H5F_t *f, const uint8 *p, H5HG_t *hobj);
+static void *H5O_layout_decode(H5F_t *f, const uint8 *p, H5O_shared_t *sh);
static herr_t H5O_layout_encode(H5F_t *f, uint8 *p, const void *_mesg);
static void *H5O_layout_copy(const void *_mesg, void *_dest);
static size_t H5O_layout_size(H5F_t *f, const void *_mesg);
@@ -23,16 +23,17 @@ static herr_t H5O_layout_debug(H5F_t *f, const void *_mesg, FILE * stream,
/* This message derives from H5O */
const H5O_class_t H5O_LAYOUT[1] = {{
- H5O_LAYOUT_ID, /*message id number */
- "layout", /*message name for debugging */
- sizeof(H5O_layout_t), /*native message size */
- H5O_layout_decode, /*decode message */
- H5O_layout_encode, /*encode message */
- H5O_layout_copy, /*copy the native value */
- H5O_layout_size, /*size of message on disk */
- NULL, /*reset method */
- NULL, /*no share method */
- H5O_layout_debug, /*debug the message */
+ H5O_LAYOUT_ID, /*message id number */
+ "layout", /*message name for debugging */
+ sizeof(H5O_layout_t), /*native message size */
+ H5O_layout_decode, /*decode message */
+ H5O_layout_encode, /*encode message */
+ H5O_layout_copy, /*copy the native value */
+ H5O_layout_size, /*size of message on disk */
+ NULL, /*reset method */
+ NULL, /*get share method */
+ NULL, /*set share method */
+ H5O_layout_debug, /*debug the message */
}};
/* Interface initialization */
@@ -59,7 +60,7 @@ static hbool_t interface_initialize_g = FALSE;
*-------------------------------------------------------------------------
*/
static void *
-H5O_layout_decode(H5F_t *f, const uint8 *p, H5HG_t __unused__ *hobj)
+H5O_layout_decode(H5F_t *f, const uint8 *p, H5O_shared_t __unused__ *sh)
{
H5O_layout_t *mesg = NULL;
intn i;
@@ -69,7 +70,7 @@ H5O_layout_decode(H5F_t *f, const uint8 *p, H5HG_t __unused__ *hobj)
/* check args */
assert(f);
assert(p);
- assert (!hobj || !H5HG_defined (hobj));
+ assert (!sh);
/* decode */
mesg = H5MM_xcalloc(1, sizeof(H5O_layout_t));
diff --git a/src/H5Oname.c b/src/H5Oname.c
index a31e08d..acf6764 100644
--- a/src/H5Oname.c
+++ b/src/H5Oname.c
@@ -22,7 +22,7 @@
#define PABLO_MASK H5O_name_mask
/* PRIVATE PROTOTYPES */
-static void *H5O_name_decode(H5F_t *f, const uint8 *p, H5HG_t *hobj);
+static void *H5O_name_decode(H5F_t *f, const uint8 *p, H5O_shared_t *sh);
static herr_t H5O_name_encode(H5F_t *f, uint8 *p, const void *_mesg);
static void *H5O_name_copy(const void *_mesg, void *_dest);
static size_t H5O_name_size(H5F_t *f, const void *_mesg);
@@ -32,16 +32,17 @@ static herr_t H5O_name_debug(H5F_t *f, const void *_mesg, FILE * stream,
/* This message derives from H5O */
const H5O_class_t H5O_NAME[1] = {{
- H5O_NAME_ID, /*message id number */
- "name", /*message name for debugging */
- sizeof(H5O_name_t), /*native message size */
- H5O_name_decode, /*decode message */
- H5O_name_encode, /*encode message */
- H5O_name_copy, /*copy the native value */
- H5O_name_size, /*raw message size */
- H5O_name_reset, /*free internal memory */
- NULL, /*no share method */
- H5O_name_debug, /*debug the message */
+ H5O_NAME_ID, /*message id number */
+ "name", /*message name for debugging */
+ sizeof(H5O_name_t), /*native message size */
+ H5O_name_decode, /*decode message */
+ H5O_name_encode, /*encode message */
+ H5O_name_copy, /*copy the native value */
+ H5O_name_size, /*raw message size */
+ H5O_name_reset, /*free internal memory */
+ NULL, /*get share method */
+ NULL, /*set share method */
+ H5O_name_debug, /*debug the message */
}};
/* Interface initialization */
@@ -68,7 +69,8 @@ static hbool_t interface_initialize_g = FALSE;
*-------------------------------------------------------------------------
*/
static void *
-H5O_name_decode(H5F_t __unused__ *f, const uint8 *p, H5HG_t __unused__ *hobj)
+H5O_name_decode(H5F_t __unused__ *f, const uint8 *p,
+ H5O_shared_t __unused__ *sh)
{
H5O_name_t *mesg;
@@ -77,7 +79,7 @@ H5O_name_decode(H5F_t __unused__ *f, const uint8 *p, H5HG_t __unused__ *hobj)
/* check args */
assert(f);
assert(p);
- assert (!hobj || !H5HG_defined (hobj));
+ assert (!sh);
/* decode */
mesg = H5MM_xcalloc(1, sizeof(H5O_name_t));
diff --git a/src/H5Oprivate.h b/src/H5Oprivate.h
index 7db9313..677241e 100644
--- a/src/H5Oprivate.h
+++ b/src/H5Oprivate.h
@@ -66,16 +66,18 @@
2 + /*sizeof message data */ \
4) /*reserved */
+struct H5O_shared_t;
typedef struct H5O_class_t {
intn id; /*message type ID on disk */
const char *name; /*for debugging */
size_t native_size; /*size of native message */
- void *(*decode)(H5F_t*, const uint8*, H5HG_t*);
+ void *(*decode)(H5F_t*, const uint8*, struct H5O_shared_t*);
herr_t (*encode)(H5F_t*, uint8*, const void*);
void *(*copy)(const void*, void*); /*copy native value */
size_t (*raw_size)(H5F_t*, const void*);/*sizeof raw val */
herr_t (*reset)(void *); /*free nested data structs */
- herr_t (*share)(H5F_t*, const void*, H5HG_t*);
+ herr_t (*get_share)(H5F_t*, const void*, struct H5O_shared_t*);
+ herr_t (*set_share)(H5F_t*, void*, const struct H5O_shared_t*);
herr_t (*debug)(H5F_t*, const void*, FILE*, intn, intn);
} H5O_class_t;
@@ -205,7 +207,13 @@ typedef struct H5O_name_t {
#define H5O_SHARED_ID 0x000f
extern const H5O_class_t H5O_SHARED[1];
-typedef H5HG_t H5O_shared_t;
+typedef struct H5O_shared_t {
+ hbool_t in_gh; /*shared by global heap? */
+ union {
+ H5HG_t gh; /*global heap info */
+ H5G_entry_t ent; /*symbol table entry info */
+ } u;
+} H5O_shared_t;
/*
* Object header continuation message.
diff --git a/src/H5Osdspace.c b/src/H5Osdspace.c
index 3a34fea..66361e4 100644
--- a/src/H5Osdspace.c
+++ b/src/H5Osdspace.c
@@ -25,7 +25,7 @@ static char RcsId[] = "@(#)$Revision$";
#define PABLO_MASK H5O_sdspace_mask
/* PRIVATE PROTOTYPES */
-static void *H5O_sdspace_decode(H5F_t *f, const uint8 *p, H5HG_t *hobj);
+static void *H5O_sdspace_decode(H5F_t *f, const uint8 *p, H5O_shared_t *sh);
static herr_t H5O_sdspace_encode(H5F_t *f, uint8 *p, const void *_mesg);
static void *H5O_sdspace_copy(const void *_mesg, void *_dest);
static size_t H5O_sdspace_size(H5F_t *f, const void *_mesg);
@@ -35,16 +35,17 @@ static herr_t H5O_sdspace_reset(void *_mesg);
/* This message derives from H5O */
const H5O_class_t H5O_SDSPACE[1] = {{
- H5O_SDSPACE_ID, /* message id number */
- "simple_dspace", /* message name for debugging */
- sizeof(H5S_simple_t), /* native message size */
- H5O_sdspace_decode, /* decode message */
- H5O_sdspace_encode, /* encode message */
- H5O_sdspace_copy, /* copy the native value */
- H5O_sdspace_size, /* size of symbol table entry */
- H5O_sdspace_reset, /* default reset method */
- NULL, /* no share method */
- H5O_sdspace_debug, /* debug the message */
+ H5O_SDSPACE_ID, /* message id number */
+ "simple_dspace", /* message name for debugging */
+ sizeof(H5S_simple_t), /* native message size */
+ H5O_sdspace_decode, /* decode message */
+ H5O_sdspace_encode, /* encode message */
+ H5O_sdspace_copy, /* copy the native value */
+ H5O_sdspace_size, /* size of symbol table entry */
+ H5O_sdspace_reset, /* default reset method */
+ NULL, /* get share method */
+ NULL, /* set share method */
+ H5O_sdspace_debug, /* debug the message */
}};
/* Is the interface initialized? */
@@ -75,7 +76,7 @@ static hbool_t interface_initialize_g = FALSE;
instead of just four bytes.
--------------------------------------------------------------------------*/
static void *
-H5O_sdspace_decode(H5F_t *f, const uint8 *p, H5HG_t __unused__ *hobj)
+H5O_sdspace_decode(H5F_t *f, const uint8 *p, H5O_shared_t __unused__ *sh)
{
H5S_simple_t *sdim = NULL;/* New simple dimensionality structure */
intn u; /* local counting variable */
@@ -86,7 +87,7 @@ H5O_sdspace_decode(H5F_t *f, const uint8 *p, H5HG_t __unused__ *hobj)
/* check args */
assert(f);
assert(p);
- assert (!hobj || !H5HG_defined (hobj));
+ assert (!sh);
/* decode */
if ((sdim = H5MM_xcalloc(1, sizeof(H5S_simple_t))) != NULL) {
diff --git a/src/H5Oshared.c b/src/H5Oshared.c
index 37c7312..2789297 100644
--- a/src/H5Oshared.c
+++ b/src/H5Oshared.c
@@ -18,7 +18,7 @@
#include <H5MMprivate.h>
#include <H5Oprivate.h>
-static void *H5O_shared_decode (H5F_t*, const uint8*, H5HG_t *hobj);
+static void *H5O_shared_decode (H5F_t*, const uint8*, H5O_shared_t *sh);
static herr_t H5O_shared_encode (H5F_t*, uint8*, const void*);
static size_t H5O_shared_size (H5F_t*, const void*);
static herr_t H5O_shared_debug (H5F_t*, const void*, FILE*, intn, intn);
@@ -33,7 +33,8 @@ const H5O_class_t H5O_SHARED[1] = {{
NULL, /*no copy method */
H5O_shared_size, /*size method */
NULL, /*no reset method */
- NULL, /*no share method */
+ NULL, /*get share method */
+ NULL, /*set share method */
H5O_shared_debug, /*debug method */
}};
@@ -60,7 +61,7 @@ static hbool_t interface_initialize_g = FALSE;
*-------------------------------------------------------------------------
*/
static void *
-H5O_shared_decode (H5F_t *f, const uint8 *buf, H5HG_t __unused__ *hobj)
+H5O_shared_decode (H5F_t *f, const uint8 *buf, H5O_shared_t __unused__ *sh)
{
H5O_shared_t *mesg;
@@ -69,12 +70,17 @@ H5O_shared_decode (H5F_t *f, const uint8 *buf, H5HG_t __unused__ *hobj)
/* Check args */
assert (f);
assert (buf);
- assert (!hobj || !H5HG_defined (hobj));
+ assert (!sh);
/* Decode */
mesg = H5MM_xcalloc (1, sizeof *mesg);
- H5F_addr_decode (f, &buf, &(mesg->addr));
- INT32DECODE (buf, mesg->idx);
+ UINT32DECODE (buf, mesg->in_gh);
+ if (mesg->in_gh) {
+ H5F_addr_decode (f, &buf, &(mesg->u.gh.addr));
+ INT32DECODE (buf, mesg->u.gh.idx);
+ } else {
+ H5G_ent_decode (f, &buf, &(mesg->u.ent));
+ }
FUNC_LEAVE (mesg);
}
@@ -109,8 +115,13 @@ H5O_shared_encode (H5F_t *f, uint8 *buf/*out*/, const void *_mesg)
assert (mesg);
/* Encode */
- H5F_addr_encode (f, &buf, &(mesg->addr));
- INT32ENCODE (buf, mesg->idx);
+ INT32ENCODE (buf, mesg->in_gh);
+ if (mesg->in_gh) {
+ H5F_addr_encode (f, &buf, &(mesg->u.gh.addr));
+ INT32ENCODE (buf, mesg->u.gh.idx);
+ } else {
+ H5G_ent_encode (f, &buf, &(mesg->u.ent));
+ }
FUNC_LEAVE (SUCCEED);
}
@@ -135,8 +146,15 @@ H5O_shared_encode (H5F_t *f, uint8 *buf/*out*/, const void *_mesg)
static size_t
H5O_shared_size (H5F_t *f, const void __unused__ *_mesg)
{
+ size_t size;
+
FUNC_ENTER (H5O_shared_size, 0);
- FUNC_LEAVE (H5F_SIZEOF_ADDR(f)+4);
+
+ size = 4 + /*the flags field */
+ MAX (H5F_SIZEOF_ADDR(f)+4, /*sharing via global heap */
+ H5G_SIZEOF_ENTRY(f)); /*sharing by another obj hdr */
+
+ FUNC_LEAVE (size);
}
@@ -171,14 +189,22 @@ H5O_shared_debug (H5F_t __unused__ *f, const void *_mesg,
assert (indent>=0);
assert (fwidth>=0);
- fprintf (stream, "%*s%-*s ", indent, "", fwidth,
- "Collection address:");
- H5F_addr_print (stream, &(mesg->addr));
- fprintf (stream, "\n");
-
- fprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
- "Object ID within collection:",
- mesg->idx);
-
+ if (mesg->in_gh) {
+ HDfprintf (stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Sharing method",
+ "Global heap");
+ HDfprintf (stream, "%*s%-*s %a\n", indent, "", fwidth,
+ "Collection address:",
+ &(mesg->u.gh.addr));
+ HDfprintf (stream, "%*s%-*s %d\n", indent, "", fwidth,
+ "Object ID within collection:",
+ mesg->u.gh.idx);
+ } else {
+ HDfprintf (stream, "%*s%-*s %s\n", indent, "", fwidth,
+ "Sharing method",
+ "Obj Hdr");
+ H5G_ent_debug (f, &(mesg->u.ent), stream, indent, fwidth, NULL);
+ }
+
FUNC_LEAVE (SUCCEED);
}
diff --git a/src/H5Ostab.c b/src/H5Ostab.c
index 37c749b..7eb8d6e 100644
--- a/src/H5Ostab.c
+++ b/src/H5Ostab.c
@@ -23,7 +23,7 @@
#define PABLO_MASK H5O_stab_mask
/* PRIVATE PROTOTYPES */
-static void *H5O_stab_decode(H5F_t *f, const uint8 *p, H5HG_t *hobj);
+static void *H5O_stab_decode(H5F_t *f, const uint8 *p, H5O_shared_t *sh);
static herr_t H5O_stab_encode(H5F_t *f, uint8 *p, const void *_mesg);
static void *H5O_stab_copy(const void *_mesg, void *_dest);
static size_t H5O_stab_size(H5F_t *f, const void *_mesg);
@@ -32,16 +32,17 @@ static herr_t H5O_stab_debug(H5F_t *f, const void *_mesg,
/* This message derives from H5O */
const H5O_class_t H5O_STAB[1] = {{
- H5O_STAB_ID, /*message id number */
- "stab", /*message name for debugging */
- sizeof(H5O_stab_t), /*native message size */
- H5O_stab_decode, /*decode message */
- H5O_stab_encode, /*encode message */
- H5O_stab_copy, /*copy the native value */
- H5O_stab_size, /*size of symbol table entry */
- NULL, /*default reset method */
- NULL, /*no share method */
- H5O_stab_debug, /*debug the message */
+ H5O_STAB_ID, /*message id number */
+ "stab", /*message name for debugging */
+ sizeof(H5O_stab_t), /*native message size */
+ H5O_stab_decode, /*decode message */
+ H5O_stab_encode, /*encode message */
+ H5O_stab_copy, /*copy the native value */
+ H5O_stab_size, /*size of symbol table entry */
+ NULL, /*default reset method */
+ NULL, /*get share method */
+ NULL, /*set share method */
+ H5O_stab_debug, /*debug the message */
}};
/* Interface initialization */
@@ -67,7 +68,7 @@ static hbool_t interface_initialize_g = FALSE;
*-------------------------------------------------------------------------
*/
static void *
-H5O_stab_decode(H5F_t *f, const uint8 *p, H5HG_t __unused__ *hobj)
+H5O_stab_decode(H5F_t *f, const uint8 *p, H5O_shared_t __unused__ *sh)
{
H5O_stab_t *stab;
@@ -76,7 +77,7 @@ H5O_stab_decode(H5F_t *f, const uint8 *p, H5HG_t __unused__ *hobj)
/* check args */
assert(f);
assert(p);
- assert (!hobj || !H5HG_defined (hobj));
+ assert (!sh);
/* decode */
stab = H5MM_xcalloc(1, sizeof(H5O_stab_t));
diff --git a/src/H5T.c b/src/H5T.c
index 8648a4e..1e10135 100644
--- a/src/H5T.c
+++ b/src/H5T.c
@@ -12,6 +12,7 @@ static char RcsId[] = "@(#)$Revision$";
#define H5T_PACKAGE /*suppress error about including H5Tpkg */
#include <H5private.h> /*generic functions */
+#include <H5Dprivate.h> /*datasets (for H5Tcopy) */
#include <H5Iprivate.h> /*ID functions */
#include <H5Eprivate.h> /*error handling */
#include <H5Gprivate.h> /*groups */
@@ -94,6 +95,7 @@ H5T_init_interface(void)
(herr_t (*)(void *)) H5T_close)) != FAIL) {
ret_value = H5_add_exit(&H5T_term_interface);
}
+
/*
* Initialize pre-defined data types that depend on the architecture.
*/
@@ -158,7 +160,8 @@ H5T_init_interface(void)
/* TIME */
dt = H5MM_xcalloc(1, sizeof(H5T_t));
- dt->locked = TRUE;
+ dt->state = H5T_STATE_IMMUTABLE;
+ H5F_addr_undef (&(dt->ent.header));
dt->type = H5T_TIME;
dt->size = 1;
dt->u.atomic.order = H5Tget_order(H5T_NATIVE_INT_g);
@@ -173,7 +176,8 @@ H5T_init_interface(void)
/* STRING */
dt = H5MM_xcalloc(1, sizeof(H5T_t));
- dt->locked = TRUE;
+ dt->state = H5T_STATE_IMMUTABLE;
+ H5F_addr_undef (&(dt->ent.header));
dt->type = H5T_STRING;
dt->size = 1;
dt->u.atomic.order = H5T_ORDER_NONE;
@@ -190,7 +194,8 @@ H5T_init_interface(void)
/* BITFIELD */
dt = H5MM_xcalloc(1, sizeof(H5T_t));
- dt->locked = TRUE;
+ dt->state = H5T_STATE_IMMUTABLE;
+ H5F_addr_undef (&(dt->ent.header));
dt->type = H5T_BITFIELD;
dt->size = 1;
dt->u.atomic.order = H5Tget_order(H5T_NATIVE_INT_g);
@@ -205,7 +210,8 @@ H5T_init_interface(void)
/* OPAQUE */
dt = H5MM_xcalloc(1, sizeof(H5T_t));
- dt->locked = TRUE;
+ dt->state = H5T_STATE_IMMUTABLE;
+ H5F_addr_undef (&(dt->ent.header));
dt->type = H5T_OPAQUE;
dt->size = 1;
dt->u.atomic.order = H5T_ORDER_NONE;
@@ -254,7 +260,7 @@ H5T_init_interface(void)
/*-------------------------------------------------------------------------
* Function: H5T_unlock_cb
*
- * Purpose: Clear the locked flag for a data type. This function is
+ * Purpose: Clear the immutable flag for a data type. This function is
* called when the library is closing in order to unlock all
* registered data types and thus make them free-able.
*
@@ -270,11 +276,15 @@ H5T_init_interface(void)
*-------------------------------------------------------------------------
*/
static intn
-H5T_unlock_cb (void *dt, const void __unused__ *key)
+H5T_unlock_cb (void *_dt, const void __unused__ *key)
{
+ H5T_t *dt = (H5T_t *)_dt;
+
FUNC_ENTER (H5T_unlock_cb, FAIL);
assert (dt);
- ((H5T_t*)dt)->locked = FALSE;
+ if (H5T_STATE_IMMUTABLE==dt->state) {
+ dt->state = H5T_STATE_RDONLY;
+ }
FUNC_LEAVE (0);
}
@@ -420,6 +430,136 @@ H5Tcreate(H5T_class_t type, size_t size)
/*-------------------------------------------------------------------------
+ * Function: H5Topen
+ *
+ * Purpose: Opens a named data type.
+ *
+ * Return: Success: Object ID of the named data type.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Monday, June 1, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hid_t
+H5Topen (hid_t loc_id, const char *name)
+{
+ H5G_t *loc = NULL;
+ H5T_t *type = NULL;
+ hid_t ret_value = FAIL;
+
+ FUNC_ENTER (H5Topen, FAIL);
+
+ /* Check args */
+ if (NULL==(loc=H5G_loc (loc_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
+ }
+ if (!name || !*name) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name");
+ }
+
+ /* Open it */
+ if (NULL==(type=H5T_open (loc, name))) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTOPENOBJ, FAIL,
+ "unable to open named data type");
+ }
+
+ /* Register the type and return the ID */
+ if ((ret_value=H5I_register (H5_DATATYPE, type))<0) {
+ H5T_close (type);
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTREGISTER, FAIL,
+ "unable to register named data type");
+ }
+
+ FUNC_LEAVE (ret_value);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Tcommit
+ *
+ * Purpose: Save a transient data type to a file and turn the type handle
+ * into a named, immutable type.
+ *
+ * Return: Success: SUCCEED
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Monday, June 1, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+herr_t
+H5Tcommit (hid_t loc_id, const char *name, hid_t type_id)
+{
+ H5G_t *loc = NULL;
+ H5T_t *type = NULL;
+
+ FUNC_ENTER (H5Tcommit, FAIL);
+
+ /* Check arguments */
+ if (NULL==(loc=H5G_loc (loc_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
+ }
+ if (!name || !*name) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL, "no name");
+ }
+ if (H5_DATATYPE!=H5I_group (type_id) ||
+ NULL==(type=H5I_object (type_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ }
+
+ /* Commit the type */
+ if (H5T_commit (loc, name, type)<0) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to commit data type");
+ }
+
+ FUNC_LEAVE (SUCCEED);
+}
+
+
+/*-------------------------------------------------------------------------
+ * Function: H5Tcommitted
+ *
+ * Purpose: Determines if a data type is committed or not.
+ *
+ * Return: Success: TRUE if committed, FALSE otherwise.
+ *
+ * Failure: FAIL
+ *
+ * Programmer: Robb Matzke
+ * Thursday, June 4, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+hbool_t
+H5Tcommitted (hid_t type_id)
+{
+ H5T_t *type = NULL;
+
+ FUNC_ENTER (H5Tcommitted, FAIL);
+
+ /* Check arguments */
+ if (H5_DATATYPE!=H5I_group (type_id) ||
+ NULL==(type=H5I_object (type_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ }
+
+ FUNC_LEAVE (H5T_STATE_OPEN==type->state || H5T_STATE_NAMED==type->state);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5Tcopy
*
* Purpose: Copies a data type. The resulting data type is not locked.
@@ -435,6 +575,12 @@ H5Tcreate(H5T_class_t type, size_t size)
*
* Modifications:
*
+ * Robb Matzke, 4 Jun 1998
+ * The returned type is always transient and unlocked. If the TYPE_ID
+ * argument is a dataset instead of a data type then this function
+ * returns a transient, modifiable data type which is a copy of the
+ * dataset's data type.
+ *
*-------------------------------------------------------------------------
*/
hid_t
@@ -442,18 +588,37 @@ H5Tcopy(hid_t type_id)
{
H5T_t *dt = NULL;
H5T_t *new_dt = NULL;
+ H5D_t *dset = NULL;
hid_t ret_value = FAIL;
FUNC_ENTER(H5Tcopy, FAIL);
- /* Check args */
- if (H5_DATATYPE != H5I_group(type_id) ||
- NULL == (dt = H5I_object(type_id))) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ switch (H5I_group (type_id)) {
+ case H5_DATATYPE:
+ /* The argument is a data type handle */
+ if (NULL==(dt=H5I_object (type_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
+ }
+ break;
+
+ case H5_DATASET:
+ /* The argument is a dataset handle */
+ if (NULL==(dset=H5I_object (type_id))) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a dataset");
+ }
+ if (NULL==(dt=H5D_typeof (dset))) {
+ HRETURN_ERROR (H5E_DATASET, H5E_CANTINIT, FAIL,
+ "unable to get the dataset data type");
+ }
+ break;
+
+ default:
+ HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL,
+ "not a data type or dataset");
}
/* Copy */
- if (NULL == (new_dt = H5T_copy(dt))) {
+ if (NULL == (new_dt = H5T_copy(dt, H5T_COPY_TRANSIENT))) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL, "can't copy");
}
@@ -496,8 +661,8 @@ H5Tclose(hid_t type_id)
NULL == (dt = H5I_object(type_id))) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
}
- if (dt->locked) {
- HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "predefined data type");
+ if (H5T_STATE_IMMUTABLE==dt->state) {
+ HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "immutable data type");
}
/* When the reference count reaches zero the resources are freed */
@@ -557,7 +722,8 @@ H5Tequal(hid_t type1_id, hid_t type2_id)
* the application doesn't inadvertently change or delete a
* predefined type.
*
- * Once a data type is locked it can never be unlocked.
+ * Once a data type is locked it can never be unlocked unless
+ * the entire library is closed.
*
* Return: Success: SUCCEED
*
@@ -568,6 +734,10 @@ H5Tequal(hid_t type1_id, hid_t type2_id)
*
* Modifications:
*
+ * Robb Matzke, 1 Jun 1998
+ * It is illegal to lock a named data type since we must allow named
+ * types to be closed (to release file resources) but locking a type
+ * prevents that.
*-------------------------------------------------------------------------
*/
herr_t
@@ -582,7 +752,14 @@ H5Tlock(hid_t type_id)
NULL == (dt = H5I_object(type_id))) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
}
- dt->locked = TRUE;
+ if (H5T_STATE_NAMED==dt->state || H5T_STATE_OPEN==dt->state) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "unable to lock named data type");
+ }
+ if (H5T_lock (dt, TRUE)<0) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to lock transient data type");
+ }
FUNC_LEAVE(SUCCEED);
}
@@ -703,7 +880,7 @@ H5Tset_size(hid_t type_id, size_t size)
!H5T_is_atomic(dt)) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (size <= 0) {
@@ -762,7 +939,6 @@ H5Tset_size(hid_t type_id, size_t size)
}
/* Commit */
- H5T_unshare (dt);
dt->size = size;
dt->u.atomic.offset = offset;
dt->u.atomic.prec = prec;
@@ -839,7 +1015,7 @@ H5Tset_order(hid_t type_id, H5T_order_t order)
!H5T_is_atomic(dt)) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (order < 0 || order > H5T_ORDER_NONE) {
@@ -847,7 +1023,6 @@ H5Tset_order(hid_t type_id, H5T_order_t order)
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.order = order;
FUNC_LEAVE(SUCCEED);
}
@@ -939,7 +1114,7 @@ H5Tset_precision(hid_t type_id, size_t prec)
!H5T_is_atomic(dt)) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (prec <= 0) {
@@ -993,7 +1168,6 @@ H5Tset_precision(hid_t type_id, size_t prec)
}
/* Commit */
- H5T_unshare (dt);
dt->size = size;
dt->u.atomic.offset = offset;
dt->u.atomic.prec = prec;
@@ -1108,7 +1282,7 @@ H5Tset_offset(hid_t type_id, size_t offset)
!H5T_is_atomic(dt)) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (H5T_STRING == dt->type && offset != 0) {
@@ -1122,7 +1296,6 @@ H5Tset_offset(hid_t type_id, size_t offset)
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.offset = offset;
FUNC_LEAVE(SUCCEED);
@@ -1198,7 +1371,7 @@ H5Tset_pad(hid_t type_id, H5T_pad_t lsb, H5T_pad_t msb)
!H5T_is_atomic(dt)) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an atomic data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (lsb < 0 || lsb >= H5T_NPAD || msb < 0 || msb >= H5T_NPAD) {
@@ -1206,7 +1379,6 @@ H5Tset_pad(hid_t type_id, H5T_pad_t lsb, H5T_pad_t msb)
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.lsb_pad = lsb;
dt->u.atomic.msb_pad = msb;
@@ -1282,7 +1454,7 @@ H5Tset_sign(hid_t type_id, H5T_sign_t sign)
H5T_INTEGER != dt->type) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not an integer data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (sign < 0 || sign >= H5T_NSGN) {
@@ -1290,7 +1462,6 @@ H5Tset_sign(hid_t type_id, H5T_sign_t sign)
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.u.i.sign = sign;
FUNC_LEAVE(SUCCEED);
}
@@ -1383,7 +1554,7 @@ H5Tset_fields(hid_t type_id, size_t spos, size_t epos, size_t esize,
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
"not a floating-point data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (epos + esize > dt->u.atomic.prec) {
@@ -1415,7 +1586,6 @@ H5Tset_fields(hid_t type_id, size_t spos, size_t epos, size_t esize,
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.u.f.sign = spos;
dt->u.atomic.u.f.epos = epos;
dt->u.atomic.u.f.mpos = mpos;
@@ -1495,12 +1665,11 @@ H5Tset_ebias(hid_t type_id, size_t ebias)
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
"not a floating-point data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.u.f.ebias = ebias;
FUNC_LEAVE(SUCCEED);
@@ -1578,7 +1747,7 @@ H5Tset_norm(hid_t type_id, H5T_norm_t norm)
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
"not a floating-point data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (norm < 0 || norm > H5T_NORM_NONE) {
@@ -1586,7 +1755,6 @@ H5Tset_norm(hid_t type_id, H5T_norm_t norm)
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.u.f.norm = norm;
FUNC_LEAVE(SUCCEED);
}
@@ -1667,7 +1835,7 @@ H5Tset_inpad(hid_t type_id, H5T_pad_t pad)
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL,
"not a floating-point data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (pad < 0 || pad >= H5T_NPAD) {
@@ -1676,7 +1844,6 @@ H5Tset_inpad(hid_t type_id, H5T_pad_t pad)
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.u.f.pad = pad;
FUNC_LEAVE(SUCCEED);
}
@@ -1754,7 +1921,7 @@ H5Tset_cset(hid_t type_id, H5T_cset_t cset)
H5T_STRING != dt->type) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a string data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (cset < 0 || cset >= H5T_NCSET) {
@@ -1763,7 +1930,6 @@ H5Tset_cset(hid_t type_id, H5T_cset_t cset)
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.u.s.cset = cset;
FUNC_LEAVE(SUCCEED);
}
@@ -1843,7 +2009,7 @@ H5Tset_strpad(hid_t type_id, H5T_str_t strpad)
H5T_STRING != dt->type) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a string data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_CANTINIT, FAIL, "data type is read-only");
}
if (strpad < 0 || strpad >= H5T_NSTR) {
@@ -1851,7 +2017,6 @@ H5Tset_strpad(hid_t type_id, H5T_str_t strpad)
}
/* Commit */
- H5T_unshare (dt);
dt->u.atomic.u.s.pad = strpad;
FUNC_LEAVE(SUCCEED);
}
@@ -2051,6 +2216,10 @@ H5Tget_member_dims(hid_t type_id, int membno,
*
* Modifications:
*
+ * Robb Matzke, 4 Jun 1998
+ * If the member type is a named type then this function returns a
+ * handle to the re-opened named type.
+ *
*-------------------------------------------------------------------------
*/
hid_t
@@ -2072,7 +2241,8 @@ H5Tget_member_type(hid_t type_id, int membno)
}
/* Copy data type into an atom */
- if (NULL == (memb_dt = H5T_copy(dt->u.compnd.memb[membno].type))) {
+ if (NULL == (memb_dt = H5T_copy(dt->u.compnd.memb[membno].type,
+ H5T_COPY_REOPEN))) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTINIT, FAIL,
"unable to copy member data type");
}
@@ -2128,7 +2298,7 @@ H5Tinsert(hid_t parent_id, const char *name, size_t offset, hid_t member_id)
H5T_COMPOUND != parent->type) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type");
}
- if (parent->locked) {
+ if (H5T_STATE_TRANSIENT!=parent->state) {
HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "parent type read-only");
}
if (!name || !*name) {
@@ -2179,7 +2349,7 @@ H5Tpack(hid_t type_id)
H5T_COMPOUND != dt->type) {
HRETURN_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a compound data type");
}
- if (dt->locked) {
+ if (H5T_STATE_TRANSIENT!=dt->state) {
HRETURN_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "data type is read-only");
}
@@ -2194,98 +2364,6 @@ H5Tpack(hid_t type_id)
/*-------------------------------------------------------------------------
- * Function: H5Tshare
- *
- * Purpose: Marks a data type as sharable. Using the type during the
- * creation of a dataset will cause the dataset object header to
- * point to the type in the global heap instead of containing
- * the type directly in its object header. Subsequent
- * modifications to a shared type cause the type to become
- * unshared.
- *
- * Return: Success: SUCCEED
- *
- * Failure: FAIL
- *
- * Programmer: Robb Matzke
- * Tuesday, March 31, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-herr_t
-H5Tshare (hid_t loc_id, hid_t type_id)
-{
- H5G_t *loc = NULL;
- H5T_t *dt = NULL;
-
- FUNC_ENTER (H5Tshare, FAIL);
-
- /* Check arguments */
- if (NULL==(loc=H5G_loc (loc_id))) {
- HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
- }
- if (H5_DATATYPE!=H5I_group (type_id) ||
- NULL==(dt=H5I_object (type_id))) {
- HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
- }
-
- /* Make it sharable */
- if (H5T_share (H5G_fileof (loc), dt)<0) {
- HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
- "unable to make data type sharable");
- }
-
- FUNC_LEAVE (SUCCEED);
-}
-
-
-/*-------------------------------------------------------------------------
- * Function: H5Tis_shared
- *
- * Purpose: Determines if a data type is shared in the specified file.
- * The TYPE_ID is the type in question and LOC_ID is a file id
- * or group id (a group id is used only to identify the file).
- *
- * Return: Success: TRUE or FALSE
- *
- * Failure: FAIL
- *
- * Programmer: Robb Matzke
- * Friday, April 3, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-hbool_t
-H5Tis_shared (hid_t loc_id, hid_t type_id)
-{
- H5G_t *loc = NULL;
- H5T_t *dt = NULL;
- hbool_t ret_value = FAIL;
-
- FUNC_ENTER (H5Tis_shared, FAIL);
-
- /* Check arguments */
- if (NULL==(loc=H5G_loc (loc_id))) {
- HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a location");
- }
- if (H5_DATATYPE!=H5I_group (type_id) ||
- NULL==(dt=H5I_object (type_id))) {
- HRETURN_ERROR (H5E_ARGS, H5E_BADTYPE, FAIL, "not a data type");
- }
-
- /* Is it sharable */
- ret_value = (H5HG_defined (&(dt->sh_heap)) &&
- dt->sh_file->shared==H5G_fileof(loc)->shared) ? TRUE : FALSE;
-
- FUNC_LEAVE (ret_value);
-}
-
-
-/*-------------------------------------------------------------------------
* Function: H5Tregister_hard
*
* Purpose: Register a hard conversion function for a data type
@@ -2425,8 +2503,10 @@ H5Tregister_soft(const char *name, H5T_class_t src_cls, H5T_class_t dst_cls,
* data type temporarily to an object id before we query the functions
* capabilities.
*/
- if ((src_id = H5I_register(H5_DATATYPE, H5T_copy(path->src))) < 0 ||
- (dst_id = H5I_register(H5_DATATYPE, H5T_copy(path->dst))) < 0) {
+ if ((src_id = H5I_register(H5_DATATYPE,
+ H5T_copy(path->src, H5T_COPY_ALL))) < 0 ||
+ (dst_id = H5I_register(H5_DATATYPE,
+ H5T_copy(path->dst, H5T_COPY_ALL))) < 0) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL,
"unable to register data types for conv query");
}
@@ -2545,9 +2625,11 @@ H5Tunregister(H5T_conv_t func)
* object id's for the data types.
*/
if ((src_id = H5I_register(H5_DATATYPE,
- H5T_copy(path->src))) < 0 ||
+ H5T_copy(path->src,
+ H5T_COPY_ALL))) < 0 ||
(dst_id = H5I_register(H5_DATATYPE,
- H5T_copy(path->dst))) < 0) {
+ H5T_copy(path->dst,
+ H5T_COPY_ALL))) < 0) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, FAIL,
"unable to register conv types for query");
}
@@ -2679,16 +2761,68 @@ H5T_create(H5T_class_t type, size_t size)
"unknown data type class");
}
+ H5F_addr_undef (&(dt->ent.header));
dt->size = size;
FUNC_LEAVE(dt);
}
/*-------------------------------------------------------------------------
+ * Function: H5T_open
+ *
+ * Purpose: Open a named data type.
+ *
+ * Return: Success: Ptr to a new data type.
+ *
+ * Failure: NULL
+ *
+ * Programmer: Robb Matzke
+ * Monday, June 1, 1998
+ *
+ * Modifications:
+ *
+ *-------------------------------------------------------------------------
+ */
+H5T_t *
+H5T_open (H5G_t *loc, const char *name)
+{
+ H5T_t *dt = NULL;
+ H5G_entry_t ent;
+
+ FUNC_ENTER (H5T_open, NULL);
+ assert (loc);
+ assert (name && *name);
+
+ /*
+ * Find the named data type object header and read the data type message
+ * from it.
+ */
+ if (H5G_find (loc, name, NULL, &ent/*out*/)<0) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_NOTFOUND, NULL, "not found");
+ }
+ if (H5O_open (&ent)<0) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTOPENOBJ, NULL,
+ "unable to open named data type");
+ }
+ if (NULL==(dt=H5O_read (&ent, H5O_DTYPE, 0, NULL))) {
+ H5O_close (&ent);
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, NULL,
+ "unable to load type message from object header");
+ }
+
+ /* Mark the type as named and open */
+ dt->state = H5T_STATE_OPEN;
+ dt->ent = ent;
+
+ FUNC_LEAVE (dt);
+}
+
+
+/*-------------------------------------------------------------------------
* Function: H5T_copy
*
* Purpose: Copies datatype OLD_DT. The resulting data type is not
- * locked.
+ * locked and is a transient type.
*
* Return: Success: Pointer to a new copy of the OLD_DT argument.
*
@@ -2699,10 +2833,20 @@ H5T_create(H5T_class_t type, size_t size)
*
* Modifications:
*
+ * Robb Matzke, 4 Jun 1998
+ * Added the METHOD argument. If it's H5T_COPY_TRANSIENT then the
+ * result will be an unlocked transient type. Otherwise if it's
+ * H5T_COPY_ALL then the result is a named type if the original is a
+ * named type, but the result is not opened. Finally, if it's
+ * H5T_COPY_REOPEN and the original type is a named type then the result
+ * is a named type and the type object header is opened again. The
+ * H5T_COPY_REOPEN method is used when returning a named type to the
+ * application.
+ *
*-------------------------------------------------------------------------
*/
H5T_t *
-H5T_copy(const H5T_t *old_dt)
+H5T_copy(const H5T_t *old_dt, H5T_copy_t method)
{
H5T_t *new_dt=NULL, *tmp=NULL;
intn i;
@@ -2716,8 +2860,43 @@ H5T_copy(const H5T_t *old_dt)
/* copy */
new_dt = H5MM_xcalloc(1, sizeof(H5T_t));
*new_dt = *old_dt;
- new_dt->locked = FALSE;
+ switch (method) {
+ case H5T_COPY_TRANSIENT:
+ /*
+ * Return an unlocked transient type.
+ */
+ new_dt->state = H5T_STATE_TRANSIENT;
+ HDmemset (&(new_dt->ent), 0, sizeof(new_dt->ent));
+ H5F_addr_undef (&(new_dt->ent.header));
+ break;
+
+ case H5T_COPY_ALL:
+ /*
+ * Return a transient type (locked or unlocked) or an unopened named
+ * type.
+ */
+ if (H5T_STATE_OPEN==new_dt->state) {
+ new_dt->state = H5T_STATE_NAMED;
+ }
+ break;
+
+ case H5T_COPY_REOPEN:
+ /*
+ * Return a transient type (locked or unlocked) or an opened named
+ * type.
+ */
+ if (H5F_addr_defined (&(new_dt->ent.header))) {
+ if (H5O_open (&(new_dt->ent))<0) {
+ H5MM_xfree (new_dt);
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTOPENOBJ, NULL,
+ "unable to reopen named data type");
+ }
+ new_dt->state = H5T_STATE_OPEN;
+ }
+ break;
+ }
+
if (H5T_COMPOUND == new_dt->type) {
/*
* Copy all member fields to new type, then overwrite the
@@ -2732,7 +2911,7 @@ H5T_copy(const H5T_t *old_dt)
for (i = 0; i < new_dt->u.compnd.nmembs; i++) {
s = new_dt->u.compnd.memb[i].name;
new_dt->u.compnd.memb[i].name = H5MM_xstrdup(s);
- tmp = H5T_copy (old_dt->u.compnd.memb[i].type);
+ tmp = H5T_copy (old_dt->u.compnd.memb[i].type, method);
new_dt->u.compnd.memb[i].type = tmp;
}
}
@@ -2742,179 +2921,178 @@ H5T_copy(const H5T_t *old_dt)
/*-------------------------------------------------------------------------
- * Function: H5T_close
+ * Function: H5T_commit
*
- * Purpose: Frees a data type and all associated memory. If the data
- * type is locked then nothing happens.
+ * Purpose: Commit a type, giving it a name and causing it to become
+ * immutable.
*
* Return: Success: SUCCEED
*
* Failure: FAIL
*
* Programmer: Robb Matzke
- * Monday, December 8, 1997
+ * Monday, June 1, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
herr_t
-H5T_close(H5T_t *dt)
+H5T_commit (H5G_t *loc, const char *name, H5T_t *type)
{
- intn i;
-
- FUNC_ENTER(H5T_close, FAIL);
-
- assert(dt);
+ herr_t ret_value = FAIL;
+
+ FUNC_ENTER (H5T_commit, FAIL);
/*
- * Don't free locked datatypes unless we are shutting the interface
- * down.
+ * Check arguments. We cannot commit an immutable type because H5Tclose()
+ * normally fails on such types (try H5Tclose(H5T_NATIVE_INT)) but closing
+ * a named type should always succeed.
*/
- if (!dt->locked) {
- if (dt && H5T_COMPOUND == dt->type) {
- for (i = 0; i < dt->u.compnd.nmembs; i++) {
- H5MM_xfree(dt->u.compnd.memb[i].name);
- H5T_close (dt->u.compnd.memb[i].type);
- }
- H5MM_xfree(dt->u.compnd.memb);
- H5MM_xfree(dt);
+ assert (loc);
+ assert (name && *name);
+ assert (type);
+ if (H5T_STATE_NAMED==type->state || H5T_STATE_OPEN==type->state) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "data type is already committed");
+ }
+ if (H5T_STATE_IMMUTABLE==type->state) {
+ HRETURN_ERROR (H5E_ARGS, H5E_BADVALUE, FAIL,
+ "data type is immutable");
+ }
- } else if (dt) {
- H5MM_xfree(dt);
+ /*
+ * Create the object header and open it for write access. Insert the data
+ * type message and then give the object header a name.
+ */
+ if (H5O_create (H5G_fileof (loc), 64, &(type->ent))<0) {
+ HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to create data type object header");
+ }
+ if (H5O_modify (&(type->ent), H5O_DTYPE, 0, H5O_FLAG_CONSTANT, type)<0) {
+ HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to update type header message");
+ }
+ if (H5G_insert (loc, name, &(type->ent))<0) {
+ HGOTO_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to name data type");
+ }
+ type->state = H5T_STATE_OPEN;
+ ret_value = SUCCEED;
+
+ done:
+ if (ret_value<0) {
+ if (H5F_addr_defined (&(type->ent.header))) {
+ H5O_close (&(type->ent));
+ H5F_addr_undef (&(type->ent.header));
}
}
-
- FUNC_LEAVE(SUCCEED);
+ FUNC_LEAVE (ret_value);
}
/*-------------------------------------------------------------------------
- * Function: H5T_share
+ * Function: H5T_lock
+ *
+ * Purpose: Lock a transient data type making it read-only. If IMMUTABLE
+ * is set then the type cannot be closed except when the library
+ * itself closes.
*
- * Purpose: Causes a data type to be marked as sharable. If the data
- * type isn't already marked sharable in the specified file then
- * it is written to the global heap of that file and the heap
- * location information is added to the sh_file and sh_heap
- * fields of the data type.
+ * This function is a no-op if the type is not transient or if
+ * the type is already read-only or immutable.
*
* Return: Success: SUCCEED
*
* Failure: FAIL
*
* Programmer: Robb Matzke
- * Tuesday, March 31, 1998
+ * Thursday, June 4, 1998
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
herr_t
-H5T_share (H5F_t *f, H5T_t *dt)
+H5T_lock (H5T_t *dt, hbool_t immutable)
{
- FUNC_ENTER (H5T_share, FAIL);
-
- /* Check args */
- assert (f);
+ FUNC_ENTER (H5T_lock, FAIL);
assert (dt);
- /*
- * If the type is sharable in some other file then unshare it first. A
- * type can only be sharable in one file at a time.
- */
- if (H5HG_defined (&(dt->sh_heap)) && f->shared!=dt->sh_file->shared) {
- H5T_unshare (dt);
- H5E_clear (); /*don't really care if it fails*/
+ switch (dt->state) {
+ case H5T_STATE_TRANSIENT:
+ dt->state = immutable ? H5T_STATE_IMMUTABLE : H5T_STATE_RDONLY;
+ break;
+ case H5T_STATE_RDONLY:
+ if (immutable) dt->state = H5T_STATE_IMMUTABLE;
+ break;
+ case H5T_STATE_IMMUTABLE:
+ case H5T_STATE_NAMED:
+ case H5T_STATE_OPEN:
+ /*void*/
+ break;
}
- /*
- * Write the message to the global heap if it isn't already shared in
- * this file.
- */
- if (!H5HG_defined (&(dt->sh_heap))) {
- if (H5O_share (f, H5O_DTYPE, dt, &(dt->sh_heap))<0) {
- HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
- "unable to store data type message in global heap");
- }
- dt->sh_file = f;
- }
-
FUNC_LEAVE (SUCCEED);
}
/*-------------------------------------------------------------------------
- * Function: H5T_unshare
+ * Function: H5T_close
*
- * Purpose: If a data type is in the global heap then this function
- * removes that information from the H5T_t struct.
+ * Purpose: Frees a data type and all associated memory. If the data
+ * type is locked then nothing happens.
*
* Return: Success: SUCCEED
*
* Failure: FAIL
*
* Programmer: Robb Matzke
- * Tuesday, March 31, 1998
+ * Monday, December 8, 1997
*
* Modifications:
*
*-------------------------------------------------------------------------
*/
herr_t
-H5T_unshare (H5T_t *dt)
+H5T_close(H5T_t *dt)
{
- FUNC_ENTER (H5T_unshare, FAIL);
+ intn i;
- /* Check args */
- assert (dt);
+ FUNC_ENTER(H5T_close, FAIL);
- H5HG_undef (&(dt->sh_heap));
- dt->sh_file = NULL;
+ assert(dt);
- FUNC_LEAVE (SUCCEED);
-}
+ /*
+ * If a named type is being closed then close the object header also.
+ */
+ if (H5T_STATE_OPEN==dt->state) {
+ assert (H5F_addr_defined (&(dt->ent.header)));
+ if (H5O_close (&(dt->ent))<0) {
+ HRETURN_ERROR (H5E_DATATYPE, H5E_CANTINIT, FAIL,
+ "unable to close data type object header");
+ }
+ dt->state = H5T_STATE_NAMED;
+ }
-
-/*-------------------------------------------------------------------------
- * Function: H5T_invalidate_cb
- *
- * Purpose: This is a callback function for H5I_search(). When a file is
- * closed we scan through the data type list and invalidate
- * shared info for all types that have sharing enabled for the
- * specified file. This insures that we don't having dangling
- * pointers from data types to files. We have to do this with
- * data types but not datasets because a dataset_id always
- * corresponds to an open object header which prevents the file
- * from closing in the first place, but a data type can exist
- * independent of a file and doesn't have an object header.
- *
- * Return: Success: 0, this function never returns a non-zero
- * value because that would terminate
- * H5I_search().
- *
- * Failure: 0
- *
- * Programmer: Robb Matzke
- * Friday, April 3, 1998
- *
- * Modifications:
- *
- *-------------------------------------------------------------------------
- */
-intn
-H5T_invalidate_cb (void *obj, const void *call_data)
-{
- H5T_t *dt = (H5T_t *)obj;
- const H5F_t *f = (const H5F_t*)call_data; /*used only for comparison*/
-
- FUNC_ENTER (H5T_invalidate, 0);
+ /*
+ * Don't free locked datatypes unless we are shutting down the
+ * interface.
+ */
+ if (H5T_STATE_IMMUTABLE!=dt->state) {
+ if (dt && H5T_COMPOUND == dt->type) {
+ for (i = 0; i < dt->u.compnd.nmembs; i++) {
+ H5MM_xfree(dt->u.compnd.memb[i].name);
+ H5T_close (dt->u.compnd.memb[i].type);
+ }
+ H5MM_xfree(dt->u.compnd.memb);
+ H5MM_xfree(dt);
- if (H5HG_defined (&(dt->sh_heap)) && dt->sh_file->shared==f->shared) {
- H5T_unshare (dt);
- H5E_clear ();
+ } else if (dt) {
+ H5MM_xfree(dt);
+ }
}
-
- FUNC_LEAVE (0);
+
+ FUNC_LEAVE(SUCCEED);
}
@@ -3003,7 +3181,7 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member)
/* check args */
assert(parent && H5T_COMPOUND == parent->type);
- assert(!parent->locked);
+ assert(H5T_STATE_TRANSIENT==parent->state);
assert(member);
assert(name && *name);
@@ -3036,12 +3214,11 @@ H5T_insert(H5T_t *parent, const char *name, size_t offset, const H5T_t *member)
}
/* Add member to end of member array */
- H5T_unshare (parent);
i = parent->u.compnd.nmembs;
parent->u.compnd.memb[i].name = H5MM_xstrdup(name);
parent->u.compnd.memb[i].offset = offset;
parent->u.compnd.memb[i].ndims = 0; /*defaults to scalar */
- parent->u.compnd.memb[i].type = H5T_copy (member);
+ parent->u.compnd.memb[i].type = H5T_copy (member, H5T_COPY_ALL);
parent->u.compnd.nmembs++;
FUNC_LEAVE(SUCCEED);
@@ -3074,9 +3251,8 @@ H5T_pack(H5T_t *dt)
FUNC_ENTER(H5T_pack, FAIL);
assert(dt);
- assert(!dt->locked);
+ assert(H5T_STATE_TRANSIENT==dt->state);
- H5T_unshare (dt);
if (H5T_COMPOUND == dt->type) {
/* Recursively pack the members */
for (i = 0; i < dt->u.compnd.nmembs; i++) {
@@ -3534,8 +3710,8 @@ H5T_path_find(const char *name, const H5T_t *src, const H5T_t *dst,
/* insert */
path = H5T_path_g + md;
HDmemset(path, 0, sizeof(H5T_path_t));
- path->src = H5T_copy(src);
- path->dst = H5T_copy(dst);
+ path->src = H5T_copy(src, H5T_COPY_ALL);
+ path->dst = H5T_copy(dst, H5T_COPY_ALL);
/* Associate a function with the path if possible */
if (func) {
@@ -3545,8 +3721,10 @@ H5T_path_find(const char *name, const H5T_t *src, const H5T_t *dst,
path->is_hard = TRUE;
path->cdata.command = H5T_CONV_INIT;
path->cdata.stats = H5MM_xcalloc (1, sizeof(H5T_stats_t));
- if ((src_id=H5I_register(H5_DATATYPE, H5T_copy(path->src))) < 0 ||
- (dst_id=H5I_register(H5_DATATYPE, H5T_copy(path->dst))) < 0) {
+ if ((src_id=H5I_register(H5_DATATYPE,
+ H5T_copy(path->src, H5T_COPY_ALL))) < 0 ||
+ (dst_id=H5I_register(H5_DATATYPE,
+ H5T_copy(path->dst, H5T_COPY_ALL))) < 0) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL,
"unable to register conv types for query");
}
@@ -3567,9 +3745,11 @@ H5T_path_find(const char *name, const H5T_t *src, const H5T_t *dst,
continue;
}
if ((src_id=H5I_register(H5_DATATYPE,
- H5T_copy(path->src))) < 0 ||
+ H5T_copy(path->src,
+ H5T_COPY_ALL))) < 0 ||
(dst_id=H5I_register(H5_DATATYPE,
- H5T_copy(path->dst))) < 0) {
+ H5T_copy(path->dst,
+ H5T_COPY_ALL))) < 0) {
HRETURN_ERROR(H5E_DATATYPE, H5E_CANTREGISTER, NULL,
"unable to register conv types for query");
}
@@ -3665,7 +3845,7 @@ H5T_timer_end (H5_timer_t *timer, H5T_cdata_t *cdata, size_t nelmts)
herr_t
H5T_debug(H5T_t *dt, FILE * stream)
{
- const char *s = "";
+ const char *s1="", *s2="";
int i, j;
uint64 tmp;
@@ -3677,53 +3857,70 @@ H5T_debug(H5T_t *dt, FILE * stream)
switch (dt->type) {
case H5T_INTEGER:
- s = "int";
+ s1 = "int";
break;
case H5T_FLOAT:
- s = "float";
+ s1 = "float";
break;
case H5T_TIME:
- s = "time";
+ s1 = "time";
break;
case H5T_STRING:
- s = "str";
+ s1 = "str";
break;
case H5T_BITFIELD:
- s = "bits";
+ s1 = "bits";
break;
case H5T_OPAQUE:
- s = "opaque";
+ s1 = "opaque";
break;
case H5T_COMPOUND:
- s = "struct";
+ s1 = "struct";
break;
default:
- s = "";
+ s1 = "";
+ break;
+ }
+
+ switch (dt->state) {
+ case H5T_STATE_TRANSIENT:
+ s2 = "[transient]";
+ break;
+ case H5T_STATE_RDONLY:
+ s2 = "[constant]";
+ break;
+ case H5T_STATE_IMMUTABLE:
+ s2 = "[predefined]";
+ break;
+ case H5T_STATE_NAMED:
+ s2 = "[named,closed]";
+ break;
+ case H5T_STATE_OPEN:
+ s2 = "[named,open]";
break;
}
- fprintf(stream, "%s%s {nbytes=%lu",
- s, dt->locked ? "[!]" : "", (unsigned long)(dt->size));
+ fprintf(stream, "%s%s {nbytes=%lu", s1, s2, (unsigned long)(dt->size));
if (H5T_is_atomic(dt)) {
switch (dt->u.atomic.order) {
case H5T_ORDER_BE:
- s = "BE";
+ s1 = "BE";
break;
case H5T_ORDER_LE:
- s = "LE";
+ s1 = "LE";
break;
case H5T_ORDER_VAX:
- s = "VAX";
+ s1 = "VAX";
break;
case H5T_ORDER_NONE:
- s = "NONE";
+ s1 = "NONE";
break;
default:
- s = "order?";
+ s1 = "order?";
break;
}
- fprintf(stream, ", %s", s);
+ fprintf(stream, ", %s", s1);
if (dt->u.atomic.offset) {
fprintf(stream, ", offset=%lu",
@@ -3737,39 +3934,39 @@ H5T_debug(H5T_t *dt, FILE * stream)
case H5T_INTEGER:
switch (dt->u.atomic.u.i.sign) {
case H5T_SGN_NONE:
- s = "unsigned";
+ s1 = "unsigned";
break;
case H5T_SGN_2:
- s = NULL;
+ s1 = NULL;
break;
default:
- s = "sign?";
+ s1 = "sign?";
break;
}
- if (s)
- fprintf(stream, ", %s", s);
+ if (s1)
+ fprintf(stream, ", %s", s1);
break;
case H5T_FLOAT:
switch (dt->u.atomic.u.f.norm) {
case H5T_NORM_IMPLIED:
- s = "implied";
+ s1 = "implied";
break;
case H5T_NORM_MSBSET:
- s = "msbset";
+ s1 = "msbset";
break;
case H5T_NORM_NONE:
- s = "no-norm";
+ s1 = "no-norm";
break;
default:
- s = "norm?";
+ s1 = "norm?";
break;
}
fprintf(stream, ", sign=%lu+1",
(unsigned long) (dt->u.atomic.u.f.sign));
fprintf(stream, ", mant=%lu+%lu (%s)",
(unsigned long) (dt->u.atomic.u.f.mpos),
- (unsigned long) (dt->u.atomic.u.f.msize), s);
+ (unsigned long) (dt->u.atomic.u.f.msize), s1);
fprintf(stream, ", exp=%lu+%lu",
(unsigned long) (dt->u.atomic.u.f.epos),
(unsigned long) (dt->u.atomic.u.f.esize));
diff --git a/src/H5Tconv.c b/src/H5Tconv.c
index 9a0f833..626859d 100644
--- a/src/H5Tconv.c
+++ b/src/H5Tconv.c
@@ -243,12 +243,13 @@ H5T_conv_struct_init (H5T_t *src, H5T_t *dst, H5T_cdata_t *cdata)
}
}
if (priv->src2dst[i]>=0) {
- type = H5T_copy (src->u.compnd.memb[i].type);
+ type = H5T_copy (src->u.compnd.memb[i].type, H5T_COPY_ALL);
tid = H5I_register (H5_DATATYPE, type);
assert (tid>=0);
priv->src_memb_id[priv->src2dst[i]] = tid;
- type = H5T_copy (dst->u.compnd.memb[priv->src2dst[i]].type);
+ type = H5T_copy (dst->u.compnd.memb[priv->src2dst[i]].type,
+ H5T_COPY_ALL);
tid = H5I_register (H5_DATATYPE, type);
assert (tid>=0);
priv->dst_memb_id[priv->src2dst[i]] = tid;
diff --git a/src/H5Tpkg.h b/src/H5Tpkg.h
index bb2bc2b..dea8b48 100644
--- a/src/H5Tpkg.h
+++ b/src/H5Tpkg.h
@@ -63,10 +63,18 @@ typedef struct H5T_compnd_t {
struct H5T_member_t *memb; /*array of struct members */
} H5T_compnd_t;
+typedef enum H5T_state_t {
+ H5T_STATE_TRANSIENT, /*type is a modifiable transient */
+ H5T_STATE_RDONLY, /*transient, not modifiable, closable*/
+ H5T_STATE_IMMUTABLE, /*constant, not closable */
+ H5T_STATE_NAMED, /*named constant, not open */
+ H5T_STATE_OPEN /*named constant, open object header */
+} H5T_state_t;
+
struct H5T_t {
- hbool_t locked; /*if locked, then can't be modified */
- H5HG_t sh_heap; /*if defined, type is in global heap */
- H5F_t *sh_file; /*file pointer if this is a shared type */
+ H5T_state_t state; /*current state of the type */
+ H5G_entry_t ent; /*the type is a named type */
+ H5F_t *sh_file;/*file pointer if this is a shared type */
H5T_class_t type; /*which class of type is this? */
size_t size; /*total size of an instance of this type */
union {
diff --git a/src/H5Tprivate.h b/src/H5Tprivate.h
index 0a1178a..26fe27b 100644
--- a/src/H5Tprivate.h
+++ b/src/H5Tprivate.h
@@ -34,16 +34,22 @@ typedef struct H5T_stats_t {
#endif
} H5T_stats_t;
+/* How to copy a data type */
+typedef enum H5T_copy_t {
+ H5T_COPY_TRANSIENT,
+ H5T_COPY_ALL,
+ H5T_COPY_REOPEN
+} H5T_copy_t;
/* Private functions */
herr_t H5T_init (void);
herr_t H5T_init_interface (void);
+H5T_t *H5T_open (H5G_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_t *H5T_copy (const H5T_t *old_dt, H5T_copy_t method);
+herr_t H5T_commit (H5G_t *loc, const char *name, H5T_t *type);
+herr_t H5T_lock (H5T_t *dt, hbool_t immutable);
herr_t H5T_close (H5T_t *dt);
-herr_t H5T_share (H5F_t *f, H5T_t *dt);
-herr_t H5T_unshare (H5T_t *dt);
-intn H5T_invalidate_cb (void *obj, const void *call_data);
size_t H5T_get_size (const H5T_t *dt);
intn H5T_cmp (const H5T_t *dt1, const H5T_t *dt2);
hbool_t H5T_is_atomic (const H5T_t *dt);
diff --git a/src/H5Tpublic.h b/src/H5Tpublic.h
index 1fc4477..1d7885a 100644
--- a/src/H5Tpublic.h
+++ b/src/H5Tpublic.h
@@ -178,13 +178,14 @@ extern hid_t H5T_NATIVE_BITFIELD_g;
extern hid_t H5T_NATIVE_OPAQUE_g;
/* Operations defined on all data types */
+hid_t H5Topen (hid_t loc_id, const char *name);
hid_t H5Tcreate (H5T_class_t type, size_t size);
hid_t H5Tcopy (hid_t type_id);
herr_t H5Tclose (hid_t type_id);
hbool_t H5Tequal (hid_t type1_id, hid_t type2_id);
herr_t H5Tlock (hid_t type_id);
-herr_t H5Tshare (hid_t location_id, hid_t type_id);
-hbool_t H5Tis_shared (hid_t location_id, hid_t type_id);
+herr_t H5Tcommit (hid_t loc_id, const char *name, hid_t type_id);
+hbool_t H5Tcommitted (hid_t type_id);
/* Operations defined on compound data types */
herr_t H5Tinsert (hid_t parent_id, const char *name, size_t offset,
diff --git a/src/H5detect.c b/src/H5detect.c
index 3f7c251..9b7959b 100644
--- a/src/H5detect.c
+++ b/src/H5detect.c
@@ -306,7 +306,8 @@ H5T_init (void)\n\
/* The part common to fixed and floating types */
printf("\
dt = H5MM_xcalloc (1, sizeof(H5T_t));\n\
- dt->locked = TRUE;\n\
+ dt->state = H5T_STATE_IMMUTABLE;\n\
+ H5F_addr_undef (&(dt->ent.header));\n\
dt->type = H5T_%s;\n\
dt->size = %d;\n\
dt->u.atomic.order = H5T_ORDER_%s;\n\
diff --git a/src/h5ls.c b/src/h5ls.c
index f96448c..64207be 100644
--- a/src/h5ls.c
+++ b/src/h5ls.c
@@ -89,6 +89,9 @@ list (hid_t group, const char *name, void __unused__ *op_data)
strcpy (buf+sizeof(buf)-4, "...");
}
printf (" -> %s\n", buf);
+ } else if ((obj=H5Topen (group, name))>=0) {
+ printf ("Data type\n");
+ H5Tclose (obj);
} else {
printf ("Unknown Type\n");
}