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  *  For details of the HDF libraries, see the HDF Documentation at:
16  *    http://hdfgroup.org/HDF5/doc/
17  *
18  */
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif /* __cplusplus */
23 
24 #include <jni.h>
25 #include <stdlib.h>
26 #include "hdf5.h"
27 #include "h5jni.h"
28 #include "h5lImp.h"
29 
30 /*
31  * Pointer to the JNI's Virtual Machine; used for callback functions.
32  */
33 extern JavaVM *jvm;
34 
35 typedef struct _cb_wrapper {
36     jobject visit_callback;
37     jobject op_data;
38 } cb_wrapper;
39 
40 /********************/
41 /* Local Prototypes */
42 /********************/
43 
44 static herr_t H5L_iterate_cb(hid_t g_id, const char *name, const H5L_info_t *info, void *cb_data);
45 
46 /*
47  * Class:     hdf_hdf5lib_H5
48  * Method:    H5Lcopy
49  * Signature: (JLjava/lang/String;JLjava/lang/String;JJ)V
50  */
51 JNIEXPORT void JNICALL
Java_hdf_hdf5lib_H5_H5Lcopy(JNIEnv * env,jclass clss,jlong cur_loc_id,jstring cur_name,jlong dst_loc_id,jstring dst_name,jlong create_id,jlong access_id)52 Java_hdf_hdf5lib_H5_H5Lcopy
53     (JNIEnv *env, jclass clss, jlong cur_loc_id, jstring cur_name, jlong dst_loc_id,
54         jstring dst_name, jlong create_id, jlong access_id)
55 {
56     const char *lCurName = NULL;
57     const char *lDstName = NULL;
58     herr_t      status = FAIL;
59 
60     UNUSED(clss);
61 
62     if (NULL == cur_name)
63         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lcopy: src name is NULL");
64     if (NULL == dst_name)
65         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lcopy: dest name is NULL");
66 
67     PIN_JAVA_STRING(ENVONLY, cur_name, lCurName, NULL, "H5Lcopy: src name not pinned");
68     PIN_JAVA_STRING(ENVONLY, dst_name, lDstName, NULL, "H5Lcopy: dest name not pinned");
69 
70     if ((status = H5Lcopy((hid_t)cur_loc_id, lCurName, (hid_t)dst_loc_id, lDstName, (hid_t)create_id, (hid_t)access_id)) < 0)
71         H5_LIBRARY_ERROR(ENVONLY);
72 
73 done:
74     if (lDstName)
75         UNPIN_JAVA_STRING(ENVONLY, dst_name, lDstName);
76     if (lCurName)
77         UNPIN_JAVA_STRING(ENVONLY, cur_name, lCurName);
78 } /* end Java_hdf_hdf5lib_H5_H5Lcopy */
79 
80 /*
81  * Class:     hdf_hdf5lib_H5
82  * Method:    H5Lcreate_external
83  * Signature: (Ljava/lang/String;Ljava/lang/String;JLjava/lang/String;JJ)V
84  */
85 JNIEXPORT void JNICALL
Java_hdf_hdf5lib_H5_H5Lcreate_1external(JNIEnv * env,jclass clss,jstring file_name,jstring cur_name,jlong dst_loc_id,jstring dst_name,jlong create_id,jlong access_id)86 Java_hdf_hdf5lib_H5_H5Lcreate_1external
87     (JNIEnv *env, jclass clss, jstring file_name, jstring cur_name,
88         jlong dst_loc_id, jstring dst_name, jlong create_id, jlong access_id)
89 {
90     const char *lFileName = NULL;
91     const char *lCurName = NULL;
92     const char *lDstName = NULL;
93     herr_t      status = FAIL;
94 
95     UNUSED(clss);
96 
97     if (NULL == file_name)
98         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lcreate_external: file name is NULL");
99     if (NULL == cur_name)
100         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lcreate_external: object name is NULL");
101     if (NULL == dst_name)
102         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lcreate_external: link name is NULL");
103 
104     PIN_JAVA_STRING(ENVONLY, file_name, lFileName, NULL, "H5Lcreate_external: file name not pinned");
105     PIN_JAVA_STRING(ENVONLY, cur_name, lCurName, NULL, "H5Lcreate_external: object name not pinned");
106     PIN_JAVA_STRING(ENVONLY, dst_name, lDstName, NULL, "H5Lcreate_external: link name not pinned");
107 
108     if ((status = H5Lcreate_external(lFileName, lCurName, (hid_t)dst_loc_id, lDstName, (hid_t)create_id, (hid_t)access_id)) < 0)
109         H5_LIBRARY_ERROR(ENVONLY);
110 
111 done:
112     if (lDstName)
113         UNPIN_JAVA_STRING(ENVONLY, dst_name, lDstName);
114     if (lCurName)
115         UNPIN_JAVA_STRING(ENVONLY, cur_name, lCurName);
116     if (lFileName)
117         UNPIN_JAVA_STRING(ENVONLY, file_name, lFileName);
118 } /* end Java_hdf_hdf5lib_H5_H5Lcreate_1external */
119 
120 /*
121  * Class:     hdf_hdf5lib_H5
122  * Method:    H5Lcreate_hard
123  * Signature: (JLjava/lang/String;JLjava/lang/String;JJ)V
124  */
125 JNIEXPORT void JNICALL
Java_hdf_hdf5lib_H5_H5Lcreate_1hard(JNIEnv * env,jclass clss,jlong cur_loc_id,jstring cur_name,jlong dst_loc_id,jstring dst_name,jlong create_id,jlong access_id)126 Java_hdf_hdf5lib_H5_H5Lcreate_1hard
127     (JNIEnv *env, jclass clss, jlong cur_loc_id, jstring cur_name,
128         jlong dst_loc_id, jstring dst_name, jlong create_id, jlong access_id)
129 {
130     const char *lCurName = NULL;
131     const char *lDstName = NULL;
132     herr_t      status = FAIL;
133 
134     UNUSED(clss);
135 
136     if (NULL == cur_name)
137         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lcreate_hard: object name is NULL");
138     if (NULL == dst_name)
139         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lcreate_hard: link name is NULL");
140 
141     PIN_JAVA_STRING(ENVONLY, cur_name, lCurName, NULL, "H5Lcreate_hard: object name not pinned");
142     PIN_JAVA_STRING(ENVONLY, dst_name, lDstName, NULL, "H5Lcreate_hard: link name not pinned");
143 
144     if ((status = H5Lcreate_hard((hid_t)cur_loc_id, lCurName, (hid_t)dst_loc_id, lDstName, (hid_t)create_id, (hid_t)access_id)) < 0)
145         H5_LIBRARY_ERROR(ENVONLY);
146 
147 done:
148     if (lDstName)
149         UNPIN_JAVA_STRING(ENVONLY, dst_name, lDstName);
150     if (lCurName)
151         UNPIN_JAVA_STRING(ENVONLY, cur_name, lCurName);
152 } /* end Java_hdf_hdf5lib_H5_H5Lcreate_1hard */
153 
154 /*
155  * Class:     hdf_hdf5lib_H5
156  * Method:    H5Lcreate_soft
157  * Signature: (Ljava/lang/String;JLjava/lang/String;JJ)V
158  */
159 JNIEXPORT void JNICALL
Java_hdf_hdf5lib_H5_H5Lcreate_1soft(JNIEnv * env,jclass clss,jstring cur_name,jlong dst_loc_id,jstring dst_name,jlong create_id,jlong access_id)160 Java_hdf_hdf5lib_H5_H5Lcreate_1soft
161     (JNIEnv *env, jclass clss, jstring cur_name, jlong dst_loc_id,
162         jstring dst_name, jlong create_id, jlong access_id)
163 {
164     const char *linkTarget = NULL;
165     const char *linkName = NULL;
166     herr_t      status = FAIL;
167 
168     UNUSED(clss);
169 
170     if (NULL == cur_name)
171         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lcreate_soft: link target is NULL");
172     if (NULL == dst_name)
173         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lcreate_soft: link name is NULL");
174 
175     PIN_JAVA_STRING(ENVONLY, cur_name, linkTarget, NULL, "H5Lcreate_soft: link target not pinned");
176     PIN_JAVA_STRING(ENVONLY, dst_name, linkName, NULL, "H5Lcreate_soft: link name not pinned");
177 
178     if ((status = H5Lcreate_soft(linkTarget, (hid_t)dst_loc_id, linkName, (hid_t)create_id, (hid_t)access_id)) < 0)
179         H5_LIBRARY_ERROR(ENVONLY);
180 
181 done:
182     if (linkName)
183         UNPIN_JAVA_STRING(ENVONLY, dst_name, linkName);
184     if (linkTarget)
185         UNPIN_JAVA_STRING(ENVONLY, cur_name, linkTarget);
186 } /* end Java_hdf_hdf5lib_H5_H5Lcreate_1soft */
187 
188 /*
189  * Class:     hdf_hdf5lib_H5
190  * Method:    H5Ldelete
191  * Signature: (JLjava/lang/String;J)V
192  */
193 JNIEXPORT void JNICALL
Java_hdf_hdf5lib_H5_H5Ldelete(JNIEnv * env,jclass clss,jlong loc_id,jstring name,jlong access_id)194 Java_hdf_hdf5lib_H5_H5Ldelete
195     (JNIEnv *env, jclass clss, jlong loc_id, jstring name, jlong access_id)
196 {
197     const char *linkName = NULL;
198     herr_t      status = FAIL;
199 
200     UNUSED(clss);
201 
202     if (NULL == name)
203         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Ldelete: link name is NULL");
204 
205     PIN_JAVA_STRING(ENVONLY, name, linkName, NULL, "H5Ldelete: link name not pinned");
206 
207     if ((status = H5Ldelete((hid_t)loc_id, linkName, (hid_t)access_id)) < 0)
208         H5_LIBRARY_ERROR(ENVONLY);
209 
210 done:
211     if (linkName)
212         UNPIN_JAVA_STRING(ENVONLY, name, linkName);
213 } /* end Java_hdf_hdf5lib_H5_H5Ldelete */
214 
215 /*
216  * Class:     hdf_hdf5lib_H5
217  * Method:    H5Ldelete_by_idx
218  * Signature: (JLjava/lang/String;IIJJ)V
219  */
220 JNIEXPORT void JNICALL
Java_hdf_hdf5lib_H5_H5Ldelete_1by_1idx(JNIEnv * env,jclass clss,jlong loc_id,jstring name,jint index_field,jint order,jlong link_n,jlong access_id)221 Java_hdf_hdf5lib_H5_H5Ldelete_1by_1idx
222     (JNIEnv *env, jclass clss, jlong loc_id, jstring name,
223         jint index_field, jint order, jlong link_n, jlong access_id)
224 {
225     const char *groupName = NULL;
226     hsize_t     n = (hsize_t)link_n;
227     herr_t      status = FAIL;
228 
229     UNUSED(clss);
230 
231     if (NULL == name)
232         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Ldelete_by_idx: group name is NULL");
233 
234     PIN_JAVA_STRING(ENVONLY, name, groupName, NULL, "H5Ldelete_by_idx: group name not pinned");
235 
236     if ((status = H5Ldelete_by_idx((hid_t)loc_id, groupName, (H5_index_t)index_field, (H5_iter_order_t)order, n, (hid_t)access_id)) < 0)
237         H5_LIBRARY_ERROR(ENVONLY);
238 
239 done:
240     if (groupName)
241         UNPIN_JAVA_STRING(ENVONLY, name, groupName);
242 } /* end Java_hdf_hdf5lib_H5_H5Ldelete_1by_1idx */
243 
244 /*
245  * Class:     hdf_hdf5lib_H5
246  * Method:    H5Lexists
247  * Signature: (JLjava/lang/String;J)Z
248  */
249 JNIEXPORT jboolean JNICALL
Java_hdf_hdf5lib_H5_H5Lexists(JNIEnv * env,jclass clss,jlong loc_id,jstring name,jlong access_id)250 Java_hdf_hdf5lib_H5_H5Lexists
251     (JNIEnv *env, jclass clss, jlong loc_id, jstring name, jlong access_id)
252 {
253     const char *linkName = NULL;
254     htri_t      bval = JNI_FALSE;
255 
256     UNUSED(clss);
257 
258     if (NULL == name)
259         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lexists: link name is NULL");
260 
261     PIN_JAVA_STRING(ENVONLY, name, linkName, NULL, "H5Lexists: link name not pinned");
262 
263     if ((bval = H5Lexists((hid_t)loc_id, linkName, (hid_t)access_id)) < 0)
264         H5_LIBRARY_ERROR(ENVONLY);
265 
266     bval = (bval > 0) ? JNI_TRUE : JNI_FALSE;
267 
268 done:
269     if (linkName)
270         UNPIN_JAVA_STRING(ENVONLY, name, linkName);
271 
272     return (jboolean)bval;
273 } /* end Java_hdf_hdf5lib_H5_H5Lexists */
274 
275 /*
276  * Class:     hdf_hdf5lib_H5
277  * Method:    H5Lget_info
278  * Signature: (JLjava/lang/String;J)Lhdf/hdf5lib/structs/H5L_info_t;
279  */
280 JNIEXPORT jobject JNICALL
Java_hdf_hdf5lib_H5_H5Lget_1info(JNIEnv * env,jclass clss,jlong loc_id,jstring name,jlong access_id)281 Java_hdf_hdf5lib_H5_H5Lget_1info
282     (JNIEnv *env, jclass clss, jlong loc_id, jstring name, jlong access_id)
283 {
284     H5L_info_t  infobuf;
285     const char *linkName = NULL;
286     jvalue      args[5];
287     herr_t      status = FAIL;
288     jobject     ret_obj = NULL;
289 
290     UNUSED(clss);
291 
292     if (NULL == name)
293         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lget_info: link name is NULL");
294 
295     PIN_JAVA_STRING(ENVONLY, name, linkName, NULL, "H5Lget_info: link name not pinned");
296 
297     if ((status = H5Lget_info((hid_t)loc_id, linkName, &infobuf, (hid_t)access_id)) < 0)
298         H5_LIBRARY_ERROR(ENVONLY);
299 
300     args[0].i = infobuf.type;
301     args[1].z = infobuf.corder_valid;
302     args[2].j = infobuf.corder;
303     args[3].i = infobuf.cset;
304     args[4].j = (infobuf.type == H5L_TYPE_HARD) ? (jlong) infobuf.u.address : (jlong) infobuf.u.val_size;
305 
306     CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5L_info_t", "(IZJIJ)V", args, ret_obj);
307 
308 done:
309     if (linkName)
310         UNPIN_JAVA_STRING(ENVONLY, name, linkName);
311 
312     return ret_obj;
313 } /* end Java_hdf_hdf5lib_H5_H5Lget_1info */
314 
315 /*
316  * Class:     hdf_hdf5lib_H5
317  * Method:    H5Lget_info_by_idx
318  * Signature: (JLjava/lang/String;IIJJ)Lhdf/hdf5lib/structs/H5L_info_t;
319  */
320 JNIEXPORT jobject JNICALL
Java_hdf_hdf5lib_H5_H5Lget_1info_1by_1idx(JNIEnv * env,jclass clss,jlong loc_id,jstring name,jint index_field,jint order,jlong link_n,jlong access_id)321 Java_hdf_hdf5lib_H5_H5Lget_1info_1by_1idx
322     (JNIEnv *env, jclass clss, jlong loc_id, jstring name,
323         jint index_field, jint order, jlong link_n, jlong access_id)
324 {
325     H5L_info_t  infobuf;
326     const char *groupName = NULL;
327     jvalue      args[5];
328     herr_t      status = FAIL;
329     jobject     ret_obj = NULL;
330 
331     UNUSED(clss);
332 
333     if (NULL == name)
334         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lget_info_by_idx: group name is NULL");
335 
336     PIN_JAVA_STRING(ENVONLY, name, groupName, NULL, "H5Lget_info_by_idx: group name not pinned");
337 
338     if ((status = H5Lget_info_by_idx((hid_t)loc_id, groupName, (H5_index_t)index_field, (H5_iter_order_t)order, (hsize_t)link_n, &infobuf, (hid_t)access_id)) < 0)
339         H5_LIBRARY_ERROR(ENVONLY);
340 
341     args[0].i = infobuf.type;
342     args[1].z = infobuf.corder_valid;
343     args[2].j = infobuf.corder;
344     args[3].i = infobuf.cset;
345     args[4].j = (infobuf.type == H5L_TYPE_HARD) ? (jlong) infobuf.u.address : (jlong) infobuf.u.val_size;
346 
347     CALL_CONSTRUCTOR(ENVONLY, "hdf/hdf5lib/structs/H5L_info_t", "(IZJIJ)V", args, ret_obj);
348 
349 done:
350     if (groupName)
351         UNPIN_JAVA_STRING(ENVONLY, name, groupName);
352 
353     return ret_obj;
354 } /* end Java_hdf_hdf5lib_H5_H5Lget_1info_1by_1idx */
355 
356 /*
357  * Class:     hdf_hdf5lib_H5
358  * Method:    H5Lget_name_by_idx
359  * Signature: (JLjava/lang/String;IIJJ)Ljava/lang/String;
360  */
361 JNIEXPORT jstring JNICALL
Java_hdf_hdf5lib_H5_H5Lget_1name_1by_1idx(JNIEnv * env,jclass clss,jlong loc_id,jstring name,jint index_field,jint order,jlong link_n,jlong access_id)362 Java_hdf_hdf5lib_H5_H5Lget_1name_1by_1idx
363     (JNIEnv *env, jclass clss, jlong loc_id, jstring name,
364         jint index_field, jint order, jlong link_n, jlong access_id)
365 {
366     const char *groupName = NULL;
367     jstring     str = NULL;
368     ssize_t     status_size = -1;
369     char       *linkName = NULL;
370 
371     UNUSED(clss);
372 
373     if (NULL == name)
374         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lget_name_by_idx: group name is NULL");
375 
376     PIN_JAVA_STRING(ENVONLY, name, groupName, NULL, "H5Lget_name_by_idx: group name not pinned");
377 
378     /* Get the length of the link name */
379     if ((status_size = H5Lget_name_by_idx((hid_t)loc_id, groupName, (H5_index_t)index_field, (H5_iter_order_t)order, (hsize_t)link_n, (char *)NULL, (size_t)0, H5P_DEFAULT)) < 0)
380         H5_LIBRARY_ERROR(ENVONLY);
381 
382     /* add extra space for the null terminator */
383     if (NULL == (linkName = (char *) HDmalloc(sizeof(char) * (size_t)status_size + 1)))
384         H5_JNI_FATAL_ERROR(ENVONLY, "H5Lget_name_by_idx: failed to allocate buffer for link name");
385 
386     if ((H5Lget_name_by_idx((hid_t)loc_id, groupName, (H5_index_t)index_field, (H5_iter_order_t)order, (hsize_t)link_n, (char *)linkName, (size_t)status_size + 1, (hid_t)access_id)) < 0)
387         H5_LIBRARY_ERROR(ENVONLY);
388     linkName[status_size] = '\0';
389 
390     if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, linkName)))
391         CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
392 
393 done:
394     if (linkName)
395         HDfree(linkName);
396     if (groupName)
397         UNPIN_JAVA_STRING(ENVONLY, name, groupName);
398 
399     return str;
400 } /* end Java_hdf_hdf5lib_H5_H5Lget_1name_1by_1idx */
401 
402 /*
403  * Class:     hdf_hdf5lib_H5
404  * Method:    H5Lget_value
405  * Signature: (JLjava/lang/String;[Ljava/lang/String;J)I
406  */
407 JNIEXPORT jint JNICALL
Java_hdf_hdf5lib_H5_H5Lget_1value(JNIEnv * env,jclass clss,jlong loc_id,jstring name,jobjectArray link_value,jlong access_id)408 Java_hdf_hdf5lib_H5_H5Lget_1value
409     (JNIEnv *env, jclass clss, jlong loc_id, jstring name, jobjectArray link_value, jlong access_id)
410 {
411     H5L_info_t  infobuf;
412     const char *file_name = NULL;
413     const char *obj_name = NULL;
414     const char *linkName = NULL;
415     jstring     str;
416     herr_t      status;
417     char       *linkValue = NULL;
418 
419     UNUSED(clss);
420 
421     if (NULL == name)
422         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lget_value: link name is NULL");
423 
424     infobuf.type = H5L_TYPE_ERROR;
425 
426     PIN_JAVA_STRING(ENVONLY, name, linkName, NULL, "H5Lget_value: link name not pinned");
427 
428     /* Get the length of the link value */
429     if ((status = H5Lget_info((hid_t)loc_id, linkName, &infobuf, H5P_DEFAULT)) < 0)
430         H5_LIBRARY_ERROR(ENVONLY);
431 
432     if (H5L_TYPE_HARD == infobuf.type)
433         H5_JNI_FATAL_ERROR(ENVONLY, "H5Lget_val: hard links are unsupported");
434 
435     if (NULL == (linkValue = (char *) HDmalloc(sizeof(char) * infobuf.u.val_size + 1)))
436         H5_JNI_FATAL_ERROR(ENVONLY, "H5Lget_val: failed to allocate buffer for link value");
437 
438     if ((status = H5Lget_val((hid_t)loc_id, linkName, (void *)linkValue, infobuf.u.val_size + 1, (hid_t)access_id)) < 0)
439         H5_LIBRARY_ERROR(ENVONLY);
440     linkValue[infobuf.u.val_size] = '\0';
441 
442     switch (infobuf.type) {
443         case H5L_TYPE_SOFT:
444         {
445             if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, linkValue)))
446                 CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
447 
448             ENVPTR->SetObjectArrayElement(ENVONLY, link_value, 0, str);
449             CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
450 
451             break;
452         }
453 
454         case H5L_TYPE_EXTERNAL:
455         {
456             if ((status = H5Lunpack_elink_val(linkValue, (size_t)infobuf.u.val_size, (unsigned *)NULL, &file_name, &obj_name)) < 0)
457                 H5_LIBRARY_ERROR(ENVONLY);
458 
459             if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, obj_name)))
460                 CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
461 
462             ENVPTR->SetObjectArrayElement(ENVONLY, link_value, 0, str);
463             CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
464 
465             if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, file_name)))
466                 CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
467 
468             ENVPTR->SetObjectArrayElement(ENVONLY, link_value, 1, str);
469             CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
470 
471             break;
472         }
473 
474         case H5L_TYPE_ERROR:
475         case H5L_TYPE_MAX:
476         case H5L_TYPE_HARD:
477         default:
478             H5_JNI_FATAL_ERROR(ENVONLY, "H5Lget_val: invalid link type");
479             break;
480     }
481 
482 done:
483     if (linkValue)
484         HDfree(linkValue);
485     if (linkName)
486         UNPIN_JAVA_STRING(ENVONLY, name, linkName);
487 
488     return infobuf.type;
489 } /* end Java_hdf_hdf5lib_H5_H5Lget_1val */
490 
491 /*
492  * Class:     hdf_hdf5lib_H5
493  * Method:    H5Lget_value_by_idx
494  * Signature: (JLjava/lang/String;IIJ[Ljava/lang/String;J)I
495  */
496 JNIEXPORT jint JNICALL
Java_hdf_hdf5lib_H5_H5Lget_1value_1by_1idx(JNIEnv * env,jclass clss,jlong loc_id,jstring name,jint index_field,jint order,jlong link_n,jobjectArray link_value,jlong access_id)497 Java_hdf_hdf5lib_H5_H5Lget_1value_1by_1idx
498     (JNIEnv *env, jclass clss, jlong loc_id, jstring name, jint index_field, jint order,
499         jlong link_n, jobjectArray link_value, jlong access_id)
500 {
501     H5L_info_t  infobuf;
502     const char *file_name = NULL;
503     const char *obj_name = NULL;
504     const char *grpName = NULL;
505     jstring     str;
506     herr_t      status;
507     void       *linkValue = NULL;
508 
509     UNUSED(clss);
510 
511     infobuf.type = H5L_TYPE_ERROR;
512 
513     if (NULL == name)
514         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lget_val_by_idx: group name is NULL");
515 
516     PIN_JAVA_STRING(ENVONLY, name, grpName, NULL, "H5Lget_val_by_idx: group name not pinned");
517 
518     /* Get the length of the link value */
519     if ((status = H5Lget_info_by_idx((hid_t)loc_id, grpName, (H5_index_t)index_field, (H5_iter_order_t)order, (hsize_t)link_n, &infobuf, (hid_t)access_id)) < 0)
520         H5_LIBRARY_ERROR(ENVONLY);
521 
522     if (H5L_TYPE_HARD == infobuf.type)
523         H5_JNI_FATAL_ERROR(ENVONLY, "H5Lget_val_by_idx: hard links are unsupported")
524 
525     if (!infobuf.u.val_size)
526         H5_LIBRARY_ERROR(ENVONLY);
527 
528     if (NULL == (linkValue = (void *) HDmalloc(infobuf.u.val_size + 1)))
529         H5_JNI_FATAL_ERROR(ENVONLY, "H5Lget_val_by_idx: failed to allocate buffer for link value");
530 
531     if ((status = H5Lget_val_by_idx((hid_t)loc_id, grpName, (H5_index_t)index_field, (H5_iter_order_t)order, (hsize_t)link_n, (void *)linkValue, infobuf.u.val_size + 1, (hid_t)access_id)) < 0)
532         H5_LIBRARY_ERROR(ENVONLY);
533     ((char *) linkValue)[infobuf.u.val_size] = '\0';
534 
535     switch (infobuf.type) {
536         case H5L_TYPE_SOFT:
537         {
538             if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, (char *)linkValue)))
539                 CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
540 
541             ENVPTR->SetObjectArrayElement(ENVONLY, link_value, 0, str);
542             CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
543 
544             break;
545         }
546 
547         case H5L_TYPE_EXTERNAL:
548         {
549             if ((status = H5Lunpack_elink_val((char *)linkValue, (size_t)infobuf.u.val_size, (unsigned *)NULL, (const char **)&file_name, (const char**)&obj_name)) < 0)
550                 H5_LIBRARY_ERROR(ENVONLY);
551 
552             if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, obj_name)))
553                 CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
554 
555             ENVPTR->SetObjectArrayElement(ENVONLY, link_value, 0, str);
556             CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
557 
558             if (NULL == (str = ENVPTR->NewStringUTF(ENVONLY, file_name)))
559                 CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
560 
561             ENVPTR->SetObjectArrayElement(ENVONLY, link_value, 1, str);
562             CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
563 
564             break;
565         }
566 
567         case H5L_TYPE_ERROR:
568         case H5L_TYPE_MAX:
569         case H5L_TYPE_HARD:
570         default:
571             H5_JNI_FATAL_ERROR(ENVONLY, "H5Lget_val_by_idx: invalid link type");
572             break;
573     }
574 
575 done:
576     if (linkValue)
577         HDfree(linkValue);
578     if (grpName)
579         UNPIN_JAVA_STRING(ENVONLY, name, grpName);
580 
581     return infobuf.type;
582 } /* end Java_hdf_hdf5lib_H5_H5Lget_1val_1by_1idx */
583 
584 /*
585  * Class:     hdf_hdf5lib_H5
586  * Method:    H5Lmove
587  * Signature: (JLjava/lang/String;JLjava/lang/String;JJ)V
588  */
589 JNIEXPORT void JNICALL
Java_hdf_hdf5lib_H5_H5Lmove(JNIEnv * env,jclass clss,jlong cur_loc_id,jstring cur_name,jlong dst_loc_id,jstring dst_name,jlong create_id,jlong access_id)590 Java_hdf_hdf5lib_H5_H5Lmove
591     (JNIEnv *env, jclass clss, jlong cur_loc_id, jstring cur_name,
592         jlong dst_loc_id, jstring dst_name, jlong create_id, jlong access_id)
593 {
594     const char *lCurName = NULL;
595     const char *lDstName = NULL;
596     herr_t      status = FAIL;
597 
598     UNUSED(clss);
599 
600     if (NULL == cur_name)
601         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lmove: src name is NULL");
602     if (NULL == dst_name)
603         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lmove: dest name is NULL");
604 
605     PIN_JAVA_STRING(ENVONLY, cur_name, lCurName, NULL, "H5Lmove: src name not pinned");
606     PIN_JAVA_STRING(ENVONLY, dst_name, lDstName, NULL, "H5Lmove: dest name not pinned");
607 
608     if ((status = H5Lmove((hid_t)cur_loc_id, lCurName, (hid_t)dst_loc_id, lDstName, (hid_t)create_id, (hid_t)access_id)) < 0)
609         H5_LIBRARY_ERROR(ENVONLY);
610 
611 done:
612     if (lDstName)
613         UNPIN_JAVA_STRING(ENVONLY, dst_name, lDstName);
614     if (lCurName)
615         UNPIN_JAVA_STRING(ENVONLY, cur_name, lCurName);
616 } /* end Java_hdf_hdf5lib_H5_H5Lmove */
617 
618 static herr_t
H5L_iterate_cb(hid_t g_id,const char * name,const H5L_info_t * info,void * cb_data)619 H5L_iterate_cb
620     (hid_t g_id, const char *name, const H5L_info_t *info, void *cb_data)
621 {
622     cb_wrapper *wrapper = (cb_wrapper *)cb_data;
623     jmethodID   constructor, mid;
624     jobject     cb_info_t = NULL;
625     jobject     visit_callback = wrapper->visit_callback;
626     jstring     str;
627     JNIEnv     *cbenv = NULL;
628     jclass      cls;
629     jvalue      args[5];
630     void       *op_data = (void *)wrapper->op_data;
631     jint        status = -1;
632 
633     if (JVMPTR->AttachCurrentThread(JVMPAR, (void **)&cbenv, NULL) < 0) {
634         CHECK_JNI_EXCEPTION(CBENVONLY, JNI_TRUE);
635         H5_JNI_FATAL_ERROR(CBENVONLY, "H5L_iterate_cb: failed to attach current thread to JVM");
636     }
637 
638     if (NULL == (cls = CBENVPTR->GetObjectClass(CBENVONLY, visit_callback)))
639         CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE);
640 
641     if (NULL == (mid = CBENVPTR->GetMethodID(CBENVONLY, cls, "callback", "(JLjava/lang/String;Lhdf/hdf5lib/structs/H5L_info_t;Lhdf/hdf5lib/callbacks/H5L_iterate_t;)I")))
642         CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE);
643 
644     if (NULL == (str = CBENVPTR->NewStringUTF(CBENVONLY, name)))
645         CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE);
646 
647     args[0].i = info->type;
648     args[1].z = info->corder_valid;
649     args[2].j = info->corder;
650     args[3].i = info->cset;
651     args[4].j = (info->type == H5L_TYPE_HARD) ? (jlong)info->u.address : (jlong)info->u.val_size;
652 
653     /* Get a reference to your class if you don't have it already */
654     if (NULL == (cls = CBENVPTR->FindClass(CBENVONLY, "hdf/hdf5lib/structs/H5L_info_t")))
655         CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE);
656 
657     /* Get a reference to the constructor; the name is <init> */
658     if (NULL == (constructor = CBENVPTR->GetMethodID(CBENVONLY, cls, "<init>", "(IZJIJ)V")))
659         CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE);
660 
661     if (NULL == (cb_info_t = CBENVPTR->NewObjectA(CBENVONLY, cls, constructor, args))) {
662         HDprintf("FATAL ERROR: hdf/hdf5lib/structs/H5L_info_t: Creation failed\n");
663         CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE);
664     }
665 
666     status = CBENVPTR->CallIntMethod(CBENVONLY, visit_callback, mid, g_id, str, cb_info_t, op_data);
667     CHECK_JNI_EXCEPTION(CBENVONLY, JNI_FALSE);
668 
669 done:
670     if (cbenv)
671         JVMPTR->DetachCurrentThread(JVMPAR);
672 
673     return (herr_t)status;
674 } /* end H5L_iterate_cb */
675 
676 /*
677  * Class:     hdf_hdf5lib_H5
678  * Method:    H5Lvisit
679  * Signature: (JIILjava/lang/Object;Ljava/lang/Object;)I
680  */
681 JNIEXPORT jint JNICALL
Java_hdf_hdf5lib_H5_H5Lvisit(JNIEnv * env,jclass clss,jlong grp_id,jint idx_type,jint order,jobject callback_op,jobject op_data)682 Java_hdf_hdf5lib_H5_H5Lvisit
683     (JNIEnv *env, jclass clss, jlong grp_id, jint idx_type, jint order,
684         jobject callback_op, jobject op_data)
685 {
686     cb_wrapper wrapper = { callback_op, op_data };
687     herr_t     status = FAIL;
688 
689     UNUSED(clss);
690 
691     ENVPTR->GetJavaVM(ENVONLY, &jvm);
692     CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
693 
694     if (NULL == op_data)
695         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lvisit: op_data is NULL");
696     if (NULL == callback_op)
697         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lvisit: callback_op is NULL");
698 
699     if ((status = H5Lvisit((hid_t)grp_id, (H5_index_t)idx_type, (H5_iter_order_t)order, (H5L_iterate_t)H5L_iterate_cb, (void *)&wrapper)) < 0)
700         H5_LIBRARY_ERROR(ENVONLY);
701 
702 done:
703     return status;
704 } /* end Java_hdf_hdf5lib_H5_H5Lvisit */
705 
706 /*
707  * Class:     hdf_hdf5lib_H5
708  * Method:    H5Lvisit_by_name
709  * Signature: (JLjava/lang/String;IILjava/lang/Object;Ljava/lang/Object;J)I
710  */
711 JNIEXPORT jint JNICALL
Java_hdf_hdf5lib_H5_H5Lvisit_1by_1name(JNIEnv * env,jclass clss,jlong grp_id,jstring name,jint idx_type,jint order,jobject callback_op,jobject op_data,jlong access_id)712 Java_hdf_hdf5lib_H5_H5Lvisit_1by_1name
713     (JNIEnv *env, jclass clss, jlong grp_id, jstring name, jint idx_type, jint order,
714         jobject callback_op, jobject op_data, jlong access_id)
715 {
716     cb_wrapper  wrapper = { callback_op, op_data };
717     const char *grpName = NULL;
718     herr_t      status = FAIL;
719 
720     UNUSED(clss);
721 
722     ENVPTR->GetJavaVM(ENVONLY, &jvm);
723     CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
724 
725     if (NULL == op_data)
726         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lvisit_by_name: op_data is NULL");
727     if (NULL == callback_op)
728         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lvisit_by_name: callback_op is NULL");
729     if (NULL == name)
730         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Lvisit_by_name: group name is NULL");
731 
732     PIN_JAVA_STRING(ENVONLY, name, grpName, NULL, "H5Lvisit_by_name: group name not pinned");
733 
734     if ((status = H5Lvisit_by_name((hid_t)grp_id, grpName, (H5_index_t)idx_type, (H5_iter_order_t)order, (H5L_iterate_t)H5L_iterate_cb, (void *)&wrapper, (hid_t)access_id)) < 0)
735         H5_LIBRARY_ERROR(ENVONLY);
736 
737 done:
738     if (grpName)
739         UNPIN_JAVA_STRING(ENVONLY, name, grpName);
740 
741     return status;
742 } /* end Java_hdf_hdf5lib_H5_H5Lvisit_1by_1name */
743 
744 /*
745  * Class:     hdf_hdf5lib_H5
746  * Method:    H5Literate
747  * Signature: (JIIJLjava/lang/Object;Ljava/lang/Object;)I
748  */
749 JNIEXPORT jint JNICALL
Java_hdf_hdf5lib_H5_H5Literate(JNIEnv * env,jclass clss,jlong grp_id,jint idx_type,jint order,jlong idx,jobject callback_op,jobject op_data)750 Java_hdf_hdf5lib_H5_H5Literate
751     (JNIEnv *env, jclass clss, jlong grp_id, jint idx_type, jint order,
752         jlong idx, jobject callback_op, jobject op_data)
753 {
754     cb_wrapper wrapper = { callback_op, op_data };
755     hsize_t    start_idx = (hsize_t)idx;
756     herr_t     status = FAIL;
757 
758     UNUSED(clss);
759 
760     ENVPTR->GetJavaVM(ENVONLY, &jvm);
761     CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
762 
763     if (NULL == op_data)
764         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Literate: op_data is NULL");
765     if (NULL == callback_op)
766         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Literate: callback_op is NULL");
767 
768     if ((status = H5Literate((hid_t)grp_id, (H5_index_t)idx_type, (H5_iter_order_t)order, (hsize_t *)&start_idx, (H5L_iterate_t)H5L_iterate_cb, (void *)&wrapper)) < 0)
769         H5_LIBRARY_ERROR(ENVONLY);
770 
771 done:
772     return status;
773 } /* end Java_hdf_hdf5lib_H5_H5Literate */
774 
775 /*
776  * Class:     hdf_hdf5lib_H5
777  * Method:    H5Literate_by_name
778  * Signature: (JLjava/lang/String;IIJLjava/lang/Object;Ljava/lang/Object;J)I
779  */
780 JNIEXPORT jint JNICALL
Java_hdf_hdf5lib_H5_H5Literate_1by_1name(JNIEnv * env,jclass clss,jlong grp_id,jstring name,jint idx_type,jint order,jlong idx,jobject callback_op,jobject op_data,jlong access_id)781 Java_hdf_hdf5lib_H5_H5Literate_1by_1name
782     (JNIEnv *env, jclass clss, jlong grp_id, jstring name, jint idx_type, jint order,
783         jlong idx, jobject callback_op, jobject op_data, jlong access_id)
784 {
785     cb_wrapper  wrapper = { callback_op, op_data };
786     const char *groupName = NULL;
787     hsize_t     start_idx = (hsize_t)idx;
788     herr_t      status = FAIL;
789 
790     UNUSED(clss);
791 
792     ENVPTR->GetJavaVM(ENVONLY, &jvm);
793     CHECK_JNI_EXCEPTION(ENVONLY, JNI_FALSE);
794 
795     if (NULL == op_data)
796         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Literate_by_name: op_data is NULL");
797     if (NULL == callback_op)
798         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Literate_by_name: callback_op is NULL");
799     if (NULL == name)
800         H5_NULL_ARGUMENT_ERROR(ENVONLY, "H5Literate_by_name: group name is NULL");
801 
802     PIN_JAVA_STRING(ENVONLY, name, groupName, NULL, "H5Literate_by_name: group name not pinned");
803 
804     if ((status = H5Literate_by_name((hid_t)grp_id, groupName, (H5_index_t)idx_type, (H5_iter_order_t)order, (hsize_t*)&start_idx, (H5L_iterate_t)H5L_iterate_cb, (void*)&wrapper, (hid_t)access_id)) < 0)
805         H5_LIBRARY_ERROR(ENVONLY);
806 
807 done:
808     if (groupName)
809         UNPIN_JAVA_STRING(ENVONLY, name, groupName);
810 
811     return status;
812 } /* end Java_hdf_hdf5lib_H5_H5Literate_1by_1name */
813 
814 /*
815  * Class:     hdf_hdf5lib_H5
816  * Method:    H5Lis_registered
817  * Signature: (I)I
818  */
819 JNIEXPORT jint JNICALL
Java_hdf_hdf5lib_H5_H5Lis_1registered(JNIEnv * env,jclass clss,jint link_cls_id)820 Java_hdf_hdf5lib_H5_H5Lis_1registered
821     (JNIEnv *env, jclass clss, jint link_cls_id)
822 {
823     htri_t ret_val = FAIL;
824 
825     UNUSED(clss);
826 
827     if ((ret_val = H5Lis_registered((H5L_type_t)link_cls_id)) < 0)
828         H5_LIBRARY_ERROR(ENVONLY);
829 
830 done:
831     return (int)ret_val;
832 } /* end Java_hdf_hdf5lib_H5_H5Lis_1registered */
833 
834 /*
835  * Class:     hdf_hdf5lib_H5
836  * Method:    H5Lunregister
837  * Signature: (I)V
838  */
839 JNIEXPORT void JNICALL
Java_hdf_hdf5lib_H5_H5Lunregister(JNIEnv * env,jclass clss,jint link_cls_id)840 Java_hdf_hdf5lib_H5_H5Lunregister
841     (JNIEnv *env, jclass clss, jint link_cls_id)
842 {
843     UNUSED(clss);
844 
845     if (H5Lunregister((H5L_type_t)link_cls_id) < 0)
846         H5_LIBRARY_ERROR(ENVONLY);
847 
848 done:
849     return;
850 } /* end Java_hdf_hdf5lib_H5_H5Lunregister */
851 
852 
853 #ifdef __cplusplus
854 } /* end extern "C" */
855 #endif /* __cplusplus */
856