1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 /*-------------------------------------------------------------------------
15  *
16  * Created:	H5G.c
17  *		Jul 18 1997
18  *		Robb Matzke <matzke@llnl.gov>
19  *
20  * Purpose:	Symbol table functions.	 The functions that begin with
21  *		`H5G_stab_' don't understand the naming system; they operate
22  * 		on a single symbol table at a time.
23  *
24  *		The functions that begin with `H5G_node_' operate on the leaf
25  *		nodes of a symbol table B-tree.  They should be defined in
26  *		the H5Gnode.c file.
27  *
28  *		The remaining functions know how to traverse the group
29  *		directed graph.
30  *
31  * Names:	Object names are a slash-separated list of components.  If
32  *		the name begins with a slash then it's absolute, otherwise
33  *		it's relative ("/foo/bar" is absolute while "foo/bar" is
34  *		relative).  Multiple consecutive slashes are treated as
35  *		single slashes and trailing slashes are ignored.  The special
36  *		case `/' is the root group.  Every file has a root group.
37  *
38  *		API functions that look up names take a location ID and a
39  *		name.  The location ID can be a file ID or a group ID and the
40  *		name can be relative or absolute.
41  *
42  *              +--------------+----------- +--------------------------------+
43  * 		| Location ID  | Name       | Meaning                        |
44  *              +--------------+------------+--------------------------------+
45  * 		| File ID      | "/foo/bar" | Find `foo' within `bar' within |
46  *		|              |            | the root group of the specified|
47  *		|              |            | file.                          |
48  *              +--------------+------------+--------------------------------+
49  * 		| File ID      | "foo/bar"  | Find `foo' within `bar' within |
50  *		|              |            | the root group of the specified|
51  *		|              |            | file.                          |
52  *              +--------------+------------+--------------------------------+
53  * 		| File ID      | "/"        | The root group of the specified|
54  *		|              |            | file.                          |
55  *              +--------------+------------+--------------------------------+
56  * 		| File ID      | "."        | The root group of the specified|
57  *		|              |            | the specified file.            |
58  *              +--------------+------------+--------------------------------+
59  * 		| Group ID     | "/foo/bar" | Find `foo' within `bar' within |
60  *		|              |            | the root group of the file     |
61  *		|              |            | containing the specified group.|
62  *              +--------------+------------+--------------------------------+
63  * 		| Group ID     | "foo/bar"  | File `foo' within `bar' within |
64  *		|              |            | the specified group.           |
65  *              +--------------+------------+--------------------------------+
66  * 		| Group ID     | "/"        | The root group of the file     |
67  *		|              |            | containing the specified group.|
68  *              +--------------+------------+--------------------------------+
69  * 		| Group ID     | "."        | The specified group.           |
70  *              +--------------+------------+--------------------------------+
71  *
72  *
73  *-------------------------------------------------------------------------
74  */
75 
76 /****************/
77 /* Module Setup */
78 /****************/
79 
80 #define H5G_PACKAGE		/*suppress error about including H5Gpkg   */
81 
82 /* Interface initialization */
83 #define H5_INTERFACE_INIT_FUNC	H5G_init_interface
84 
85 
86 /***********/
87 /* Headers */
88 /***********/
89 #include "H5private.h"		/* Generic Functions			*/
90 #include "H5ACprivate.h"	/* Metadata cache			*/
91 #include "H5Eprivate.h"		/* Error handling		  	*/
92 #include "H5Gpkg.h"		/* Groups		  		*/
93 #include "H5Iprivate.h"		/* IDs			  		*/
94 #include "H5Pprivate.h"         /* Property lists                       */
95 
96 
97 /****************/
98 /* Local Macros */
99 /****************/
100 
101 
102 /******************/
103 /* Local Typedefs */
104 /******************/
105 
106 
107 /********************/
108 /* Package Typedefs */
109 /********************/
110 
111 
112 /********************/
113 /* Local Prototypes */
114 /********************/
115 
116 
117 /*********************/
118 /* Package Variables */
119 /*********************/
120 
121 
122 /*****************************/
123 /* Library Private Variables */
124 /*****************************/
125 
126 
127 /*******************/
128 /* Local Variables */
129 /*******************/
130 
131 /* Group ID class */
132 static const H5I_class_t H5I_GROUP_CLS[1] = {{
133     H5I_GROUP,			/* ID class value */
134     H5I_CLASS_REUSE_IDS,	/* Class flags */
135     0,				/* # of reserved IDs for class */
136     (H5I_free_t)H5G_close	/* Callback routine for closing objects of this class */
137 }};
138 
139 
140 
141 /*-------------------------------------------------------------------------
142  * Function:	H5G__init
143  *
144  * Purpose:	Initialize the interface from some other package.
145  *
146  * Return:	Success:	non-negative
147  *		Failure:	negative
148  *
149  * Programmer:	Quincey Koziol
150  *              Saturday, November 11, 2006
151  *
152  *-------------------------------------------------------------------------
153  */
154 herr_t
H5G__init(void)155 H5G__init(void)
156 {
157     herr_t ret_value = SUCCEED;   /* Return value */
158 
159     FUNC_ENTER_NOAPI(FAIL)
160     /* FUNC_ENTER() does all the work */
161 
162 done:
163     FUNC_LEAVE_NOAPI(ret_value)
164 } /* end H5G__init() */
165 
166 
167 /*-------------------------------------------------------------------------
168  * Function:	H5G_init_interface
169  *
170  * Purpose:	Initializes the H5G interface.
171  *
172  * Return:	Non-negative on success/Negative on failure
173  *
174  * Programmer:	Robb Matzke
175  *		Monday, January	 5, 1998
176  *
177  * Notes:       The group creation properties are registered in the property
178  *              list interface initialization routine (H5P_init_interface)
179  *              so that the file creation property class can inherit from it
180  *              correctly. (Which allows the file creation property list to
181  *              control the group creation properties of the root group of
182  *              a file) QAK - 24/10/2005
183  *
184  *-------------------------------------------------------------------------
185  */
186 static herr_t
H5G_init_interface(void)187 H5G_init_interface(void)
188 {
189     herr_t          ret_value = SUCCEED;  /* Return value */
190 
191     FUNC_ENTER_NOAPI_NOINIT
192 
193     /* Initialize the atom group for the group IDs */
194     if(H5I_register_type(H5I_GROUP_CLS) < 0)
195 	HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to initialize interface")
196 
197 done:
198     FUNC_LEAVE_NOAPI(ret_value)
199 } /* end H5G_init_interface() */
200 
201 
202 /*-------------------------------------------------------------------------
203  * Function:	H5G_term_interface
204  *
205  * Purpose:	Terminates the H5G interface
206  *
207  * Return:	Success:	Positive if anything is done that might
208  *				affect other interfaces; zero otherwise.
209  *
210  * 		Failure:	Negative.
211  *
212  * Programmer:	Robb Matzke
213  *		Monday, January	 5, 1998
214  *
215  *-------------------------------------------------------------------------
216  */
217 int
H5G_term_interface(void)218 H5G_term_interface(void)
219 {
220     int	n = 0;
221 
222     FUNC_ENTER_NOAPI_NOINIT_NOERR
223 
224     if(H5_interface_initialize_g) {
225         if(H5I_nmembers(H5I_GROUP) > 0) {
226             (void)H5I_clear_type(H5I_GROUP, FALSE, FALSE);
227             n++; /*H5I*/
228         } /* end if */
229         else {
230             /* Close deprecated interface */
231             n += H5G__term_deprec_interface();
232 
233             /* Destroy the group object id group */
234             (void)H5I_dec_type_ref(H5I_GROUP);
235             n++; /*H5I*/
236 
237             /* Mark closed */
238             H5_interface_initialize_g = 0;
239         } /* end else */
240     } /* end if */
241 
242     FUNC_LEAVE_NOAPI(n)
243 } /* end H5G_term_interface() */
244 
245 
246 /*-------------------------------------------------------------------------
247  * Function:	H5Gcreate2
248  *
249  * Purpose:	Creates a new group relative to LOC_ID, giving it the
250  *              specified creation property list GCPL_ID and access
251  *              property list GAPL_ID.  The link to the new group is
252  *              created with the LCPL_ID.
253  *
254  * Usage:       H5Gcreate2(loc_id, char *name, lcpl_id, gcpl_id, gapl_id)
255  *                  hid_t loc_id;	  IN: File or group identifier
256  *                  const char *name; IN: Absolute or relative name of the new group
257  *                  hid_t lcpl_id;	  IN: Property list for link creation
258  *                  hid_t gcpl_id;	  IN: Property list for group creation
259  *                  hid_t gapl_id;	  IN: Property list for group access
260  *
261  * Return:	Success:	The object ID of a new, empty group open for
262  *				writing.  Call H5Gclose() when finished with
263  *				the group.
264  *
265  *		Failure:	FAIL
266  *
267  * Programmer:  Quincey Koziol
268  *	        April 5, 2007
269  *
270  *-------------------------------------------------------------------------
271  */
272 hid_t
H5Gcreate2(hid_t loc_id,const char * name,hid_t lcpl_id,hid_t gcpl_id,hid_t gapl_id)273 H5Gcreate2(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id,
274     hid_t gapl_id)
275 {
276     H5G_loc_t	    loc;                /* Location to create group */
277     H5G_t	   *grp = NULL;         /* New group created */
278     hid_t	    ret_value;          /* Return value */
279 
280     FUNC_ENTER_API(FAIL)
281     H5TRACE5("i", "i*siii", loc_id, name, lcpl_id, gcpl_id, gapl_id);
282 
283     /* Check arguments */
284     if(H5G_loc(loc_id, &loc) < 0)
285 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
286     if(!name || !*name)
287 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
288 
289     /* Get correct property list */
290     if(H5P_DEFAULT == lcpl_id)
291         lcpl_id = H5P_LINK_CREATE_DEFAULT;
292     else
293         if(TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))
294             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link creation property list")
295 
296     /* Check group creation property list */
297     if(H5P_DEFAULT == gcpl_id)
298         gcpl_id = H5P_GROUP_CREATE_DEFAULT;
299     else
300         if(TRUE != H5P_isa_class(gcpl_id, H5P_GROUP_CREATE))
301             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group create property list")
302 
303     /* Check the group access property list */
304     if(H5P_DEFAULT == gapl_id)
305         gapl_id = H5P_GROUP_ACCESS_DEFAULT;
306     else
307         if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS))
308             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list")
309 
310     /* Create the new group & get its ID */
311     if(NULL == (grp = H5G__create_named(&loc, name, lcpl_id, gcpl_id, gapl_id, H5AC_dxpl_id)))
312         HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group")
313     if((ret_value = H5I_register(H5I_GROUP, grp, TRUE)) < 0)
314 	HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
315 
316 done:
317     if(ret_value < 0)
318         if(grp && H5G_close(grp) < 0)
319             HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group")
320 
321     FUNC_LEAVE_API(ret_value)
322 } /* end H5Gcreate2() */
323 
324 
325 /*-------------------------------------------------------------------------
326  * Function:	H5Gcreate_anon
327  *
328  * Purpose:	Creates a new group relative to LOC_ID, giving it the
329  *              specified creation property list GCPL_ID and access
330  *              property list GAPL_ID.
331  *
332  *              The resulting ID should be linked into the file with
333  *              H5Olink or it will be deleted when closed.
334  *
335  *              Given the default setting, H5Gcreate_anon() followed by
336  *              H5Olink() will have the same function as H5Gcreate2().
337  *
338  * Usage:       H5Gcreate_anon(loc_id, char *name, gcpl_id, gapl_id)
339  *                  hid_t loc_id;	  IN: File or group identifier
340  *                  const char *name; IN: Absolute or relative name of the new group
341  *                  hid_t gcpl_id;	  IN: Property list for group creation
342  *                  hid_t gapl_id;	  IN: Property list for group access
343  *
344  * Example:	To create missing groups "A" and "B01" along the given path "/A/B01/grp"
345  *              hid_t create_id = H5Pcreate(H5P_GROUP_CREATE);
346  *              int   status = H5Pset_create_intermediate_group(create_id, TRUE);
347  *              hid_t gid = H5Gcreate_anon(file_id, "/A/B01/grp", create_id, H5P_DEFAULT);
348  *
349  * Return:	Success:	The object ID of a new, empty group open for
350  *				writing.  Call H5Gclose() when finished with
351  *				the group.
352  *
353  *		Failure:	FAIL
354  *
355  * Programmer:  Peter Cao
356  *	        May 08, 2005
357  *
358  *-------------------------------------------------------------------------
359  */
360 hid_t
H5Gcreate_anon(hid_t loc_id,hid_t gcpl_id,hid_t gapl_id)361 H5Gcreate_anon(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id)
362 {
363     H5G_loc_t	    loc;
364     H5G_t	   *grp = NULL;
365     H5G_obj_create_t gcrt_info;         /* Information for group creation */
366     hid_t	    ret_value;
367 
368     FUNC_ENTER_API(FAIL)
369     H5TRACE3("i", "iii", loc_id, gcpl_id, gapl_id);
370 
371     /* Check arguments */
372     if(H5G_loc(loc_id, &loc) < 0)
373 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
374 
375     /* Check group creation property list */
376     if(H5P_DEFAULT == gcpl_id)
377         gcpl_id = H5P_GROUP_CREATE_DEFAULT;
378     else
379         if(TRUE != H5P_isa_class(gcpl_id, H5P_GROUP_CREATE))
380             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group create property list")
381 
382     /* Check the group access property list */
383     if(H5P_DEFAULT == gapl_id)
384         gapl_id = H5P_GROUP_ACCESS_DEFAULT;
385     else
386         if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS))
387             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list")
388 
389     /* Set up group creation info */
390     gcrt_info.gcpl_id = gcpl_id;
391     gcrt_info.cache_type = H5G_NOTHING_CACHED;
392     HDmemset(&gcrt_info.cache, 0, sizeof(gcrt_info.cache));
393 
394     /* Create the new group & get its ID */
395     if(NULL == (grp = H5G__create(loc.oloc->file, &gcrt_info, H5AC_dxpl_id)))
396         HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group")
397     if((ret_value = H5I_register(H5I_GROUP, grp, TRUE)) < 0)
398 	HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
399 
400 done:
401     /* Release the group's object header, if it was created */
402     if(grp) {
403         H5O_loc_t *oloc;         /* Object location for group */
404 
405         /* Get the new group's object location */
406         if(NULL == (oloc = H5G_oloc(grp)))
407             HDONE_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object location of group")
408 
409         /* Decrement refcount on group's object header in memory */
410         if(H5O_dec_rc_by_loc(oloc, H5AC_dxpl_id) < 0)
411            HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object")
412     } /* end if */
413 
414     /* Cleanup on failure */
415     if(ret_value < 0)
416         if(grp && H5G_close(grp) < 0)
417             HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group")
418 
419     FUNC_LEAVE_API(ret_value)
420 } /* end H5Gcreate_anon() */
421 
422 
423 /*-------------------------------------------------------------------------
424  * Function:	H5Gopen2
425  *
426  * Purpose:	Opens an existing group for modification.  When finished,
427  *		call H5Gclose() to close it and release resources.
428  *
429  *              This function allows the user the pass in a Group Access
430  *              Property List, which H5Gopen1() does not.
431  *
432  * Return:	Success:	Object ID of the group.
433  *		Failure:	FAIL
434  *
435  * Programmer:	James Laird
436  *		Thursday, July 27, 2006
437  *
438  *-------------------------------------------------------------------------
439  */
440 hid_t
H5Gopen2(hid_t loc_id,const char * name,hid_t gapl_id)441 H5Gopen2(hid_t loc_id, const char *name, hid_t gapl_id)
442 {
443     H5G_t       *grp = NULL;            /* Group opened */
444     H5G_loc_t	loc;                    /* Location of parent for group */
445     hid_t       ret_value;              /* Return value */
446 
447     FUNC_ENTER_API(FAIL)
448     H5TRACE3("i", "i*si", loc_id, name, gapl_id);
449 
450     /* Check args */
451     if(H5G_loc(loc_id, &loc) < 0)
452         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
453     if(!name || !*name)
454         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
455 
456     /* Check the group access property list */
457     if(H5P_DEFAULT == gapl_id)
458         gapl_id = H5P_GROUP_ACCESS_DEFAULT;
459     else
460         if(TRUE != H5P_isa_class(gapl_id, H5P_GROUP_ACCESS))
461             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group access property list")
462 
463     /* Open the group */
464     if((grp = H5G__open_name(&loc, name, gapl_id, H5AC_ind_dxpl_id)) == NULL)
465         HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
466 
467     /* Register an ID for the group */
468     if((ret_value = H5I_register(H5I_GROUP, grp, TRUE)) < 0)
469         HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
470 
471 done:
472     if(ret_value < 0) {
473         if(grp && H5G_close(grp) < 0)
474             HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group")
475     } /* end if */
476 
477     FUNC_LEAVE_API(ret_value)
478 } /* end H5Gopen2() */
479 
480 
481 /*-------------------------------------------------------------------------
482  * Function:	H5Gget_create_plist
483  *
484  * Purpose:	Returns a copy of the group creation property list.
485  *
486  * Return:	Success:	ID for a copy of the group creation
487  *				property list.  The property list ID should be
488  *				released by calling H5Pclose().
489  *
490  *		Failure:	FAIL
491  *
492  * Programmer:	Quincey Koziol
493  *		Tuesday, October 25, 2005
494  *
495  *-------------------------------------------------------------------------
496  */
497 hid_t
H5Gget_create_plist(hid_t group_id)498 H5Gget_create_plist(hid_t group_id)
499 {
500     H5G_t		*group = NULL;
501     hid_t		ret_value = FAIL;
502 
503     FUNC_ENTER_API(FAIL)
504     H5TRACE1("i", "i", group_id);
505 
506     /* Check args */
507     if(NULL == (group = (H5G_t *)H5I_object_verify(group_id, H5I_GROUP)))
508 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
509 
510     if((ret_value = H5G_get_create_plist(group)) < 0)
511 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
512 
513 done:
514     FUNC_LEAVE_API(ret_value)
515 } /* end H5Gget_create_plist() */
516 
517 
518 /*-------------------------------------------------------------------------
519  * Function:	H5G_get_create_plist
520  *
521  * Purpose:	Private function for H5Gget_create_plist
522  *
523  * Return:	Success:	ID for a copy of the group creation
524  *				property list.  The property list ID should be
525  *				released by calling H5Pclose().
526  *
527  *		Failure:	FAIL
528  *
529  * Programmer:	Quincey Koziol
530  *		Tuesday, October 25, 2005
531  *
532  *-------------------------------------------------------------------------
533  */
534 hid_t
H5G_get_create_plist(H5G_t * grp)535 H5G_get_create_plist(H5G_t *grp)
536 {
537     H5O_linfo_t         linfo;		        /* Link info message            */
538     htri_t	        ginfo_exists;
539     htri_t	        linfo_exists;
540     htri_t              pline_exists;
541     H5P_genplist_t      *gcpl_plist;
542     H5P_genplist_t      *new_plist;
543     hid_t		new_gcpl_id = FAIL;
544     hid_t		ret_value = FAIL;
545 
546     FUNC_ENTER_NOAPI(FAIL)
547 
548     /* Copy the default group creation property list */
549     if(NULL == (gcpl_plist = (H5P_genplist_t *)H5I_object(H5P_LST_GROUP_CREATE_ID_g)))
550          HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get default group creation property list")
551     if((new_gcpl_id = H5P_copy_plist(gcpl_plist, TRUE)) < 0)
552         HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to copy the creation property list")
553     if(NULL == (new_plist = (H5P_genplist_t *)H5I_object(new_gcpl_id)))
554         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "can't get property list")
555 
556     /* Retrieve any object creation properties */
557     if(H5O_get_create_plist(&grp->oloc, H5AC_ind_dxpl_id, new_plist) < 0)
558         HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't get object creation info")
559 
560     /* Check for the group having a group info message */
561     if((ginfo_exists = H5O_msg_exists(&(grp->oloc), H5O_GINFO_ID, H5AC_ind_dxpl_id)) < 0)
562 	HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header")
563     if(ginfo_exists) {
564         H5O_ginfo_t ginfo;		/* Group info message            */
565 
566         /* Read the group info */
567         if(NULL == H5O_msg_read(&(grp->oloc), H5O_GINFO_ID, &ginfo, H5AC_ind_dxpl_id))
568             HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get group info")
569 
570         /* Set the group info for the property list */
571         if(H5P_set(new_plist, H5G_CRT_GROUP_INFO_NAME, &ginfo) < 0)
572             HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set group info")
573     } /* end if */
574 
575     /* Check for the group having a link info message */
576     if((linfo_exists = H5G__obj_get_linfo(&(grp->oloc), &linfo, H5AC_ind_dxpl_id)) < 0)
577 	HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to read object header")
578     if(linfo_exists) {
579         /* Set the link info for the property list */
580         if(H5P_set(new_plist, H5G_CRT_LINK_INFO_NAME, &linfo) < 0)
581             HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set link info")
582     } /* end if */
583 
584     /* Check for the group having a pipeline message */
585     if((pline_exists = H5O_msg_exists(&(grp->oloc), H5O_PLINE_ID, H5AC_ind_dxpl_id)) < 0)
586         HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to read object header")
587     if(pline_exists) {
588         H5O_pline_t pline;      /* Pipeline message */
589 
590         /* Read the pipeline */
591         if(NULL == H5O_msg_read(&(grp->oloc), H5O_PLINE_ID, &pline, H5AC_ind_dxpl_id))
592             HGOTO_ERROR(H5E_SYM, H5E_BADMESG, FAIL, "can't get link pipeline")
593 
594         /* Set the pipeline for the property list */
595         if(H5P_set(new_plist, H5O_CRT_PIPELINE_NAME, &pline) < 0)
596             HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set link pipeline")
597     } /* end if */
598 
599     /* Set the return value */
600     ret_value = new_gcpl_id;
601 
602 done:
603     if(ret_value < 0) {
604         if(new_gcpl_id > 0)
605             if(H5I_dec_app_ref(new_gcpl_id) < 0)
606                 HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "can't free")
607     } /* end if */
608 
609     FUNC_LEAVE_NOAPI(ret_value)
610 } /* end H5G_get_create_plist() */
611 
612 
613 /*-------------------------------------------------------------------------
614  * Function:	H5Gget_info
615  *
616  * Purpose:	Retrieve information about a group.
617  *
618  * Return:	Success:	Non-negative
619  *		Failure:	Negative
620  *
621  * Programmer:	Quincey Koziol
622  *		November 27 2006
623  *
624  *-------------------------------------------------------------------------
625  */
626 herr_t
H5Gget_info(hid_t grp_id,H5G_info_t * grp_info)627 H5Gget_info(hid_t grp_id, H5G_info_t *grp_info)
628 {
629     H5I_type_t  id_type;                /* Type of ID */
630     H5G_loc_t	loc;                    /* Location of group */
631     herr_t      ret_value = SUCCEED;    /* Return value */
632 
633     FUNC_ENTER_API(FAIL)
634     H5TRACE2("e", "i*x", grp_id, grp_info);
635 
636     /* Check args */
637     id_type = H5I_get_type(grp_id);
638     if(!(H5I_GROUP == id_type || H5I_FILE == id_type))
639         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument")
640     if(!grp_info)
641         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct")
642 
643     /* Get group location */
644     if(H5G_loc(grp_id, &loc) < 0)
645         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
646 
647     /* Retrieve the group's information */
648     if(H5G__obj_info(loc.oloc, grp_info/*out*/, H5AC_ind_dxpl_id) < 0)
649         HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info")
650 
651 done:
652     FUNC_LEAVE_API(ret_value)
653 } /* end H5Gget_info() */
654 
655 
656 /*-------------------------------------------------------------------------
657  * Function:	H5Gget_info_by_name
658  *
659  * Purpose:	Retrieve information about a group.
660  *
661  * Return:	Success:	Non-negative
662  *		Failure:	Negative
663  *
664  * Programmer:	Quincey Koziol
665  *		November 27 2006
666  *
667  *-------------------------------------------------------------------------
668  */
669 herr_t
H5Gget_info_by_name(hid_t loc_id,const char * name,H5G_info_t * grp_info,hid_t lapl_id)670 H5Gget_info_by_name(hid_t loc_id, const char *name, H5G_info_t *grp_info,
671     hid_t lapl_id)
672 {
673     H5G_loc_t	loc;                    /* Location of group */
674     H5G_loc_t   grp_loc;                /* Location used to open group */
675     H5G_name_t  grp_path;            	/* Opened object group hier. path */
676     H5O_loc_t   grp_oloc;            	/* Opened object object location */
677     hbool_t     loc_found = FALSE;      /* Location at 'name' found */
678     herr_t      ret_value = SUCCEED;    /* Return value */
679 
680     FUNC_ENTER_API(FAIL)
681     H5TRACE4("e", "i*s*xi", loc_id, name, grp_info, lapl_id);
682 
683     /* Check args */
684     if(H5G_loc(loc_id, &loc) < 0)
685         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
686     if(!name || !*name)
687         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
688     if(!grp_info)
689         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct")
690     if(H5P_DEFAULT == lapl_id)
691         lapl_id = H5P_LINK_ACCESS_DEFAULT;
692     else
693         if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
694             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
695 
696     /* Set up opened group location to fill in */
697     grp_loc.oloc = &grp_oloc;
698     grp_loc.path = &grp_path;
699     H5G_loc_reset(&grp_loc);
700 
701     /* Find the group object */
702     if(H5G_loc_find(&loc, name, &grp_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0)
703         HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found")
704     loc_found = TRUE;
705 
706     /* Retrieve the group's information */
707     if(H5G__obj_info(grp_loc.oloc, grp_info/*out*/, H5AC_ind_dxpl_id) < 0)
708         HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info")
709 
710 done:
711     if(loc_found && H5G_loc_free(&grp_loc) < 0)
712         HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location")
713 
714     FUNC_LEAVE_API(ret_value)
715 } /* end H5Gget_info_by_name() */
716 
717 
718 /*-------------------------------------------------------------------------
719  * Function:	H5Gget_info_by_idx
720  *
721  * Purpose:	Retrieve information about a group, according to the order
722  *              of an index.
723  *
724  * Return:	Success:	Non-negative
725  *		Failure:	Negative
726  *
727  * Programmer:	Quincey Koziol
728  *		November 27 2006
729  *
730  *-------------------------------------------------------------------------
731  */
732 herr_t
H5Gget_info_by_idx(hid_t loc_id,const char * group_name,H5_index_t idx_type,H5_iter_order_t order,hsize_t n,H5G_info_t * grp_info,hid_t lapl_id)733 H5Gget_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type,
734     H5_iter_order_t order, hsize_t n, H5G_info_t *grp_info, hid_t lapl_id)
735 {
736     H5G_loc_t	loc;                    /* Location of group */
737     H5G_loc_t   grp_loc;                /* Location used to open group */
738     H5G_name_t  grp_path;            	/* Opened object group hier. path */
739     H5O_loc_t   grp_oloc;            	/* Opened object object location */
740     hbool_t     loc_found = FALSE;      /* Entry at 'name' found */
741     herr_t      ret_value = SUCCEED;    /* Return value */
742 
743     FUNC_ENTER_API(FAIL)
744     H5TRACE7("e", "i*sIiIoh*xi", loc_id, group_name, idx_type, order, n, grp_info,
745              lapl_id);
746 
747     /* Check args */
748     if(H5G_loc(loc_id, &loc) < 0)
749         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
750     if(!group_name || !*group_name)
751 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
752     if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
753 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
754     if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
755 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
756     if(!grp_info)
757         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct")
758     if(H5P_DEFAULT == lapl_id)
759         lapl_id = H5P_LINK_ACCESS_DEFAULT;
760     else
761         if(TRUE != H5P_isa_class(lapl_id, H5P_LINK_ACCESS))
762             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link access property list ID")
763 
764     /* Set up opened group location to fill in */
765     grp_loc.oloc = &grp_oloc;
766     grp_loc.path = &grp_path;
767     H5G_loc_reset(&grp_loc);
768 
769     /* Find the object's location, according to the order in the index */
770     if(H5G_loc_find_by_idx(&loc, group_name, idx_type, order, n, &grp_loc/*out*/, lapl_id, H5AC_ind_dxpl_id) < 0)
771         HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found")
772     loc_found = TRUE;
773 
774     /* Retrieve the group's information */
775     if(H5G__obj_info(grp_loc.oloc, grp_info/*out*/, H5AC_ind_dxpl_id) < 0)
776         HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info")
777 
778 done:
779     /* Release the object location */
780     if(loc_found && H5G_loc_free(&grp_loc) < 0)
781         HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location")
782 
783     FUNC_LEAVE_API(ret_value)
784 } /* end H5Gget_info_by_idx() */
785 
786 
787 /*-------------------------------------------------------------------------
788  * Function:	H5Gclose
789  *
790  * Purpose:	Closes the specified group.  The group ID will no longer be
791  *		valid for accessing the group.
792  *
793  * Return:	Non-negative on success/Negative on failure
794  *
795  * Programmer:	Robb Matzke
796  *		Wednesday, December 31, 1997
797  *
798  *-------------------------------------------------------------------------
799  */
800 herr_t
H5Gclose(hid_t group_id)801 H5Gclose(hid_t group_id)
802 {
803     herr_t ret_value = SUCCEED;         /* Return value */
804 
805     FUNC_ENTER_API(FAIL)
806     H5TRACE1("e", "i", group_id);
807 
808     /* Check args */
809     if(NULL == H5I_object_verify(group_id,H5I_GROUP))
810 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
811 
812     /*
813      * Decrement the counter on the group atom.	 It will be freed if the count
814      * reaches zero.
815      */
816     if(H5I_dec_app_ref(group_id) < 0)
817     	HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group")
818 
819 done:
820     FUNC_LEAVE_API(ret_value)
821 } /* end H5Gclose() */
822 
823