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 #include "H5Gmodule.h"          /* This source code file is part of the H5G module */
81 
82 
83 /***********/
84 /* Headers */
85 /***********/
86 #include "H5private.h"		/* Generic Functions			*/
87 #include "H5ACprivate.h"	/* Metadata cache			*/
88 #include "H5Eprivate.h"		/* Error handling		  	*/
89 #include "H5Gpkg.h"		/* Groups		  		*/
90 #include "H5Iprivate.h"		/* IDs			  		*/
91 #include "H5Pprivate.h"         /* Property lists                       */
92 
93 
94 /****************/
95 /* Local Macros */
96 /****************/
97 
98 
99 /******************/
100 /* Local Typedefs */
101 /******************/
102 
103 
104 /********************/
105 /* Package Typedefs */
106 /********************/
107 
108 
109 /********************/
110 /* Local Prototypes */
111 /********************/
112 
113 
114 /*********************/
115 /* Package Variables */
116 /*********************/
117 
118 /* Package initialization variable */
119 hbool_t H5_PKG_INIT_VAR = FALSE;
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     0,				/* 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 /* Flag indicating "top" of interface has been initialized */
140 static hbool_t H5G_top_package_initialize_s = FALSE;
141 
142 
143 
144 /*-------------------------------------------------------------------------
145  * Function:	H5G__init_package
146  *
147  * Purpose:	Initializes the H5G interface.
148  *
149  * Return:	Non-negative on success/Negative on failure
150  *
151  * Programmer:	Robb Matzke
152  *		Monday, January	 5, 1998
153  *
154  * Notes:       The group creation properties are registered in the property
155  *              list interface initialization routine (H5P_init_package)
156  *              so that the file creation property class can inherit from it
157  *              correctly. (Which allows the file creation property list to
158  *              control the group creation properties of the root group of
159  *              a file) QAK - 24/10/2005
160  *
161  *-------------------------------------------------------------------------
162  */
163 herr_t
H5G__init_package(void)164 H5G__init_package(void)
165 {
166     herr_t          ret_value = SUCCEED;  /* Return value */
167 
168     FUNC_ENTER_PACKAGE
169 
170     /* Initialize the atom group for the group IDs */
171     if(H5I_register_type(H5I_GROUP_CLS) < 0)
172 	HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to initialize interface")
173 
174     /* Mark "top" of interface as initialized, too */
175     H5G_top_package_initialize_s = TRUE;
176 
177 done:
178     FUNC_LEAVE_NOAPI(ret_value)
179 } /* end H5G__init_package() */
180 
181 
182 /*-------------------------------------------------------------------------
183  * Function:	H5G_top_term_package
184  *
185  * Purpose:	Close the "top" of the interface, releasing IDs, etc.
186  *
187  * Return:	Success:	Positive if anything is done that might
188  *				affect other interfaces; zero otherwise.
189  * 		Failure:	Negative.
190  *
191  * Programmer:	Quincey Koziol
192  *		Sunday, September	13, 2015
193  *
194  *-------------------------------------------------------------------------
195  */
196 int
H5G_top_term_package(void)197 H5G_top_term_package(void)
198 {
199     int	n = 0;
200 
201     FUNC_ENTER_NOAPI_NOINIT_NOERR
202 
203     if(H5G_top_package_initialize_s) {
204         if(H5I_nmembers(H5I_GROUP) > 0) {
205             (void)H5I_clear_type(H5I_GROUP, FALSE, FALSE);
206             n++; /*H5I*/
207         } /* end if */
208 
209         /* Mark closed */
210         if(0 == n)
211             H5G_top_package_initialize_s = FALSE;
212     } /* end if */
213 
214     FUNC_LEAVE_NOAPI(n)
215 } /* end H5G_top_term_package() */
216 
217 
218 /*-------------------------------------------------------------------------
219  * Function:	H5G_term_package
220  *
221  * Purpose:	Terminates the H5G interface
222  *
223  * Note:	Finishes shutting down the interface, after
224  *		H5G_top_term_package() is called
225  *
226  * Return:	Success:	Positive if anything is done that might
227  *				affect other interfaces; zero otherwise.
228  * 		Failure:	Negative.
229  *
230  * Programmer:	Robb Matzke
231  *		Monday, January	 5, 1998
232  *
233  *-------------------------------------------------------------------------
234  */
235 int
H5G_term_package(void)236 H5G_term_package(void)
237 {
238     int	n = 0;
239 
240     FUNC_ENTER_NOAPI_NOINIT_NOERR
241 
242     if(H5_PKG_INIT_VAR) {
243         /* Sanity checks */
244         HDassert(0 == H5I_nmembers(H5I_GROUP));
245         HDassert(FALSE == H5G_top_package_initialize_s);
246 
247         /* Destroy the group object id group */
248         n += (H5I_dec_type_ref(H5I_GROUP) > 0);
249 
250         /* Mark closed */
251         if(0 == n)
252             H5_PKG_INIT_VAR = FALSE;
253     } /* end if */
254 
255     FUNC_LEAVE_NOAPI(n)
256 } /* end H5G_term_package() */
257 
258 
259 /*-------------------------------------------------------------------------
260  * Function:	H5Gcreate2
261  *
262  * Purpose:	Creates a new group relative to LOC_ID, giving it the
263  *              specified creation property list GCPL_ID and access
264  *              property list GAPL_ID.  The link to the new group is
265  *              created with the LCPL_ID.
266  *
267  * Usage:       H5Gcreate2(loc_id, char *name, lcpl_id, gcpl_id, gapl_id)
268  *                  hid_t loc_id;	  IN: File or group identifier
269  *                  const char *name; IN: Absolute or relative name of the new group
270  *                  hid_t lcpl_id;	  IN: Property list for link creation
271  *                  hid_t gcpl_id;	  IN: Property list for group creation
272  *                  hid_t gapl_id;	  IN: Property list for group access
273  *
274  * Return:	Success:	The object ID of a new, empty group open for
275  *				writing.  Call H5Gclose() when finished with
276  *				the group.
277  *
278  *		Failure:	FAIL
279  *
280  * Programmer:  Quincey Koziol
281  *	        April 5, 2007
282  *
283  *-------------------------------------------------------------------------
284  */
285 hid_t
H5Gcreate2(hid_t loc_id,const char * name,hid_t lcpl_id,hid_t gcpl_id,hid_t gapl_id)286 H5Gcreate2(hid_t loc_id, const char *name, hid_t lcpl_id, hid_t gcpl_id,
287     hid_t gapl_id)
288 {
289     H5G_loc_t	    loc;                /* Location to create group */
290     H5G_t	   *grp = NULL;         /* New group created */
291     hid_t           dxpl_id = H5AC_ind_read_dxpl_id; /* dxpl used by library */
292     hid_t	    ret_value;          /* Return value */
293 
294     FUNC_ENTER_API(FAIL)
295     H5TRACE5("i", "i*siii", loc_id, name, lcpl_id, gcpl_id, gapl_id);
296 
297     /* Check arguments */
298     if(H5G_loc(loc_id, &loc) < 0)
299 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
300     if(!name || !*name)
301 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
302 
303     /* Get correct property list */
304     if(H5P_DEFAULT == lcpl_id)
305         lcpl_id = H5P_LINK_CREATE_DEFAULT;
306     else
307         if(TRUE != H5P_isa_class(lcpl_id, H5P_LINK_CREATE))
308             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not link creation property list")
309 
310     /* Check group creation property list */
311     if(H5P_DEFAULT == gcpl_id)
312         gcpl_id = H5P_GROUP_CREATE_DEFAULT;
313     else
314         if(TRUE != H5P_isa_class(gcpl_id, H5P_GROUP_CREATE))
315             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group create property list")
316 
317     /* Verify access property list and get correct dxpl */
318     if(H5P_verify_apl_and_dxpl(&gapl_id, H5P_CLS_GACC, &dxpl_id, loc_id, TRUE) < 0)
319         HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set access and transfer property lists")
320 
321     /* Create the new group & get its ID */
322     if(NULL == (grp = H5G__create_named(&loc, name, lcpl_id, gcpl_id, gapl_id, dxpl_id)))
323         HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group")
324     if((ret_value = H5I_register(H5I_GROUP, grp, TRUE)) < 0)
325 	HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
326 
327 done:
328     if(ret_value < 0)
329         if(grp && H5G_close(grp) < 0)
330             HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group")
331 
332     FUNC_LEAVE_API(ret_value)
333 } /* end H5Gcreate2() */
334 
335 
336 /*-------------------------------------------------------------------------
337  * Function:	H5Gcreate_anon
338  *
339  * Purpose:	Creates a new group relative to LOC_ID, giving it the
340  *              specified creation property list GCPL_ID and access
341  *              property list GAPL_ID.
342  *
343  *              The resulting ID should be linked into the file with
344  *              H5Olink or it will be deleted when closed.
345  *
346  *              Given the default setting, H5Gcreate_anon() followed by
347  *              H5Olink() will have the same function as H5Gcreate2().
348  *
349  * Usage:       H5Gcreate_anon(loc_id, char *name, gcpl_id, gapl_id)
350  *                  hid_t loc_id;	  IN: File or group identifier
351  *                  const char *name; IN: Absolute or relative name of the new group
352  *                  hid_t gcpl_id;	  IN: Property list for group creation
353  *                  hid_t gapl_id;	  IN: Property list for group access
354  *
355  * Example:	To create missing groups "A" and "B01" along the given path "/A/B01/grp"
356  *              hid_t create_id = H5Pcreate(H5P_GROUP_CREATE);
357  *              int   status = H5Pset_create_intermediate_group(create_id, TRUE);
358  *              hid_t gid = H5Gcreate_anon(file_id, "/A/B01/grp", create_id, H5P_DEFAULT);
359  *
360  * Return:	Success:	The object ID of a new, empty group open for
361  *				writing.  Call H5Gclose() when finished with
362  *				the group.
363  *
364  *		Failure:	FAIL
365  *
366  * Programmer:  Peter Cao
367  *	        May 08, 2005
368  *
369  *-------------------------------------------------------------------------
370  */
371 hid_t
H5Gcreate_anon(hid_t loc_id,hid_t gcpl_id,hid_t gapl_id)372 H5Gcreate_anon(hid_t loc_id, hid_t gcpl_id, hid_t gapl_id)
373 {
374     H5G_loc_t	    loc;
375     H5G_t	   *grp = NULL;
376     H5G_obj_create_t gcrt_info;         /* Information for group creation */
377     hid_t           dxpl_id = H5AC_ind_read_dxpl_id; /* dxpl used by library */
378     hid_t	    ret_value;
379 
380     FUNC_ENTER_API(FAIL)
381     H5TRACE3("i", "iii", loc_id, gcpl_id, gapl_id);
382 
383     /* Check arguments */
384     if(H5G_loc(loc_id, &loc) < 0)
385 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
386 
387     /* Check group creation property list */
388     if(H5P_DEFAULT == gcpl_id)
389         gcpl_id = H5P_GROUP_CREATE_DEFAULT;
390     else
391         if(TRUE != H5P_isa_class(gcpl_id, H5P_GROUP_CREATE))
392             HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not group create property list")
393 
394     /* Verify access property list and get correct dxpl */
395     if(H5P_verify_apl_and_dxpl(&gapl_id, H5P_CLS_GACC, &dxpl_id, loc_id, TRUE) < 0)
396         HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set access and transfer property lists")
397 
398     /* Set up group creation info */
399     gcrt_info.gcpl_id = gcpl_id;
400     gcrt_info.cache_type = H5G_NOTHING_CACHED;
401     HDmemset(&gcrt_info.cache, 0, sizeof(gcrt_info.cache));
402 
403     /* Create the new group & get its ID */
404     if(NULL == (grp = H5G__create(loc.oloc->file, &gcrt_info, dxpl_id)))
405         HGOTO_ERROR(H5E_SYM, H5E_CANTINIT, FAIL, "unable to create group")
406     if((ret_value = H5I_register(H5I_GROUP, grp, TRUE)) < 0)
407 	HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
408 
409 done:
410     /* Release the group's object header, if it was created */
411     if(grp) {
412         H5O_loc_t *oloc;         /* Object location for group */
413 
414         /* Get the new group's object location */
415         if(NULL == (oloc = H5G_oloc(grp)))
416             HDONE_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "unable to get object location of group")
417 
418         /* Decrement refcount on group's object header in memory */
419         if(H5O_dec_rc_by_loc(oloc, dxpl_id) < 0)
420            HDONE_ERROR(H5E_SYM, H5E_CANTDEC, FAIL, "unable to decrement refcount on newly created object")
421     } /* end if */
422 
423     /* Cleanup on failure */
424     if(ret_value < 0)
425         if(grp && H5G_close(grp) < 0)
426             HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group")
427 
428     FUNC_LEAVE_API(ret_value)
429 } /* end H5Gcreate_anon() */
430 
431 
432 /*-------------------------------------------------------------------------
433  * Function:	H5Gopen2
434  *
435  * Purpose:	Opens an existing group for modification.  When finished,
436  *		call H5Gclose() to close it and release resources.
437  *
438  *              This function allows the user the pass in a Group Access
439  *              Property List, which H5Gopen1() does not.
440  *
441  * Return:	Success:	Object ID of the group.
442  *		Failure:	FAIL
443  *
444  * Programmer:	James Laird
445  *		Thursday, July 27, 2006
446  *
447  *-------------------------------------------------------------------------
448  */
449 hid_t
H5Gopen2(hid_t loc_id,const char * name,hid_t gapl_id)450 H5Gopen2(hid_t loc_id, const char *name, hid_t gapl_id)
451 {
452     H5G_t       *grp = NULL;            /* Group opened */
453     H5G_loc_t	loc;                    /* Location of parent for group */
454     hid_t       dxpl_id = H5AC_ind_read_dxpl_id; /* dxpl used by library */
455     hid_t       ret_value;              /* Return value */
456 
457     FUNC_ENTER_API(FAIL)
458     H5TRACE3("i", "i*si", loc_id, name, gapl_id);
459 
460     /* Check args */
461     if(H5G_loc(loc_id, &loc) < 0)
462         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
463     if(!name || !*name)
464         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
465 
466     /* Verify access property list and get correct dxpl */
467     if(H5P_verify_apl_and_dxpl(&gapl_id, H5P_CLS_GACC, &dxpl_id, loc_id, FALSE) < 0)
468         HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set access and transfer property lists")
469 
470     /* Open the group */
471     if((grp = H5G__open_name(&loc, name, gapl_id, dxpl_id)) == NULL)
472         HGOTO_ERROR(H5E_SYM, H5E_CANTOPENOBJ, FAIL, "unable to open group")
473 
474     /* Register an ID for the group */
475     if((ret_value = H5I_register(H5I_GROUP, grp, TRUE)) < 0)
476         HGOTO_ERROR(H5E_ATOM, H5E_CANTREGISTER, FAIL, "unable to register group")
477 
478 done:
479     if(ret_value < 0) {
480         if(grp && H5G_close(grp) < 0)
481             HDONE_ERROR(H5E_SYM, H5E_CLOSEERROR, FAIL, "unable to release group")
482     } /* end if */
483 
484     FUNC_LEAVE_API(ret_value)
485 } /* end H5Gopen2() */
486 
487 
488 /*-------------------------------------------------------------------------
489  * Function:	H5Gget_create_plist
490  *
491  * Purpose:	Returns a copy of the group creation property list.
492  *
493  * Return:	Success:	ID for a copy of the group creation
494  *				property list.  The property list ID should be
495  *				released by calling H5Pclose().
496  *
497  *		Failure:	FAIL
498  *
499  * Programmer:	Quincey Koziol
500  *		Tuesday, October 25, 2005
501  *
502  *-------------------------------------------------------------------------
503  */
504 hid_t
H5Gget_create_plist(hid_t group_id)505 H5Gget_create_plist(hid_t group_id)
506 {
507     H5G_t		*group = NULL;
508     hid_t		ret_value = FAIL;
509 
510     FUNC_ENTER_API(FAIL)
511     H5TRACE1("i", "i", group_id);
512 
513     /* Check args */
514     if(NULL == (group = (H5G_t *)H5I_object_verify(group_id, H5I_GROUP)))
515 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
516 
517     if((ret_value = H5G_get_create_plist(group)) < 0)
518 	HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
519 
520 done:
521     FUNC_LEAVE_API(ret_value)
522 } /* end H5Gget_create_plist() */
523 
524 
525 /*-------------------------------------------------------------------------
526  * Function:	H5Gget_info
527  *
528  * Purpose:	Retrieve information about a group.
529  *
530  * Return:	Success:	Non-negative
531  *		Failure:	Negative
532  *
533  * Programmer:	Quincey Koziol
534  *		November 27 2006
535  *
536  *-------------------------------------------------------------------------
537  */
538 herr_t
H5Gget_info(hid_t grp_id,H5G_info_t * grp_info)539 H5Gget_info(hid_t grp_id, H5G_info_t *grp_info)
540 {
541     H5I_type_t  id_type;                /* Type of ID */
542     H5G_loc_t	loc;                    /* Location of group */
543     herr_t      ret_value = SUCCEED;    /* Return value */
544 
545     FUNC_ENTER_API(FAIL)
546     H5TRACE2("e", "i*x", grp_id, grp_info);
547 
548     /* Check args */
549     id_type = H5I_get_type(grp_id);
550     if(!(H5I_GROUP == id_type || H5I_FILE == id_type))
551         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid argument")
552     if(!grp_info)
553         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct")
554 
555     /* Get group location */
556     if(H5G_loc(grp_id, &loc) < 0)
557         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
558 
559     /* Retrieve the group's information */
560     if(H5G__obj_info(loc.oloc, grp_info/*out*/, H5AC_ind_read_dxpl_id) < 0)
561         HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info")
562 
563 done:
564     FUNC_LEAVE_API(ret_value)
565 } /* end H5Gget_info() */
566 
567 
568 /*-------------------------------------------------------------------------
569  * Function:	H5Gget_info_by_name
570  *
571  * Purpose:	Retrieve information about a group.
572  *
573  * Return:	Success:	Non-negative
574  *		Failure:	Negative
575  *
576  * Programmer:	Quincey Koziol
577  *		November 27 2006
578  *
579  *-------------------------------------------------------------------------
580  */
581 herr_t
H5Gget_info_by_name(hid_t loc_id,const char * name,H5G_info_t * grp_info,hid_t lapl_id)582 H5Gget_info_by_name(hid_t loc_id, const char *name, H5G_info_t *grp_info,
583     hid_t lapl_id)
584 {
585     H5G_loc_t	loc;                    /* Location of group */
586     H5G_loc_t   grp_loc;                /* Location used to open group */
587     H5G_name_t  grp_path;            	/* Opened object group hier. path */
588     H5O_loc_t   grp_oloc;            	/* Opened object object location */
589     hbool_t     loc_found = FALSE;      /* Location at 'name' found */
590     hid_t       dxpl_id = H5AC_ind_read_dxpl_id; /* dxpl used by library */
591     herr_t      ret_value = SUCCEED;    /* Return value */
592 
593     FUNC_ENTER_API(FAIL)
594     H5TRACE4("e", "i*s*xi", loc_id, name, grp_info, lapl_id);
595 
596     /* Check args */
597     if(H5G_loc(loc_id, &loc) < 0)
598         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
599     if(!name || !*name)
600         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name")
601     if(!grp_info)
602         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct")
603 
604     /* Verify access property list and get correct dxpl */
605     if(H5P_verify_apl_and_dxpl(&lapl_id, H5P_CLS_LACC, &dxpl_id, loc_id, FALSE) < 0)
606         HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set access and transfer property lists")
607 
608     /* Set up opened group location to fill in */
609     grp_loc.oloc = &grp_oloc;
610     grp_loc.path = &grp_path;
611     H5G_loc_reset(&grp_loc);
612 
613     /* Find the group object */
614     if(H5G_loc_find(&loc, name, &grp_loc/*out*/, lapl_id, dxpl_id) < 0)
615         HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found")
616     loc_found = TRUE;
617 
618     /* Retrieve the group's information */
619     if(H5G__obj_info(grp_loc.oloc, grp_info/*out*/, dxpl_id) < 0)
620         HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info")
621 
622 done:
623     if(loc_found && H5G_loc_free(&grp_loc) < 0)
624         HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location")
625 
626     FUNC_LEAVE_API(ret_value)
627 } /* end H5Gget_info_by_name() */
628 
629 
630 /*-------------------------------------------------------------------------
631  * Function:	H5Gget_info_by_idx
632  *
633  * Purpose:	Retrieve information about a group, according to the order
634  *              of an index.
635  *
636  * Return:	Success:	Non-negative
637  *		Failure:	Negative
638  *
639  * Programmer:	Quincey Koziol
640  *		November 27 2006
641  *
642  *-------------------------------------------------------------------------
643  */
644 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)645 H5Gget_info_by_idx(hid_t loc_id, const char *group_name, H5_index_t idx_type,
646     H5_iter_order_t order, hsize_t n, H5G_info_t *grp_info, hid_t lapl_id)
647 {
648     H5G_loc_t	loc;                    /* Location of group */
649     H5G_loc_t   grp_loc;                /* Location used to open group */
650     H5G_name_t  grp_path;            	/* Opened object group hier. path */
651     H5O_loc_t   grp_oloc;            	/* Opened object object location */
652     hbool_t     loc_found = FALSE;      /* Entry at 'name' found */
653     hid_t       dxpl_id = H5AC_ind_read_dxpl_id; /* dxpl used by library */
654     herr_t      ret_value = SUCCEED;    /* Return value */
655 
656     FUNC_ENTER_API(FAIL)
657     H5TRACE7("e", "i*sIiIoh*xi", loc_id, group_name, idx_type, order, n, grp_info,
658              lapl_id);
659 
660     /* Check args */
661     if(H5G_loc(loc_id, &loc) < 0)
662         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a location")
663     if(!group_name || !*group_name)
664 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no name specified")
665     if(idx_type <= H5_INDEX_UNKNOWN || idx_type >= H5_INDEX_N)
666 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid index type specified")
667     if(order <= H5_ITER_UNKNOWN || order >= H5_ITER_N)
668 	HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid iteration order specified")
669     if(!grp_info)
670         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "no info struct")
671 
672     /* Verify access property list and get correct dxpl */
673     if(H5P_verify_apl_and_dxpl(&lapl_id, H5P_CLS_LACC, &dxpl_id, loc_id, FALSE) < 0)
674         HGOTO_ERROR(H5E_SYM, H5E_CANTSET, FAIL, "can't set access and transfer property lists")
675 
676     /* Set up opened group location to fill in */
677     grp_loc.oloc = &grp_oloc;
678     grp_loc.path = &grp_path;
679     H5G_loc_reset(&grp_loc);
680 
681     /* Find the object's location, according to the order in the index */
682     if(H5G_loc_find_by_idx(&loc, group_name, idx_type, order, n, &grp_loc/*out*/,
683                            lapl_id, dxpl_id) < 0)
684         HGOTO_ERROR(H5E_SYM, H5E_NOTFOUND, FAIL, "group not found")
685     loc_found = TRUE;
686 
687     /* Retrieve the group's information */
688     if(H5G__obj_info(grp_loc.oloc, grp_info/*out*/, dxpl_id) < 0)
689         HGOTO_ERROR(H5E_SYM, H5E_CANTGET, FAIL, "can't retrieve group info")
690 
691 done:
692     /* Release the object location */
693     if(loc_found && H5G_loc_free(&grp_loc) < 0)
694         HDONE_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "can't free location")
695 
696     FUNC_LEAVE_API(ret_value)
697 } /* end H5Gget_info_by_idx() */
698 
699 
700 /*-------------------------------------------------------------------------
701  * Function:	H5Gclose
702  *
703  * Purpose:	Closes the specified group.  The group ID will no longer be
704  *		valid for accessing the group.
705  *
706  * Return:	Non-negative on success/Negative on failure
707  *
708  * Programmer:	Robb Matzke
709  *		Wednesday, December 31, 1997
710  *
711  *-------------------------------------------------------------------------
712  */
713 herr_t
H5Gclose(hid_t group_id)714 H5Gclose(hid_t group_id)
715 {
716     herr_t  ret_value = SUCCEED;    /* Return value                     */
717 
718     FUNC_ENTER_API(FAIL)
719     H5TRACE1("e", "i", group_id);
720 
721     /* Check args */
722     if(NULL == H5I_object_verify(group_id,H5I_GROUP))
723         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
724 
725     /*
726      * Decrement the counter on the group atom.	 It will be freed if the count
727      * reaches zero.
728      */
729     if(H5I_dec_app_ref(group_id) < 0)
730     	HGOTO_ERROR(H5E_SYM, H5E_CANTRELEASE, FAIL, "unable to close group")
731 
732 done:
733     FUNC_LEAVE_API(ret_value)
734 } /* end H5Gclose() */
735 
736 
737 /*-------------------------------------------------------------------------
738  * Function:    H5Gflush
739  *
740  * Purpose:     Flushes all buffers associated with a group to disk.
741  *
742  * Return:      Non-negative on success, negative on failure
743  *
744  * Programmer:  Mike McGreevy
745  *              May 19, 2010
746  *
747  *-------------------------------------------------------------------------
748  */
749 herr_t
H5Gflush(hid_t group_id)750 H5Gflush(hid_t group_id)
751 {
752     H5G_t *grp;        /* Dataset for this operation */
753     herr_t ret_value = SUCCEED; /* return value */
754 
755     FUNC_ENTER_API(FAIL)
756     H5TRACE1("e", "i", group_id);
757 
758     /* Check args */
759     if(NULL == (grp = (H5G_t *)H5I_object_verify(group_id, H5I_GROUP)))
760         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
761 
762     /* Flush object's metadata to file */
763     if(H5O_flush_common(&grp->oloc, group_id, H5AC_ind_read_dxpl_id) < 0)
764         HGOTO_ERROR(H5E_SYM, H5E_CANTFLUSH, FAIL, "unable to flush group and object flush callback")
765 
766 done:
767     FUNC_LEAVE_API(ret_value)
768 } /* H5Gflush */
769 
770 
771 /*-------------------------------------------------------------------------
772  * Function:    H5Grefresh
773  *
774  * Purpose:     Refreshes all buffers associated with a dataset.
775  *
776  * Return:      Non-negative on success, negative on failure
777  *
778  * Programmer:  Mike McGreevy
779  *              July 21, 2010
780  *
781  *-------------------------------------------------------------------------
782  */
783 herr_t
H5Grefresh(hid_t group_id)784 H5Grefresh(hid_t group_id)
785 {
786     H5G_t * grp = NULL;
787     herr_t ret_value = SUCCEED; /* return value */
788 
789     FUNC_ENTER_API(FAIL)
790     H5TRACE1("e", "i", group_id);
791 
792     /* Check args */
793     if(NULL == (grp = (H5G_t *)H5I_object_verify(group_id, H5I_GROUP)))
794         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a group")
795 
796     /* Call private function to refresh group object */
797     if ((H5O_refresh_metadata(group_id, grp->oloc, H5AC_ind_read_dxpl_id)) < 0)
798         HGOTO_ERROR(H5E_SYM, H5E_CANTLOAD, FAIL, "unable to refresh group")
799 
800 done:
801     FUNC_LEAVE_API(ret_value)
802 } /* H5Grefresh */
803 
804