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:		H5Plapl.c
17  *			July 14 2006
18  *			James Laird <jlaird@ncsa.uiuc.edu>
19  *
20  * Purpose:		Link access property list class routines
21  *
22  *-------------------------------------------------------------------------
23  */
24 
25 /****************/
26 /* Module Setup */
27 /****************/
28 
29 #include "H5Pmodule.h"          /* This source code file is part of the H5P module */
30 
31 
32 /***********/
33 /* Headers */
34 /***********/
35 #include "H5private.h"		/* Generic Functions			*/
36 #include "H5Eprivate.h"		/* Error handling		  	*/
37 #include "H5Iprivate.h"		/* IDs			  		*/
38 #include "H5Lprivate.h"		/* Links		  		*/
39 #include "H5MMprivate.h"	/* Memory management			*/
40 #include "H5Ppkg.h"		/* Property lists		  	*/
41 
42 
43 /****************/
44 /* Local Macros */
45 /****************/
46 
47 /* ========  Link access properties ======== */
48 /* Definitions for number of soft links to traverse */
49 #define H5L_ACS_NLINKS_SIZE        sizeof(size_t)
50 #define H5L_ACS_NLINKS_DEF         H5L_NUM_LINKS /*max symlinks to follow per lookup  */
51 #define H5L_ACS_NLINKS_ENC         H5P__encode_size_t
52 #define H5L_ACS_NLINKS_DEC         H5P__decode_size_t
53 
54 
55 /* Definitions for external link prefix */
56 #define H5L_ACS_ELINK_PREFIX_SIZE        sizeof(char *)
57 #define H5L_ACS_ELINK_PREFIX_DEF         NULL /*default is no prefix */
58 #define H5L_ACS_ELINK_PREFIX_SET         H5P__lacc_elink_pref_set
59 #define H5L_ACS_ELINK_PREFIX_GET         H5P__lacc_elink_pref_get
60 #define H5L_ACS_ELINK_PREFIX_ENC         H5P__lacc_elink_pref_enc
61 #define H5L_ACS_ELINK_PREFIX_DEC         H5P__lacc_elink_pref_dec
62 #define H5L_ACS_ELINK_PREFIX_DEL         H5P__lacc_elink_pref_del
63 #define H5L_ACS_ELINK_PREFIX_COPY        H5P__lacc_elink_pref_copy
64 #define H5L_ACS_ELINK_PREFIX_CMP         H5P__lacc_elink_pref_cmp
65 #define H5L_ACS_ELINK_PREFIX_CLOSE       H5P__lacc_elink_pref_close
66 
67 /* Definitions for setting fapl of external link access */
68 #define H5L_ACS_ELINK_FAPL_SIZE        	sizeof(hid_t)
69 #define H5L_ACS_ELINK_FAPL_DEF         	H5P_DEFAULT
70 #define H5L_ACS_ELINK_FAPL_SET		H5P__lacc_elink_fapl_set
71 #define H5L_ACS_ELINK_FAPL_GET		H5P__lacc_elink_fapl_get
72 #define H5L_ACS_ELINK_FAPL_ENC		H5P__lacc_elink_fapl_enc
73 #define H5L_ACS_ELINK_FAPL_DEC         	H5P__lacc_elink_fapl_dec
74 #define H5L_ACS_ELINK_FAPL_DEL		H5P__lacc_elink_fapl_del
75 #define H5L_ACS_ELINK_FAPL_COPY        	H5P__lacc_elink_fapl_copy
76 #define H5L_ACS_ELINK_FAPL_CMP        	H5P__lacc_elink_fapl_cmp
77 #define H5L_ACS_ELINK_FAPL_CLOSE       	H5P__lacc_elink_fapl_close
78 
79 /* Definitions for file access flags for external link traversal */
80 #define H5L_ACS_ELINK_FLAGS_SIZE        sizeof(unsigned)
81 #define H5L_ACS_ELINK_FLAGS_DEF         H5F_ACC_DEFAULT
82 #define H5L_ACS_ELINK_FLAGS_ENC         H5P__encode_unsigned
83 #define H5L_ACS_ELINK_FLAGS_DEC         H5P__decode_unsigned
84 
85 /* Definitions for callback function for external link traversal */
86 #define H5L_ACS_ELINK_CB_SIZE           sizeof(H5L_elink_cb_t)
87 #define H5L_ACS_ELINK_CB_DEF            {NULL,NULL}
88 
89 #ifdef H5_HAVE_PARALLEL
90 /* Definition for reading metadata collectively */
91 #define H5L_ACS_COLL_MD_READ_SIZE   sizeof(H5P_coll_md_read_flag_t)
92 #define H5L_ACS_COLL_MD_READ_DEF    H5P_USER_FALSE
93 #define H5L_ACS_COLL_MD_READ_ENC    H5P__encode_coll_md_read_flag_t
94 #define H5L_ACS_COLL_MD_READ_DEC    H5P__decode_coll_md_read_flag_t
95 #endif /* H5_HAVE_PARALLEL */
96 
97 /******************/
98 /* Local Typedefs */
99 /******************/
100 
101 
102 /********************/
103 /* Package Typedefs */
104 /********************/
105 
106 
107 /********************/
108 /* Local Prototypes */
109 /********************/
110 
111 /* Property class callbacks */
112 static herr_t H5P__lacc_reg_prop(H5P_genclass_t *pclass);
113 
114 /* Property list callbacks */
115 static herr_t H5P__lacc_elink_pref_set(hid_t prop_id, const char* name, size_t size, void* value);
116 static herr_t H5P__lacc_elink_pref_get(hid_t prop_id, const char* name, size_t size, void* value);
117 static herr_t H5P__lacc_elink_pref_enc(const void *value, void **_pp, size_t *size, void *udata);
118 static herr_t H5P__lacc_elink_pref_dec(const void **_pp, void *value);
119 static herr_t H5P__lacc_elink_pref_del(hid_t prop_id, const char* name, size_t size, void* value);
120 static herr_t H5P__lacc_elink_pref_copy(const char* name, size_t size, void* value);
121 static int H5P__lacc_elink_pref_cmp(const void *value1, const void *value2, size_t size);
122 static herr_t H5P__lacc_elink_pref_close(const char* name, size_t size, void* value);
123 static herr_t H5P__lacc_elink_fapl_set(hid_t prop_id, const char* name, size_t size, void* value);
124 static herr_t H5P__lacc_elink_fapl_get(hid_t prop_id, const char* name, size_t size, void* value);
125 static herr_t H5P__lacc_elink_fapl_enc(const void *value, void **_pp, size_t *size, void *udata);
126 static herr_t H5P__lacc_elink_fapl_dec(const void **_pp, void *value);
127 static herr_t H5P__lacc_elink_fapl_del(hid_t prop_id, const char* name, size_t size, void* value);
128 static herr_t H5P__lacc_elink_fapl_copy(const char* name, size_t size, void* value);
129 static int H5P__lacc_elink_fapl_cmp(const void *value1, const void *value2, size_t size);
130 static herr_t H5P__lacc_elink_fapl_close(const char* name, size_t size, void* value);
131 
132 
133 /*********************/
134 /* Package Variables */
135 /*********************/
136 
137 /* Dataset creation property list class library initialization object */
138 const H5P_libclass_t H5P_CLS_LACC[1] = {{
139     "link access",		/* Class name for debugging     */
140     H5P_TYPE_LINK_ACCESS,       /* Class type                   */
141 
142     &H5P_CLS_ROOT_g,		/* Parent class                 */
143     &H5P_CLS_LINK_ACCESS_g,	/* Pointer to class             */
144     &H5P_CLS_LINK_ACCESS_ID_g,	/* Pointer to class ID          */
145     &H5P_LST_LINK_ACCESS_ID_g,	/* Pointer to default property list ID */
146     H5P__lacc_reg_prop,		/* Default property registration routine */
147 
148     NULL,		        /* Class creation callback      */
149     NULL,		        /* Class creation callback info */
150     NULL,			/* Class copy callback          */
151     NULL,		        /* Class copy callback info     */
152     NULL,			/* Class close callback         */
153     NULL 		        /* Class close callback info    */
154 }};
155 
156 
157 /*****************************/
158 /* Library Private Variables */
159 /*****************************/
160 
161 
162 /*******************/
163 /* Local Variables */
164 /*******************/
165 
166 /* Property value defaults */
167 static const size_t H5L_def_nlinks_g = H5L_ACS_NLINKS_DEF; 	   /* Default number of soft links to traverse */
168 static const char *H5L_def_elink_prefix_g = H5L_ACS_ELINK_PREFIX_DEF; /* Default external link prefix string */
169 static const hid_t H5L_def_fapl_id_g = H5L_ACS_ELINK_FAPL_DEF;    /* Default fapl for external link access */
170 static const unsigned H5L_def_elink_flags_g = H5L_ACS_ELINK_FLAGS_DEF; /* Default file access flags for external link traversal */
171 static const H5L_elink_cb_t H5L_def_elink_cb_g = H5L_ACS_ELINK_CB_DEF; /* Default external link traversal callback */
172 #ifdef H5_HAVE_PARALLEL
173 static const H5P_coll_md_read_flag_t H5L_def_coll_md_read_g = H5L_ACS_COLL_MD_READ_DEF;  /* Default setting for the collective metedata read flag */
174 #endif /* H5_HAVE_PARALLEL */
175 
176 
177 /*-------------------------------------------------------------------------
178  * Function:    H5P__lacc_reg_prop
179  *
180  * Purpose:     Register the dataset creation property list class's properties
181  *
182  * Return:      Non-negative on success/Negative on failure
183  *
184  * Programmer:  Quincey Koziol
185  *              October 31, 2006
186  *
187  *-------------------------------------------------------------------------
188  */
189 static herr_t
H5P__lacc_reg_prop(H5P_genclass_t * pclass)190 H5P__lacc_reg_prop(H5P_genclass_t *pclass)
191 {
192     herr_t ret_value = SUCCEED;         	   /* Return value */
193 
194     FUNC_ENTER_STATIC
195 
196     /* Register property for number of links traversed */
197     if(H5P_register_real(pclass, H5L_ACS_NLINKS_NAME, H5L_ACS_NLINKS_SIZE, &H5L_def_nlinks_g,
198             NULL, NULL, NULL, H5L_ACS_NLINKS_ENC, H5L_ACS_NLINKS_DEC,
199             NULL, NULL, NULL, NULL) < 0)
200          HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
201 
202     /* Register property for external link prefix */
203     if(H5P_register_real(pclass, H5L_ACS_ELINK_PREFIX_NAME, H5L_ACS_ELINK_PREFIX_SIZE, &H5L_def_elink_prefix_g,
204             NULL, H5L_ACS_ELINK_PREFIX_SET, H5L_ACS_ELINK_PREFIX_GET, H5L_ACS_ELINK_PREFIX_ENC, H5L_ACS_ELINK_PREFIX_DEC,
205             H5L_ACS_ELINK_PREFIX_DEL, H5L_ACS_ELINK_PREFIX_COPY, H5L_ACS_ELINK_PREFIX_CMP, H5L_ACS_ELINK_PREFIX_CLOSE) < 0)
206          HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
207 
208     /* Register fapl for link access */
209     if(H5P_register_real(pclass, H5L_ACS_ELINK_FAPL_NAME, H5L_ACS_ELINK_FAPL_SIZE, &H5L_def_fapl_id_g,
210              NULL, H5L_ACS_ELINK_FAPL_SET, H5L_ACS_ELINK_FAPL_GET, H5L_ACS_ELINK_FAPL_ENC, H5L_ACS_ELINK_FAPL_DEC,
211              H5L_ACS_ELINK_FAPL_DEL, H5L_ACS_ELINK_FAPL_COPY, H5L_ACS_ELINK_FAPL_CMP, H5L_ACS_ELINK_FAPL_CLOSE) < 0)
212          HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
213 
214     /* Register property for external link file access flags */
215     if(H5P_register_real(pclass, H5L_ACS_ELINK_FLAGS_NAME, H5L_ACS_ELINK_FLAGS_SIZE, &H5L_def_elink_flags_g,
216              NULL, NULL, NULL, H5L_ACS_ELINK_FLAGS_ENC, H5L_ACS_ELINK_FLAGS_DEC,
217              NULL, NULL, NULL, NULL) < 0)
218          HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
219 
220     /* Register property for external link file traversal callback */
221     /* (Note: this property should not have an encode/decode callback -QAK) */
222     if(H5P_register_real(pclass, H5L_ACS_ELINK_CB_NAME, H5L_ACS_ELINK_CB_SIZE, &H5L_def_elink_cb_g,
223              NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL) < 0)
224          HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
225 
226 #ifdef H5_HAVE_PARALLEL
227     /* Register the metadata collective read flag */
228     if(H5P_register_real(pclass, H5_COLL_MD_READ_FLAG_NAME, H5L_ACS_COLL_MD_READ_SIZE, &H5L_def_coll_md_read_g,
229             NULL, NULL, NULL, H5L_ACS_COLL_MD_READ_ENC, H5L_ACS_COLL_MD_READ_DEC,
230             NULL, NULL, NULL, NULL) < 0)
231         HGOTO_ERROR(H5E_PLIST, H5E_CANTINSERT, FAIL, "can't insert property into class")
232 #endif /* H5_HAVE_PARALLEL */
233 
234 done:
235     FUNC_LEAVE_NOAPI(ret_value)
236 } /* end H5P__lacc_reg_prop() */
237 
238 
239 /*-------------------------------------------------------------------------
240  * Function:    H5P__lacc_elink_fapl_set
241  *
242  * Purpose:     Copies an external link FAPL property when it's set for a property list
243  *
244  * Return:      Success:        Non-negative
245  *              Failure:        Negative
246  *
247  * Programmer:  Quincey Koziol
248  *              Wednesday, Sept 2, 2015
249  *
250  *-------------------------------------------------------------------------
251  */
252 static herr_t
H5P__lacc_elink_fapl_set(hid_t H5_ATTR_UNUSED prop_id,const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)253 H5P__lacc_elink_fapl_set(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
254     size_t H5_ATTR_UNUSED size, void *value)
255 {
256     hid_t          l_fapl_id;
257     herr_t         ret_value = SUCCEED;
258 
259     FUNC_ENTER_STATIC
260 
261     /* Sanity check */
262     HDassert(value);
263 
264     /* Get the FAPL ID */
265     l_fapl_id = *(const hid_t *)value;
266 
267     /* Duplicate the FAPL, if it's non-default */
268     if(l_fapl_id != H5P_DEFAULT) {
269         H5P_genplist_t *l_fapl_plist;
270 
271         if(NULL == (l_fapl_plist = (H5P_genplist_t *)H5P_object_verify(l_fapl_id, H5P_FILE_ACCESS)))
272             HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get property list")
273 	if(((*(hid_t *)value) = H5P_copy_plist(l_fapl_plist, FALSE)) < 0)
274 	    HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy file access property list")
275     } /* end if */
276 
277 done:
278     FUNC_LEAVE_NOAPI(ret_value)
279 } /* end H5P__lacc_elink_fapl_set() */
280 
281 
282 /*-------------------------------------------------------------------------
283  * Function:    H5P__lacc_elink_fapl_get
284  *
285  * Purpose:     Copies an external link FAPL property when it's retrieved from a property list
286  *
287  * Return:      Success:        Non-negative
288  *              Failure:        Negative
289  *
290  * Programmer:  Quincey Koziol
291  *              Wednesday, Sept 2, 2015
292  *
293  *-------------------------------------------------------------------------
294  */
295 static herr_t
H5P__lacc_elink_fapl_get(hid_t H5_ATTR_UNUSED prop_id,const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)296 H5P__lacc_elink_fapl_get(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
297     size_t H5_ATTR_UNUSED size, void *value)
298 {
299     hid_t          l_fapl_id;
300     herr_t         ret_value = SUCCEED;
301 
302     FUNC_ENTER_STATIC
303 
304     /* Sanity check */
305     HDassert(value);
306 
307     /* Get the FAPL ID */
308     l_fapl_id = *(const hid_t *)value;
309 
310     /* Duplicate the FAPL, if it's non-default */
311     if(l_fapl_id != H5P_DEFAULT) {
312         H5P_genplist_t *l_fapl_plist;
313 
314         if(NULL == (l_fapl_plist = (H5P_genplist_t *)H5P_object_verify(l_fapl_id, H5P_FILE_ACCESS)))
315             HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get property list")
316 	if(((*(hid_t *)value) = H5P_copy_plist(l_fapl_plist, FALSE)) < 0)
317 	    HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy file access property list")
318     } /* end if */
319 
320 done:
321     FUNC_LEAVE_NOAPI(ret_value)
322 } /* end H5P__lacc_elink_fapl_get() */
323 
324 
325 /*-------------------------------------------------------------------------
326  * Function:       H5P__lacc_elink_fapl_enc
327  *
328  * Purpose:        Callback routine which is called whenever the elink FAPL
329  *                 property in the dataset access property list is
330  *                 encoded.
331  *
332  * Return:	   Success:	Non-negative
333  *		   Failure:	Negative
334  *
335  * Programmer:     Quincey Koziol
336  *                 Wednesday, August 15, 2012
337  *
338  *-------------------------------------------------------------------------
339  */
340 static herr_t
H5P__lacc_elink_fapl_enc(const void * value,void ** _pp,size_t * size,void * _udata)341 H5P__lacc_elink_fapl_enc(const void *value, void **_pp, size_t *size, void *_udata)
342 {
343     const hid_t *elink_fapl = (const hid_t *)value;         /* Property to encode */
344     uint8_t **pp = (uint8_t **)_pp;
345     H5P_enc_cb_info_t *udata = (H5P_enc_cb_info_t *)_udata; /* User data for encode callback */
346     H5P_genplist_t *fapl_plist;         /* Pointer to property list */
347     hbool_t non_default_fapl = FALSE;   /* Whether the FAPL is non-default */
348     size_t fapl_size = 0;               /* FAPL's encoded size */
349     herr_t ret_value = SUCCEED;         /* Return value */
350 
351     FUNC_ENTER_STATIC
352 
353     /* Check for non-default FAPL */
354     if(*elink_fapl != H5P_DEFAULT) {
355         if(NULL == (fapl_plist = (H5P_genplist_t *)H5P_object_verify(*elink_fapl, H5P_FILE_ACCESS)))
356             HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get property list")
357         non_default_fapl = TRUE;
358     } /* end if */
359 
360     if(NULL != *pp) {
361         /* Store whether the FAPL is non-default */
362         *(*pp)++ = (uint8_t)non_default_fapl;
363     } /* end if */
364 
365     /* Encode the property list, if non-default */
366     /* (if *pp == NULL, will only compute the size) */
367     if(non_default_fapl) {
368         if(H5P__encode(fapl_plist, TRUE, NULL, &fapl_size, udata->fapl_id) < 0)
369             HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "can't encode property list")
370 
371         if(*pp) {
372             uint64_t enc_value;
373             unsigned enc_size;
374 
375             /* encode the length of the plist */
376             enc_value = (uint64_t)fapl_size;
377             enc_size = H5VM_limit_enc_size(enc_value);
378             HDassert(enc_size < 256);
379             *(*pp)++ = (uint8_t)enc_size;
380             UINT64ENCODE_VAR(*pp, enc_value, enc_size);
381 
382             /* encode the plist */
383             if(H5P__encode(fapl_plist, TRUE, *pp, &fapl_size, udata->fapl_id) < 0)
384                 HGOTO_ERROR(H5E_PLIST, H5E_CANTENCODE, FAIL, "can't encode property list")
385 
386             *pp += fapl_size;
387         }
388         fapl_size += (1 + H5VM_limit_enc_size((uint64_t)fapl_size));
389     } /* end if */
390 
391     *size += (1 + fapl_size);      /* Non-default flag, plus encoded property list size */
392 
393 done:
394     FUNC_LEAVE_NOAPI(ret_value)
395 } /* end H5P__lacc_elink_fapl_enc() */
396 
397 
398 /*-------------------------------------------------------------------------
399  * Function:       H5P__lacc_elink_fapl_dec
400  *
401  * Purpose:        Callback routine which is called whenever the elink FAPL
402  *                 property in the dataset access property list is
403  *                 decoded.
404  *
405  * Return:	   Success:	Non-negative
406  *		   Failure:	Negative
407  *
408  * Programmer:     Quincey Koziol
409  *                 Wednesday, August 15, 2012
410  *
411  *-------------------------------------------------------------------------
412  */
413 static herr_t
H5P__lacc_elink_fapl_dec(const void ** _pp,void * _value)414 H5P__lacc_elink_fapl_dec(const void **_pp, void *_value)
415 {
416     hid_t *elink_fapl = (hid_t *)_value;        /* The elink FAPL value */
417     const uint8_t **pp = (const uint8_t **)_pp;
418     hbool_t non_default_fapl;           /* Whether the FAPL is non-default */
419     herr_t ret_value = SUCCEED;         /* Return value */
420 
421     FUNC_ENTER_STATIC
422 
423     /* Sanity check */
424     HDassert(pp);
425     HDassert(*pp);
426     HDassert(elink_fapl);
427     HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
428 
429     /* Determine if the FAPL is non-default */
430     non_default_fapl = (hbool_t)*(*pp)++;
431 
432     if(non_default_fapl) {
433         size_t fapl_size = 0;                /* Encoded size of property list */
434         unsigned enc_size;
435         uint64_t enc_value;
436 
437         /* Decode the plist length */
438         enc_size = *(*pp)++;
439         HDassert(enc_size < 256);
440         UINT64DECODE_VAR(*pp, enc_value, enc_size);
441         fapl_size = (size_t)enc_value;
442 
443         /* Decode the property list */
444         if((*elink_fapl = H5P__decode(*pp)) < 0)
445             HGOTO_ERROR(H5E_PLIST, H5E_CANTDECODE, FAIL, "can't decode property")
446 
447         *pp += fapl_size;
448     } /* end if */
449     else
450         *elink_fapl = H5P_DEFAULT;
451 
452 done:
453     FUNC_LEAVE_NOAPI(ret_value)
454 } /* end H5P__lacc_elink_fapl_dec() */
455 
456 
457 /*--------------------------------------------------------------------------
458  * Function:	H5P__lacc_elink_fapl_del
459  *
460  * Purpose:	Close the FAPL for link access
461  *
462  * Return:	Success:	Non-negative
463  * 		Failure:	Negative
464  *
465  * Programmer:	Vailin Choi
466  *		Tuesday, Sept 23, 2008
467  *
468  *--------------------------------------------------------------------------
469  */
470 static herr_t
H5P__lacc_elink_fapl_del(hid_t H5_ATTR_UNUSED prop_id,const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)471 H5P__lacc_elink_fapl_del(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
472 {
473     hid_t          l_fapl_id;
474     herr_t         ret_value = SUCCEED;
475 
476     FUNC_ENTER_STATIC
477 
478     /* Sanity check */
479     HDassert(value);
480 
481     /* Get the FAPL ID */
482     l_fapl_id = (*(const hid_t *)value);
483 
484     /* Close the FAPL */
485     if(l_fapl_id != H5P_DEFAULT && H5I_dec_ref(l_fapl_id) < 0)
486 	HGOTO_ERROR(H5E_PLIST, H5E_CANTRELEASE, FAIL, "unable to close atom for file access property list")
487 
488 done:
489     FUNC_LEAVE_NOAPI(ret_value)
490 } /* end H5P__lacc_elink_fapl_del() */
491 
492 
493 /*--------------------------------------------------------------------------
494  * Function:	H5P__lacc_elink_fapl_copy
495  *
496  * Purpose:	Copy the FAPL for link access
497  *
498  * Return:	Success:	Non-negative
499  * 		Failure:	Negative
500  *
501  * Programmer:	Vailin Choi
502  *		Tuesday, Sept 23, 2008
503  *
504  *--------------------------------------------------------------------------
505  */
506 static herr_t
H5P__lacc_elink_fapl_copy(const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)507 H5P__lacc_elink_fapl_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
508 {
509     hid_t          l_fapl_id;
510     herr_t         ret_value = SUCCEED;
511 
512     FUNC_ENTER_STATIC
513 
514     /* Sanity check */
515     HDassert(value);
516 
517     /* Get the FAPL ID */
518     l_fapl_id = (*(const hid_t *)value);
519 
520     /* Duplicate the FAPL, if it's non-default */
521     if(l_fapl_id != H5P_DEFAULT) {
522         H5P_genplist_t *l_fapl_plist;
523 
524         if(NULL == (l_fapl_plist = (H5P_genplist_t *)H5P_object_verify(l_fapl_id, H5P_FILE_ACCESS)))
525             HGOTO_ERROR(H5E_PLIST, H5E_BADTYPE, FAIL, "can't get property list")
526 	if(((*(hid_t *)value) = H5P_copy_plist(l_fapl_plist, FALSE)) < 0)
527 	    HGOTO_ERROR(H5E_PLIST, H5E_CANTCOPY, FAIL, "unable to copy file access property list")
528     } /* end if */
529 
530 done:
531     FUNC_LEAVE_NOAPI(ret_value)
532 } /* end H5P__lacc_elink_fapl_copy() */
533 
534 
535 /*-------------------------------------------------------------------------
536  * Function:       H5P__lacc_elink_fapl_cmp
537  *
538  * Purpose:        Callback routine which is called whenever the elink FAPL
539  *                 property in the link access property list is
540  *                 compared.
541  *
542  * Return:         zero if VALUE1 and VALUE2 are equal, non zero otherwise.
543  *
544  * Programmer:     Quincey Koziol
545  *                 Wednesday, August 15, 2012
546  *
547  *-------------------------------------------------------------------------
548  */
549 static int
H5P__lacc_elink_fapl_cmp(const void * value1,const void * value2,size_t H5_ATTR_UNUSED size)550 H5P__lacc_elink_fapl_cmp(const void *value1, const void *value2, size_t H5_ATTR_UNUSED size)
551 {
552     const hid_t *fapl1 = (const hid_t *)value1;
553     const hid_t *fapl2 = (const hid_t *)value2;
554     H5P_genplist_t *obj1, *obj2;          /* Property lists to compare */
555     int ret_value = 0;
556 
557     FUNC_ENTER_STATIC_NOERR
558 
559     /* Check for comparison with default value */
560     if(*fapl1 == 0 && *fapl2 > 0) HGOTO_DONE(1);
561     if(*fapl1 > 0 && *fapl2 == 0) HGOTO_DONE(-1);
562 
563     /* Get the property list objects */
564     obj1 = (H5P_genplist_t *)H5I_object(*fapl1);
565     obj2 = (H5P_genplist_t *)H5I_object(*fapl2);
566 
567     /* Check for NULL property lists */
568     if(obj1 == NULL && obj2 != NULL) HGOTO_DONE(1);
569     if(obj1 != NULL && obj2 == NULL) HGOTO_DONE(-1);
570     if(obj1 && obj2) {
571         herr_t status;
572 
573         status = H5P_cmp_plist(obj1, obj2, &ret_value);
574         HDassert(status >= 0);
575     } /* end if */
576 
577 done:
578     FUNC_LEAVE_NOAPI(ret_value)
579 } /* end H5P__lacc_elink_fapl_cmp() */
580 
581 
582 /*--------------------------------------------------------------------------
583  * Function:	H5P__lacc_elink_fapl_close
584  *
585  * Purpose:	Close the FAPL for link access
586  *
587  * Return:	Success:	Non-negative
588  * 		Failure:	Negative
589  *
590  * Programmer:	Vailin Choi
591  *		Tuesday, Sept 23, 2008
592  *
593  *---------------------------------------------------------------------------
594  */
595 static herr_t
H5P__lacc_elink_fapl_close(const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)596 H5P__lacc_elink_fapl_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
597 {
598     hid_t		l_fapl_id;
599     herr_t     		ret_value = SUCCEED;
600 
601     FUNC_ENTER_STATIC
602 
603     /* Sanity check */
604     HDassert(value);
605 
606     /* Get the FAPL ID */
607     l_fapl_id = (*(const hid_t *)value);
608 
609     /* Close the FAPL */
610     if((l_fapl_id > H5P_DEFAULT) && (H5I_dec_ref(l_fapl_id) < 0))
611 	HGOTO_ERROR(H5E_PLIST, H5E_CANTRELEASE, FAIL, "unable to close atom for file access property list")
612 
613 done:
614     FUNC_LEAVE_NOAPI(ret_value)
615 } /* end H5P__lacc_elink_fapl_close() */
616 
617 
618 /*-------------------------------------------------------------------------
619  * Function:    H5P__lacc_elink_pref_set
620  *
621  * Purpose:     Copies an external link prefix property when it's set for a property list
622  *
623  * Return:      Success:        Non-negative
624  *              Failure:        Negative
625  *
626  * Programmer:  Quincey Koziol
627  *              Wednesday, Sept 2, 2015
628  *
629  *-------------------------------------------------------------------------
630  */
631 static herr_t
H5P__lacc_elink_pref_set(hid_t H5_ATTR_UNUSED prop_id,const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)632 H5P__lacc_elink_pref_set(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
633     size_t H5_ATTR_UNUSED size, void *value)
634 {
635     FUNC_ENTER_STATIC_NOERR
636 
637     /* Sanity check */
638     HDassert(value);
639 
640     /* Copy the prefix */
641     *(char **)value = H5MM_xstrdup(*(const char **)value);
642 
643     FUNC_LEAVE_NOAPI(SUCCEED)
644 } /* end H5P__lacc_elink_pref_set() */
645 
646 
647 /*-------------------------------------------------------------------------
648  * Function:    H5P__lacc_elink_pref_get
649  *
650  * Purpose:     Copies an external link prefix property when it's retrieved from a property list
651  *
652  * Return:      Success:        Non-negative
653  *              Failure:        Negative
654  *
655  * Programmer:  Quincey Koziol
656  *              Wednesday, Sept 2, 2015
657  *
658  *-------------------------------------------------------------------------
659  */
660 static herr_t
H5P__lacc_elink_pref_get(hid_t H5_ATTR_UNUSED prop_id,const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)661 H5P__lacc_elink_pref_get(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
662     size_t H5_ATTR_UNUSED size, void *value)
663 {
664     FUNC_ENTER_STATIC_NOERR
665 
666     /* Sanity check */
667     HDassert(value);
668 
669     /* Copy the prefix */
670     *(char **)value = H5MM_xstrdup(*(const char **)value);
671 
672     FUNC_LEAVE_NOAPI(SUCCEED)
673 } /* end H5P__lacc_elink_pref_get() */
674 
675 
676 /*-------------------------------------------------------------------------
677  * Function:       H5P__lacc_elink_pref_enc
678  *
679  * Purpose:        Callback routine which is called whenever the elink flags
680  *                 property in the dataset access property list is
681  *                 encoded.
682  *
683  * Return:	   Success:	Non-negative
684  *		   Failure:	Negative
685  *
686  * Programmer:     Mohamad Chaarawi
687  *                 Monday, October 10, 2011
688  *
689  *-------------------------------------------------------------------------
690  */
691 static herr_t
H5P__lacc_elink_pref_enc(const void * value,void ** _pp,size_t * size,void H5_ATTR_UNUSED * udata)692 H5P__lacc_elink_pref_enc(const void *value, void **_pp, size_t *size, void H5_ATTR_UNUSED *udata)
693 {
694     const char *elink_pref = *(const char * const *)value;
695     uint8_t **pp = (uint8_t **)_pp;
696     size_t len = 0;
697     uint64_t enc_value;
698     unsigned enc_size;
699 
700     FUNC_ENTER_STATIC_NOERR
701 
702     HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
703 
704     /* calculate prefix length */
705     if(NULL != elink_pref)
706         len = HDstrlen(elink_pref);
707 
708     enc_value = (uint64_t)len;
709     enc_size = H5VM_limit_enc_size(enc_value);
710     HDassert(enc_size < 256);
711 
712     if(NULL != *pp) {
713         /* encode the length of the prefix */
714         *(*pp)++ = (uint8_t)enc_size;
715         UINT64ENCODE_VAR(*pp, enc_value, enc_size);
716 
717         /* encode the prefix */
718         if(NULL != elink_pref) {
719             HDmemcpy(*(char **)pp, elink_pref, len);
720             *pp += len;
721         } /* end if */
722     } /* end if */
723 
724     *size += (1 + enc_size);
725     if(NULL != elink_pref)
726         *size += len;
727 
728     FUNC_LEAVE_NOAPI(SUCCEED)
729 } /* end H5P__lacc_elink_pref_enc() */
730 
731 
732 /*-------------------------------------------------------------------------
733  * Function:       H5P__lacc_elink_pref_dec
734  *
735  * Purpose:        Callback routine which is called whenever the elink prefix
736  *                 property in the dataset access property list is
737  *                 decoded.
738  *
739  * Return:	   Success:	Non-negative
740  *		   Failure:	Negative
741  *
742  * Programmer:     Mohamad Chaarawi
743  *                 Monday, October 10, 2011
744  *
745  *-------------------------------------------------------------------------
746  */
747 static herr_t
H5P__lacc_elink_pref_dec(const void ** _pp,void * _value)748 H5P__lacc_elink_pref_dec(const void **_pp, void *_value)
749 {
750     char **elink_pref = (char **)_value;
751     const uint8_t **pp = (const uint8_t **)_pp;
752     size_t len;
753     uint64_t enc_value;                 /* Decoded property value */
754     unsigned enc_size;                  /* Size of encoded property */
755     herr_t ret_value = SUCCEED;
756 
757     FUNC_ENTER_STATIC
758 
759     HDassert(pp);
760     HDassert(*pp);
761     HDassert(elink_pref);
762     HDcompile_assert(sizeof(size_t) <= sizeof(uint64_t));
763 
764     /* Decode the size */
765     enc_size = *(*pp)++;
766     HDassert(enc_size < 256);
767 
768     /* Decode the value */
769     UINT64DECODE_VAR(*pp, enc_value, enc_size);
770     len = (size_t)enc_value;
771 
772     if(0 != len) {
773         /* Make a copy of the user's prefix string */
774         if(NULL == (*elink_pref = (char *)H5MM_malloc(len + 1)))
775             HGOTO_ERROR(H5E_RESOURCE, H5E_CANTINIT, FAIL, "memory allocation failed for prefix")
776         HDstrncpy(*elink_pref, *(const char **)pp, len);
777         (*elink_pref)[len] = '\0';
778 
779         *pp += len;
780     } /* end if */
781     else
782         *elink_pref = NULL;
783 
784 done:
785     FUNC_LEAVE_NOAPI(ret_value)
786 } /* end H5P__lacc_elink_pref_dec() */
787 
788 
789 /*-------------------------------------------------------------------------
790  * Function:    H5P__lacc_elink_pref_del
791  *
792  * Purpose:     Frees memory used to store the external link prefix string
793  *
794  * Return:      Non-negative on success/Negative on failure
795  *
796  * Programmer:  Quincey Koziol
797  *              November 2, 2006
798  *
799  *-------------------------------------------------------------------------
800  */
801 static herr_t
H5P__lacc_elink_pref_del(hid_t H5_ATTR_UNUSED prop_id,const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)802 H5P__lacc_elink_pref_del(hid_t H5_ATTR_UNUSED prop_id, const char H5_ATTR_UNUSED *name,
803     size_t H5_ATTR_UNUSED size, void *value)
804 {
805     FUNC_ENTER_STATIC_NOERR
806 
807     HDassert(value);
808 
809     H5MM_xfree(*(void **)value);
810 
811     FUNC_LEAVE_NOAPI(SUCCEED)
812 } /* end H5P__lacc_elink_pref_del() */
813 
814 
815 /*-------------------------------------------------------------------------
816  * Function:    H5P__lacc_elink_pref_copy
817  *
818  * Purpose:     Creates a copy of the external link prefix string
819  *
820  * Return:      Non-negative on success/Negative on failure
821  *
822  * Programmer:  Quincey Koziol
823  *              November 2, 2006
824  *
825  *-------------------------------------------------------------------------
826  */
827 static herr_t
H5P__lacc_elink_pref_copy(const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)828 H5P__lacc_elink_pref_copy(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
829 {
830     FUNC_ENTER_STATIC_NOERR
831 
832     HDassert(value);
833 
834     *(char **)value = H5MM_xstrdup(*(const char **)value);
835 
836     FUNC_LEAVE_NOAPI(SUCCEED)
837 } /* end H5P__lacc_elink_pref_copy() */
838 
839 
840 /*-------------------------------------------------------------------------
841  * Function:       H5P__lacc_elink_pref_cmp
842  *
843  * Purpose:        Callback routine which is called whenever the elink prefix
844  *                 property in the dataset creation property list is
845  *                 compared.
846  *
847  * Return:         zero if VALUE1 and VALUE2 are equal, non zero otherwise.
848  *
849  * Programmer:     Mohamad Chaarawi
850  *                 Thursday, November 3, 2011
851  *
852  *-------------------------------------------------------------------------
853  */
854 static int
H5P__lacc_elink_pref_cmp(const void * value1,const void * value2,size_t H5_ATTR_UNUSED size)855 H5P__lacc_elink_pref_cmp(const void *value1, const void *value2, size_t H5_ATTR_UNUSED size)
856 {
857     const char *pref1 = *(const char * const *)value1;
858     const char *pref2 = *(const char * const *)value2;
859     int ret_value = 0;
860 
861     FUNC_ENTER_STATIC_NOERR
862 
863     if(NULL == pref1 && NULL != pref2)
864         HGOTO_DONE(1);
865     if(NULL != pref1 && NULL == pref2)
866         HGOTO_DONE(-1);
867     if(NULL != pref1 && NULL != pref2)
868         ret_value = HDstrcmp(pref1, pref2);
869 
870 done:
871     FUNC_LEAVE_NOAPI(ret_value)
872 } /* end H5P__lacc_elink_pref_cmp() */
873 
874 
875 /*-------------------------------------------------------------------------
876  * Function:    H5P__lacc_elink_pref_close
877  *
878  * Purpose:     Frees memory used to store the external link prefix string
879  *
880  * Return:      Non-negative on success/Negative on failure
881  *
882  * Programmer:  Quincey Koziol
883  *              November 2, 2006
884  *
885  *-------------------------------------------------------------------------
886  */
887 static herr_t
H5P__lacc_elink_pref_close(const char H5_ATTR_UNUSED * name,size_t H5_ATTR_UNUSED size,void * value)888 H5P__lacc_elink_pref_close(const char H5_ATTR_UNUSED *name, size_t H5_ATTR_UNUSED size, void *value)
889 {
890     FUNC_ENTER_STATIC_NOERR
891 
892     HDassert(value);
893 
894     H5MM_xfree(*(void **)value);
895 
896     FUNC_LEAVE_NOAPI(SUCCEED)
897 } /* end H5P__lacc_elink_pref_close() */
898 
899 
900 /*-------------------------------------------------------------------------
901  * Function:    H5Pset_nlinks
902  *
903  * Purpose:     Set the number of soft or UD link traversals allowed before
904  *              the library assumes it has found a cycle and aborts the
905  *              traversal.
906  *
907  *              The limit on soft or UD link traversals is designed to
908  *              terminate link traversal if one or more links form a cycle.
909  *              However, users may have a file with a legitimate path
910  *              formed of a large number of soft or user-defined links.
911  *              This property can be used to allow traversal of as many
912  *              links as desired.
913  *
914  * Return:	Non-negative on success/Negative on failure
915  *
916  * Programmer:	James Laird
917  *              Friday, July 14, 2006
918  *
919  *-------------------------------------------------------------------------
920  */
921 herr_t
H5Pset_nlinks(hid_t plist_id,size_t nlinks)922 H5Pset_nlinks(hid_t plist_id, size_t nlinks)
923 {
924     H5P_genplist_t *plist;              /* Property list pointer */
925     herr_t ret_value = SUCCEED;         /* Return value */
926 
927     FUNC_ENTER_API(FAIL)
928     H5TRACE2("e", "iz", plist_id, nlinks);
929 
930     if(nlinks <= 0)
931         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "number of links must be positive");
932 
933     /* Get the plist structure */
934     if(NULL == (plist = H5P_object_verify(plist_id, H5P_LINK_ACCESS)))
935         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
936 
937     /* Set number of links */
938     if(H5P_set(plist, H5L_ACS_NLINKS_NAME, &nlinks) < 0)
939         HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set nlink info")
940 
941 done:
942     FUNC_LEAVE_API(ret_value)
943 } /* end H5Pset_nlinks() */
944 
945 
946 /*-------------------------------------------------------------------------
947  * Function:    H5Pget_nlinks
948  *
949  * Purpose:	Gets the number of soft or user-defined links that can be
950  *              traversed before a failure occurs.
951  *
952  *              Retrieves the current setting for the nlinks property on
953  *              the given property list.
954  *
955  * Return:	Non-negative on success/Negative on failure
956  *
957  * Programmer:	James Laird
958  *              Friday, July 14, 2006
959  *
960  *-------------------------------------------------------------------------
961  */
962 herr_t
H5Pget_nlinks(hid_t plist_id,size_t * nlinks)963 H5Pget_nlinks(hid_t plist_id, size_t *nlinks)
964 {
965     H5P_genplist_t *plist;              /* Property list pointer */
966     herr_t ret_value = SUCCEED;         /* Return value */
967 
968     FUNC_ENTER_API(FAIL)
969     H5TRACE2("e", "i*z", plist_id, nlinks);
970 
971     if(!nlinks)
972         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid pointer passed in");
973 
974     /* Get the plist structure */
975     if(NULL == (plist = H5P_object_verify(plist_id, H5P_LINK_ACCESS)))
976         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
977 
978     /* Get the current number of links */
979     if(H5P_get(plist, H5L_ACS_NLINKS_NAME, nlinks) < 0)
980         HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get number of links")
981 
982 done:
983     FUNC_LEAVE_API(ret_value)
984 }
985 
986 
987 /*-------------------------------------------------------------------------
988  * Function:    H5Pset_elink_prefix
989  *
990  * Purpose:     Set a prefix to be applied to the path of any external links
991  *              traversed.  The prefix is appended to the filename stored
992  *              in the external link.
993  *
994  * Return:	Non-negative on success/Negative on failure
995  *
996  * Programmer:	James Laird
997  *              Thursday, August 3, 2006
998  *
999  *-------------------------------------------------------------------------
1000  */
1001 herr_t
H5Pset_elink_prefix(hid_t plist_id,const char * prefix)1002 H5Pset_elink_prefix(hid_t plist_id, const char *prefix)
1003 {
1004     H5P_genplist_t *plist;              /* Property list pointer */
1005     herr_t ret_value = SUCCEED;         /* Return value */
1006 
1007     FUNC_ENTER_API(FAIL)
1008     H5TRACE2("e", "i*s", plist_id, prefix);
1009 
1010     /* Get the plist structure */
1011     if(NULL == (plist = H5P_object_verify(plist_id, H5P_LINK_ACCESS)))
1012         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
1013 
1014     /* Set prefix */
1015     if(H5P_set(plist, H5L_ACS_ELINK_PREFIX_NAME, &prefix) < 0)
1016         HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set prefix info")
1017 
1018 done:
1019     FUNC_LEAVE_API(ret_value)
1020 } /* end H5Pset_elink_prefix() */
1021 
1022 
1023 /*-------------------------------------------------------------------------
1024  * Function:    H5Pget_elink_prefix
1025  *
1026  * Purpose:	Gets the prefix to be applied to any external link
1027  *              traversals made using this property list.
1028  *
1029  *              If the pointer is not NULL, it points to a user-allocated
1030  *              buffer.
1031  *
1032  * Return:	Non-negative on success/Negative on failure
1033  *
1034  * Programmer:	James Laird
1035  *              Thursday, August 3, 2006
1036  *
1037  *-------------------------------------------------------------------------
1038  */
1039 ssize_t
H5Pget_elink_prefix(hid_t plist_id,char * prefix,size_t size)1040 H5Pget_elink_prefix(hid_t plist_id, char *prefix, size_t size)
1041 {
1042     H5P_genplist_t *plist;              /* Property list pointer */
1043     char *my_prefix;                    /* Library's copy of the prefix */
1044     size_t	len;                    /* Length of prefix string */
1045     ssize_t 	ret_value;              /* Return value */
1046 
1047     FUNC_ENTER_API(FAIL)
1048     H5TRACE3("Zs", "i*sz", plist_id, prefix, size);
1049 
1050     /* Get the plist structure */
1051     if(NULL == (plist = H5P_object_verify(plist_id, H5P_LINK_ACCESS)))
1052         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
1053 
1054     /* Get the current prefix */
1055     if(H5P_peek(plist, H5L_ACS_ELINK_PREFIX_NAME, &my_prefix) < 0)
1056         HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get external link prefix")
1057 
1058     /* Check for prefix being set */
1059     if(my_prefix) {
1060         /* Copy to user's buffer, if given */
1061         len = HDstrlen(my_prefix);
1062         if(prefix) {
1063             HDstrncpy(prefix, my_prefix, MIN(len + 1, size));
1064             if(len >= size)
1065                 prefix[size - 1] = '\0';
1066         } /* end if */
1067     } /* end if */
1068     else
1069         len = 0;
1070 
1071     /* Set return value */
1072     ret_value = (ssize_t)len;
1073 
1074 done:
1075     FUNC_LEAVE_API(ret_value)
1076 } /* end H5Pget_elink_prefix() */
1077 
1078 /*-------------------------------------------------------------------------
1079  * Function:    H5Pset_elink_fapl
1080  *
1081  * Purpose:     Sets the file access property list for link access
1082  *
1083  * Return:	Non-negative on success/Negative on failure
1084  *
1085  * Programmer:
1086  *              Vailin Choi; Tuesday, September 12th, 2008
1087  *
1088  *-------------------------------------------------------------------------
1089  */
1090 herr_t
H5Pset_elink_fapl(hid_t lapl_id,hid_t fapl_id)1091 H5Pset_elink_fapl(hid_t lapl_id, hid_t fapl_id)
1092 {
1093     H5P_genplist_t 	*plist;         /* Property list pointer */
1094     herr_t ret_value = SUCCEED;         /* Return value */
1095 
1096     FUNC_ENTER_API(FAIL)
1097     H5TRACE2("e", "ii", lapl_id, fapl_id);
1098 
1099     /* Check arguments */
1100     if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS)))
1101         HGOTO_ERROR(H5E_ARGS, H5E_BADTYPE, FAIL, "not a link access property list");
1102 
1103     /* Set the file access property list for the link access */
1104     if(H5P_set(plist, H5L_ACS_ELINK_FAPL_NAME, &fapl_id) < 0)
1105         HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set fapl for link")
1106 
1107 done:
1108     FUNC_LEAVE_API(ret_value)
1109 } /* end H5Pset_elink_fapl() */
1110 
1111 
1112 /*-------------------------------------------------------------------------
1113  * Function:    H5Pget_elink_fapl
1114  *
1115  * Purpose:	Gets the file access property list identifier that is
1116  *		set for link access property.
1117  *
1118  * Return:	Non-negative on success/Negative on failure
1119  *
1120  * Programmer:
1121  *              Vailin Choi; Tuesday, September 12th, 2008
1122  *
1123  *-------------------------------------------------------------------------
1124  */
1125 hid_t
H5Pget_elink_fapl(hid_t lapl_id)1126 H5Pget_elink_fapl(hid_t lapl_id)
1127 {
1128     H5P_genplist_t *plist; 	/* Property list pointer */
1129     hid_t ret_value;		/* Return value */
1130 
1131     FUNC_ENTER_API(FAIL)
1132     H5TRACE1("i", "i", lapl_id);
1133 
1134     /* Get the plist structure */
1135     if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS)))
1136         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
1137 
1138     if(H5P_get(plist, H5L_ACS_ELINK_FAPL_NAME, &ret_value) < 0)
1139         HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get fapl for links")
1140 
1141 done:
1142     FUNC_LEAVE_API(ret_value);
1143 } /* end H5Pget_elink_fapl() */
1144 
1145 
1146 /*-------------------------------------------------------------------------
1147  * Function:    H5Pset_elink_acc_flags
1148  *
1149  * Purpose:     Sets the file access flags to be used when traversing an
1150  *              external link.  This should be either H5F_ACC_RDONLY or
1151  *              H5F_ACC_RDWR, or H5F_ACC_DEFAULT to unset the value.
1152  *
1153  * Return:      Non-negative on success/Negative on failure
1154  *
1155  * Programmer:  Neil Fortner
1156  *              Tuesday, December 9, 2008
1157  *
1158  *-------------------------------------------------------------------------
1159  */
1160 herr_t
H5Pset_elink_acc_flags(hid_t lapl_id,unsigned flags)1161 H5Pset_elink_acc_flags(hid_t lapl_id, unsigned flags)
1162 {
1163     H5P_genplist_t *plist;              /* Property list pointer */
1164     herr_t ret_value = SUCCEED;         /* Return value */
1165 
1166     FUNC_ENTER_API(FAIL)
1167     H5TRACE2("e", "iIu", lapl_id, flags);
1168 
1169     /* Check that flags are valid */
1170     if((    flags != H5F_ACC_RDWR)      && (flags != (H5F_ACC_RDWR   | H5F_ACC_SWMR_WRITE))
1171         && (flags != H5F_ACC_RDONLY)    && (flags != (H5F_ACC_RDONLY | H5F_ACC_SWMR_READ))
1172         && (flags != H5F_ACC_DEFAULT))
1173         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "invalid file open flags")
1174 
1175     /* Get the plist structure */
1176     if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS)))
1177         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
1178 
1179     /* Set flags */
1180     if(H5P_set(plist, H5L_ACS_ELINK_FLAGS_NAME, &flags) < 0)
1181         HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set access flags")
1182 
1183 done:
1184     FUNC_LEAVE_API(ret_value)
1185 } /* end H5Pset_elink_acc_flags() */
1186 
1187 
1188 /*-------------------------------------------------------------------------
1189  * Function:    H5Pget_elink_acc_flags
1190  *
1191  * Purpose:     Gets the file access flags to be used when traversing an
1192  *              external link.
1193  *
1194  * Return:      Non-negative on success/Negative on failure
1195  *
1196  * Programmer:  Neil Fortner
1197  *              Tuesday, December 9, 2008
1198  *
1199  *-------------------------------------------------------------------------
1200  */
1201 herr_t
H5Pget_elink_acc_flags(hid_t lapl_id,unsigned * flags)1202 H5Pget_elink_acc_flags(hid_t lapl_id, unsigned *flags)
1203 {
1204     H5P_genplist_t *plist;              /* Property list pointer */
1205     herr_t ret_value = SUCCEED;         /* Return value */
1206 
1207     FUNC_ENTER_API(FAIL)
1208     H5TRACE2("e", "i*Iu", lapl_id, flags);
1209 
1210     /* Get the plist structure */
1211     if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS)))
1212         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
1213 
1214     /* Get flags */
1215     if(flags)
1216         if(H5P_get(plist, H5L_ACS_ELINK_FLAGS_NAME, flags) < 0)
1217             HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, 0, "can't get access flags")
1218 
1219 done:
1220     FUNC_LEAVE_API(ret_value)
1221 } /* end H5Pget_elink_acc_flags() */
1222 
1223 
1224 /*-------------------------------------------------------------------------
1225  * Function:    H5Pset_elink_cb
1226  *
1227  * Purpose:     Sets the file access flags to be used when traversing an
1228  *              external link.  This should be either H5F_ACC_RDONLY or
1229  *              H5F_ACC_RDWR.
1230  *
1231  * Return:      Non-negative on success/Negative on failure
1232  *
1233  * Programmer:  Neil Fortner
1234  *              Tuesday, December 15, 2008
1235  *
1236  *-------------------------------------------------------------------------
1237  */
1238 herr_t
H5Pset_elink_cb(hid_t lapl_id,H5L_elink_traverse_t func,void * op_data)1239 H5Pset_elink_cb(hid_t lapl_id, H5L_elink_traverse_t func, void *op_data)
1240 {
1241     H5P_genplist_t  *plist;                 /* Property list pointer */
1242     H5L_elink_cb_t  cb_info;                /* Callback info struct */
1243     herr_t          ret_value = SUCCEED;    /* Return value */
1244 
1245     FUNC_ENTER_API(FAIL)
1246     H5TRACE3("e", "ix*x", lapl_id, func, op_data);
1247 
1248     /* Check if the callback function is NULL and the user data is non-NULL.
1249      * This is almost certainly an error as the user data will not be used. */
1250     if(!func && op_data)
1251         HGOTO_ERROR(H5E_ARGS, H5E_BADVALUE, FAIL, "callback is NULL while user data is not")
1252 
1253     /* Get the plist structure */
1254     if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS)))
1255         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
1256 
1257     /* Populate the callback info struct */
1258     cb_info.func = func;
1259     cb_info.user_data = op_data;
1260 
1261     /* Set callback info */
1262     if(H5P_set(plist, H5L_ACS_ELINK_CB_NAME, &cb_info) < 0)
1263         HGOTO_ERROR(H5E_PLIST, H5E_CANTSET, FAIL, "can't set callback info")
1264 
1265 done:
1266     FUNC_LEAVE_API(ret_value)
1267 } /* end H5Pset_elink_acc_flags() */
1268 
1269 
1270 /*-------------------------------------------------------------------------
1271  * Function:    H5Pget_elink_cb
1272  *
1273  * Purpose:     Gets the file access flags to be used when traversing an
1274  *              external link.
1275  *
1276  * Return:      Non-negative on success/Negative on failure
1277  *
1278  * Programmer:  Neil Fortner
1279  *              Tuesday, December 15, 2008
1280  *
1281  *-------------------------------------------------------------------------
1282  */
1283 herr_t
H5Pget_elink_cb(hid_t lapl_id,H5L_elink_traverse_t * func,void ** op_data)1284 H5Pget_elink_cb(hid_t lapl_id, H5L_elink_traverse_t *func, void **op_data)
1285 {
1286     H5P_genplist_t  *plist;                 /* Property list pointer */
1287     H5L_elink_cb_t  cb_info;                /* Callback info struct */
1288     herr_t          ret_value = SUCCEED;    /* Return value */
1289 
1290     FUNC_ENTER_API(FAIL)
1291     H5TRACE3("e", "i*x**x", lapl_id, func, op_data);
1292 
1293     /* Get the plist structure */
1294     if(NULL == (plist = H5P_object_verify(lapl_id, H5P_LINK_ACCESS)))
1295         HGOTO_ERROR(H5E_ATOM, H5E_BADATOM, FAIL, "can't find object for ID")
1296 
1297     /* Get callback_info */
1298     if(H5P_get(plist, H5L_ACS_ELINK_CB_NAME, &cb_info) < 0)
1299         HGOTO_ERROR(H5E_PLIST, H5E_CANTGET, FAIL, "can't get callback info")
1300 
1301     if(func)
1302         *func = cb_info.func;
1303     if(op_data)
1304         *op_data = cb_info.user_data;
1305 
1306 done:
1307     FUNC_LEAVE_API(ret_value)
1308 } /* end H5Pget_elink_cb() */
1309 
1310