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