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