diff options
-rw-r--r-- | src/H5A.c | 32 | ||||
-rw-r--r-- | src/H5D.c | 123 | ||||
-rw-r--r-- | src/H5Dprivate.h | 1 | ||||
-rw-r--r-- | src/H5Epublic.h | 8 | ||||
-rw-r--r-- | src/H5F.c | 6 | ||||
-rw-r--r-- | src/H5Gent.c | 6 | ||||
-rw-r--r-- | src/H5Gpkg.h | 3 | ||||
-rw-r--r-- | src/H5Gprivate.h | 6 | ||||
-rw-r--r-- | src/H5O.c | 93 | ||||
-rw-r--r-- | src/H5Oattr.c | 13 | ||||
-rw-r--r-- | src/H5Ocomp.c | 8 | ||||
-rw-r--r-- | src/H5Ocont.c | 27 | ||||
-rw-r--r-- | src/H5Odtype.c | 97 | ||||
-rw-r--r-- | src/H5Oefl.c | 27 | ||||
-rw-r--r-- | src/H5Olayout.c | 27 | ||||
-rw-r--r-- | src/H5Oname.c | 28 | ||||
-rw-r--r-- | src/H5Oprivate.h | 14 | ||||
-rw-r--r-- | src/H5Osdspace.c | 27 | ||||
-rw-r--r-- | src/H5Oshared.c | 62 | ||||
-rw-r--r-- | src/H5Ostab.c | 27 | ||||
-rw-r--r-- | src/H5T.c | 771 | ||||
-rw-r--r-- | src/H5Tconv.c | 5 | ||||
-rw-r--r-- | src/H5Tpkg.h | 14 | ||||
-rw-r--r-- | src/H5Tprivate.h | 14 | ||||
-rw-r--r-- | src/H5Tpublic.h | 5 | ||||
-rw-r--r-- | src/H5detect.c | 3 | ||||
-rw-r--r-- | src/h5ls.c | 3 |
27 files changed, 924 insertions, 526 deletions
@@ -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); @@ -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) /* @@ -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 @@ -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)); @@ -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\ @@ -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"); } |