1c4ea6ebe1857e5a388c0b09683c17c0bd6241e3
[vpp.git] / vpp-japi / japi / vppjni_env.c
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include <jni.h>
16
17 #include "vppjni_env.h"
18
19 // Head of the class registration list.
20 static vppjni_class_t *class_head;
21 // Head of the class registration list.
22 static vppjni_field_t *field_head;
23
24 void vppjni_register_class(vppjni_class_t *ptr)
25 {
26     vppjni_class_t **where = &class_head;
27     while (*where != NULL) {
28         where = &((*where)->next);
29     }
30     *where = ptr;
31 }
32
33 void vppjni_register_field(vppjni_field_t *ptr) {
34     vppjni_field_t **where = &field_head;
35     while (*where != NULL) {
36         where = &((*where)->next);
37     }
38     *where = ptr;
39 }
40
41 jobject vppjni_new_object(JNIEnv *env, const vppjni_class_t *ptr, va_list ap) {
42     jobject obj = (*env)->NewObjectV(env, ptr->jclass, ptr->jinit, ap);
43     if ((*env)->ExceptionCheck(env)) {
44         (*env)->ExceptionDescribe(env);
45         return NULL;
46     }
47
48     return obj;
49 }
50
51 int vppjni_init(JNIEnv *env)
52 {
53     vppjni_class_t *cwlk;
54     vppjni_field_t *fwlk;
55
56     for (cwlk = class_head; cwlk != NULL; cwlk = cwlk->next) {
57         jclass cls;
58         jmethodID method;
59
60         cls = (*env)->FindClass(env, cwlk->fqcn);
61         if ((*env)->ExceptionCheck(env)) {
62             (*env)->ExceptionDescribe(env);
63             vppjni_uninit(env);
64             return JNI_ERR;
65         }
66
67         method = (*env)->GetMethodID(env, cls, "<init>", cwlk->init_sig);
68         if ((*env)->ExceptionCheck(env)) {
69             (*env)->ExceptionDescribe(env);
70             vppjni_uninit(env);
71             return JNI_ERR;
72         }
73
74         cwlk->jclass = (*env)->NewGlobalRef(env, cls);
75         if (cwlk->jclass == NULL) {
76             vppjni_uninit(env);
77             return JNI_ERR;
78         }
79         cwlk->jinit = method;
80     }
81
82     for (fwlk = field_head; fwlk != NULL; fwlk = fwlk->next) {
83         fwlk->jfield = (*env)->GetFieldID(env, fwlk->clsref->jclass, fwlk->name, fwlk->type);
84         if ((*env)->ExceptionCheck(env)) {
85             (*env)->ExceptionDescribe(env);
86             vppjni_uninit(env);
87             return JNI_ERR;
88         }
89     }
90
91     return 0;
92 }
93
94 void vppjni_uninit(JNIEnv *env) {
95     vppjni_class_t *cwlk;
96     vppjni_field_t *fwlk;
97
98     for (fwlk = field_head; fwlk != NULL; fwlk = fwlk->next) {
99         fwlk->jfield = NULL;
100     }
101
102     for (cwlk = class_head; cwlk != NULL; cwlk = cwlk->next) {
103         if (cwlk->jclass != NULL ) {
104             (*env)->DeleteGlobalRef(env, cwlk->jclass);
105         }
106
107         cwlk->jclass = NULL;
108         cwlk->jinit = NULL;
109     }
110 }
111